#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/wait.h>
#include <sys/statfs.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <dirent.h>
#include <time.h>
#include "logging.h"
#include "systemcalls.h"
Go to the source code of this file.
Functions | |
| static gboolean | isSymLink (const char *szPath) |
| void | setDownloadHistory (char *dir) |
| void | scFlushFileBuffers () |
| int | get_battery_charge (void) |
| int | recursive_dircopy (const char *source, const char *dest, GSourceFunc progress_callback) |
| pid_t | get_forkexec_child_pid () |
| int | fork_exec (const int argc, char *const argv[]) |
| int | fileExists (const char *filename) |
| char * | dirCopy (const char *dirPath, const char *destinationDir, GSourceFunc progress_callback) |
| char * | fileCopy (const char *filePath, const char *destinationDir, GSourceFunc progress_callback) |
| void | fileCopy_abort () |
| int | delDir (const char *sDir) |
| void | createDownloadHistoryEntry (const char *filePath) |
| int | getEndSepratorLocation (const char *sDir) |
| const int | mkdirhier (const char *path, mode_t mode) |
| char * | strtolower (register char *s) |
Variables | |
| static char * | szDownloadHistoryDir = NULL |
| static pid_t | g_forkexec_child_pid = 0 |
| static gboolean | g_fileCopy_abort = FALSE |
Copyright (C) 2005-2008 iRex Technologies B.V. All rights reserved.
<File description>="">
Definition in file systemcalls.c.
| void createDownloadHistoryEntry | ( | const char * | filePath | ) |
Definition at line 494 of file systemcalls.c.
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 // remove existing link(s) to the target, if any 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 // directory entry read 00519 snprintf(szLinkName, sizeof(szLinkName), "%s/%s", szDownloadHistoryDir, direntp->d_name); 00520 if ( isSymLink(szLinkName) ) 00521 { 00522 // directory entry is a symlink 00523 n = readlink(szLinkName, szLinkTarget, sizeof(szLinkTarget) - 1); 00524 if (n > 0 && strncmp(szLinkTarget, filePath, n) == 0) 00525 { 00526 // symlink points to our target: delete symlink 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 // create a new symlink to the target 00537 done = FALSE; 00538 for ( sequence = 0 ; !done && sequence <= 99 ; sequence++ ) 00539 { 00540 // determine name of symlink 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 // create symbolic link, replace existing link when present 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 }

| int delDir | ( | const char * | sDir | ) |
Definition at line 466 of file systemcalls.c.
00467 { 00468 char* cp; 00469 char* argv[10]; 00470 int argc; 00471 00472 // Do nothing if called with empty string or a string of 1 char 00473 // This kind of makes sure no stupid person calls this with "/" 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 }

| char* dirCopy | ( | const char * | dirPath, | |
| const char * | destinationDir, | |||
| GSourceFunc | progress_callback | |||
| ) |
Definition at line 247 of file systemcalls.c.
00248 { 00249 int i, ret; 00250 char *cp, *extension; 00251 char *dirName; 00252 char *buf; 00253 int bufsize; 00254 00255 // 00256 // Check if the resulting dirName already exists 00257 // 00258 00259 // Layout of dirPath: 00260 // [PATH NAME]/[FILENAME].[EXT] 00261 // dirName--^ ^ 00262 // extension-------- 00263 00264 // First: extract the filename from the dirPath 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 // Create destination filename 00277 bufsize = strlen(dirName) + strlen(destinationDir) + 5; 00278 buf = malloc(sizeof(char) * bufsize); 00279 snprintf(buf, bufsize, "%s/%s", destinationDir, dirName); 00280 00281 // Extract extension, modify dirName to strip extension 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 // Add a sequence number, in case of duplicate filenames 00294 // TODO: MvdW: Do we need to change the title in the manifest to reflect the sequence number? 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 // Clean up on error 00323 DIRCOPY_ERROR: 00324 perror(""); 00325 free(dirName); 00326 free(buf); 00327 return NULL; 00328 }

| char* fileCopy | ( | const char * | filePath, | |
| const char * | destinationDir, | |||
| GSourceFunc | progress_callback | |||
| ) |
Definition at line 334 of file systemcalls.c.
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 // Show some indication of being busy 00350 timeout = g_timeout_add(PROGRESS_CALLBACK_TIMEOUT, progress_callback, NULL); 00351 } 00352 00353 // 00354 // Check if the resulting filename already exists 00355 // 00356 00357 // Layout of filePath: 00358 // [PATH NAME]/[FILENAME].[EXT] 00359 // fileName--^ ^ 00360 // extension-------- 00361 00362 // First: extract the filename from the filePath 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 // Create destination filename 00375 bufsize = strlen(fileName) + strlen(destinationDir) + 5; 00376 destinationFile = malloc(sizeof(char) * bufsize); 00377 snprintf(destinationFile, bufsize, "%s/%s", destinationDir, fileName); 00378 00379 // Extract extension, modify fileName to strip extension 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 // Add a sequence number, in case of duplicate filenames 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 // copy source file to target file 1024 bytes at a time 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 // stop showing busy 00443 g_source_remove(timeout); 00444 } 00445 00446 free(fileName); 00447 return destinationFile; 00448 00449 // Clean up on error 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 }

| void fileCopy_abort | ( | void | ) |
| int fileExists | ( | const char * | filename | ) |
Definition at line 235 of file systemcalls.c.
00236 { 00237 struct stat buf; 00238 00239 if (filename == NULL) 00240 { 00241 return 0; 00242 } 00243 00244 return (stat(filename, &buf) == 0); 00245 }
| int fork_exec | ( | const int | argc, | |
| char *const | argv[] | |||
| ) |
Definition at line 198 of file systemcalls.c.
00199 { 00200 int rc = -1; 00201 int pid; 00202 int status; 00203 00204 g_assert(argv[argc] == NULL); 00205 00206 // spawn child process 00207 switch (pid = fork()) 00208 { 00209 case 0: 00210 // child process: execute command 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 // error: fork failed 00217 DL_ERRORPRINTF("fork returns [%d] errno [%d] - %s", pid, errno, strerror(errno)); 00218 g_assert_not_reached(); 00219 break; 00220 00221 default: 00222 // parent process: wait for child and return its exit value 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 }
| int get_battery_charge | ( | void | ) |
Retrieve the current battery charge
Definition at line 92 of file systemcalls.c.
00093 { 00094 int pwr_fd; 00095 unsigned int battery_current; 00096 short current; 00097 00098 int charge = 0; // return value 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) // percentage 0 ... 100 00110 { 00111 perror("ioctl read battery_charge failed"); 00112 } 00113 else if (ioctl(pwr_fd, BATTERY_IOCTL_READ_CURRENT, &battery_current) == -1) // current in milliamps 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 }
| pid_t get_forkexec_child_pid | ( | ) |
| int getEndSepratorLocation | ( | const char * | sDir | ) |
Definition at line 576 of file systemcalls.c.
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 }
| static gboolean isSymLink | ( | const char * | szPath | ) | [static] |
Definition at line 69 of file systemcalls.c.
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 }
| const int mkdirhier | ( | const char * | path, | |
| mode_t | mode | |||
| ) |
Definition at line 589 of file systemcalls.c.
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 // ptr = next '/' or end-of-string 00616 ptr = strchr(ptr, '/'); 00617 if (ptr == NULL) 00618 { 00619 ptr = dir + strlen(dir); 00620 } 00621 00622 // truncate dir and check whether it exists 00623 old_char = *ptr; 00624 *ptr = '\0'; 00625 if ((stat(dir, &s) != 0)) 00626 { 00627 if (mkdir(dir, mode) != 0) 00628 { 00629 // cannot make dir: fail 00630 goto END_MKDIRHIER; 00631 } 00632 } 00633 else if ( !S_ISDIR(s.st_mode) && !S_ISLNK(s.st_mode)) 00634 { 00635 // parent not directory or link: fail 00636 goto END_MKDIRHIER; 00637 } 00638 00639 // restore dir and advance 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 }
| int recursive_dircopy | ( | const char * | source, | |
| const char * | dest, | |||
| GSourceFunc | progress_callback | |||
| ) |
Definition at line 137 of file systemcalls.c.
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 // Show some indication of being busy 00149 timeout = g_timeout_add(PROGRESS_CALLBACK_TIMEOUT, progress_callback, NULL); 00150 } 00151 00152 // command = cp -r <source-directory> <target-directory> 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; // success 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 // clean up incomplete destination 00180 delDir(dest); 00181 } 00182 00183 if (progress_callback) 00184 { 00185 // stop showing busy 00186 g_source_remove(timeout); 00187 } 00188 00189 return ret; 00190 }

| void scFlushFileBuffers | ( | ) |
| void setDownloadHistory | ( | char * | dir | ) |
Definition at line 62 of file systemcalls.c.
00063 { 00064 szDownloadHistoryDir = strdup(dir); 00065 }
| char* strtolower | ( | register char * | s | ) |
Definition at line 654 of file systemcalls.c.
00655 { 00656 char *ret = s; 00657 for ( ; *s; s++) if (isupper(*s)) *s = tolower(*s); 00658 return ret; 00659 }
gboolean g_fileCopy_abort = FALSE [static] |
Definition at line 56 of file systemcalls.c.
pid_t g_forkexec_child_pid = 0 [static] |
Definition at line 55 of file systemcalls.c.
char* szDownloadHistoryDir = NULL [static] |
Definition at line 54 of file systemcalls.c.
1.5.6