home *** CD-ROM | disk | FTP | other *** search
- Subject: v08i034: Uumail release 4.2, Part02/04
- Newsgroups: mod.sources
- Approved: mirror!rs
-
- Submitted by: sob@soma.BCM.TMC.EDU (Stan Barber)
- Mod.sources: Volume 8, Issue 34
- Archive-name: uumail4/Part02
-
- [ IMPORTANT NOTE: This version superceeds the recent net.sources posting
- because it also inclues the Patch#1. An earlier version of Uumail
- was next in the backlog, hence this "rapid" posting. --r$ ]
-
- #! /bin/sh
-
- # Make a new directory for the uumail sources, cd to it,
- # and run kits 1 thru 4 through sh.
- # When all 4 kits have been run, read README.
-
- echo "This is uumail kit 2 (of 4). If kit 2 is complete, the line"
- echo '"'"End of kit 2 (of 4)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- echo Extracting uumail.c
- cat >uumail.c <<'!STUFFY!FUNK!'
- /*
- * U U M A I L
- * This program when invoked in the form:
- * uumail host!user will consult the local usemap for
- * the proper routing.
- *
- * If it finds it, it will invoke the proper uux call
- * to send the mail.
- * Otherwise it aborts with an error 68 (host unknown)
- ***************************************************************************
- This work in its current form is Copyright 1986 Stan Barber
- with the exception of resolve, gethostname and the original getpath which
- as far as I know are in the Public Domain. This software may be distributed
- freely as long as no profit is made from such distribution and this notice
- is reproducted in whole.
- ***************************************************************************
- This software is provided on an "as is" basis with no guarantee of
- usefulness or correctness of operation for any purpose, intended or
- otherwise. The author is in no way liable for this software's performance
- or any damage it may cause to any data of any kind anywhere.
- ***************************************************************************
- * $Log: uumail.c,v $
- * Revision 4.2 87/02/02 15:43:50 sob
- * Added fix for lost line at the beginning of the message problems
- *
- * Revision 4.1 86/12/15 13:14:44 sob
- * Added attempted fix for null userid in from line on some system V machines.
- *
- * Revision 4.0 86/11/17 16:02:36 sob
- * Release version 4.0 -- uumail
- *
- * Revision 3.16 86/10/28 23:26:05 sob
- * installed header bug fix from steve@jplgodo
- *
- * Revision 3.15 86/10/20 15:05:52 sob
- * Ready for beta test
- *
- * Revision 3.14 86/10/20 13:24:02 sob
- * Additions to correctly deal with KNOWNHOST
- *
- * Revision 3.13 86/10/10 18:25:03 sob
- * Now deals with all forms of addresses correctly... close to beta release now
- *
- * Revision 3.12 86/10/07 13:22:23 sob
- * Made more changes to be compatilble with new Configure script
- *
- * Revision 3.11 86/10/07 01:07:33 sob
- * Correction for LOG definition
- *
- * Revision 3.10 86/10/07 01:02:19 sob
- * Altered to work correctly with new Configure script
- *
- * Revision 3.9 86/10/06 15:03:04 sob
- * Fixed another problem with getting neighbors in getpath.
- *
- * Revision 3.8 86/10/01 15:52:08 sob
- * Reveresed sense of nghborflag to make it work right.
- *
- * Revision 3.7 86/09/22 17:52:36 sob
- * This version appears to work when using and not using resolve.
- * Now to alpha test
- *
- * Revision 3.6 86/09/22 15:58:19 sob
- * This version works correctly with resolve in the compilation. Now
- * to check the other alternatives.
- * Stan
- *
- * Revision 3.5 86/09/22 12:44:24 sob
- * Added KNOWNHOST definition to allow a place to punt unresolved mail.
- * Hopefully this will help sites with small databases
- *
- * Revision 3.4 86/09/02 23:32:14 sob
- * Now works with resolve... need to clean up for release.
- * Stan
- *
- * Revision 3.3 86/08/18 14:13:16 sob
- * checkpoint
- *
- * Revision 3.2 86/07/11 17:59:19 sob
- * This version now adapted to work with the uumail package.
- * Thanks to Mark and the UUCP project for their work on smail!
- * Stan
- *
- * Revision 3.1 86/05/27 15:01:27 sob
- * Added modification suggested by tp@ndm20.UUCP to allow user
- * to specify if uuname will be used to determine uucp neighbors.
- * Stan Barber
- *
- * Revision 3.0 86/03/14 12:05:00 sob
- * Release of 3/15/86 --- 3rd Release
- *
- * Revision 2.20 86/03/14 11:57:46 sob
- *
- *
- * Revision 2.19 86/03/11 11:29:11 sob
- * Added Copyright Notice
- *
- * Revision 2.18 86/03/04 18:20:40 sob
- * Fixed some problems with local vs. non-local mail.
- *
- * Revision 2.17 86/02/26 03:06:47 sob
- * Added error checking for a null name.
- *
- * Revision 2.16 86/02/23 23:49:40 sob
- *
- *
- * Revision 2.15 86/02/23 23:19:09 sob
- * This version will hopefully work with the new pipeoutput option from
- * aliasing.
- * Stan
- *
- * Revision 2.14 86/02/18 02:56:38 sob
- * Correct pointer problem with linked list.
- * Stan
- *
- * Revision 2.13 86/02/17 18:43:37 sob
- * Updated with linked list for addresses. This will allow aliasing which
- * will be added next.
- * Stan
- *
- * Revision 2.12 86/02/17 17:33:12 sob
- * This update incorporates changes to the command line flags to
- * conform more with the syntax of sendmail.
- * Stan
- *
- * Revision 2.11 86/02/07 16:06:16 sob
- * Altered the code to always unlink the temporary letter file when
- * DEBUG is NOT defined.
- * Stan
- *
- * Revision 2.10 85/12/26 16:50:23 sob
- * Added fixes to allow uupath myhostname to work correctly.
- * Stan
- *
- * Revision 2.9 85/12/10 20:36:01 sob
- * Added new return flag from getpath EX_TEMPFAIL to signal that the
- * path database is currently being updated.
- *
- * Revision 2.8 85/12/02 16:51:39 sob
- * Added a fix to cope with percents in addresses returned by opath.
- * Thank to steve@umd-cs.UUCP for the bug report.
- *
- * Revision 2.7 85/11/18 12:36:48 sob
- * Added the -h option to cause uumail NOT to add a From_ line.
- *
- * Revision 2.6 85/11/14 20:20:06 sob
- * Added #ifdef DEBUG to allow compiliation with out DEBUG installed
- *
- * Revision 2.5 85/11/14 20:14:11 sob
- * Another little buggie in the log format...sheesh.
- *
- * Revision 2.4 85/11/13 15:53:18 sob
- * Reformated the log file a little bit.
- *
- * Revision 2.3 85/11/08 03:03:51 sob
- * This is the release version.
- *
- *
- * Revision 2.2 85/09/30 02:51:18 sob
- * This version uses opath when defined during compile time.
- * With a bit of cleaning up, this is a release version.
- *
- * Revision 2.1 85/09/30 02:46:06 sob
- * *** empty log message ***
- *
- * Revision 2.0 85/09/09 18:22:56 UUCP
- * *** empty log message ***
- *
- * Revision 2.0 85/09/09 18:22:56 UUCP
- * Added flags to conform with sendmail. Also updated the flags it could send
- * to uux to conform with 4.3 uux command.
- * Will add name resolution and header checking.
- * Also will allow multiple addresses per line.
- *
- * Revision 1.7 85/08/03 00:49:14 UUCP
- * Cleaned up with lint.
- * Stan Barber
- *
- * Revision 1.6 85/07/11 19:30:00 sob
- * changed PATHSIZE to PATHSIZ to conform with uupath
- *
- * Revision 1.5 85/07/11 18:08:13 sob
- * This one works both as uumail and uupath!
- * Stan
- *
- * Revision 1.4 85/07/10 18:35:05 sob
- * moved DBM to getpath
- * Stan Barber
- *
- * Revision 1.3 85/07/09 01:28:14 sob
- * First attempt to integrate uupath
- * Not successful. Changed PATHALIAS define
- * to DBM... will ultimately alter getpath as well
- * added gethostname call to fill in for local host.
- *
- * Revision 1.2 85/07/08 05:29:16 sob
- * This one works with pathalias database...
- * need to modify to substitue for uupath.
- * Stan
- *
- * Revision 1.1 85/07/08 03:11:10 sob
- * Initial revision
- *
- */
- #define _DEFINE
-
- #include "uuconf.h"
- #include "patchlevel.h"
-
- EXTERN bool uupath;
- extern int errno;
- extern struct passwd *getpwuid();
- extern FILE *popen();
- extern char *ctime();
- extern char *getlogin();
- extern char *index();
- extern char *rindex();
- extern char *malloc();
- extern char *getenv();
- extern char *Alias();
- extern bool nghborflag;
- EXTERN char progname[12];
- EXTERN char *paths;
- char * bangpath[BUFSIZ];
- char templet[64];
- struct mailname addrlist; /* list of addresses */
- int local;
-
-
- main(argc, argv)
- char **argv;
- {
- FILE *out, *tmpf; /* output to uux, temp file */
-
- char sender[512]; /* accumulated path of sender */
- char user[NAMESIZ];
- char cmd[2000];
- char **av;
- int i,
- error = 0,
- hopcount = 30;
-
- char c,
- grade = 'C',
- *path, /* uupath to the system */
- *p, *q, *r, /* tmp pointer to argv's */
- *FullName;
- bool GrabTo,safecf,NoAlias,startuux,noheader,metoo;
- extern intsig();
- struct mailname *lp;
- int form;
-
- if (signal(SIGINT, SIG_IGN) != SIG_IGN)
- (void) signal(SIGINT, intsig);
- if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
- (void) signal(SIGHUP, intsig);
- (void) signal(SIGTERM, intsig);
- (void) signal(SIGPIPE, SIG_IGN);
- /* initialize Boolean Values */
- startuux = safecf = TRUE;
- metoo=GrabTo=NoAlias=noheader = FALSE;
-
- for (i = 3; i < 20; i++)
- (void) close(i);
- errno = 0;
- nghborflag = TRUE; /* use uuname if possible */
- gethostname(Myname,32);
- paths=DATABASE;
- #ifdef LOG
- logfile=LOGFILE;
- #endif
- FullName=getenv("NAME");
- argv[argc] = NULL;
- av = argv;
- p = rindex(*av, '/');
- if (p++ == NULL)
- p = *av;
- strcpy(progname ,p);
- if(strcmp(p,"uupath") == 0)
- uupath = TRUE;
- while ((p = *++av) != NULL && p[0] == '-')
- {
- switch (p[1])
- {
-
- case 'g': /* set grade */
- grade = p[2];
- break;
-
- # ifdef DEBUG
- case 'd': /* debug */
- Debug= atoi(&p[2]);
- if (Debug == 0) Debug = 1;
- setbuf(stdout, (char *) NULL);
- (void) printf("Version %s\n", Version);
- break;
- # endif DEBUG
-
- case 'f': /* from address */
- case 'r': /* obsolete -f flag */
- p += 2;
- if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
- {
- p = *++av;
- if (p == NULL || *p == '-')
- {
- syserr("No \"from\" person");
- av--;
- break;
- }
- }
- if (from != NULL)
- {
- syserr("More than one \"from\" person");
- break;
- }
- from = p;
- break;
-
- case 'F': /* set full name */
- p += 2;
- if (*p == '\0' && ((p = *++av) == NULL || *p == '-'))
- {
- syserr("Bad -F flag");
- av--;
- break;
- }
- FullName = p;
- break;
-
- case 'w': /* just print the path */
- uupath = TRUE;
- break;
- case 'h': /* don't add a From line */
- noheader = TRUE;
- break;
- case 'N': /* don't use uuname to get neighbors */
- nghborflag = FALSE;
- break;
- case 'n': /* don't alias any addresses */
- NoAlias = TRUE;
- break;
- case 't': /* read Header for addresses */
- GrabTo = TRUE;
- break;
- case 'o': /* sendmail-like options flag */
- switch(p[2]){
- case 'm': /* send this message to the sender*/
- metoo=TRUE;
- break;
- case 'c': /* don't connect to expensive
- mailer, or don't start uux*/
- startuux = FALSE;
- break;
- }
- break;
- case 'b': /* sendmail-like operation mode flag */
- switch(p[2]){
- case MD_DELIVER: /* deliver the mail */
- uupath = FALSE;
- break;
- case MD_VERIFY: /* verify an address */
- uupath = TRUE;
- break;
- default:
- (void) fprintf(stderr,
- "%s: mode %c not supported\n",
- progname,p[2]);
- exit(EX_USAGE);
- }
- break;
- }
-
- }
-
- handle = JUSTUUCP; /* default handling is just uucp */
- if(*av==NULL && GrabTo!= TRUE)
- {
- (void) fprintf(stderr,"Usage: %s [flags] address\n",progname);
- exit(EX_USAGE);
- }
-
-
- #ifndef NOALIAS
- if (AliasFile == NULL) AliasFile = ALIASFILE;
- #endif
-
- /* get login name of the sender... use environment variables if possible */
-
- if(from==NULL || strlen(from) == 0){
- if (((from = getenv("LOGNAME")) == NULL) || (strlen(from) == 0))
- from = getenv("USER");
- if ((from == NULL) || (strlen(from) == 0))
- from = getlogin();
- if ((from == NULL) || (strlen(from) == 0))
- from = getpwuid(geteuid())->pw_name;
- }
-
- /* if from is still null, set it equal to UUMAIL daemon -- kluge! */
-
- if (from == NULL) from = MAILERDAEMON;
-
- /* If this is not uupath, then there must be a letter */
-
- if (!uupath)
- {
- #ifdef DEBUG
- if (Debug) (void) printf("Mail from %s\n",from);
- #endif
- /*
- * Make temporary file for letter
- * (I wish ACCESS(2) would take care of this better !!)
- */
- if ((p=getenv("HOME"))== NULL)
- p="/tmp";
- sprintf(&templet[0],"%s/.uumXXXXXX",p);
- mktemp(templet);
- unlink(templet);
- if ((i=open(templet,2)) < 0)
- {
- p="/tmp";
-
- sprintf(&templet[0],"%s/.uumXXXXXX",p);
- mktemp(templet);
- unlink(templet);
- }
- else
- {
- close(i);
- unlink(templet);
- }
- #ifdef DEBUG
- if (Debug>2) (void) fprintf(stderr,"Temp file is %s\n",templet);
- #endif
- if((tmpf = fopen(templet, "w")) == NULL){
- (void) fprintf(stderr, "%s : can't open %s for writing\n", progname,templet);
- fclose(stdin);
- exit(EX_CANTCREAT);
-
- }
- while(fgets(lbuf,sizeof lbuf,stdin))
- fputs(lbuf,tmpf);
- (void) fclose(tmpf);
- (void) fclose(stdin);
- /* file now saved */
- if((tmpf = fopen(templet, "r")) == NULL){
- (void) fprintf(stderr, "%s : can't open %s for reading\n", progname,templet);
- unlink(templet);
- exit(EX_OSERR);
- }
-
- }
- (void) strcpy(sender, "");
-
- path = malloc(PATHSIZ);
-
- /* build address list */
-
-
- while (*av != NULL && *av != NULL)
- add(*av++,&addrlist);
-
- if(metoo) add(from,&addrlist); /* add me to the list too */
-
- if(!NoAlias) alias(); /* do aliasing if not turned off */
- #ifndef NOALIAS /* process forwarding files */
- for (lp = addrlist.m_next;lp;lp = lp->m_next) forward(lp->m_name);
- #endif
-
- for (lp = addrlist.m_next;lp;lp = lp->m_next) /* mail it out */
- {
-
- if(strlen(lp->m_name) == 0) continue;
-
- local = 0;
-
- q = p = lp->m_name;
-
-
- /* this is uupath command */
- if (uupath)
- {
- if ((error = getpath (p, path,paths)) != EX_OK)
- patherror(error,p);
- if (strcmp(path,"%s") == 0) local = 1;
- }
- #ifdef RESOLVE
- else
- {
- /* check for pipe to another program output here */
- if (lp->m_pipe == TRUE){
- strcat(cmd,lp->m_name);
- goto pipeout;
- }
- r = malloc(PATHSIZ);
- strcpy(r,p);
- if (index(p,'@') != NULL) handle = ALL;
- /* try one */
- form = resolve(p,path,user);
- if ( (form == LOCAL && path[0] == '\0')
- || form == ERROR || form == ROUTE || form == DOMAIN){
- if (user[0] != '\0') strcpy(p,user);
- path[0] = user[0] = '\0';
- /* try two */
- if (index(p,'@') != NULL) handle = ALL;
- form = resolve(p,path,user);
- }
- /* we could punt at this point, but let's forward it to a known
- host that might be able to resolve it */
-
- #ifdef KNOWNHOST /* ugly... alternate suggestions welcome */
- if ( (exitstat || form == ERROR)
- && (index(r,'@') != NULL || index(r,'!') != NULL) ){
- strcpy(p,KNOWNHOST);
- strcat(p,"!");
- strcat(p,r);
- user[0] = '\0';
- form = resolve(p,path,user);
- }
- #endif
-
- #ifdef DEBUG
- if ((Debug > 1) && (!exitstat))
- (void) fprintf(stderr,"resolve returns %s!%s\n",path,user);
- #endif
-
- if (exitstat || form == ERROR )
- /* no match in pathalias database */
- {
- deadletter(tmpf,local,exitstat,p);
- unlink(templet);
- exit(exitstat);
- }
-
-
- if (form == LOCAL)
- {
- strcpy(path,Myname);
- local = 1;
- }
- } /* end of else uupath */
- #else
- else
- {
- p = index(q,'!');
- if (p == NULL) local++;
- else *p = '\0';
- if(!local){
- if ((error = getpath (q,path,paths)) != EX_OK)
- patherror(error,q);
- if (*path != '\0' && index(path,'!'))
- *(rindex(path,'!')+1) = '\0';
- p++;
- strcat(path,p);
- p = index(path,'!');
- if (p != NULL) {
- *p = '\0';
- p++;
- strcpy(user,p);
- }
- else
- {
- strcpy(user,path);
- local++;
- }
- }
- }
- #endif
-
- #ifdef DEBUG
- if(Debug>3)
- (void) fprintf(stderr,
- "p = %s path = %s user = %s\n",p, path,user);
- #endif
-
- if (uupath)
- {
- if (*path != '\0') *(rindex(path,'!')+1) = '\0';
- (void) printf("Path to %s: %susername\n",
- lp->m_name,path);
- continue;
- }
- else
- {
- if (local)
- (void) sprintf(cmd, LOCALMAIL, user);
- else {
- (void) sprintf(cmd,"%s - ",REALUUX);
- if (!startuux)
- strcat(cmd,"-r");
- #ifndef NORETURN
- if (from)
- {
- strcat(cmd," -a");
- strcat(cmd,from);
- }
- #endif
- #ifndef NOGRADE
- if (grade)
- {
- char work[10];
- (void) sprintf(work," -g%c",grade);
- strcat(cmd,work);
- }
- #endif
- if (index(user, '!'))
- {
- char work[100];
- (void)sprintf(work,
- " %s!rmail \\(%s\\)",path,user);
- strcat(cmd,work);
- }
- else
- {
- char work[100];
- (void) sprintf(work, " %s!rmail %s",
- path,user);
- strcat(cmd,work);
- }
- }
- pipeout:
- #ifdef DEBUG
- if (Debug) (void) fprintf(stderr,"Command is %s\n",cmd);
- #endif
- rewind(tmpf);
- #ifdef DEBUG
- if (Debug)
- out = fopen("UUMAIL.TEST","w");
- else
- #endif
- out = popen(cmd, "w");
- /* fputs(lbuf, out); */
- /* reprocess header ? */
- if (!noheader) Putfrom(tmpf,out);
- while (fgets(lbuf, sizeof lbuf, tmpf))
- fputs(lbuf, out);
-
- /* may not be needed */
- if (local!=0)
- (void) fprintf(out,"\n.\n");
-
- #ifdef DEBUG
- if (Debug)
- i = fclose(out);
- else
- #endif
- i = pclose(out);
- if ((i & 0377) != 0)
- {
- (void) fprintf(stderr, "pclose: status 0%o\n", i);
- deadletter(tmpf,local,EX_OSERR);
- #ifdef DEBUG
- if (Debug <3)
- #endif
- unlink(templet);
- exit(EX_OSERR);
- }
- #ifdef LOG
- maillog(cmd);
- #endif
- }
- }
- #ifdef DEBUG
- if (Debug <3)
- #endif
- unlink(templet);
- exit(EX_OK);
- }
-
- /* print an error message on stderr */
-
- syserr(string)
- char * string;
- {
- (void) fprintf(stderr,"%s\n",string);
- }
-
- /* make a unix type From line and send it out the stream */
- /* based on smail code (rline subroutine ) to be compatible with RFC 976 */
-
- Putfrom(into,outto)
- FILE *into, *outto;
- {
- char *asctime();
- struct tm *bp, *localtime();
- char *tp, *zp,*c;
- int parts,fromflag=0;
- char *partv[16];
- char buf[BUFSIZ], addr[PATHSIZ], domain[PATHSIZ], user[NAMESIZ];
- int form;
- extern build();
- long iop, offset;
- (void) strcpy( bangpath,""); /* zero bang path */
- /* code from smail follows (Thanks Mark!) */
- for( ;; )
- {
- offset=ftell(into); /* get current position in file */
- if ( fgets( buf, sizeof(buf), into )==NULL )
- break;
- if ( strncmp( "From ", buf, 5 )
- && strncmp( ">From ", buf, 6 ) )
- break;
- /*
- ** Crack the line apart using ssplit.
- */
- if( c = index( buf, '\n' ) );
- *c = '\0';
-
- parts = ssplit( buf, ' ', partv );
- /*
- ** Tack host! onto the bangpath argument if "remote from host" is present.
- */
-
- if ( parts > 3
- && !strncmp( "remote from ", partv[parts-3], 12 ) )
- {
- (void) strcat( bangpath, partv[parts-1] );
- (void) strcat( bangpath, "!" );
- }
- /*
- ** Stuff user name into addr, overwriting the user name from previous
- ** From_ lines, since only the last one counts. Then rewrite user@host
- ** into host!user, since @'s don't belong in the From_ argument.
- */
- (void) strncpy( addr, partv[1], partv[2]-partv[1]-1 );
- addr[partv[2]-partv[1]-1] = '\0'; /* ugh */
-
- (void) parse( addr, domain, user );
- if(*domain == '\0') {
- form= LOCAL;
- } else {
- form = UUCP;
- }
-
- build( domain, user, form, addr );
-
- }
- /*
- ** Now tack the user name onto the from argument.
- */
- (void) strcat( bangpath, addr );
- /*
- ** If we still have no from argument, we have junk headers.
- ** We use the from name determined at startup time.
- */
- if (bangpath[0] == '\0') strcpy(bangpath,from);
-
- /*
- * Format time
- */
- time(&iop);
- bp = localtime(&iop);
- tp = asctime(bp);
- /* zp = tzname[bp->tm_isdst];*/
-
- /* sprintf(buf, "%s%s %.16s %.3s %.5s", from, tp, zp, tp+20);*/
- (void) sprintf(buf, "From %s %.16s %.4s", bangpath, tp, tp+20);
-
- if (local == 0){
- strcat(buf," remote from ");
- strcat(buf,Myname);
- }
-
- strcat(buf,"\n");
- /* if there is no output file (no headers), exit */
- if (outto == NULL) return;
- (void) write(outto->_file,buf,strlen(buf));
- /* now reset the input file to the beginning of the header
- * following the "From " lines
- */
- (void) fseek(into,offset,0);
- (void) fflush(outto);
-
- }
-
- /* end of code derived from smail */
-
-
- /* go here on a signal we want to catch */
- intsig()
- {
- unlink(templet);
- exit(EX_OK);
- }
-
- /* put command strings in the logfile */
-
- #ifdef LOG
-
- maillog(command)
- char * command;
- {
- FILE *f;
- char atime[24];
- long clock;
- time (&clock);
- strncpy(atime,ctime(&clock),24);
-
- if ((f=fopen(logfile,"a")) != NULL)
- {
- (void) fprintf(f,"%s: %s - %s\n",progname,atime,command);
- fclose(f);
- }
- }
-
- #endif
-
- /* print a path error and exit */
- patherror(error,name)
- int error;
- char * name;
- {
- switch(error){
- case EX_NOHOST:
- (void) fprintf(stderr,"System %s not found in network map.\n",
- name);
- break;
- case EX_NOINPUT:
- (void) fprintf(stderr,
- "Database %s could not be opened.\n",paths);
- break;
- case EX_TEMPFAIL:
- (void) fprintf(stderr,
- "Database %s is being updated.\nTry again later.\n",paths);
- break;
- }
- exit(EX_NOHOST);
- }
- !STUFFY!FUNK!
- echo Extracting getpath.c
- cat >getpath.c <<'!STUFFY!FUNK!'
- /*
- * Name: getpath -- return the full usenet path of the given name
- *
- * Paramaters: sysname (input) -- The system name to be expanded
- * pathname (output) The usenet path of the given system name
- * pathfile (input) the file to search for the system name
- *
- * Returns: EX_OK -- path found
- * EX_NOHOST -- path not found
- * EX_NOINPUT-- unable to open usemap
- * EX_TEMPFAIL -- database being rebuilt
- *
- * Original Version Author: J. Donnelly 3/82
- *
- */
-
- /* IF YOU ARE USING A DBM DATABASE, READ THIS!
- * If the special sentinel value of @@@ is not present in the
- * database, then it is assumed that the database is being
- * rebuilt and the requesting process is blocked for TIMEOUT
- * (default = 180) seconds. If, after 5 such blocks, the
- * sentinel is not present, the error code EX_TEMPFAIL is returned.
- * The same is true if the dbm files cannot be initialized.
- */
-
- /***************************************************************************
- This work in its current form is Copyright 1986 Stan Barber
- with the exception of opath, gethostname and the original getpath which
- as far as I know are in the Public Domain. This software may be distributed
- freely as long as no profit is made from such distribution and this notice
- is reproducted in whole.
- ***************************************************************************
- This software is provided on an "as is" basis with no guarantee of
- usefulness or correctness of operation for any purpose, intended or
- otherwise. The author is in no way liable for this software's performance
- or any damage it may cause to any data of any kind anywhere.
- ***************************************************************************/
- /* 22-jun-83 Sheppard
- * modified to rewind path file (if open), rather than open again
- *
- * $Log: getpath.c,v $
- * Revision 4.0 86/11/17 16:02:15 sob
- * Release version 4.0 -- uumail
- *
- * Revision 3.11 86/11/06 01:59:48 sob
- * Altered DBM to UUDBM to avoid possible conflicts under 4.3 BSD
- * Thanks to page@ulowell for the report
- *
- * Revision 3.10 86/10/20 15:05:14 sob
- * Ready for beta test
- *
- * Revision 3.9 86/10/20 13:23:36 sob
- * Revisions to work more correctly in SORTED and nonSORTED databases
- *
- * Revision 3.7 86/10/10 18:24:16 sob
- * Moved dbm.h include here from uuconf.h
- *
- * Revision 3.6 86/10/06 15:03:23 sob
- * Fixed another problem with getting neighbors in getpath.
- *
- * Revision 3.5 86/10/01 15:49:15 sob
- * Revisions to deal with problems arrising from the neighbors array.
- * Still not completely solved.
- *
- * Revision 3.4 86/07/11 17:58:07 sob
- * Fixed the alternate case conversion to work right.
- * Stan
- *
- * Revision 3.3 86/07/10 15:29:21 sob
- * Added modifications that allow getpath to work with hosts that have
- * names that are all uppercase or all lowercase.
- * Stan
- *
- * Revision 3.2 86/07/06 17:39:57 sob
- * Added changes provided to dynamically allocate enough space for
- * neighbors array. Thanks to rct for the help.
- * Stan
- *
- * Revision 3.0 86/03/14 12:04:46 sob
- * Release of 3/15/86 --- 3rd Release
- *
- * Revision 1.19 86/03/14 11:57:23 sob
- * updated copyright
- *
- * Revision 1.18 86/03/11 11:28:58 sob
- * Added Copyright Notice
- *
- * Revision 1.17 86/03/03 17:16:59 sob
- * Added fixes provided by desint!geoff.
- * Stan
- *
- * Revision 1.16 86/02/24 12:45:36 sob
- * Bug fix in scanning the list from uuname.
- * Stan
- *
- * Revision 1.15 86/02/23 23:01:53 sob
- * This version will use data from the uuname command as well as
- * data from the database
- *
- * Revision 1.14 85/12/13 15:23:21 sob
- * Added patches from umd-cs!steve
- *
- * Revision 1.13 85/12/10 20:36:58 sob
- * Added modifications suggested in gatech's version of uumail.
- * Now, the DBM version of the database needs to have a SENTINAL in it
- * to indicate that the DATABASE is not being updated. Also added similiar
- * indicators to the non-DBM version to compare modification times and act
- * accordingly.
- *
- * Revision 1.12 85/12/02 15:48:39 sob
- * Combined speed hacks and old way of reading database and
- * added compile flag SORTED. If database is SORTED and not DBM, use
- * -DSORTED in CFLAGS to make it fast. If database is not sorted
- * DO NOT use this flag.
- *
- * Revision 1.11 85/11/24 15:03:41 sob
- * Added changes suggested by regina!mark
- *
- * Revision 1.10 85/11/24 04:21:45 sob
- * Added efficiency hacks supplied by meccts!asby (Shane P. McCarron)
- *
- * Revision 1.9 85/11/14 20:21:49 sob
- * Added #ifdef DEBUG to allow compilation without DEBUG
- *
- * Revision 1.8 85/11/08 03:04:49 sob
- * release version
- *
- * Revision 1.7 85/09/30 02:47:40 sob
- * Altered to use path filename from global variable.
- *
- * Revision 1.6 85/08/03 00:48:57 UUCP
- * Cleaned up with lint.
- * Stan Barber
- *
- * Revision 1.5 85/07/19 17:45:13 UUCP
- * Added \t as a valid seperation character for the database
- * in the non DBM case. This is what pathalias uses.
- *
- * Revision 1.4 85/07/19 16:44:07 UUCP
- * revised to return proper things in accordance with sysexits
- * Stan
- *
- * Revision 1.3 85/07/11 19:30:31 sob
- * added "uuconf.h" include file and deleted duplicated information
- *
- * Revision 1.2 85/07/10 18:30:59 sob
- * updated to add DBM capabilities
- * Stan Barber, Baylor College of Medicine
- *
- * Revision 1.1 85/07/10 18:03:28 sob
- * Initial revision
- *
- */
-
- #include "uuconf.h"
- #ifdef UUDBM
- #include <dbm.h>
- #else
- #include <sys/types.h>
- #include <sys/stat.h>
- #endif
-
- static char rcsid[] = "$Header: getpath.c,v 4.0 86/11/17 16:02:15 sob Exp $";
- extern char * index();
-
- extern FILE * fopen (), *popen();
- FILE * in;
- bool nghborflag,gotneighbors;
- char **neighbors, *n_array; /* rct */
-
- int getpath (sysname, pathname, pathfile)
- char *sysname, *pathname,*pathfile;
- {
- int indx,x;
- char ACsysname[NAMESIZ]; /* alternate case sysname */
- #ifdef UUDBM
- datum lhs,rhs;
- #else
- struct stat st;
- time_t modtime;
- char name[NAMESIZ];
- #ifdef SORTED
- int scomp();
-
- long lo,hi;
- long cur;
- long last;
- static char buf[256];
- #else
- char * p, * q, t;
- #endif
- #endif
-
-
- /* build sysname in the alternate case to conform to methods in SMAIL */
- if (*(sysname) == '.' || isupper(*sysname)) /* a kludge */
- {
- for (x=0;x<strlen(sysname);x++)
- ACsysname[x] = tolower(*(sysname+x));
- }
- else
- {
- for (x=0;x<strlen(sysname);x++)
- ACsysname[x] = toupper(*(sysname+x));
- }
-
- if (x < NAMESIZ) ACsysname[x] = '\0';
- /* end case switch */
- #ifdef DEBUG
- if (Debug>2) (void) fprintf
- (stderr,"getpath: Sysname = %s, Alternate = %s, Pathfile = %s\n",
- sysname,ACsysname,paths);
- #endif
- if(nghborflag == TRUE)
- {
- if (gotneighbors != TRUE) getneighbors();
- indx = 0;
- /* is it a neighbor? */
- while(neighbors[indx] != NULL && *(neighbors[indx]) != '\0'){
- if(!strcmp(sysname, neighbors[indx])
- || !strcmp(ACsysname,neighbors[indx])){
- strcpy(pathname, neighbors[indx]);
- strcat(pathname, "!%s");
- return(EX_OK);
- }
- indx++;
- }
- }
- /* not a neighbor, let's look in the database */
- #ifdef UUDBM
- for (indx = 0; indx < 5; indx++)
- {
- if ((x = dbminit (pathfile)) >= 0)
- break;
-
- #ifdef DEBUG
- if (Debug>2)
- (void) fprintf (stderr, "Database unavailable. Sleeping.\n");
- #endif
- sleep (TIMEOUT);
- }
-
- if (x < 0)
- return(EX_OSFILE);
-
- lhs.dptr = SENTINEL;
- lhs.dsize = strlen (SENTINEL) + 1;
- for (indx = 0; indx < 5; indx++)
- {
- rhs = fetch (lhs);
- if (rhs.dsize > 0)
- break;
-
- #ifdef DEBUG
- if (Debug>2)
- (void) fprintf (stderr, "Database incomplete. Sleeping.\n");
- #endif
- sleep (TIMEOUT);
- }
- if (rhs.dsize <= 0)
- return(EX_TEMPFAIL);
-
- lhs.dptr = sysname;
- lhs.dsize = strlen(sysname)+1;
- rhs = fetch(lhs);
- if (rhs.dptr == NULL){ /* try other case */
- lhs.dptr=ACsysname;
- rhs = fetch(lhs);
- if (rhs.dptr == NULL) return(EX_NOHOST); /* no name found */
- }
- strcpy(pathname,rhs.dptr);
- return(EX_OK); /* system name found */
-
- #else
- if (in == NULL)
- {
- for (indx = 0; indx < 5; indx++)
- {
- if ((in = fopen(pathfile, "r")) != NULL)
- break;
-
- #ifdef DEBUG
- if (Debug>2)
- (void) fprintf (stderr, "Database unavailable. Sleeping.\n");
- #endif
- sleep (TIMEOUT);
- }
- if (in == NULL)
- return(EX_OSFILE);
- }
- else
- rewind(in);
- indx = 0;
- strcpy(name,sysname);
- restart:
- indx++;
- if (indx > 5) return(EX_TEMPFAIL);
- stat(pathfile, &st);
- modtime=st.st_mtime; /* original last modification time */
-
- #ifdef SORTED
- lo = 0;
- hi = st.st_size;
- last = 0;
- cur = hi >> 1;
-
- while (cur > lo && cur < hi)
- {
- stat(pathfile,&st);
- if (st.st_mtime > modtime) goto restart;
- (void)fseek(in, cur, 0);
- if (fgets(buf, sizeof(buf), in)== NULL) return(EX_TEMPFAIL);
- cur = ftell(in);
- if (fgets(buf, sizeof(buf), in) == NULL) return(EX_TEMPFAIL);
-
- #ifdef DEBUG
- if (Debug > 4)
- (void) printf("Found site %s\n", buf);
- #endif
- if (scomp(name, buf) < 0) hi = cur;
- else
- if (scomp(name, buf) > 0) lo = cur;
- else
- {
- buf[strlen(buf)-1] = '\0';
- strcpy(pathname, (char *)index(buf, '\t') + 1);
- return(EX_OK);
- }
- cur = lo + ((hi - lo)>>1);
- if (last == cur)
- {
- (void)fseek(in, lo, 0);
- do
- {
- if (fgets(buf, sizeof(buf), in) == NULL)
- return(EX_TEMPFAIL);
- lo = ftell(in);
- if (scomp(name, buf) == 0 )
- {
- buf[strlen(buf)-1] = '\0';
- strcpy(pathname, (char *)index(buf, '\t') + 1);
- return(EX_OK);
- }
- } while (lo <= hi);
- break;
- } /* end if */
- last = cur;
- } /* end while */
- if (!strcmp(name,ACsysname)) return(EX_NOHOST);
- else {
- strcpy(name,ACsysname);
- goto restart;
- }
- #else
- p = (char *) malloc(NAMESIZ);
- if (p == NULL) return(EX_OSERR); /* can't get space */
- q = p;
- for (;;)
- {
- p = q;
- while ((t = getc(in)) != EOF && (*p++ = t) != ' ' && t != '\t');
- /* read the system name */
- stat(pathfile,&st);
- if (st.st_mtime > modtime) goto restart;
- /* database update in progress */
- if( t == EOF ) return(EX_NOHOST);
- *--p = '\0'; /* set end of string */
- p = q;
- #ifdef DEBUG
- if (Debug>4) (void) printf("Found %s\n",p);
- #endif
- if (!strcmp (p,name) || !strcmp(p,ACsysname))break;
- while (((t = getc (in)) !=EOF && t != '\n')); /* skip this path */
- }
- p = pathname; /* save start loc of pathname */
- while ((*pathname++ = getc (in)) != '\n' && *(pathname-1) != EOF);
- *--pathname = '\0';
- pathname = p;
- return(EX_OK); /* system name found */
-
- #endif
- #endif
- }
-
- #ifdef SORTED
- #define MAPTAB(c) ((c=='\t')?'\0':c)
-
- int scomp(a,b)
- char *a,*b;
- {
- int r;
- while (!(r=(MAPTAB(*a)-MAPTAB(*b))) && *a && *b && *a!='\t' && *b!='\t')
- {
- a++; b++;
- }
- return(r);
- }
- #endif
-
- getneighbors()
- {
- FILE *ppntr;
- char * ptr;
- int x = 0;
- char n_neigh[16], *calloc(); /* rct */
- int nelem = 0; /* rct */
-
- gotneighbors = TRUE;
-
- /*
- * Let's get the number of neighbors we have.
- *
- * Beginning of added code. --rct
- */
-
- if((ppntr = popen("uuname | wc -l", "r")) != NULL){
- #ifdef DEBUG
- if(Debug > 2)
- (void)fprintf(stderr, "Starting uuname | wc -l\n");
- #endif
- }
- else{
- (void)fprintf(stderr, "Error: popen\(\"uuname | wc -l\"\)\n");
- exit(1);
- }
- if((fgets(n_neigh, sizeof(n_neigh), ppntr)) != (char *)0){
- if((ptr = index(n_neigh, '\n')) != (char *)0)
- *ptr = '\0';
- }
- else{
- (void)fprintf(stderr, "Error: fgets\(n_neigh\)\n");
- exit(2);
- }
- #ifdef DEBUG
- if (Debug > 2)
- (void)fprintf(stderr, "n_neigh = %s\n", n_neigh);
- #endif
- (void)pclose(ppntr);
-
- /*
- * Allocate storage for neighbors based on n_neigh.
- * Assumption being made here is that no system has a name
- * longer than 14 characters. If this assumption ever turns
- * out to be wrong, lots of other code will break before this
- * does! --rct
- */
-
- nelem = atoi(n_neigh) + 2;
-
- if(((neighbors = (char **)calloc((unsigned)nelem,
- sizeof(char **))) == (char **)0) ||
- ((n_array = calloc((unsigned)nelem, 15)) == (char *)0)){
- (void)fprintf(stderr, "Error: getneighbors\(\): calloc\(\)\n");
- exit(3);
- }
-
- /*
- * Set up pointers.
- */
-
- for(x = 0; x < nelem; x++)
- neighbors[x] = &n_array[x * 15];
-
- /*
- * Now, let's read them in!
- *
- * End of added code. --rct
- */
-
- if ((ppntr = popen("uuname", "r")) != NULL) {
- #ifdef DEBUG
- if (Debug>2)
- (void)fprintf(stderr, "Starting uuname\n");
- #endif
- x = 0;
- while((fgets(neighbors[x], 15, ppntr)) != NULL){
- if ((ptr = index(neighbors[x], '\n')) != NULL)
- *ptr = '\0';
- #ifdef DEBUG
- if (Debug>4)
- (void) fprintf(stderr, "Neighbor # %d: %s\n",
- x + 1, neighbors[x]);
- #endif
- x++;
- }
- (void) pclose(ppntr);
- }
- strcpy(neighbors[x], Myname);
- }
-
-
-
- !STUFFY!FUNK!
- echo Extracting resolve.c
- cat >resolve.c <<'!STUFFY!FUNK!'
- /*
- **
- ** Resolve.c
- **
- ** Routes then resolves addresses into UUCP or LOCAL.
- **
- */
- #ifndef lint
- static char *sccsid="@(#)$Header: resolve.c,v 4.0 86/11/17 16:02:28 sob Exp $";
- #endif
-
- #include <ctype.h>
- #include <stdio.h>
- #include "uuconf.h"
-
-
-
- /*
- **
- ** rsvp(): how to resolve addresses.
- **
- ** After parsing an address into <form>, the resolved form will be
- ** rsvp( form ). If == ROUTE, we route the parsed address and parse again.
- **
- */
-
- # define rsvp(a) table[(int)a-1][handle-1]
-
- int table[5][3] = {
- /* all uucponly none */
- { ERROR, ERROR, ERROR }, /* error */
- { LOCAL, LOCAL, LOCAL }, /* local */
- { ROUTE, LOCAL, LOCAL }, /* domain */
- { UUCP, UUCP, LOCAL }, /* uucp */
- { ERROR, ERROR, ERROR }}; /* route */
-
-
- /*
- ** NOTE: in this module <domainv> replaces <hostv>. <domainv> contains
- ** the domain part of each address, though by the time it leaves here it
- ** can only be a host name.
- */
-
-
- /*
- **
- ** resolve(): resolve addresses to <host, user, form>.
- **
- ** This is a gnarly piece of code, but it does it all. Each section
- ** is documented.
- **
- */
-
- resolve( address, domain, user )
- char *address; /* the input address */
- char *domain; /* the returned domain */
- char *user; /* the returned user */
- {
- int form; /* the returned form */
- int parts; /* to ssplit addresses */
- char *partv[PATHSIZ]; /* " " " */
- char temp[PATHSIZ]; /* " " " */
- int i;
-
-
- /*
- ** If we set REROUTE and are prepared to deliver UUCP mail, we split the
- ** address apart at !'s and try to resolve successively larger righthand
- ** substrings until we succeed. Regularly, we just resolve the whole thing
- ** once.
- */
- if ( rsvp( UUCP ) == UUCP )
- parts = ssplit( address, '!', partv );
- else
- parts = 1, partv[0] = address;
- /*
- ** This for( i ) loop selects successively larger righthand substrings
- ** for BULLYing, see above.
- */
- for( i = parts - 1; i >= 0; i-- )
- {
- /*
- ** Parse the address. If we are BULLYing and our substring parses to
- ** the LOCAL address, we skip to the next larger.
- */
- (void) strcpy( temp, partv[i] );
- form = parse( temp, domain, user );
- #ifdef DEBUG
- if (Debug>2)
- printf("resolve: parse address '%s' = %s @ %s (%d)\n",temp,user,domain,form);
- #endif
- if ( i && form == LOCAL )
- continue;
- /*
- ** Routing is next step, so we break out if we don't have a UUCP form (if
- ** we are set to route ALWAYS or REROUTE) or a ROUTE form.
- */
- if ( rsvp( form ) != ROUTE &&
- ( rsvp( form ) != UUCP ) )
- break;
- /*
- ** Apply router. If BULLYing and routing failed, try next larger substring.
- */
- if ( route( form, domain, user, temp ) )
- continue;
- /*
- ** After routing, reparse and resolve.
- */
- form = parse( temp, domain, user );
- #ifdef DEBUG
- if (Debug>2)printf("resolve: parse route '%s' = %s @ %s (%d)\n",temp,user,domain,form);
- #endif
- break;
- }
- /*
- ** For LOCAL mail in non-local format, we rewrite the full address into
- ** <user> and leave <domain> blank.
- */
- if ( rsvp( form ) == LOCAL && form != LOCAL )
- {
- build( domain, user, form, temp );
- (void) strcpy( user, temp );
- (void) strcpy( domain, "" );
- form = LOCAL;
- }
- /*
- ** If we were supposed to route and address but failed (form == ERROR),
- ** or after routing once we are left with an address that still needs to
- ** be routed (rsvp( form ) == ROUTE), complain. It is possible that we
- ** may want to resolve this address more than once (if the routing tables
- ** return a domain-style address), but most likely this address partially
- ** resolved to this host.
- */
- if ( form == ERROR || rsvp( form ) == ROUTE )
- {
- exitstat = EX_NOHOST;
- #ifdef DEBUG
- if (Debug) printf( "%s...couldn't resolve %s.\n", address, domain );
- #endif
- form = ERROR;
- }
- return ( form );
- }
-
-
- /*
- **
- ** parse(): parse <address> into <domain, user, form>.
- **
- ** input form
- ** ----- ----
- ** user LOCAL
- ** domain!user DOMAIN
- ** user@domain DOMAIN
- ** @domain,address LOCAL (just for sendmail)
- ** host!address UUCP
- **
- */
-
- parse( address, domain, user )
- char *address; /* input address */
- char *domain; /* output domain */
- char *user; /* output user */
- {
- int parts;
- char *partv[PATHSIZ]; /* to crack address */
-
- /*
- ** If this is route address form @hosta,@hostb:user@hostd, break for
- ** LOCAL since only sendmail would want to eat it.
- */
- if ( *address == '@' )
- goto local;
- /*
- ** Try splitting at !. If it works, see if the piece before the ! has
- ** a . in it (domain!user, form DOMAIN) or not (host!user, form UUCP).
- */
- if ( ssplit( address, '!', partv ) > 1 )
- {
- (void) strcpy( user, partv[1] );
- (void) strncpy( domain, partv[0], partv[1]-partv[0]-1 );
- domain[partv[1]-partv[0]-1] = '\0';
- if( ( parts = ssplit( domain, '.', partv ) ) < 2 )
- return( UUCP );
- if( partv[parts-1][0] == '\0' )
- partv[parts-1][-1] = '\0'; /* strip trailing . */
- return ( DOMAIN );
- }
- /*
- ** Try splitting at @. If it work, this is user@domain, form DOMAIN.
- ** Prefer the righthand @ in a@b@c.
- */
- if ( ( parts = ssplit( address, '@', partv ) ) >= 2 )
- {
- (void) strcpy( domain, partv[parts-1] );
- (void) strncpy( user, partv[0], partv[parts-1]-partv[0]-1 );
- user[partv[parts-1]-partv[0]-1] = '\0';
- return ( DOMAIN );
- }
- /*
- ** Done trying. This must be just a user name, form LOCAL.
- */
- local:
- (void) strcpy( user, address );
- (void) strcpy( domain, "" );
- return( LOCAL ); /* user */
- }
-
-
- /*
- **
- ** route(): route domain, plug in user.
- **
- ** Less complicated than it looks. Each section is documented.
- **
- */
-
- route( form, domain, user, result )
- int form; /* domain is UUCP host? */
- char *domain; /* domain or host name */
- char *user; /* user name */
- char *result; /* output route */
- {
- int domains, step; /* to split domain */
- char *domainv[MAXDOMS]; /* " " " */
- char temp[PATHSIZ], path[PATHSIZ];
-
- /*
- ** Fully qualify the domain, and then strip the last (top level domain)
- ** component off, so that we look it up separately.
- */
- (void) strcpy( temp, ".");
- (void) strcat( temp, domain );
-
- domains = ssplit( temp+1, '.', domainv );
- /* If the domain ends in .UUCP, trim that off. */
- if ( domains && isuucp(domainv[domains-1]))
- domainv[domains-1][-1] = '\0';
- /*
- ** Try to get the path for successive components of the domain.
- ** Example for osgd.cb.att.uucp:
- ** osgd.cb.att
- ** cb.att
- ** att
- ** uucp ( remember stripping top level? )
- ** Returns with error if we find no path.
- */
- step = 0;
- while ( step<domains && getpath( domainv[step]-1, path,paths )
- /* w/dot */
- && getpath( domainv[step] , path, paths) )
- /* no dot */
- step++;
- if ( step == domains )
- {
- #ifdef DEBUG
- if(Debug>2) printf( "resolve: getpath '%s' failed\n", domain );
- #endif
- exitstat = EX_NOHOST;
- return( exitstat );
- }
- #ifdef DEBUG
- if(Debug>2)printf("resolve: getpath '%s' (%s) = %s\n",domain,domainv[step],path);
- #endif
- /*
- ** If we matched on the entire domain name, this address is fully resolved,
- ** and we plug <user> into it. If we matched on only part of the domain
- ** name, we plug <domain>!<user> in.
- */
- build( domain, user, step ? UUCP:LOCAL, temp+1 );
- (void) sprintf( result, path, temp+1 );
- exitstat=EX_OK;
- return( exitstat );
- }
-
- /*
- * Return 1 iff the string is "UUCP" (ignore case).
- */
- isuucp(str)
- char *str;
- {
- if (islower(*str) != 'u') return 0;
- ++str;
- if (islower(*str) != 'u') return 0;
- ++str;
- if (islower(*str) != 'c') return 0;
- ++str;
- if (islower(*str) != 'p') return 0;
- ++str;
- if (*str != '\0') return 0;
- return 1;
- }
-
- /*
- **
- ** qualifydomain(): turn domain into full domain name.
- **
- ** Best explained by examples, if hostdomain = a.b.c.UUCP
- ** host.domain.UUCP -> host.domain.UUCP
- ** host.b -> host.b.c.UUCP
- ** host.x -> host.x.UUCP
- **
- */
-
- /* qualifydomain():
- * Taken out 3/21/86 by MRH - if hostdomain is, say. a.b.c.COM,
- * and domain is x.UUCP, it turns it into x.UUCP.COM and then
- * barfs on it. I don't see a way to handle PQN's this easily.
- */
-
- build( domain, user, form, result )
- char *domain;
- char *user;
- int form;
- char *result;
- {
- switch( form )
- {
- case LOCAL:
- (void) sprintf( result, "%s", user );
- break;
- case UUCP:
- (void) sprintf( result, "%s!%s", domain, user );
- break;
- case DOMAIN:
- (void) sprintf( result, "%s@%s", user, domain );
- break;
- }
- }
-
-
-
- /*
- ** ssplit(): split a line into array pointers.
- **
- ** Each pointer wordv[i] points to the first character after the i'th
- ** occurence of c in buf. Note that each wordv[i] includes wordv[i+1].
- **
- */
-
- ssplit( buf, c, ptr )
- register char *buf; /* line to split up */
- char c; /* character to split on */
- char **ptr; /* the resultant vector */
- {
- int count = 0;
- int wasword = 0;
-
- for( ; *buf; buf++ )
- {
- if ( !wasword )
- count++, *ptr++ = buf;
- wasword = ( c != *buf );
- }
- if ( !wasword )
- count++, *ptr++ = buf;
- *ptr = NULL;
- return( count );
- }
-
- !STUFFY!FUNK!
- echo Extracting aliascheck.c
- cat >aliascheck.c <<'!STUFFY!FUNK!'
- #ifndef lint
- static char * rcsid="$Header: aliascheck.c,v 4.0 86/11/17 16:02:05 sob Exp $";
- #endif
- /***************************************************************************
- This work in its current form is Copyright 1986 Stan Barber
- with the exception of resolve, gethostname and the original getpath which
- as far as I know are in the Public Domain. This software may be distributed
- freely as long as no profit is made from such distribution and this notice
- is reproducted in whole.
- ***************************************************************************
- This software is provided on an "as is" basis with no guarantee of
- usefulness or correctness of operation for any purpose, intended or
- otherwise. The author is in no way liable for this software's performance
- or any damage it may cause to any data of any kind anywhere.
- ***************************************************************************/
- /* This program based in part on the aliascheck program from MH Version 1.7 */
- #include "uuconf.h"
- #include <grp.h>
- #include <sys/param.h>
-
- #ifdef LIBNDIR
- #include <ndir.h>
- #else
- #ifdef USENDIR
- #include "ndir.h"
- #else
- #include <dir.h>
- #endif
- #endif
-
- char *AliasFile = ALIASFILE;
- char *Password = "/etc/passwd";
- char *MailDir = MAILFILE;
-
- char *termptr;
-
- struct mailname {
- struct mailname *m_next;
- char *m_name;
- int m_seen;
- } users, bad;
-
- char *getcpy(str)
- {
- register char *cp;
-
- cp = (char *) malloc(strlen(str) + 1);
- strcpy(cp, str);
- return(cp);
- }
- uleq(c1, c2)
- register char *c1, *c2;
- {
- register int c;
-
- while(c = *c1++)
- if((c|040) != (*c2|040))
- return(0);
- else
- c2++;
- return(*c2 == 0);
- }
-
- char *parse(ptr, buf)
- register char *ptr;
- char *buf;
- {
- register char *cp;
-
- cp = buf;
- while(isspace(*ptr) || *ptr == ',' || *ptr == ':')
- ptr++;
- while(isalnum(*ptr) || *ptr == '/' || *ptr == '-' || *ptr == '.')
- *cp++ = *ptr++;
- if(cp == buf) {
- switch(*ptr) {
- case '<':
- case '*':
- case '=':
- *cp++ = *ptr++;
- }
- }
- *cp = 0;
- if(cp == buf)
- return 0;
- termptr = ptr;
- return buf;
- }
-
-
- char *mail = 0;
- FILE *out;
- int donecd = 0;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- register char *cp, *pp, **cpp;
- register struct mailname *lp;
- register struct group *gp;
- struct direct *dir;
- DIR *dirp;
- char line[256], pbuf[64];
- FILE *a;
-
- if(argc == 3 && strcmp(argv[1], "-mail") == 0)
- mail = argv[2];
- if(!mail)
- out = stdout;
- if((a = fopen(Password, "r")) == NULL) {
- om();
- fprintf(out, "Can't open password file ");
- perror(Password);
- exit(1);
- }
- while(fgets(line, sizeof line, a)) {
- if(line[0] == '\n' || line[0] == ';')
- continue;
- cp = parse(line, pbuf);
- add(cp, &users);
- }
- fclose(a);
- if((a = fopen(AliasFile, "r")) == NULL) {
- om();
- fprintf(out, "Can't open alias file: %s\n", AliasFile);
- donecd = 1;
- } else {
- while(fgets(line, sizeof line, a)) {
- if(line[0] == '\n' || line[0] == ';')
- continue;
- cp = parse(line, pbuf);
- if(check(cp, 0)) {
- add(line, &bad);
- donecd = 1;
- }
- }
- fclose(a);
- if(donecd < 1) {
- if(out)
- fprintf(out, "No Alias Inconsistencies.\n");
- } else {
- om();
- fprintf(out, "%s :: %s Collisions:\n",
- Password, AliasFile);
- fprintf(out, "Colliding alias lines:\n");
- for(lp = bad.m_next; lp; lp = lp->m_next)
- fprintf(out, "%s", lp->m_name);
- donecd = 1;
- }
- }
- while(gp = getgrent()) {
- for(cpp = gp->gr_mem; *cpp; cpp++)
- if(!check(*cpp, 1)) {
- om();
- fprintf(out, "Group: %s--User: %s not in /etc/passwd\n",
- gp->gr_name, *cpp);
- donecd = 2;
- }
- }
- if(donecd < 2 && out)
- fprintf(out, "No extraneous group entries.\n");
- #ifdef RAND
- for(lp = users.m_next; lp; lp = lp->m_next)
- if(lp->m_seen == 0) {
- om();
- fprintf(out, "User: %s not in a group.\n", lp->m_name);
- donecd = 3;
- }
- if(donecd < 3 && out)
- fprintf(out, "No Users not in any group.\n");
- #endif
- if ((dirp = opendir(MailDir)) == 0) {
- om();
- fprintf(out, "Can't open mail directory: %s\n", MailDir);
- donecd = 4;
- } else {
- (void) readdir(dirp); /* skip . */
- (void) readdir(dirp); /* skip .. */
- while (dir = readdir(dirp)) {
- if (!check(dir->d_name, 0)) {
- om();
- fprintf(out, "Mail drop: %s--Nonexistent user.\n",
- dir->d_name);
- donecd = 4;
- }
- }
- closedir(dirp);
- }
- if(donecd < 4 && out)
- fprintf(out, "No Extra mail drops.\n");
-
- exit(donecd);
- }
-
-
- add(name, list)
- char *name;
- struct mailname *list;
- {
- register struct mailname *mp;
- char *getcpy();
-
- for(mp = list; mp->m_next; mp = mp->m_next)
- ;
- mp->m_next = (struct mailname *) malloc(sizeof *mp->m_next);
- mp = mp->m_next;
- mp->m_next = 0;
- mp->m_name = getcpy(name);
- }
-
- check(name, mark)
- char *name;
- int mark;
- {
- register struct mailname *mp;
-
- for(mp = users.m_next; mp; mp = mp->m_next)
- if(uleq(name, mp->m_name)) {
- if(mark)
- mp->m_seen = 1;
- return 1;
- }
- return 0;
- }
-
-
- om()
- {
- int pipes[2], child;
-
- if(out)
- return;
- if(mail) {
- pipe(pipes);
- out = fdopen(pipes[1], "w");
- if((child = fork()) == -1) {
- fprintf(stderr, "Aliascheck: no forks!\n");
- exit(1);
- }
- if(child == 0) {
- close(pipes[1]);
- close(0);
- dup(pipes[0]);
- close(pipes[0]);
- execl("/bin/mail", "mail", mail, 0);
- execl("/usr/bin/mail", "mail", mail, 0);
- execl("/bin/bellmail", "mail", mail,0);
- perror("mail");
- exit(1);
- }
- fprintf(out, "Aliascheck: ");
- }
- }
-
- #ifdef USENDIR
- #include "ndir.c"
- #endif
- !STUFFY!FUNK!
- echo Extracting MANIFEST
- cat >MANIFEST <<'!STUFFY!FUNK!'
- After all the uumail kits are run you should have the following files:
-
- Filename Kit Description
- -------- --- -----------
- Alias.Design 3 How the aliasing mechanism works.
- Binary.Only 3 How to use uumail at a site with a Binary Only license.
- Configure 1 A shell script that deals with system dependancies.
- MANIFEST 2 This list of files.
- Makefile.SH 3 The makefile builder.
- README 1 READ THIS FIRST!
- SYNOPSIS.txt 3 General features of uumail (for mod.sources)
- Sendmail 3 How to use uumail with Sendmail.
- address.1.SH 3 Manual Page builder for address
- address.c 3 address program file
- alias.c 3 The aliasing subroutines based on the ideas in MH.
- aliascheck.c 2 A program to check the format of alias files.
- deadletter.c 3 The subroutine that deals with returning mail that fails.
- gethostnam.c 3 The subroutine that returns the name of the local host.
- getpath.c 2 The paths database search subroutine.
- kitleader 4 Shell script to produce front of kit. (SYSTEM DEPENDANT)
- kitlists.c 3 Kit packer (SYSTEM DEPENDANT)
- kittrailer 4 Shell script to product end of kit. (SYSTEM DEPENDANT)
- makedepend.SH 3 Shell script to generate make dependancies.
- makekit 3 Shell script to make a kit file
- manifake 1 Shell script to make MANIFEST.new file.
- manimake 3 Shell script to make MANIFEST file.
- ndir.c 3 Source file for Berkeley directory subroutine simulation
- ndir.h 3 Include file for Berkeley directory subroutine simulation
- palias 3 Sample paths database file.
- patchlevel.h 3 Patch level and version header file
- resolve.c 2 The path resolving subroutine.
- rmail.c 3 rmail replacement to call uumail.
- uumail.8.SH 3 The manual page builder for uumail.8.
- uumail.c 2 The main program for uumail/uupath.
- uux.c 3 uux replacement for Binary Only sites.
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 2 (of 4)"
- cat /dev/null >kit2isdone
- config=true
- for iskit in 1 2 3 4 ; do
- if test -f kit${iskit}isdone; then
- echo "You have run kit ${iskit}."
- else
- echo "You still need to run kit ${iskit}."
- config=false
- fi
- done
- case $config in
- true)
- echo "You have run all your kits. Please read README and then type Configure."
- chmod 755 Configure
- ;;
- esac
- : I do not append .signature, but someone might mail this.
- exit
-
-