Advertisement
puppet106

cerberus.c

Jun 17th, 2020
1,982
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.92 KB | None | 0 0
  1. // Cerberus, guard folder for added files or directories, execute commands on them
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <stdlib.h>
  5. #include <dirent.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8. #include <sys/wait.h>
  9. #include <sys/types.h>
  10. #include <sys/stat.h>
  11. #include <errno.h>
  12. #include <ftw.h>
  13.  
  14. #define workdirectory "compressed"
  15. #define compressionprogram "zip"
  16. #define compressiondirectoryoption "-r"
  17. #define compressionextension ".zip"
  18. #define skipdirectorystring "tmp"
  19. #define movefilesleeptime 1
  20. #define movedirectorysleeptime 30
  21. #define MAXNAME 100
  22.  
  23. // global variables, enumerations
  24. enum ENTRIES { FILEENTRY=1, DIRECTORYENTRY };
  25. typedef unsigned long ul;
  26. static ul dirtotal;
  27.  
  28. // functions declarations
  29. void workonfile(char *filename, int type);
  30. int isFile(char* name);
  31. off_t filesize(char *filename);
  32. int isEntryEligible(char *filename);
  33. int findsimple(char text[], const char token[]);
  34. int dirsum(const char *fpath, const struct stat *sb, int typeflag);
  35.  
  36. int main()
  37. {
  38.   DIR *dir = opendir(".");
  39.   struct dirent *result;
  40.   unsigned long filesno=0;
  41.   int i;
  42.  
  43.   if ((isFile(workdirectory))) {
  44.    printf("work directory not accessible\n");
  45.   exit(EXIT_FAILURE); }
  46.  
  47.     printf("Cerberus started..\n");
  48.     while (1) {
  49.      rewinddir(dir);
  50.      result=readdir(dir);
  51.      while (!(i=isEntryEligible(result->d_name))) {
  52.       result=readdir(dir);
  53.       if (result==NULL)
  54.      break; }
  55.      sleep(1); // don't overtire the cpu
  56.      if (result!=NULL) { // skip NULL entry
  57.       ++filesno;
  58.       printf("\n%ld.", filesno);
  59.       if (i==FILEENTRY)
  60.        printf("file");
  61.       if (i==DIRECTORYENTRY)
  62.        printf("directory");
  63.       printf(" name: %s; i-number: %ld\n", result->d_name, (long)result->d_ino);
  64.     workonfile(result->d_name, i); } }
  65.    
  66.  return 0;    
  67. }
  68.  
  69. // move file to defined work directory, daemonize compress and remove
  70. void workonfile(char *filename, int type)
  71. {
  72.   char command[MAXNAME*3];
  73.   int i;
  74.   off_t tsize[2];
  75.  
  76.    if (type==FILEENTRY) { // file
  77.     while (1) { // give time to the file to be copied, downloaded
  78.      tsize[0]=filesize(filename);
  79.      sleep(movefilesleeptime);
  80.      tsize[1]=filesize(filename);
  81.      if (tsize[0]==tsize[1])
  82.     break; }
  83.    sprintf(command, "mv %s %s", filename, workdirectory); }
  84.    else { // directory
  85.     while (1) {
  86.      ftw(filename, &dirsum, 1);
  87.      tsize[0]=dirtotal;
  88.      sleep(movedirectorysleeptime);
  89.      ftw(filename, &dirsum, 1);
  90.      tsize[1]=dirtotal;
  91.      if (tsize[0]==tsize[1])
  92.     break; }
  93.     sprintf(command, "cp -r %s %s", filename, workdirectory);
  94.     system(command);
  95.     sprintf(command, "rm -rf %s", filename); }
  96.    system(command);
  97.    i=fork();
  98.    if (i<0) exit(EXIT_FAILURE); // fork error, unlikely
  99.    if (i>0) return; // parent returns
  100.  
  101.    // compress file and unlink
  102.    // child continues
  103.    i=fork();
  104.    if (i<0) exit(EXIT_FAILURE);
  105.    if (i>0) { // parent waits for child to compress
  106.     waitpid(i, NULL, 0);
  107.     if (type==1) {
  108.      sprintf(command, "%s/%s", workdirectory, filename);
  109.     unlink(command); }
  110.     else {
  111.      sprintf(command, "rm -rf %s/%s", workdirectory, filename);
  112.     system(command);
  113.     }
  114.    exit(EXIT_SUCCESS); } // close process
  115.  
  116.    // second child continues to compression
  117.    chdir(workdirectory);
  118.    if (type==FILEENTRY)
  119.     sprintf(command, "%s %s%s %s", compressionprogram, filename, compressionextension, filename);
  120.    else
  121.     sprintf(command, "%s %s %s%s %s", compressionprogram, compressiondirectoryoption, filename, compressionextension, filename);
  122.    system(command);
  123.    exit(EXIT_SUCCESS); // close process
  124. }
  125.  
  126. // is file or directory
  127. int isFile(char* name)
  128. {
  129.   DIR *directory=opendir(name);
  130.  
  131.    if (directory!=NULL) {
  132.     closedir(directory);
  133.    return 0; }
  134.  
  135.    if (errno==ENOTDIR)
  136.     return 1;
  137.  
  138.  return -1; // nothing found
  139. }
  140.  
  141. // return filesize in bytes
  142. off_t filesize(char *filename)
  143. {
  144.   struct stat st;
  145.  
  146.    stat(filename, &st);
  147.  
  148.  return st.st_size;
  149. }
  150.  
  151. // is entry eligible for processing
  152. int isEntryEligible(char *filename)
  153. {
  154.   int i;
  155.  
  156.    i=isFile(filename);
  157.    if (i==1) // file
  158.     return FILEENTRY;
  159.    if (!i && !findsimple(filename, skipdirectorystring))
  160.     if (strcmp(filename, ".") && strcmp(filename, "..") && strcmp(filename, workdirectory))
  161.      return DIRECTORYENTRY;
  162.    
  163.  return 0;  
  164. }
  165.  
  166. // find command in text
  167. int findsimple(char text[], const char token[])
  168. {
  169.   int i, n, hit=0;
  170.   char ttoken[MAXNAME];
  171.  
  172.    for (i=0;i<strlen(text);i++) {
  173.     if (tolower(text[i])==token[0]) {
  174.      hit=i+1;
  175.      for (n=0;n<strlen(token) && (i+n)<strlen(text);n++)
  176.       ttoken[n]=tolower(text[i+n]);
  177.      ttoken[n]='\0';
  178.      if (strcmp(ttoken, token))
  179.       hit=0;
  180.      else
  181.    break; } }
  182.    
  183.  return hit;
  184. }
  185.  
  186. // directory entries size summary
  187. int dirsum(const char *fpath, const struct stat *sb, int typeflag)
  188. {
  189.  dirtotal=0;
  190.  
  191.   dirtotal += sb->st_size;
  192.  
  193.  return 0;
  194. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement