00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "../pub/getopt.h"
00032 #include "cf.defs.h"
00033 #include "cf.extern.h"
00034
00035 #ifdef NT
00036 #include <process.h>
00037 #endif
00038
00039
00040
00041
00042
00043
00044 #ifdef HAVE_PTHREAD_H
00045 # include <pthread.h>
00046 #endif
00047
00048 #ifdef HAVE_SCHED_H
00049 # include <sched.h>
00050 #endif
00051
00052 #ifdef HAVE_PTHREAD_H
00053 pthread_attr_t PTHREADDEFAULTS;
00054 pthread_mutex_t MUTEX_COUNT = PTHREAD_MUTEX_INITIALIZER;
00055 pthread_mutex_t MUTEX_HOSTNAME = PTHREAD_MUTEX_INITIALIZER;
00056 #endif
00057
00058
00059
00060
00061
00062 int NO_FORK = false;
00063 int ONCE = false;
00064
00065 struct option CFDOPTIONS[] =
00066 {
00067 { "help",no_argument,0,'h' },
00068 { "debug",optional_argument,0,'d' },
00069 { "verbose",no_argument,0,'v' },
00070 { "file",required_argument,0,'f' },
00071 { "no-fork",no_argument,0,'F' },
00072 { "once",no_argument,0,'1'},
00073 { "foreground",no_argument,0,'g'},
00074 { "parse-only",no_argument,0,'p'},
00075 { "ld-library-path",required_argument,0,'L'},
00076 { NULL,0,0,0 }
00077 };
00078
00079 char MAILTO[bufsize];
00080 int MAXLINES = -1;
00081 const int INF_LINES = -2;
00082
00083
00084
00085
00086
00087 void CheckOptsAndInit ARGLIST((int argc,char **argv));
00088 void StartServer ARGLIST((int argc, char **argv));
00089 void Syntax ARGLIST((void));
00090 void *ExitCleanly ARGLIST((void));
00091 void *LocalExec ARGLIST((void *dummy));
00092 void MailResult ARGLIST((char *filename, char *to));
00093 int ScheduleRun ARGLIST((void));
00094 void AddClassToHeap ARGLIST((char *class));
00095 void DeleteClassFromHeap ARGLIST((char *class));
00096 void Dialogue ARGLIST((int sd,char *class));
00097 void GetCfStuff ARGLIST((void));
00098
00099
00100
00101
00102 int CompareResult ARGLIST((char *filename, char *prev_file));
00103 int FileChecksum ARGLIST((char *filename, unsigned char *digest, char type));
00104
00105
00106
00107
00108
00109 int main (argc,argv)
00110
00111 int argc;
00112 char **argv;
00113
00114 { time_t starttime = time(NULL);
00115
00116 CheckOptsAndInit(argc,argv);
00117
00118 if (!ONCE)
00119 {
00120
00121
00122 if (!GetLock("cfexecd","execd",0,0,VUQNAME,starttime))
00123 {
00124 snprintf(OUTPUT,bufsize*2,"cfexecd: Couldn't get a lock -- exists or too soon: IfElapsed %d, ExpireAfter %d\n",0,0);
00125 CfLog(cfverbose,OUTPUT,"");
00126 return 1;
00127 }
00128 }
00129
00130 StartServer(argc,argv);
00131
00132 if (!ONCE)
00133 {
00134 ReleaseCurrentLock();
00135 }
00136
00137 return 0;
00138 }
00139
00140
00141
00142
00143
00144 void CheckOptsAndInit(argc,argv)
00145
00146 int argc;
00147 char **argv;
00148
00149 { extern char *optarg;
00150 int optindex = 0;
00151 char ld_library_path[bufsize];
00152 int c;
00153
00154 ld_library_path[0] = '\0';
00155
00156 sprintf(VPREFIX, "cfexecd");
00157 openlog(VPREFIX,LOG_PID|LOG_NOWAIT|LOG_ODELAY,LOG_DAEMON);
00158
00159 while ((c=getopt_long(argc,argv,"L:d:vhpFV1g",CFDOPTIONS,&optindex)) != EOF)
00160 {
00161 switch ((char) c)
00162 {
00163 case 'd':
00164
00165 switch ((optarg==NULL)?3:*optarg)
00166 {
00167 case '1': D1 = true;
00168 break;
00169 case '2': D2 = true;
00170 break;
00171 default: DEBUG = true;
00172 break;
00173 }
00174
00175 NO_FORK = true;
00176 printf("cfexecd Debug mode: running in foreground\n");
00177 break;
00178
00179 case 'v': VERBOSE = true;
00180 break;
00181
00182 case 'V': printf("GNU %s-%s daemon\n%s\n",PACKAGE,VERSION,COPYRIGHT);
00183 printf("This program is covered by the GNU Public License and may be\n");
00184 printf("copied free of charge. No warrenty is implied.\n\n");
00185 exit(0);
00186 break;
00187
00188 case 'p': PARSEONLY = true;
00189 break;
00190
00191 case 'g': NO_FORK = true;
00192 break;
00193
00194 case 'L': Verbose("Setting LD_LIBRARY_PATH=%s\n",optarg);
00195 snprintf(ld_library_path,bufsize-1,"LD_LIBRARY_PATH=%s",optarg);
00196 putenv(ld_library_path);
00197 break;
00198
00199 case 'F':
00200 case '1': ONCE = true;
00201 NO_FORK = true;
00202 break;
00203
00204 default: Syntax();
00205 exit(1);
00206
00207 }
00208 }
00209
00210 LOGGING = true;
00211
00212 snprintf(VBUFF,bufsize,"%s/inputs/update.conf",WORKDIR);
00213 MakeDirectoriesFor(VBUFF,'y');
00214 snprintf(VBUFF,bufsize,"%s/bin/cfagent",WORKDIR);
00215 MakeDirectoriesFor(VBUFF,'y');
00216 snprintf(VBUFF,bufsize,"%s/outputs/spooled_reports",WORKDIR);
00217 MakeDirectoriesFor(VBUFF,'y');
00218
00219 snprintf(VBUFF,bufsize,"%s/inputs",WORKDIR);
00220 chmod(VBUFF,0700);
00221 snprintf(VBUFF,bufsize,"%s/outputs",WORKDIR);
00222 chmod(VBUFF,0700);
00223
00224 strncpy(VLOCKDIR,WORKDIR,bufsize-1);
00225 strncpy(VLOGDIR,WORKDIR,bufsize-1);
00226
00227 VCANONICALFILE = strdup(CanonifyName(VINPUTFILE));
00228 GetNameInfo();
00229
00230 strcpy(VUQNAME,VSYSNAME.nodename);
00231 }
00232
00233
00234
00235
00236 void StartServer(argc,argv)
00237
00238 int argc;
00239 char **argv;
00240
00241 { int time_to_run = false;
00242 time_t now = time(NULL);
00243
00244 if ((!NO_FORK) && (fork() != 0))
00245 {
00246 snprintf(OUTPUT,bufsize*2,"cfexecd starting %.24s\n",ctime(&now));
00247 CfLog(cfinform,OUTPUT,"");
00248 exit(0);
00249 }
00250
00251 if (!NO_FORK)
00252 {
00253 ActAsDaemon(0);
00254 }
00255
00256 signal(SIGINT,(void *)ExitCleanly);
00257 signal(SIGTERM,(void *)ExitCleanly);
00258 signal(SIGHUP,SIG_IGN);
00259 signal(SIGPIPE,SIG_IGN);
00260
00261 umask(077);
00262
00263 if (ONCE)
00264 {
00265 GetCfStuff();
00266 LocalExec(NULL);
00267 }
00268 else
00269 { char **nargv;
00270 int i;
00271 int pid;
00272 #ifdef HAVE_PTHREAD_H
00273 pthread_t tid;
00274 #endif
00275
00276
00277
00278
00279 nargv = malloc(sizeof(char *) * argc+2);
00280
00281 for (i = 0; i < argc; i++)
00282 {
00283 nargv[i] = argv[i];
00284 }
00285
00286 nargv[i++] = strdup("--once");
00287 nargv[i++] = NULL;
00288
00289 GetCfStuff();
00290
00291 while (true)
00292 {
00293 time_to_run = ScheduleRun();
00294
00295 if (time_to_run)
00296 {
00297 if (!GetLock("cfd","exec",exec_ifelapsed,exec_expireafter,VUQNAME,time(NULL)))
00298 {
00299 snprintf(OUTPUT,bufsize*2,"cfexecd: Couldn't get exec lock -- exists or too soon: IfElapsed %d, ExpireAfter %d\n",exec_ifelapsed,exec_expireafter);
00300 CfLog(cfverbose,OUTPUT,"");
00301 continue;
00302 }
00303
00304 GetCfStuff();
00305
00306 #ifdef NT
00307
00308
00309
00310
00311
00312 Debug("Spawning %s\n", nargv[0]);
00313 pid = spawnvp((int)_P_NOWAIT, nargv[0], nargv);
00314 if (pid < 1)
00315 {
00316 CfLog(cferror,"Can't spawn run","spawnvp");
00317 }
00318
00319 #elsif (defined HAVE_LIBPTHREAD || defined BUILDTIN_GCC_THREAD)
00320
00321 pthread_attr_init(&PTHREADDEFAULTS);
00322 pthread_attr_setdetachstate(&PTHREADDEFAULTS,PTHREAD_CREATE_DETACHED);
00323
00324 #ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
00325 pthread_attr_setstacksize(&PTHREADDEFAULTS,(size_t)2048*1024);
00326 #endif
00327
00328 if (pthread_create(&tid,&PTHREADDEFAULTS,LocalExec,NULL) != 0)
00329 {
00330 CfLog(cferror,"Can't create thread!","pthread_create");
00331 LocalExec(NULL);
00332 }
00333
00334 pthread_attr_destroy(&PTHREADDEFAULTS);
00335 #else
00336 LocalExec(NULL);
00337 #endif
00338
00339 ReleaseCurrentLock();
00340 }
00341 }
00342 }
00343 }
00344
00345
00346
00347
00348
00349 void Syntax()
00350
00351 { int i;
00352
00353 printf("GNU cfengine daemon: scheduler\n%s-%s\n%s\n",PACKAGE,VERSION,COPYRIGHT);
00354 printf("\n");
00355 printf("Options:\n\n");
00356
00357 for (i=0; CFDOPTIONS[i].name != NULL; i++)
00358 {
00359 printf("--%-20s (-%c)\n",CFDOPTIONS[i].name,(char)CFDOPTIONS[i].val);
00360 }
00361
00362 printf("\nBug reports to bug-cfengine@gnu.org (News: gnu.cfengine.bug)\n");
00363 printf("General help to help-cfengine@gnu.org (News: gnu.cfengine.help)\n");
00364 printf("Info & fixes at http://www.iu.hio.no/cfengine\n");
00365 }
00366
00367
00368
00369 void GetCfStuff()
00370
00371 { FILE *pp;
00372 char cfcom[bufsize];
00373 static char line[bufsize];
00374
00375 snprintf(cfcom,bufsize-1,"%s/bin/cfagent -z",WORKDIR);
00376
00377 if ((pp=cfpopen(cfcom,"r")) == NULL)
00378 {
00379 CfLog(cferror,"Couldn't start cfengine!","cfpopen");
00380 line[0] = '\0';
00381 return;
00382 }
00383
00384 line[0] = '\0';
00385 fgets(line,bufsize,pp);
00386 Chop(line);
00387
00388 while (strstr(line,":"))
00389 {
00390 line[0] = '\0';
00391 fgets(line,bufsize,pp);
00392 Chop(line);
00393 }
00394
00395 if (strstr(line,"No SMTP"))
00396 {
00397 CfLog(cferror,"cfengine defines no SMTP server (not even localhost)","");
00398 CfLog(cferror,"Need: smtpserver = ( ?? ) in control ","");
00399 }
00400
00401 strcpy(VMAILSERVER,line);
00402
00403 Debug("Got cfengine SMTP server as (%s)\n",VMAILSERVER);
00404
00405 line[0] = '\0';
00406 fgets(line,bufsize,pp);
00407 Chop(line);
00408
00409 if (strlen(line) == 0)
00410 {
00411 CfLog(cferror,"cfengine defines no system administrator address","");
00412 CfLog(cferror,"Need: sysadm = ( ??@?? ) in control ","");
00413 }
00414
00415 strcpy(MAILTO,line);
00416 Debug("Got cfengine sysadm variable (%s)\n",MAILTO);
00417
00418 line[0] = '\0';
00419 fgets(line,bufsize,pp);
00420 Chop(line);
00421 strcpy(VFQNAME,line);
00422 Debug("Got fully qualified name (%s)\n",VFQNAME);
00423
00424 line[0] = '\0';
00425 fgets(line,bufsize,pp);
00426 Chop(line);
00427 strcpy(VIPADDRESS,line);
00428 Debug("Got IP (%s)\n",VIPADDRESS);
00429
00430 if ((ungetc(fgetc(pp), pp)) != '[')
00431 {
00432 line[0] = '\0';
00433 fgets(line,bufsize,pp);
00434 Chop(line);
00435 if (sscanf(line, "%d", &MAXLINES) == 1)
00436 {
00437 Debug("Got max lines (%d)\n", MAXLINES);
00438 }
00439 else if (strcmp(line, "inf") == 0)
00440 {
00441 Debug("Infinite lines\n");
00442 MAXLINES = INF_LINES;
00443 }
00444 }
00445
00446 if (MAXLINES == -1)
00447 {
00448 MAXLINES = 100;
00449 Debug("Defaulting to max lines (%d)\n", MAXLINES);
00450 }
00451
00452
00453
00454 DeleteItemList(SCHEDULE);
00455 SCHEDULE = NULL;
00456
00457 while (!feof(pp))
00458 {
00459 line[0] = '\0';
00460 VBUFF[0] = '\0';
00461 fgets(line,bufsize,pp);
00462 sscanf(line,"[%[^]]",VBUFF);
00463
00464 if (strlen(VBUFF)==0)
00465 {
00466 continue;
00467 }
00468
00469 if (!IsItemIn(SCHEDULE,VBUFF))
00470 {
00471 AppendItem(&SCHEDULE,VBUFF,NULL);
00472 }
00473 }
00474
00475 cfpclose(pp);
00476
00477 if (SCHEDULE == NULL)
00478 {
00479 Verbose("No schedule defined in cfagent.conf, defaulting to Min00_05\n");
00480 AppendItem(&SCHEDULE,"Min00_05",NULL);
00481 }
00482 }
00483
00484
00485
00486 int ScheduleRun()
00487
00488 { time_t now;
00489 char timekey[64];
00490 struct Item *ip;
00491
00492 Verbose("Sleeping...\n");
00493 sleep(60);
00494
00495 now = time(NULL);
00496
00497 snprintf(timekey,63,"%s",ctime(&now));
00498 AddTimeClass(timekey);
00499
00500 for (ip = SCHEDULE; ip != NULL; ip = ip->next)
00501 {
00502 Verbose("Checking schedule %s...\n",ip->name);
00503 if (IsDefinedClass(ip->name))
00504 {
00505 Verbose("Waking up the agent at %s ~ %s \n",timekey,ip->name);
00506 DeleteItemList(VHEAP);
00507 VHEAP = NULL;
00508 GetNameInfo();
00509 return true;
00510 }
00511 }
00512
00513 DeleteItemList(VHEAP);
00514 VHEAP = NULL;
00515 GetNameInfo();
00516 return false;
00517 }
00518
00519
00520
00521
00522
00523 void *ExitCleanly()
00524
00525 {
00526 ReleaseCurrentLock();
00527 closelog();
00528
00529 exit(0);
00530 }
00531
00532
00533
00534 void *LocalExec(dummy)
00535
00536 void *dummy;
00537
00538 { FILE *pp;
00539 char line[bufsize],filename[bufsize],*sp;
00540 char cmd[bufsize];
00541 int print;
00542 time_t starttime = time(NULL);
00543 FILE *fp;
00544 #ifdef HAVE_PTHREAD_SIGMASK
00545 sigset_t sigmask;
00546
00547 sigemptyset(&sigmask);
00548 pthread_sigmask(SIG_BLOCK,&sigmask,NULL);
00549 #endif
00550
00551
00552 Verbose("------------------------------------------------------------------\n\n");
00553 Verbose(" LocalExec at %s\n",ctime(&starttime));
00554 Verbose("------------------------------------------------------------------\n");
00555
00556
00557
00558 snprintf(cmd,bufsize-1,"%s/bin/cfagent",WORKDIR);
00559 snprintf(line,100,CanonifyName(ctime(&starttime)));
00560 snprintf(filename,bufsize-1,"%s/outputs/cf_%s_%s",WORKDIR,CanonifyName(VFQNAME),line);
00561
00562
00563
00564
00565 if ((fp = fopen(filename,"w")) == NULL)
00566 {
00567 snprintf(OUTPUT,bufsize,"Couldn't open %s\n",filename);
00568 CfLog(cferror,OUTPUT,"fopen");
00569 return NULL;
00570 }
00571
00572 if ((pp = cfpopen(cmd,"r")) == NULL)
00573 {
00574 snprintf(OUTPUT,bufsize,"Couldn't open pipe to command %s\n",cmd);
00575 CfLog(cferror,OUTPUT,"cfpopen");
00576 return NULL;
00577 }
00578
00579 while (!feof(pp) && ReadLine(line,bufsize,pp))
00580 {
00581 if (ferror(pp))
00582 {
00583 fflush(pp);
00584 break;
00585 }
00586
00587 print = false;
00588
00589 for (sp = line; *sp != '\0'; sp++)
00590 {
00591 if (! isspace((int)*sp))
00592 {
00593 print = true;
00594 break;
00595 }
00596 }
00597
00598 if (print)
00599 {
00600 fprintf(fp,"%s\n",line);
00601
00602
00603
00604 if (strlen(MAILTO) == 0)
00605 {
00606 strcat(line,"\n");
00607 CfLog(cfinform,line,"");
00608 }
00609
00610 line[0] = '\0';
00611 }
00612 }
00613
00614 cfpclose(pp);
00615 Debug("Closing fp\n");
00616 fclose(fp);
00617 closelog();
00618
00619 MailResult(filename,MAILTO);
00620 return NULL;
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 int FileChecksum(filename,digest,type)
00633
00634 char *filename,type;
00635 unsigned char digest[EVP_MAX_MD_SIZE+1];
00636
00637 { FILE *file;
00638 EVP_MD_CTX context;
00639 int len, md_len;
00640 unsigned char buffer[1024];
00641 const EVP_MD *md = NULL;
00642
00643 Debug2("ChecksumFile(%c,%s)\n",type,filename);
00644 OpenSSL_add_all_digests();
00645
00646 if ((file = fopen (filename, "rb")) == NULL)
00647 {
00648 printf ("%s can't be opened\n", filename);
00649 }
00650 else
00651 {
00652 switch (type)
00653 {
00654 case 's': md = EVP_get_digestbyname("sha");
00655 break;
00656 case 'm': md = EVP_get_digestbyname("md5");
00657 break;
00658 default: FatalError("Software failure in ChecksumFile");
00659 }
00660
00661 if (!md)
00662 {
00663 return 0;
00664 }
00665
00666 EVP_DigestInit(&context,md);
00667
00668 while (len = fread(buffer,1,1024,file))
00669 {
00670 EVP_DigestUpdate(&context,buffer,len);
00671 }
00672
00673 EVP_DigestFinal(&context,digest,&md_len);
00674
00675
00676 fclose (file);
00677
00678 return(md_len);
00679 }
00680
00681 return 0;
00682 }
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692 int CompareResult(filename, prev_file)
00693
00694 char *filename, *prev_file;
00695
00696 { int i;
00697 char digest1[EVP_MAX_MD_SIZE+1];
00698 char digest2[EVP_MAX_MD_SIZE+1];
00699 int md_len1, md_len2;
00700 FILE *fp;
00701
00702 Verbose("Comparing files %s with %s\n", prev_file, filename);
00703
00704 if ((fp=fopen(prev_file,"r")) != NULL)
00705 {
00706 fclose(fp);
00707
00708 md_len1 = FileChecksum(prev_file, digest1, 'm');
00709 md_len2 = FileChecksum(filename, digest2, 'm');
00710
00711 if (md_len1 != md_len2)
00712 {
00713 return(1);
00714 }
00715
00716 for (i = 0; i < md_len1; i++)
00717 {
00718 if (digest1[i] != digest2[i])
00719 {
00720
00721 unlink(prev_file);
00722 if (symlink(filename, prev_file) == -1)
00723 {
00724 snprintf(OUTPUT,bufsize,"Could not link %s and %s",filename,prev_file);
00725 CfLog(cfinform,OUTPUT,"symlink");
00726 }
00727
00728 return(1);
00729 }
00730 }
00731
00732 return(0);
00733 }
00734 else
00735 {
00736
00737 if ( symlink(filename, prev_file) == -1 )
00738 {
00739 snprintf(OUTPUT,bufsize,"Could not link %s and %s",filename,prev_file);
00740 CfLog(cfinform,OUTPUT,"symlink");
00741 }
00742 return(1);
00743 }
00744 }
00745
00746
00747
00748 void MailResult(file,to)
00749
00750 char *file,*to;
00751
00752 { int sd, sent, count = 0;
00753 struct hostent *hp;
00754 struct sockaddr_in raddr;
00755 struct servent *server;
00756 struct stat statbuf;
00757 FILE *fp;
00758
00759
00760 char prev_file[bufsize];
00761
00762 if ((strlen(VMAILSERVER) == 0) || (strlen(to) == 0))
00763 {
00764
00765 return;
00766 }
00767
00768 if (stat(file,&statbuf) == -1)
00769 {
00770 exit(0);
00771 }
00772
00773
00774 snprintf(prev_file,bufsize-1,"%s/outputs/previous",WORKDIR);
00775
00776 if (statbuf.st_size == 0)
00777 {
00778 unlink(file);
00779
00780
00781
00782
00783 if ((fp=fopen(prev_file, "r")) != NULL )
00784 {
00785 fclose(fp);
00786 unlink(prev_file);
00787 }
00788
00789 Debug("Nothing to report in %s\n",file);
00790 return;
00791 }
00792
00793
00794
00795
00796
00797 if ( CompareResult(file,prev_file) == 0 )
00798 {
00799 Verbose("Previous output is the same as current so do not mail it\n");
00800 return;
00801 }
00802
00803 if (MAXLINES == 0)
00804 {
00805 Debug("Not mailing: EmailMaxLines was zero\n");
00806 return;
00807 }
00808
00809 Debug("Mailing results of (%s) to (%s)\n",file,to);
00810
00811 if (strlen(to) == 0)
00812 {
00813 return;
00814 }
00815
00816 if ((fp=fopen(file,"r")) == NULL)
00817 {
00818 snprintf(VBUFF,bufsize-1,"Couldn't open file %s",file);
00819 CfLog(cferror,VBUFF,"fopen");
00820 return;
00821 }
00822
00823
00824 if ((hp = gethostbyname(VMAILSERVER)) == NULL)
00825 {
00826 printf("Unknown host: %s\n", VMAILSERVER);
00827 printf("Make sure that fully qualified names can be looked up at your site!\n");
00828 printf("i.e. www.gnu.org, not just www. If you use NIS or /etc/hosts\n");
00829 printf("make sure that the full form is registered too as an alias!\n");
00830 return;
00831 }
00832
00833 if ((server = getservbyname("smtp","tcp")) == NULL)
00834 {
00835 CfLog(cferror,"Unable to lookup smtp service","getservbyname");
00836 return;
00837 }
00838
00839 bzero(&raddr,sizeof(raddr));
00840
00841 raddr.sin_port = (unsigned int) server->s_port;
00842 raddr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
00843 raddr.sin_family = AF_INET;
00844
00845 if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1)
00846 {
00847 CfLog(cferror,"Couldn't open a socket","socket");
00848 return;
00849 }
00850
00851 if (connect(sd,(void *) &raddr,sizeof(raddr)) == -1)
00852 {
00853 snprintf(OUTPUT,bufsize*2,"Couldn't connect to host %s\n",VMAILSERVER);
00854 CfLog(cfinform,OUTPUT,"connect");
00855 close(sd);
00856 return;
00857 }
00858
00859 sprintf(VBUFF,"HELO %s\r\n",VFQNAME);
00860 Dialogue(sd,VBUFF);
00861
00862 sprintf(VBUFF,"MAIL FROM: <cfengine@%s>\r\n",VFQNAME);
00863 Dialogue(sd,VBUFF);
00864
00865 sprintf(VBUFF,"RCPT TO: <%s>\r\n",to);
00866 Dialogue(sd,VBUFF);
00867
00868 Dialogue(sd,"DATA\r\n");
00869
00870 sprintf(VBUFF,"Subject: (%s/%s)\r\n",VFQNAME,VIPADDRESS);
00871 sent=send(sd,VBUFF,strlen(VBUFF),0);
00872 sprintf(VBUFF,"To: %s\r\n\r\n",to);
00873 sent=send(sd,VBUFF,strlen(VBUFF),0);
00874
00875 while(!feof(fp))
00876 {
00877 VBUFF[0] = '\0';
00878 fgets(VBUFF,bufsize,fp);
00879 if (strlen(VBUFF) > 0)
00880 {
00881 VBUFF[strlen(VBUFF)-1] = '\r';
00882 strcat(VBUFF, "\n");
00883 count++;
00884 sent=send(sd,VBUFF,strlen(VBUFF),0);
00885 }
00886 if ((MAXLINES != INF_LINES) && (count > MAXLINES))
00887 {
00888 sprintf(VBUFF,"\r\n[Mail truncated by cfengine. File is at %s on %s]\r\n",file,VFQNAME);
00889 sent=send(sd,VBUFF,strlen(VBUFF),0);
00890 break;
00891 }
00892 }
00893
00894 Dialogue(sd,".\r\n");
00895 Dialogue(sd,"QUIT\r\n");
00896
00897
00898 fclose(fp);
00899 close(sd);
00900 Debug("Done sending mail\n");
00901 }
00902
00903
00904
00905
00906
00907 void Dialogue(sd,s)
00908
00909 int sd;
00910 char *s;
00911
00912 { int sent;
00913 char ch,buf[bufsize];
00914
00915 snprintf(buf,bufsize-1,s);
00916 sent=send(sd,s,strlen(s),0);
00917
00918 Debug("SENT(%d)->%s",sent,s);
00919
00920 while (recv(sd,&ch,1,0))
00921 {
00922 if (ch == '\n' || ch == '\0')
00923 {
00924 break;
00925 }
00926 }
00927 }
00928
00929
00930
00931
00932
00933 void RotateFiles(name,number)
00934
00935 char *name;
00936 int number;
00937
00938 {
00939
00940 }
00941
00942
00943 int RecursiveTidySpecialArea(name,tp,maxrecurse,sb)
00944
00945 char *name;
00946 struct Tidy *tp;
00947 int maxrecurse;
00948 struct stat *sb;
00949
00950 {
00951 return true;
00952 }
00953
00954
00955 void yyerror(s)
00956
00957 char *s;
00958
00959 {
00960 printf("%s\n",s);
00961 }
00962
00963
00964
00965
00966