1 /*
2 Program  : watchd
3 Created  : 20.08.2001
4 Modified : $Date: 2005/05/10 04:08:15 $
5 Author   : Peter Turczak <p_turczak@wiwa.de>
6 Syntax   : watchd
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22 
23 #define __USE_BSD
24 
25 #include <sys/types.h>
26 #include <sys/timeb.h>
27 #include <sys/stat.h>
28 #include <sys/wait.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <dirent.h>
32 #include <unistd.h>
33 #include <fcntl.h>
34 #include <syslog.h>
35 #include <signal.h>
36 #include <string.h>
37 #include <ctype.h>
38 #include <errno.h>
39 #include "inifile.h"
40 #include "chain.h"
41 #include "filedb.h"
42 
43 #define FL_ACT_CHANGE		1
44 #define FL_ACT_EXISTENCE	2
45 #define FL_ACT_NOMOVE		4
46 #define FL_ACT_COPY		8
47 #define FL_ACT_DELETE		16
48 
49 #define FL_LOG_SYSLOG		64
50 #define FL_LOG_FILE		128
51 #define FL_LOG_MAIL		256
52 #define FL_LOG_ALWAYS		512
53 
54 typedef struct Twatchfolder
55 		{
56 		 char* runprg;
57 		 char* dir;
58 		 element *filechain;
59 		 uid_t user;
60 
61 		 int flags;
62 		 char *notify;
63 		 char *logfile;
64 
65 		 int gracetime;          // Remaining time 'till scanchain
66 		 int interval, curcount; // Interval will stay constant,
67 		 			 // curcount-- until exec then curcount=interval
68 		} Twatchfolder;
69 
70 Twatchfolder defaultfolder;
71 Twatchfolder *curfolder=&defaultfolder;
72 element *folders; //Chain of folders
73 
74 int interval=1; // Global rescan interval in seconds
75 int timeofgrace;// Time in intervals between calls to scanchain
76 char *tmpdir;   // Directory where the processing dirs are created. Default=/tmp
77 char *mvprg;    // Program that is used to move the files around. Default=mv
78 char *cpprg;    // Program that is used to move the files around. Default=cp
79 char *rmprg;    // Program that is used to remove the files. Default=rm
80 
81 char *config_file = NULL;
82 
83 static char default_config_filename[] = "/usr/local/etc/watchd.conf";
84 
85 #ifdef HAS_NO_MKSTEMP
mkstemp(char * template)86 int mkstemp(char *template)
87 {
88 int r;
89 char *dir=strdup(template);
90 char *prefix=NULL;
91 
92 if (strrchr(dir, '/')!=0)
93  {
94   file=strrchr(dir, '/');
95   file=0x00;
96   file++;
97 
98   if (strstr(file, "XXXXXX"))
99    {
100     (strstr(file, "XXXXXX"))[0]=0x00;
101    }
102  }
103 r=open(tempnam(dir, prefix), O_CREAT | O_RDWR | S_IRWXU);
104 
105 return(r);
106 }
107 #endif
108 
get_filestate(char * fn)109 int get_filestate(char *fn)
110 {
111 int fd=open(fn,O_RDWR);
112              /* l_type   l_whence  l_start  l_len  l_pid   */
113 struct flock fl = { F_WRLCK, SEEK_SET, 0,       0,     0 };
114 
115 if (fd>0)
116  {
117  fl.l_pid = getpid();
118  fl.l_type = F_WRLCK;
119 
120  if (fcntl(fd, F_SETLK, &fl) == -1)
121   {
122    close(fd);
123 #ifdef DEBUG
124    printf("get_filestate(%s)=%d\n",fn,0);
125 #endif
126   return(0);
127   } else {
128    close(fd);
129 #ifdef DEBUG
130    printf("get_filestate(%s)=%d\n",fn,1);
131  #endif
132    fl.l_type = F_UNLCK;  /* set to unlock same region */
133    if (fcntl(fd, F_SETLK, &fl) == -1)
134     {
135     close(fd);
136 #ifdef DEBUG
137     printf("Strange unlock behavior..\n");
138 #endif
139     }
140    return(1);
141   }
142  } else // open() failed...
143  {
144    if (isdir(fn))
145    {
146 #ifdef DEBUG
147     printf("Directory %s not processed...\n",fn);
148 #endif
149     return(2);
150    }
151    else
152     return(1);
153  }
154 
155 }
156 
splits(char * s,char * p1,char * p2)157 int splits(char *s, char* p1, char* p2)
158 {
159  char *equal=strchr(s,'=');
160  char *p2tmp;
161  int pos1 = (((equal==NULL)||(equal<s))?0:(equal-s));
162 
163  s[pos1]=0x00;			// Needed, because strncpy is too stupid to
164  				// null-terminate a substring by itself!
165  strcpy(p1,"");
166  strcpy(p2,"");
167 
168  if (pos1==0) return(1); else
169  {
170  strncpy(p1, s, pos1+1);
171  strcpy(p2, equal+1);
172 
173 // p2tmp=malloc(strlen(p2));
174 // strncpy(p2tmp,p2,strlen(p2)-1);
175 // strcpy(p2,p2tmp);
176 // free(p2tmp);
177 
178  p2tmp=strchr(p2,0xa);		// Not very nice,
179  p2[(int)p2tmp-(int)p2]=0x00;	// but in fact: It works ;)
180 
181  while (p2[0]==' ') {p2++;}       		     // Again, quick and dirty..
182  while (p1[strlen(p1)-1]==' ') {p1[strlen(p1)-1]=0;} // Need to say anything?;)
183 
184  #ifdef DEBUG
185  printf("split(s='%s',p1='%s',p2='%s',pos1=%d);\n",s,p1,p2,pos1);
186  #endif
187  return(0);
188  }
189 
190 }
191 
addfolder(Twatchfolder * f,char * dir,char * prg,uid_t uid,int interval,int flags)192 void addfolder(Twatchfolder *f, char *dir, char *prg, uid_t uid, int interval, int flags)
193 {
194 
195 if (f==NULL)
196  {
197   folders=addelement(&defaultfolder, sizeof(defaultfolder), folders);
198   folders=tail(folders);
199   curfolder=(Twatchfolder *)folders->cur;
200   curfolder->filechain=newchain();
201   f=curfolder;
202  }
203  if (prg!=NULL) f->runprg=strdup(prg);
204  if (dir!=NULL) f->dir=strdup(dir);
205  if (uid!=-1) f->user=uid;
206  if (flags!=0) f->flags=flags;
207  if (interval!=-1)
208   {
209    f->interval=interval;
210    f->curcount=interval;
211   }
212 }
213 
flags2int(char * c)214 int flags2int(char *c)
215 {
216 int r=0;
217 char *i=(char *)malloc(strlen(c)+3);
218 char *s=i;
219 char *p;
220 
221 strcpy(s, c);
222 strcat(s, " ");
223 
224 while ((p=strstr(s," "))!=NULL)
225  {
226   p[0]=0x00;
227   if (strncasecmp("CHANGE",s, 6)==0)
228    r|=FL_ACT_CHANGE;
229 
230   if (strncasecmp("EXIST",s, 5)==0)
231    r|=FL_ACT_EXISTENCE;
232 
233   if (strncasecmp("COPY",s, 4)==0)
234    r|=FL_ACT_COPY;
235 
236   if (strncasecmp("DELETE",s, 6)==0)
237    r|=FL_ACT_DELETE;
238 
239   if (strncasecmp("SYSLOG",s, 6)==0)
240    r|=FL_LOG_SYSLOG;
241 
242   if (strncasecmp("FILELOG",s, 7)==0)
243    r|=FL_LOG_FILE;
244 
245   if (strncasecmp("MAILLOG",s, 7)==0)
246   {
247    r|=FL_LOG_MAIL;
248    printf("While parsing logfile: Warning: MAILLOG is not yet implemented!\n");
249   }
250 
251   if (strncasecmp("ALWAYSLOG",s, 9)==0)
252    r|=FL_LOG_ALWAYS;
253 
254   #ifdef DEBUG
255    printf("flags2int('%s') : parsed '%s', r=%d\n", c, s, r);
256   #endif
257   s=++p;
258  }
259 
260 free(i);
261 return(r);
262 }
263 
lowercase(char * c)264 void lowercase(char *c)
265 {
266 int i;
267 
268 for (i=0;i<strlen(c);i++)
269  {
270   c[i]=tolower(c[i]);
271  }
272 }
273 
parseequal(char * buf)274 void parseequal(char* buf)
275 {
276  char *tmpc1;
277  char *tmpc2;
278  char *tmpc3;
279  int tmpi;   // a place to store temorary integers ...
280 
281  tmpc1=malloc(strlen(buf)+1);
282  tmpc2=malloc(strlen(buf)+1);
283 
284  splits(buf, tmpc1, tmpc2);
285 
286  lowercase(tmpc1);      // Drop the case on the left side...
287 
288  #ifdef DEBUG
289  printf("lowercase returned '%s'!\n",tmpc1);
290  #endif
291 
292  if (strncmp(tmpc1,"prg",3)==0)
293   {
294    #ifdef DEBUG
295    printf("'prg' line found. Adding program...\n");
296    #endif
297    addfolder(curfolder, NULL, tmpc2, -1, -1, 0);
298   }
299 
300  if (strncmp(tmpc1,"dir",3)==0)
301   {
302    #ifdef DEBUG
303    printf("'dir' line found. Adding directory...\n");
304    #endif
305    addfolder(curfolder, tmpc2, NULL, -1, -1, 0);
306   }
307 
308  if (strncmp(tmpc1,"uid",3)==0)
309   {
310    #ifdef DEBUG
311    printf("'uid' line found. Modifying program...\n");
312    #endif
313    addfolder(curfolder,NULL,NULL,atoi(tmpc2), -1, 0);
314   }
315 
316  if (strncmp(tmpc1,"flags",5)==0)
317   {
318    #ifdef DEBUG
319    printf("'flags' line found. Modifying program...\n");
320    #endif
321    addfolder(curfolder,NULL,NULL, -1, -1, flags2int(tmpc2));
322   }
323 
324  if (strncmp(tmpc1,"interval",8)==0)
325   {
326    #ifdef DEBUG
327    printf("'interval' line found. Trying to set interval...\n");
328    #endif
329 
330    tmpc3=tmpc2;
331    tmpi=atoi(tmpc3);
332    if (tmpi>0) {
333    		addfolder(curfolder, NULL, NULL, -1, tmpi, 0);
334 	       } // set interval if the value is not completely
335    		 // brain-damaged!
336    #ifdef DEBUG
337    printf("set to %d!\n",interval);
338    #endif
339   }
340 
341  if (strncmp(tmpc1,"tempdir",7)==0)
342   {
343    #ifdef DEBUG
344    printf("'tempdir' line found. Trying to set tempdir...");
345    #endif
346    strcpy(tmpdir,tmpc2);
347    if (tmpdir[strlen(tmpdir)-1]!='/') {strcat(tmpdir,"/");}
348    #ifdef DEBUG
349    printf("set to %s!\n",tmpdir);
350    #endif
351   }
352 
353  if (strncmp(tmpc1,"mv",2)==0)
354   {
355    #ifdef DEBUG
356    printf("'mv' line found. Trying to set mvprg...");
357    #endif
358    strcpy(mvprg,tmpc2);
359    #ifdef DEBUG
360    printf("set to %s!\n",mvprg);
361    #endif
362   }
363 
364  if (strncmp(tmpc1,"rm",2)==0)
365   {
366    #ifdef DEBUG
367    printf("'rm' line found. Trying to set rmprg...");
368    #endif
369    strcpy(rmprg,tmpc2);
370    #ifdef DEBUG
371    printf("set to %s!\n",rmprg);
372    #endif
373   }
374 
375  if (strncmp(tmpc1,"cp",2)==0)
376   {
377    #ifdef DEBUG
378    printf("'cp' line found. Trying to set cpprg...");
379    #endif
380    strcpy(cpprg,tmpc2);
381    #ifdef DEBUG
382    printf("set to %s!\n",cpprg);
383    #endif
384   }
385 
386  if (strncmp(tmpc1,"mail",4)==0)
387   {
388    #ifdef DEBUG
389    printf("'mail' line found. Trying to set notify...");
390    #endif
391    curfolder->notify=strdup(tmpc2);
392    #ifdef DEBUG
393    printf("set to %s!\n",cpprg);
394    #endif
395   }
396 
397  if (strncmp(tmpc1,"logfile",7)==0)
398   {
399    #ifdef DEBUG
400    printf("'logfile' line found. Trying to set logfile...");
401    #endif
402    curfolder->logfile=strdup(tmpc2);
403    #ifdef DEBUG
404    printf("set to %s!\n",curfolder->logfile);
405    #endif
406   }
407 
408  free(tmpc1);
409  free(tmpc2);
410 }
411 
defraglst()412 void defraglst()
413 {
414 // FOO BAR
415 }
416 
parsecommon(inifile * i)417 void parsecommon(inifile *i)
418 {
419  char *s=NULL;
420 
421  while ((s=ini_nextline(i))!=NULL)
422   {
423    if (strchr(s, '=')!=NULL)
424     parseequal(s);
425    free(s);
426   }
427 }
428 
dumpfolders()429 void dumpfolders()
430 {
431 element *c=head(folders);
432 
433  while (c->next!=NULL)
434   {
435    c=c->next;
436    curfolder=(Twatchfolder *)c->cur;
437    if (c->cur!=NULL)
438     printf("Will watch dir '%s' for files and run '%s' on them with uid='%d' flags: %d\n",curfolder->dir, curfolder->runprg, curfolder->user, curfolder->flags);
439   }
440 }
441 
consolidate()442 void consolidate()
443 {
444 element *c=head(folders);
445 
446 while (c->next!=NULL)
447   {
448    c=c->next;
449    curfolder=(Twatchfolder *)c->cur;
450    if (((Twatchfolder *)c->cur)->dir==NULL)
451     {
452      folders=unchain(c);
453      c=head(folders);
454     }
455   }
456 }
457 
init()458 void init()
459 {
460  inifile *f;
461  char *buf;
462  int i;
463 
464  tmpdir=malloc(1024);
465  strcpy(tmpdir,"/tmp/");
466 
467  mvprg=malloc(1024);
468  strcpy(mvprg,"/bin/mv");
469 
470  rmprg=malloc(1024);
471  strcpy(rmprg,"/bin/rm");
472 
473  cpprg=malloc(1024);
474  strcpy(cpprg,"/bin/cp");
475 
476 
477  timeofgrace=30;
478 
479  defaultfolder.flags=(FL_ACT_EXISTENCE | FL_ACT_COPY | FL_ACT_DELETE);
480  defaultfolder.gracetime=timeofgrace;
481  defaultfolder.logfile=strdup("/dev/stdout");
482 
483  folders=newchain();
484 
485  buf=malloc(1024);
486 
487 f=ini_open(config_file);
488 
489  if (!f)
490   {
491    printf("Error: Could not open /usr/local/etc/watchd.conf (%s) , exiting..\n", strerror(errno));
492 
493 
494    free (defaultfolder.logfile);
495 
496    free (buf);
497    free (cpprg);
498    free (rmprg);
499    free (mvprg);
500    free (tmpdir);
501 
502    clearlst (folders);
503 
504    exit(1);
505   }
506 
507 
508  #ifdef DEBUG
509  printf("Stage 1 : Read common options..\n");
510  #endif
511 
512  i=ini_goto_grp(f, "common");
513  if (i!=-1)
514   {
515    parsecommon(f);
516   }
517 
518  #ifdef DEBUG
519  else printf("Waring: could't read common options\n");
520  #endif
521 
522 
523  #ifdef DEBUG
524  printf("Stage 2 : Read folders..\n");
525  #endif
526 
527  ini_rewind(f);
528  while ((ini_nextgrp(f)!=-1))
529  {
530  addfolder(NULL, NULL, NULL, -1, -1, 0);
531  if (strcasecmp(f->sts.cur_grp,"common")!=0)
532   while ((buf=ini_nextline(f))!=NULL)
533    {
534     if (strstr(buf,"=")!=NULL)
535       parseequal(buf);
536     free(buf);
537    }
538  }
539 
540  ini_close(f);
541 
542  consolidate();
543 
544  #ifdef DEBUG
545   dumpfolders();
546  #endif
547 }
548 
deinit()549 void deinit()
550 {
551 element *e=head(folders);
552 Twatchfolder *w;
553 
554 #ifdef DEBUG
555 printf("deinit");
556 #endif
557 
558 while (e!=NULL)
559  {
560   #ifdef DEBUG
561    printf(".");
562   #endif
563   w=(Twatchfolder *)e->cur;
564   if (w!=NULL)
565    {
566     free(w->runprg);
567     free(w->dir);
568     killfilechain(w->filechain);
569    }
570   e=unchain(e);
571  }
572 
573 #ifdef DEBUG
574 printf("deinited\n");
575 #endif
576 }
577 
run(char * cmd,char * arg1,char * arg2,char * arg3,char * arg4,uid_t uid,int logfd)578 int run(char* cmd, char* arg1, char* arg2, char* arg3, char* arg4, uid_t uid, int logfd)
579 {
580  char **args;
581  int f;
582  int r;
583 
584  #ifdef DEBUG
585  printf("run(cmd=%s,arg1=%s,arg2=%s,arg3=%s,arg4=%s)\n",cmd, arg1, arg2, arg3, arg4);
586  #endif
587  f=fork();
588  if (f==0) {
589   if (logfd>0)
590   {
591    dup2(logfd, STDOUT_FILENO);
592    dup2(STDOUT_FILENO , STDERR_FILENO);
593    close(logfd);
594   }
595   args=malloc(sizeof(args)*5); // allocate ram for 4 arguments...
596   args[0]=strdup(cmd);
597   args[1]=arg1!=NULL?strdup(arg1):NULL;
598   args[2]=arg2!=NULL?strdup(arg2):NULL;
599   args[3]=arg3!=NULL?strdup(arg3):NULL;
600   args[4]=arg4!=NULL?strdup(arg4):NULL;
601   deinit();
602   cmd=args[0];
603  #ifdef DEBUG
604   fprintf(stderr,"forked of, uid=%d...\n", uid);
605  #endif
606    if (uid!=-1)
607     {
608      #ifdef DEBUG
609      fprintf(stderr, "Doing setuid(%d)...",uid);
610      #endif
611      if (setuid(uid)!=0)
612       {
613        #ifdef DEBUG
614        printf("failed!\n");
615        #endif
616        syslog(LOG_WARNING||LOG_DAEMON,"Could not setuid(%d): %s", uid, strerror(errno));
617       }
618      #ifdef DEBUG
619      printf("ok..\n");
620      #endif
621     }
622   #ifdef DEBUG
623   printf("Executing %s...\n", cmd);
624   #endif
625   execvp(cmd,args);
626   printf("Something went wrong! Could not execute %s... (%s) ",cmd, strerror(errno));
627   syslog(LOG_WARNING||LOG_DAEMON,"Could not execute %s",cmd);
628   exit(0); // Should never occur, but we are paranoid...
629  } else
630  {
631  #ifdef DEBUG
632   printf("pid of child=%d\n",f);
633  #endif
634   waitpid(f,&r,0); // wait for process to finish..
635  #ifdef DEBUG
636   printf("child died: pid=%d return=%d\n", f, r);
637  #endif
638  }
639 
640  return(r);
641 }
642 
prepare_logfd(Twatchfolder * folder,int * fd)643 char *prepare_logfd(Twatchfolder *folder, int *fd)
644 {
645 int r=-1;
646 char *name=strdup("/tmp/watchdrun.XXXXXX");
647 
648 if ((folder->flags & (FL_LOG_SYSLOG|FL_LOG_FILE|FL_LOG_MAIL))!=0)
649  {
650   r=mkstemp(name);
651  }
652 
653 *fd=r;
654 
655 return(name);
656 }
657 
finalize_logfd(int fd,int r,Twatchfolder * folder,char * logname)658 void finalize_logfd(int fd, int r, Twatchfolder *folder, char *logname)
659 {
660 int log,l;
661 char buf[512];
662 FILE *f;
663 
664 #ifdef DEBUG
665  printf("Entering  finalize_logfd(fd=%i, r=%d, folder, logname='%s');\n", fd, r, logname);
666 #endif
667 if (fd>0)
668  {
669 
670   if ((folder->flags&FL_LOG_ALWAYS) | (r!=0))
671    {
672     if (folder->flags&FL_LOG_FILE)
673     {
674      log=open(curfolder->logfile, O_CREAT | O_WRONLY | O_APPEND );
675      if (log>0)
676       {
677        lseek(fd, SEEK_SET, 0); // Rewind temp log file..
678        snprintf(buf, 511, "Program %s returned %d, stdout/err follows:\n", folder->runprg, r);
679        write(log, buf, strlen(buf));
680        l=222222;
681        while (l>0)
682         {
683          l=read(fd, buf, 512);
684    	 write(log, buf, l);
685          }
686        if (close(fd))     // Close the tempfile
687         {
688 	 #ifdef DEBUG
689 	 printf("Error closing fd=%d!\n",fd);
690 	 #endif
691 	}
692 
693        fd=0;
694        close(log);
695       }
696     }
697 
698     if (folder->flags&FL_LOG_SYSLOG)
699      {
700       lseek(fd, SEEK_SET, 0); // Rewind temp log file..
701       snprintf(buf, 511, "Program %s returned %d, stdout/err follows:\n", folder->runprg, r);
702       openlog(folder->runprg, LOG_PID, LOG_DAEMON);
703       f=fdopen(fd, "r");
704       while (!feof(f))
705        {
706         if (fgets(buf, 511, f)!=NULL)
707          syslog((r==0)?LOG_NOTICE:LOG_WARNING, "%s\n", buf);
708        }
709       closelog();
710       fclose(f);
711        if (close(fd))     // Close the tempfile
712         {
713 	 #ifdef DEBUG
714 	 printf("Error closing fd=%d!\n",fd);
715 	 #endif
716 	}
717       fd=0;
718      }
719 
720    }
721 
722  if (fd!=0)
723   close(fd);
724  unlink(logname);  // Kill it!
725  }
726 }
727 
728 //void processfile(char *file, char *srcdir, char *cmd, uid_t uid)
processfile(char * file,Twatchfolder * folder)729 int processfile(char *file, Twatchfolder *folder)
730 {
731 char *complete;
732 char *srcfile;
733 char *logname;
734 struct timeval tp;
735 Twatchfolder w;
736 int logfd,r;
737 
738 memcpy(&w,folder,sizeof(w));
739 
740 #ifdef DEBUG
741  printf("processfile called! (folder=%s, flags=%d\n)\n", w.dir, w.flags);
742 #endif
743 
744 complete=malloc(1024);
745 srcfile=malloc(1024);
746 
747 strcpy(srcfile,w.dir);
748 strcat(srcfile,"/");
749 strcat(srcfile,file);
750 
751 #ifdef DEBUG
752  printf("calling checkfile...\n");
753 #endif
754 
755 if ((w.flags & FL_ACT_CHANGE)!=0)
756  if (checkfile(srcfile, 0, w.filechain)!=2)
757  {
758   // Happens in case a folder should be watched for changes
759   // an there is no demand of processing
760   free(complete);
761   free(srcfile);
762   return(0);
763  }
764 
765  if ((r=get_filestate(srcfile))==1) {
766   syslog(LOG_NOTICE||LOG_DAEMON,"processing %s with %s",file,w.runprg);
767 
768   if ((w.flags & FL_ACT_COPY)!=0)
769   {
770    gettimeofday(&tp,NULL);
771    sprintf(complete, "%s/watchdtmp.%d%d", tmpdir, tp.tv_sec, tp.tv_usec);
772 
773    mkdir(complete,0700);
774    #ifdef DEBUG
775     printf("created tempdir : %s\n",complete);
776    #endif
777 
778    chown(complete, w.user, 0);
779    #ifdef DEBUG
780     printf("doing  chown(%d, %d)", w.user, 0);
781    #endif
782 
783    #ifdef DEBUG
784     printf("running cp...\n");
785    #endif
786    run(cpprg,srcfile,complete, NULL, NULL, w.user, -1);
787 
788    if ((w.flags & FL_ACT_DELETE)!=0)
789     {
790      #ifdef DEBUG
791       printf("running rm...\n");
792      #endif
793      run(rmprg, srcfile, NULL, NULL, NULL, w.user, -1);
794     }
795    strcpy(srcfile,complete);
796    strcat(srcfile,"/");
797    strcat(srcfile,file);
798   }
799 
800   logname=prepare_logfd(folder, &logfd);
801   r=run(w.runprg, srcfile, NULL, NULL, NULL, w.user, logfd);
802   finalize_logfd(logfd, r, folder, logname);
803 
804   if ((w.flags & FL_ACT_COPY) == FL_ACT_COPY)
805    run(rmprg,"-rf",complete, NULL, NULL, w.user, -1);
806 
807   if ((w.flags & FL_ACT_DELETE)!=0)
808     run(rmprg,"-rf",srcfile, NULL, NULL, w.user, -1);
809 
810  } else {
811   if (r!=2)
812    syslog(LOG_NOTICE||LOG_DAEMON,"file %s is locked, not processed",file,w.runprg);
813  }
814  free(complete);
815  free(srcfile);
816  //printf("flushing...\n");
817  fflush(stdout);
818  fflush(stdin);
819  fflush(stderr);
820  return 0;
821 
822 }
823 
isdir(char * name)824 int isdir(char *name)
825 {
826  struct stat st;
827 
828  #ifdef DEBUG
829  printf("isdir(%s)=", name);
830  #endif
831 
832  stat(name, &st);
833  if (S_ISDIR(st.st_mode)) {
834  #ifdef DEBUG
835    printf("1\n");
836  #endif
837    return(1);
838   } else {
839  #ifdef DEBUG
840    printf("0\n");
841  #endif
842    return(0);
843    }
844 }
845 
processdir(Twatchfolder * f)846 void processdir(Twatchfolder *f)
847 {
848  DIR* dir=NULL;
849  struct dirent *de;
850  char* tmpS;
851 //  int child;
852 
853  #ifdef DEBUG
854   printf("Processing dir '%s' prg='%s' uid='%d' interval='%d' curcount='%d'...\n", f->dir, f->runprg, f->user, f->interval, f->curcount);
855  #endif
856  if (f->dir!=NULL) dir=opendir(f->dir); else dir=NULL;
857  tmpS=malloc(1024);
858  if (dir!=NULL)
859   {
860    de=readdir(dir);
861    while (de!=NULL)
862    {
863     if ((strcmp(de->d_name,".")!=0) && (strcmp(de->d_name,"..")!=0))  { // we don't process dirs, yet...
864        #ifdef DEBUG
865 	printf("Processing '%s' (de->d_name).\n ", de->d_name);
866        #endif
867        processfile(de->d_name,f);
868 //       if (isdir(de->d_name)==0) {
869          #ifdef DEBUG
870          printf("Entering processdir()...");
871 	 #endif
872 //         processfile(de->d_name,f->dir,f->runprg, f->user);
873 /*	} else
874 	{
875          syslog(LOG_WARNING||LOG_DAEMON,"sorry, cannot read dirs, currently ",folders[n].dir);
876 	 printf("Found a dir!\n");
877 	 //processdir(de->d_name);
878 	} */
879 
880     }
881      de=readdir(dir);
882    }
883    closedir(dir);
884   } else
885   { printf("Warning: Could not read directory '%s'\n",f->dir);
886     syslog(LOG_WARNING||LOG_DAEMON,"could not read directory %s",f->dir);
887   }
888   free(tmpS);
889 }
890 
sighandler(int signal)891 void sighandler(int signal)
892 {
893  if (signal==SIGHUP)
894   {
895    init();  // Reread config file!
896   }
897 }
898 
899 
process_args(int argc,char * argv[])900 int process_args (int argc, char *argv[])
901 {
902 	if (argc < 2)
903 	{
904 		printf ("Usage: %s [config file]\n", argv[0]);
905 		config_file = default_config_filename;
906 		printf ("Using config file: %s\n", config_file);
907 
908 
909 //		exit (1);
910 	}
911 	else
912 	{
913 		config_file = argv[1];
914 		printf ("Using config file: %s\n", config_file);
915 	}
916 	return 0;
917 }
918 
main(int argc,char * argv[])919 int main(int argc, char *argv[])
920 {
921 //  int i;
922  element *c;
923 
924  process_args (argc, argv);
925 
926 // signal(SIGHUP, sighandler);
927 
928  init();
929 
930  #ifndef DEBUG
931  if (fork()==0) {
932  #endif
933  while (1)
934  {
935  c=head(folders);
936   while (c->next!=NULL)
937   {
938    c=c->next;
939    if (c->cur!=NULL)
940     {
941      if (((Twatchfolder *)c->cur)->gracetime--<1)
942       {
943        #ifdef DEBUG
944         printf("scanchain()\n");
945        #endif
946        ((Twatchfolder *)c->cur)->filechain=scanchain(((Twatchfolder *)c->cur)->filechain);
947        ((Twatchfolder *)c->cur)->gracetime=timeofgrace;
948       }
949      if (((Twatchfolder *)c->cur)->curcount--<1)
950       {
951        processdir((Twatchfolder *)c->cur);
952        ((Twatchfolder *)c->cur)->curcount=((Twatchfolder *)c->cur)->interval-1;
953       }
954     }
955   }
956   sleep(interval);
957  }
958  #ifndef DEBUG
959  }
960  return(0);
961  #endif
962 }
963