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