1/* 2 * Name: Main cas file 3 * 4 * Purpose: aMule Statistics 5 * 6 * Author: Pedro de Oliveira <falso@rdk.homeip.net> 7 * 8 * Copyright (c) 2004-2011 Pedro de Oliveira ( falso@rdk.homeip-net ) 9 * 10 * This file is part of aMule. 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License as published by 14 * the Free Software Foundation; either version 2 of the License, or 15 * (at your option) any later version. 16 * 17 * This program is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 * GNU General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the 24 * Free Software Foundation, Inc., 25 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 26 */ 27#include <stdio.h> 28#include <stdlib.h> 29#include <string.h> 30#include <sys/types.h> 31#include <sys/stat.h> 32#include <unistd.h> 33#include <time.h> 34#include <getopt.h> 35 36#include "version.h" 37#include "configfile.h" 38#include "functions.h" 39#include "graphics.h" 40#include "html.h" 41#include "lines.h" 42 43#ifdef HAVE_CONFIG_H 44 #include "config.h" // For HAVE_GETOPT_LONG 45#endif 46 47#ifndef HAVE_GETOPT_LONG 48/* Code from getopt_long.h - getopt_long() for systems that lack it 49 Copyright (c) 2001-2011 Arthur de Jong, GPL 2 and later */ 50# define no_argument 0 51# define required_argument 1 52# define optional_argument 2 53 54struct option { 55 const char *name; 56 int has_arg; 57 int *flag; 58 int val; 59}; 60 61int getopt_long(int argc, 62 char * const argv[], 63 const char *optstring, 64 const struct option *longopts, 65 int *longindex); 66#endif 67 68/* 69 * History: 70 * 71 * ????.??.?? - falso: creation of cas. 72 * ????.??.?? - Jacobo221: Detect connecting state 73 * ????.??.?? - falso: HTML page generation 74 * 2004.08.27 - GonoszTopi: New line handling routines, to cope with lines 75 * longer than 80 characters. Fixes buffer overflow. 76 * 2005.12.10 - fulgas: added kad info support 77 * 2005,12,16 - stefanero: fixed Kad related stuff and some other things 78 */ 79 80static struct option long_options[] = { 81 { "help", no_argument, NULL, 'h' }, 82 { "html", optional_argument, NULL, 'p' }, 83 { "picture", optional_argument, NULL, 'o' }, 84 { "config-dir", required_argument, NULL, 'c' }, 85 { NULL, 0, NULL, 0 } 86}; 87 88void usage(char *myname) 89{ 90 printf (" ___ _ _ ___ c aMule statistics\n" 91 " /'___) /'_` )/',__) by Pedro de Oliveira\n" 92 "( (___ ( (_| |\\__, \\ <falso@rdk.homeip.net>\n" 93 "`\\____)`\\__,_)(____/ Version %s\n\n" 94 95 "Usage: %s [OPTION]\n" 96 "If run without any option prints stats to stdout\n\n" 97 "OPTIONS:\n" 98#ifdef __GD__ 99 "-o, --picture, -P\tWrites the online signature picture\n" 100#endif 101 "-p, --html, -H\t\tHTML Page with stats and picture\n" 102 "-c, --config-dir\tSpecifies a config-dir different from home\n" 103 "-h, --help\t\tThis help you're reading\n", CAS_VERSION, myname); 104} 105 106#ifndef HAVE_GETOPT_LONG 107 108/* Code from getopt_long.c - getopt_long() for systems that lack it 109 Copyright (c) 2001-2011 Arthur de Jong, GPL 2 and later 110 Slightly edited for the sake of clarity by Gaznevada */ 111 112int getopt_long(int argc, 113 char * const argv[], 114 const char *optstring, 115 const struct option *longopts, 116 int *longindex) 117{ 118int i; 119int length; 120if ( (optind > 0) && (optind < argc) && 121 (strncmp(argv[optind],"--",2) == 0) && 122 (argv[optind][2] != '\0') ) { 123 for (i = 0; longopts[i].name != NULL; i++) { 124 length = strlen(longopts[i].name); 125 if (strncmp(argv[optind]+2,longopts[i].name,length) == 0) { 126 if ( (longopts[i].has_arg == no_argument) && (argv[optind][2+length] == '\0') ) { 127 optind++; 128 return longopts[i].val; 129 } 130 else if ( (longopts[i].has_arg == required_argument) && (argv[optind][2+length] == '=') ) { 131 optarg=argv[optind]+3+length; 132 optind++; 133 return longopts[i].val; 134 } 135 else if ( (longopts[i].has_arg == required_argument) && (argv[optind][2+length] == '\0') ) { 136 optarg=argv[optind+1]; 137 optind+=2; 138 return longopts[i].val; 139 } 140 else if ( (longopts[i].has_arg == optional_argument) && (argv[optind][2+length] == '=') ) { 141 optarg=argv[optind]+3+length; 142 optind++; 143 return longopts[i].val; 144 } 145 else if ( (longopts[i].has_arg==optional_argument) && (argv[optind][2+length] == '\0') ) { 146 optind++; 147 return longopts[i].val; 148 } 149 } 150 } 151} 152return getopt(argc,argv,optstring); 153} 154 155#endif // HAVE_GETOPT_LONG 156 157int main(int argc, char *argv[]) 158{ 159 /* Declaration of variables */ 160 FILE *amulesig; 161 int use_out_pic = 0; 162 int use_page = 0; 163 char *config_path=NULL; 164 char *path; 165 char *stats[20]; 166 char *lines[IMG_TEXTLINES]; 167 long lSize; 168 char * buffer; 169 int i; 170 int c; 171 int errflag = 0; 172 char *path_for_picture=NULL; 173 char *path_for_html=NULL; 174 CONF config; 175 time_t lt; 176 struct tm *ltp; 177 char arr[20]; 178 179 while ((c = getopt_long (argc, argv, "c:P:H:hpo", long_options, NULL)) != -1) 180 181 switch (c) 182 { 183 case 'c': 184 config_path=optarg; 185 break; 186 case 'h': 187 usage(argv[0]); 188 exit(0); 189 case 'H': 190 case 'p': 191 use_page=1; 192 if (optarg != NULL) { 193 path_for_html = optarg; 194 } 195 break; 196 case 'P': 197 case 'o': 198 use_out_pic=1; 199 if (optarg != NULL) { 200 path_for_picture = optarg; 201 } 202 break; 203 case '?': 204 errflag++; 205 } 206 if (errflag) { 207 usage(argv[0]); 208 exit (2); 209 } 210 211 /* get amulesig path */ 212 213 path = get_amule_path("amulesig.dat", 1, config_path); 214 215 if (path == NULL) { 216 perror("Unable to get aMule settings path\n"); 217 exit(1); 218 } 219 220 /* open the file and if not exists exit with an error */ 221 if ((amulesig = fopen(path, "r")) == NULL) { 222 fprintf(stderr, "Unable to open file %s\nCheck if you have amule online signature enabled.\n", path); 223 exit(2); 224 } 225 /* i believe this shouldnt be here. 226 The freq of update could be higher than 60 seconds. 227 And it doesn't mean that the amule is not running. 228 */ 229 /* 230 else { 231 struct stat s_file; 232 if ( stat(path, &s_file) == 0 ) { 233 time_t t_now = time(0); 234 if ( (t_now - s_file.st_mtime) > 60 ) { 235 perror("aMule online signature last updated more then 60 sec ago\n"); 236 perror("Check that your aMule is running\n"); 237 } 238 } 239 }*/ 240 free(path); 241 242 /* initialize all the strings with nothing */ 243 for (i = 0; i <= 19; i++) 244 stats[i] = 0; 245 246 /* start reading the stuff from amulesign to the stats array */ 247 // obtain file size. 248 fseek (amulesig , 0 , SEEK_END); 249 lSize = ftell (amulesig); 250 if (0 == lSize) { 251 perror("aMule signature file is 0 Byte, exiting.\n"); 252 exit(2); 253 } 254 rewind (amulesig); 255 buffer = (char*) malloc (lSize); 256 if (buffer == NULL) { 257 perror("Could not create buffer\n"); 258 exit (2); 259 } 260 if (fread(buffer,1,lSize,amulesig)){} // // prevent GCC warning 261 fclose(amulesig); 262 263 stats[0] = strtok (buffer,"\n"); 264 for (i=1;i<17;i++) { 265 stats[i] = strtok (NULL,"\n"); 266 if (NULL == stats[i]) { 267 perror("Too few fields in aMule signature file, exiting.\n"); 268 exit(2); 269 } 270 } 271 272 // local time stored as stats[17] 273 lt = time(NULL); 274 ltp = localtime(<); 275 strftime(arr, 20, "%b %d %Y, %H:%M", ltp); 276 277 // if amule isn't running say that and exit else print out the stuff 278 279 // if amule uptime is 0, then its not running... 280 if (strncmp(stats[16],"0",1) == 0 ) { 281 perror("aMule is not running\n"); 282 exit(3); 283 } 284 285 286 if (strncmp(stats[0],"2",1) == 0) 287 CreateLine(lines, 0 ,"aMule %s is connecting\n", stats[13]); 288 else 289 CreateLine(lines, 0, "aMule %s has been running for %s\n", 290 stats[13], timeconv(stats[16])); 291 292 293 294 if (strncmp(stats[0],"0",1) == 0 && strncmp(stats[5],"0",1) == 0) 295 CreateLine(lines, 1, "%s is not connected ", stats[10]); 296 else if (strncmp(stats[0],"0",1) == 0 && strncmp(stats[5],"0",1) != 0) 297 CreateLine(lines, 1, "%s is connected to ", stats[10]); 298 else 299 CreateLine(lines, 1, "%s is connected to %s [%s:%s] with ", stats[10], 300 stats[1], stats[2], stats[3]); 301 302 303 if (strncmp(stats[5],"2",1) == 0) { 304 if (strncmp(stats[4],"H",1) == 0) 305 AppendToLine(lines, 1, "HighID | Kad: ok \n"); 306 else if (strncmp(stats[4],"L",1) == 0) 307 AppendToLine(lines, 1, "LowID | Kad: ok \n"); 308 else 309 AppendToLine(lines, 1, "Kad: ok \n"); 310 } else if (strncmp(stats[5],"1",1) == 0) { 311 if (strncmp(stats[4],"H",1) == 0) 312 AppendToLine(lines, 1, "HighID | Kad: firewalled \n"); 313 else if (strncmp(stats[4],"L",1) == 0) 314 AppendToLine(lines, 1, "LowID | Kad: firewalled \n"); 315 else 316 AppendToLine(lines, 1, "Kad: firewalled \n"); 317 } else { 318 if (strncmp(stats[4],"H",1) == 0) 319 AppendToLine(lines, 1, "HighID | Kad: off \n"); 320 else if (strncmp(stats[4],"L",1) == 0) 321 AppendToLine(lines, 1, "LowID | Kad: off \n"); 322 else 323 AppendToLine(lines, 1, "but running\n"); 324 } 325 326 stats[11] = strdup(convbytes(stats[11])); 327 stats[12] = strdup(convbytes(stats[12])); 328 329 CreateLine(lines, 2, "Total Download: %s, Upload: %s\n",stats[11] , stats[12]); 330 331 stats[15] = strdup(convbytes(stats[15])); 332 stats[14] = strdup(convbytes(stats[14])); 333 334 CreateLine(lines, 3, "Session Download: %s, Upload: %s\n",stats[14], stats[15]); 335 336 CreateLine(lines, 4, "Download: %s kB/s, Upload: %s kB/s\n", stats[6], stats[7]); 337 338 CreateLine(lines, 5, "Sharing: %s file(s), Clients on queue: %s\n", stats[9] , stats[8]); 339 340 CreateLine(lines, 6, "Time: %s\n", arr); 341 342#ifdef __GD__ 343 if (use_out_pic == 1) { 344 if (!readconfig(&config)) { 345 perror("Could not read config file\n"); 346 exit(4); 347 } 348 349 if (!createimage(&config, lines, path_for_picture)) { 350 perror("Could not create image!\n"); 351 exit(5); 352 } 353 exit(0); 354 } 355#endif 356 357 if (use_page == 1) { 358 359 if (!readconfig(&config)) { 360 perror("Could not read config file\n"); 361 exit(4); 362 } 363 364 if (!create_html(stats,lines,config.template, path_for_html)) { 365 perror("Could not create the HTML Page.\n"); 366 } 367 368#ifdef __GD__ 369 if (!createimage(&config, lines, path_for_picture)) { 370 perror("Could not create image!\n"); 371 exit(5); 372 } 373#endif 374 375 376 exit(0); 377 } 378 for (i = 0; i <= 6; i++) { 379 printf("%s", lines[i]); 380 free(lines[i]); 381 } 382 free(buffer); 383 exit(0); 384} 385 386