?? updatehosts.c
字號:
/*** updatehosts - accept /etc/host file section updates via mail.**** Accepts mail on stdin, then looks at body of message for:** # begin: foo**** whereupon it writes this and all lines up to and including:** # end: foo**** to the file HOSTDIR/foo... If a line of the format:** # adminmail: goober** is encountered an acknowledgment is sent to goober. **** If it sees: ** send** it will send the sender a copy of the current hosts file. If it** sees:** help** it will send the sender a copy of the help file****** to make the program receive mail addressed to updatehosts,** add the following line to your /usr/lib/aliases file ** updatehosts: "|/usr/local/adm/hosts/updatehosts"**** Written by Bob Coggeshall (coggs@boulder.Colorado.EDU)***/#define JTY "Just thought you'd like to know.\n"#include <stdio.h>#include <ctype.h>#include <sys/param.h>#define HOSTDIR "/usr/local/adm/hosts/hostsrc/"#define HOSTS "/usr/local/adm/hosts/hostsrc/hosts"#define HELPFILE "/usr/local/adm/hosts/doc/updatehosts.catme"/** NEDITOR should be the name of the person allowed to edit **/#define NEDITOR "coggs"#define TEMPFILEPREF "/tmp/updatehosts."#define STDERR "/tmp/updatehosts.stderr"#define UMASK 002/** domainame contains your domain name **/char *domainame = "colorado.edu";char hostname[MAXHOSTNAMELEN];/* values used by upexit() */#define FAIL 1#define FAKEFAIL 0 /* avoid generating mail bounces */#define SUCCESS 0/* values returned by parsline() */#define BEGIN 1#define END 2#define ADMINMAIL 3#define MAILHEAD 4#define DATA 5#define SEND 6#define HELP 7#define SUBJECT 8 /* values used by mail() */#define INDENT 1#define NOINDENT 0char *gets();char *rindex();char *index();char *getcuradmin();FILE *fopen();FILE *freopen();char *progname;char wrkline[256]; /* yet another */char wrkline1[256]; /* yet another 1 */char realsender[256]; /* sender from the 'From ' line */char curadminmail[256]; /* current value of 'Adminmail:' arg from file */FILE *fd = NULL; /* file descriptor for writing section file */FILE *tfd = NULL; /* file descriptor for temp file */FILE *efd = NULL; /* file descriptor for stderr */char *cp; /* general purpose character pointer */char tempfile[256]; /* name of temporary file */main(ac,av)int ac;char **av;{ char arg[256]; /* rhs of arguments from input file */ char line[256]; /* general purpose line buffer */ char secfile[256]; /* name of section file */ char secname[256]; /* name of section */ char adminmail[256]; /* administrator mail arg */ int pid; /* process id */ int freadcount; /* count returned from fread() */ int systatus; /* returned by system() */ umask(UMASK); /* ** get the hostname and the program name. */ gethostname(hostname,sizeof(hostname)); if ((progname = rindex(*av,'/')) == 0) progname = *av; else progname++; /* ** redirect stderr to a file */ if ( (efd = freopen(STDERR,"w+",stderr)) == NULL) { sprintf(wrkline, "%s: couldn't freopen() %s", progname,STDERR); mail(NEDITOR,wrkline, JTY,0,0); } /* ** process input, parseline figures out what kind of line it is ** and this case statement decides what to do. */ while (gets(line) != NULL) { switch (parseline(line,arg)) { case ADMINMAIL: /* snarf adminmail arg */ if (tfd) { fputs(line,tfd); fputc('\n',tfd); } strcpy(adminmail,arg); /* ** check that old adminmail and new adminmail args match */ strcpy(wrkline,adminmail); if ((cp = index(wrkline,'@')) != 0) *cp = '\0'; strcpy(wrkline1,curadminmail); if ((cp = index(wrkline1,'@')) != 0) *cp = '\0'; if ( (strncmp(wrkline,wrkline1,sizeof(wrkline)) != 0) ) { sprintf(wrkline, "%s: new adminmail:%s and current adminmail: %s don't match", progname,adminmail,curadminmail); mail(NEDITOR,wrkline, JTY,0,0); upexit(FAKEFAIL); } break; case MAILHEAD: /* its the mail header, skip it */ strcpy(realsender,arg); /* snarf sender */ fprintf(stderr,"realsender: %s\n",realsender); break; case SUBJECT: break; case SEND: /* they want a copy of the whole thing */ sprintf(wrkline,"%s: copy of current hosts file:",progname); mail(realsender,wrkline,"",HOSTS,NOINDENT); sprintf(wrkline,"%s: sent %s copy of current hosts file", progname,realsender); mail(NEDITOR,wrkline,JTY,0,0); upexit(SUCCESS); break; case HELP: /* send them the help file */ sprintf(wrkline,"%s: help file",progname); mail(realsender,wrkline,"",HELPFILE,NOINDENT); sprintf(wrkline,"%s: sent %s the help file", progname,realsender); mail(NEDITOR,wrkline,JTY,0,0); upexit(SUCCESS); break; case DATA: /* its data, snarf it. */ if (tfd) { fputs(line,tfd); fputc('\n',tfd); } break; case BEGIN: /* ** if begin, then see if section file exists ** if it doesn't send mail and die. if it does ** open it tempfile for write. */ strcpy(secfile,HOSTDIR); strcpy(secname,arg); strcat(secfile,secname); if (access(secfile,0) != 0) { sprintf(wrkline,"%s: Can't access() %s", progname,secfile); mail(NEDITOR,wrkline, "File needs to exist before i'll overwrite it",0,0); upexit(FAKEFAIL); } /* ** read secfile and get the current adminmail: arg ** and authenticate by comparing it with sender */ strcpy(curadminmail,getcuradmin(secfile)); strcpy(wrkline,curadminmail); if ((cp = index(wrkline,'@')) != 0) *cp = '\0'; strcpy(wrkline1,realsender); if ((cp = index(wrkline1,'@')) != 0) *cp = '\0'; if ( (strncmp(wrkline,wrkline1,sizeof(wrkline)) != 0) ) { /* ** some exceptions.... */ strcpy(wrkline,NEDITOR); if ((cp = index(wrkline,'@')) != 0) *cp = '\0'; if ( (strncmp(wrkline,wrkline1,sizeof(wrkline)) == 0)|| strncmp(wrkline,"root",sizeof("root")) == 0) goto except; sprintf(wrkline, "%s: sender: %s and current adminmail: %s don't match", progname,realsender,curadminmail); mail(NEDITOR,wrkline, JTY,0,0); upexit(FAKEFAIL); } except: /* ** open temporary file. */ pid = getpid(); sprintf(tempfile,"%s%d",TEMPFILEPREF,pid); if ( (tfd = fopen(tempfile,"w+")) == 0) { sprintf(wrkline,"%s: Can't fopen() %s", progname,tempfile); mail(NEDITOR,wrkline,JTY,0,0); upexit(FAKEFAIL); } if ( (fputs("##\n",tfd)) == EOF) { sprintf(wrkline,"%s: %s: Write failed", progname, tempfile); mail(NEDITOR,wrkline,JTY,0,0); upexit(FAKEFAIL); } fputs(line,tfd); fputc('\n',tfd); break; case END: /* ** if end then close file, make sure begin and ** end agree. complain and die if not. otherwise ** send mail that things are ok */ strcpy(wrkline,HOSTDIR); strcat(wrkline,arg); if (strncmp(wrkline,secfile,strlen(tempfile)) != 0) { sprintf(wrkline,"%s %s",NEDITOR,adminmail); sprintf(wrkline1, "%s: 'End:' arg disagreed with 'Begin:' arg",progname); mail(wrkline,wrkline1,JTY,0,0); upexit(FAKEFAIL); } fputs(line,tfd); fputc('\n',tfd); fputs("##\n",tfd); (void)fseek(tfd,0L,0); if ( (fd = fopen(secfile,"w")) == 0) { sprintf(wrkline,"%s: Can't fopen() %s", progname,secfile); mail(NEDITOR,wrkline,JTY,0,0); upexit(FAKEFAIL); } while( (freadcount = fread(wrkline, sizeof(*wrkline), sizeof(wrkline),tfd)) > 0) if ((fwrite(wrkline,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -