clean_temp.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include <stdlib.h>
  2. #include <signal.h>
  3. #include <unistd.h>
  4. #include <time.h>
  5. #include <sys/types.h>
  6. #include <dirent.h>
  7. #include <sys/stat.h>
  8. #include <grass/gis.h>
  9. #include "local_proto.h"
  10. /**************************************************************
  11. * clean_temp
  12. *
  13. * looks for all files in mapset temp directory
  14. * of the form pid.n and removes those which have
  15. * been abandoned their processes (pid).
  16. *
  17. * also removes any other file found which is "old"
  18. * with an modification time greater then 4 days
  19. *
  20. * 2006: Rewritten for GRASS 6 by Roberto Flor, ITC-irst
  21. *
  22. **************************************************************/
  23. #include <limits.h>
  24. #include <string.h>
  25. #include <errno.h>
  26. #ifdef PATH_MAX
  27. #define BUF_MAX PATH_MAX
  28. #else
  29. #define BUF_MAX 4096
  30. #endif
  31. extern int errno;
  32. #define SLEEP 30 /* 30 minutes */
  33. /* Recursively scan the directory pathname, removing directory and files */
  34. void clean_dir(const char *pathname,uid_t uid,pid_t pid,time_t now,int max_age)
  35. {
  36. char buf[BUF_MAX];
  37. DIR *curdir;
  38. struct dirent *cur_entry;
  39. struct stat info;
  40. int n,pathlen;
  41. curdir = opendir(pathname);
  42. if (curdir == NULL ) {
  43. G_warning("Can't open directory %s: %s,skipping\n",pathname,strerror(errno));
  44. return;
  45. }
  46. /* loop over current dir */
  47. while ((cur_entry = readdir(curdir)))
  48. {
  49. if ((G_strcasecmp(cur_entry->d_name,".") == 0 )|| (G_strcasecmp(cur_entry->d_name,"..")==0))
  50. continue; /* Skip dir and parent dir entries */
  51. if ( (pathlen=G_snprintf(buf,BUF_MAX,"%s/%s",pathname,cur_entry->d_name)) >= BUF_MAX)
  52. G_fatal_error("clean_temp: exceeded maximum pathname length %d, got %d, should'nt happen",BUF_MAX,pathlen);
  53. if (stat(buf, &info) != 0) {
  54. G_warning("Can't stat file %s: %s,skipping\n",buf,strerror(errno));
  55. continue;
  56. }
  57. if ( S_ISDIR(info.st_mode)) { /* It's a dir, recurring */
  58. clean_dir(buf,uid,pid,now,max_age);
  59. /* Return here means we have completed the subdir recursion */
  60. /* Trying to remove the now empty dir */
  61. if ( info.st_uid != uid ) /* Not owners of dir */
  62. continue;
  63. #ifndef DEBUG_CLEAN
  64. if (rmdir(buf) != 0 ) {
  65. if ( errno != ENOTEMPTY ) {
  66. G_warning("Can't remove empty directory %s: %s,skipping\n",buf,strerror(errno));
  67. }
  68. }
  69. #else
  70. G_warning("Removing directory %s\n",buf);
  71. #endif
  72. } else { /* It's a file check it */
  73. if ( info.st_uid == uid ) { /* Remove only files owned by current user */
  74. if (sscanf (cur_entry->d_name, "%d.%d", &pid, &n) == 2 ) {
  75. if (!find_process (pid))
  76. #ifndef DEBUG_CLEAN
  77. if ( unlink (buf) != 0 )
  78. G_warning("Can't remove file %s: %s,skipping\n",buf,strerror(errno));
  79. #else
  80. G_warning("Removing file %s\n",buf);
  81. #endif
  82. } else {
  83. if ((now - info.st_mtime) > max_age) /* Not modified in 4 days: TODO configurable param */
  84. #ifndef DEBUG_CLEAN
  85. if ( unlink (buf) != 0 )
  86. G_warning("Can't remove file %s: %s,skipping\n",buf,strerror(errno));
  87. #else
  88. G_warning("Removing file %s\n",buf);
  89. #endif
  90. }
  91. }
  92. }
  93. }
  94. closedir(curdir);
  95. return;
  96. }
  97. int
  98. main (int argc, char *argv[])
  99. {
  100. char *mapset;
  101. char element[GNAME_MAX];
  102. char tmppath[BUF_MAX];
  103. pid_t ppid;
  104. pid_t pid;
  105. uid_t uid;
  106. time_t now;
  107. long max_age;
  108. G_gisinit(argv[0]) ;
  109. pid = 0;
  110. ppid = 0;
  111. if (argc > 1)
  112. sscanf(argv[1],"%d", &ppid);
  113. /* Get the mapset temp directory */
  114. G__temp_element(element);
  115. G__file_name (tmppath, element, "", mapset = G_mapset());
  116. /* get user id and current time in seconds */
  117. #ifdef __MINGW32__
  118. /* TODO */
  119. uid = -1;
  120. #else
  121. uid = getuid () ;
  122. #endif
  123. now = time(NULL) ;
  124. /* set maximum age in seconds (4 days) */
  125. max_age = 4 * 24 * 60 * 60 ;
  126. /*
  127. * Scan the temp directory and subdirectory for
  128. * files owned by the user and of the form pid.n
  129. * to be removed if the process is not running
  130. * all "old" files are removed as well
  131. */
  132. while(1)
  133. {
  134. if (ppid > 0 && !find_process(ppid))
  135. break;
  136. clean_dir(tmppath,uid,pid,now,max_age);
  137. if (ppid <= 0)
  138. break;
  139. G_sleep(SLEEP);
  140. }
  141. exit(0);
  142. }
  143. int
  144. find_process (int pid)
  145. {
  146. #ifdef __MINGW32__
  147. /* TODO */
  148. return -1;
  149. #else
  150. return (kill (pid, 0) == 0 || errno != ESRCH) ;
  151. #endif
  152. }