00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00031
00032
00033 #include <config.h>
00034 #include <stdio.h>
00035 #include <stdlib.h>
00036 #include <ctype.h>
00037 #include <string.h>
00038 #include <unistd.h>
00039 #include <sys/errno.h>
00040 #include <sys/types.h>
00041 #include <sys/param.h>
00042 #include <sys/wait.h>
00043 #include <sys/statfs.h>
00044 #include <sys/stat.h>
00045 #include <fcntl.h>
00046 #include <sys/ioctl.h>
00047 #include <dirent.h>
00048 #include <time.h>
00049
00050 #include "logging.h"
00051 #include "systemcalls.h"
00052
00053
00054 static char* szDownloadHistoryDir = NULL;
00055 static pid_t g_forkexec_child_pid = 0;
00056 static gboolean g_fileCopy_abort = FALSE;
00057
00058
00059 static gboolean isSymLink(const char *szPath);
00060
00061
00062 void setDownloadHistory(char *dir)
00063 {
00064 szDownloadHistoryDir = strdup(dir);
00065 }
00066
00067
00068
00069 static gboolean isSymLink(const char *szPath)
00070 {
00071 struct stat statBuf;
00072
00073 if ( lstat(szPath, &statBuf) == 0
00074 && S_ISLNK(statBuf.st_mode) )
00075 {
00076 return TRUE;
00077 }
00078 else
00079 {
00080 return FALSE;
00081 }
00082 }
00083
00084 void scFlushFileBuffers()
00085 {
00086 sync();
00087 sync();
00088 sync();
00089 }
00090
00091
00092 int get_battery_charge(void)
00093 {
00094 int pwr_fd;
00095 unsigned int battery_current;
00096 short current;
00097
00098 int charge = 0;
00099
00100 unsigned int charge_status = 0;
00101
00102 pwr_fd = open(POWERMGMTIFACE, O_RDWR);
00103 if (pwr_fd < 0)
00104 {
00105 perror("Error opening battery device");
00106 }
00107 else
00108 {
00109 if (ioctl(pwr_fd, BATTERY_IOCTL_READ_CHARGE, &charge_status) == -1)
00110 {
00111 perror("ioctl read battery_charge failed");
00112 }
00113 else if (ioctl(pwr_fd, BATTERY_IOCTL_READ_CURRENT, &battery_current) == -1)
00114 {
00115 perror("ioctl read battery_current failed");
00116 }
00117 else
00118 {
00119 current = battery_current & 0xFFFF;
00120 if (current > 0)
00121 {
00122 charge = 100;
00123 }
00124 else
00125 {
00126 charge = charge_status;
00127 }
00128 }
00129
00130 close(pwr_fd);
00131 }
00132
00133 DL_LOGPRINTF("return [%d]", charge);
00134 return charge;
00135 }
00136
00137 int recursive_dircopy(const char * source, const char * dest, GSourceFunc progress_callback)
00138 {
00139 int ret;
00140 int argc;
00141 char* argv[MAX_ARGS + 1];
00142 int rc;
00143 char* cp;
00144 guint timeout = 0;
00145
00146 if (progress_callback)
00147 {
00148
00149 timeout = g_timeout_add(PROGRESS_CALLBACK_TIMEOUT, progress_callback, NULL);
00150 }
00151
00152
00153 argc = 0;
00154 argv[argc++] = "cp";
00155 argv[argc++] = "-r";
00156
00157 cp = alloca(strlen(source) + 1);
00158 strcpy(cp, source);
00159 argv[argc++] = cp;
00160
00161 cp = alloca(strlen(dest) + 1);
00162 strcpy(cp, dest);
00163 argv[argc++] = cp;
00164
00165 argv[argc] = NULL;
00166 g_assert(argc < sizeof(argv)/sizeof(argv[0]));
00167 rc = fork_exec(argc, argv);
00168 if (rc == 0)
00169 {
00170 sync();
00171 ret = 0;
00172 }
00173 else
00174 {
00175 DL_ERRORPRINTF( "Cannot copy [%s] to [%s] - error [%d] [%s]",
00176 source, dest, rc, strerror(rc) );
00177 ret = rc;
00178
00179
00180 delDir(dest);
00181 }
00182
00183 if (progress_callback)
00184 {
00185
00186 g_source_remove(timeout);
00187 }
00188
00189 return ret;
00190 }
00191
00192 pid_t get_forkexec_child_pid()
00193 {
00194 return g_forkexec_child_pid;
00195 }
00196
00197
00198 int fork_exec(const int argc, char *const argv[])
00199 {
00200 int rc = -1;
00201 int pid;
00202 int status;
00203
00204 g_assert(argv[argc] == NULL);
00205
00206
00207 switch (pid = fork())
00208 {
00209 case 0:
00210
00211 rc = execvp(argv[0], argv);
00212 DL_ERRORPRINTF("execvp [%s] returns [%d] errno [%d] - %s", argv[0], rc, errno, strerror(errno));
00213 exit(1);
00214
00215 case -1:
00216
00217 DL_ERRORPRINTF("fork returns [%d] errno [%d] - %s", pid, errno, strerror(errno));
00218 g_assert_not_reached();
00219 break;
00220
00221 default:
00222
00223 g_forkexec_child_pid = pid;
00224 waitpid(pid, &status, 0);
00225 if (WIFEXITED(status))
00226 {
00227 rc = WEXITSTATUS(status);
00228 }
00229 g_forkexec_child_pid = 0;
00230 }
00231
00232 return rc;
00233 }
00234
00235 int fileExists(const char* filename)
00236 {
00237 struct stat buf;
00238
00239 if (filename == NULL)
00240 {
00241 return 0;
00242 }
00243
00244 return (stat(filename, &buf) == 0);
00245 }
00246
00247 char *dirCopy(const char* dirPath, const char* destinationDir, GSourceFunc progress_callback)
00248 {
00249 int i, ret;
00250 char *cp, *extension;
00251 char *dirName;
00252 char *buf;
00253 int bufsize;
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 cp = strrchr(dirPath, '/');
00266 if (cp)
00267 {
00268 cp++;
00269 }
00270 else
00271 {
00272 cp = (char*)dirPath;
00273 }
00274 dirName = strdup(cp);
00275
00276
00277 bufsize = strlen(dirName) + strlen(destinationDir) + 5;
00278 buf = malloc(sizeof(char) * bufsize);
00279 snprintf(buf, bufsize, "%s/%s", destinationDir, dirName);
00280
00281
00282 cp = strrchr(dirName, '.');
00283 if (cp)
00284 {
00285 *cp = '\0';
00286 extension = cp + 1;
00287 }
00288 else
00289 {
00290 extension = NULL;
00291 }
00292
00293
00294
00295 for (i = 1 ; fileExists(buf) && i <= 99 ; i++)
00296 {
00297 if (extension)
00298 {
00299
00300 snprintf(buf, bufsize, "%s/%s_%02d.%s", destinationDir, dirName, i, extension);
00301 }
00302 else
00303 {
00304 snprintf(buf, bufsize, "%s/%s_%02d", destinationDir, dirName, i);
00305 }
00306 }
00307 if (--i)
00308 {
00309 DL_WARNPRINTF("Still need to rewrite the manifest title/description for this entry [%s] [%d]", buf, i);
00310 }
00311
00312 DL_LOGPRINTF("Copy '%s' to '%s'", dirPath, buf);
00313 if ((ret = recursive_dircopy(dirPath, buf, progress_callback)) != 0)
00314 {
00315 DL_ERRORPRINTF("recursive_dircopy returned %d (%s)", ret, strerror(ret));
00316 goto DIRCOPY_ERROR;
00317 }
00318
00319 free(dirName);
00320 return buf;
00321
00322
00323 DIRCOPY_ERROR:
00324 perror("");
00325 free(dirName);
00326 free(buf);
00327 return NULL;
00328 }
00329
00330
00331
00332
00333
00334 char *fileCopy(const char* filePath, const char* destinationDir, GSourceFunc progress_callback)
00335 {
00336 int i;
00337 char *cp, *extension;
00338 char *fileName;
00339 char *destinationFile;
00340 int bufsize, bytes_read;
00341 FILE *fp_from, *fp_to = NULL;
00342 char fbuf[1024];
00343 guint timeout = 0;
00344
00345 g_fileCopy_abort = FALSE;
00346
00347 if (progress_callback)
00348 {
00349
00350 timeout = g_timeout_add(PROGRESS_CALLBACK_TIMEOUT, progress_callback, NULL);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 cp = strrchr(filePath, '/');
00364 if (cp)
00365 {
00366 cp++;
00367 }
00368 else
00369 {
00370 cp = (char*)filePath;
00371 }
00372 fileName = strdup(cp);
00373
00374
00375 bufsize = strlen(fileName) + strlen(destinationDir) + 5;
00376 destinationFile = malloc(sizeof(char) * bufsize);
00377 snprintf(destinationFile, bufsize, "%s/%s", destinationDir, fileName);
00378
00379
00380 cp = strrchr(fileName, '.');
00381 if (cp)
00382 {
00383 *cp = '\0';
00384 extension = cp + 1;
00385 }
00386 else
00387 {
00388 extension = NULL;
00389 }
00390
00391
00392 for (i = 1 ; fileExists(destinationFile) && i <= 99 ; i++)
00393 {
00394 if (extension)
00395 {
00396
00397 snprintf(destinationFile, bufsize, "%s/%s_%02d.%s", destinationDir, fileName, i, extension);
00398 }
00399 else
00400 {
00401 snprintf(destinationFile, bufsize, "%s/%s_%02d", destinationDir, fileName, i);
00402 }
00403 }
00404
00405 DL_LOGPRINTF("Copy '%s' to '%s'", filePath, destinationFile);
00406
00407 fp_from = fopen(filePath, "rb");
00408 if (!fp_from)
00409 {
00410 DL_ERRORPRINTF("Error opening file %s:", filePath);
00411 goto FILECOPY_ERROR;
00412 }
00413
00414 fp_to = fopen(destinationFile, "wb+");
00415 if (!fp_to)
00416 {
00417 DL_ERRORPRINTF("Error opening new file %s:", destinationFile);
00418 goto FILECOPY_ERROR;
00419 }
00420
00421
00422 while ((bytes_read = fread(fbuf, 1, sizeof(fbuf), fp_from)))
00423 {
00424 if (fwrite(fbuf, 1, bytes_read, fp_to) == EOF || g_fileCopy_abort)
00425 {
00426 DL_ERRORPRINTF("Error writing to target file %s:", destinationFile);
00427 goto FILECOPY_ERROR;
00428 }
00429 }
00430
00431 if (!feof(fp_from))
00432 {
00433 DL_ERRORPRINTF("Error reading from source file %s:", filePath);
00434 goto FILECOPY_ERROR;
00435 }
00436
00437 fclose(fp_from);
00438 fclose(fp_to);
00439
00440 if (progress_callback)
00441 {
00442
00443 g_source_remove(timeout);
00444 }
00445
00446 free(fileName);
00447 return destinationFile;
00448
00449
00450 FILECOPY_ERROR:
00451 perror("");
00452 fclose(fp_from);
00453 fclose(fp_to);
00454 if (progress_callback) g_source_remove(timeout);
00455 free(fileName);
00456 unlink(destinationFile);
00457 free(destinationFile);
00458 return NULL;
00459 }
00460
00461 void fileCopy_abort()
00462 {
00463 g_fileCopy_abort = TRUE;
00464 }
00465
00466 int delDir(const char* sDir)
00467 {
00468 char* cp;
00469 char* argv[10];
00470 int argc;
00471
00472
00473
00474 if ((sDir == NULL) || (strlen(sDir) <= 1))
00475 {
00476 return -1;
00477 }
00478
00479 argc = 0;
00480 argv[argc++] = "rm";
00481 argv[argc++] = "-rf";
00482
00483 cp = alloca( strlen(sDir) + 1 );
00484 g_assert(cp != NULL);
00485 strcpy(cp, sDir);
00486 argv[argc++] = cp;
00487
00488 argv[argc] = NULL;
00489 g_assert( argc < (sizeof(argv)/sizeof(argv[0])) );
00490 return fork_exec(argc, argv);
00491 }
00492
00493
00494 void createDownloadHistoryEntry(const char *filePath)
00495 {
00496 g_assert(filePath != NULL);
00497 DL_LOGPRINTF("Entry: filename [%s]", filePath);
00498
00499 int sequence;
00500 int err;
00501 int n;
00502 gboolean done;
00503 char szLinkName[PATH_MAX] = "";
00504 char szLinkTarget[PATH_MAX] = "";
00505
00506 DIR *dirp;
00507 struct dirent *direntp;
00508
00509
00510 if ((dirp = opendir(szDownloadHistoryDir)) == NULL)
00511 {
00512 DL_ERRORPRINTF("Could not open directory [%s] error [%s].", szDownloadHistoryDir, strerror(errno));
00513 }
00514 else
00515 {
00516 while ((direntp = readdir(dirp)) != NULL)
00517 {
00518
00519 snprintf(szLinkName, sizeof(szLinkName), "%s/%s", szDownloadHistoryDir, direntp->d_name);
00520 if ( isSymLink(szLinkName) )
00521 {
00522
00523 n = readlink(szLinkName, szLinkTarget, sizeof(szLinkTarget) - 1);
00524 if (n > 0 && strncmp(szLinkTarget, filePath, n) == 0)
00525 {
00526
00527 szLinkTarget[n] = '\0';
00528 DL_LOGPRINTF("Remove symlink [%s] -> [%s]", szLinkName, szLinkTarget);
00529 unlink(szLinkName);
00530 }
00531 }
00532 }
00533 closedir(dirp);
00534 }
00535
00536
00537 done = FALSE;
00538 for ( sequence = 0 ; !done && sequence <= 99 ; sequence++ )
00539 {
00540
00541 time_t t_time = time(NULL);
00542 struct tm* tm_time = localtime( &t_time );
00543 snprintf( szLinkName,
00544 MAX_PATH,
00545 "%s/Link_%04d-%02d-%02dT%02d:%02d:%02d:%02d",
00546 szDownloadHistoryDir,
00547 tm_time->tm_year + 1900,
00548 tm_time->tm_mon + 1,
00549 tm_time->tm_mday,
00550 tm_time->tm_hour,
00551 tm_time->tm_min,
00552 tm_time->tm_sec,
00553 sequence );
00554
00555
00556 if (symlink(filePath, szLinkName) == 0)
00557 {
00558 DL_LOGPRINTF("Created symlink [%s] -> [%s]", szLinkName, filePath);
00559 done = TRUE;
00560 }
00561 else
00562 {
00563 err = errno;
00564 DL_ERRORPRINTF("Error [%s] on create symlink [%s] -> [%s]", strerror(err), szLinkName, filePath);
00565 if (err == EEXIST)
00566 {
00567 DL_ERRORPRINTF("[%s] already exists", szLinkName);
00568 }
00569 }
00570 }
00571 }
00572
00573
00574
00575
00576 int getEndSepratorLocation(const char* sDir)
00577 {
00578 if( NULL==sDir) return -1;
00579
00580 int iLastPos=strlen(sDir)-1;
00581 if( '/' == sDir[iLastPos] )
00582 {
00583 return iLastPos;
00584 }
00585 return -1;
00586 }
00587
00588
00589 const int mkdirhier(const char *path, mode_t mode)
00590 {
00591 char *ptr;
00592 char *dir;
00593 char old_char;
00594 struct stat s;
00595 int rv = 0;
00596
00597 if (*path == '\0')
00598 {
00599 return 1;
00600 }
00601
00602 dir = strdup(path);
00603 if (dir == NULL)
00604 {
00605 return 0;
00606 }
00607
00608 ptr = dir;
00609 while (*ptr == '/')
00610 {
00611 ptr++;
00612 }
00613 while (*ptr != '\0')
00614 {
00615
00616 ptr = strchr(ptr, '/');
00617 if (ptr == NULL)
00618 {
00619 ptr = dir + strlen(dir);
00620 }
00621
00622
00623 old_char = *ptr;
00624 *ptr = '\0';
00625 if ((stat(dir, &s) != 0))
00626 {
00627 if (mkdir(dir, mode) != 0)
00628 {
00629
00630 goto END_MKDIRHIER;
00631 }
00632 }
00633 else if ( !S_ISDIR(s.st_mode) && !S_ISLNK(s.st_mode))
00634 {
00635
00636 goto END_MKDIRHIER;
00637 }
00638
00639
00640 *ptr = old_char;
00641 if (*ptr)
00642 {
00643 ptr++;
00644 }
00645 }
00646 rv = 1;
00647
00648 END_MKDIRHIER:
00649 free(dir);
00650 return rv;
00651 }
00652
00653
00654 char * strtolower(register char *s)
00655 {
00656 char *ret = s;
00657 for ( ; *s; s++) if (isupper(*s)) *s = tolower(*s);
00658 return ret;
00659 }