Path: seismo!harvard!husc6!talcott!panda!soma!sob From: sources-request@panda.UUCP Newsgroups: mod.sources Subject: uumail 3.0 (Part 2 of 2) Message-ID: <1791@panda.UUCP> Date: 4 May 86 13:11:36 GMT Sender: jpn@panda.UUCP Lines: 2112 Approved: jpn@panda.UUCP Mod.sources: Volume 4, Issue 92 Submitted by: soma!sob #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create the files: # alias.c # gethostnam.c # getpath.c # opath.c # uuconf.h # uumail.c # This archive created: Fri May 2 17:52:26 1986 export PATH; PATH=/bin:$PATH echo shar: extracting "'alias.c'" '(7875 characters)' if test -f 'alias.c' then echo shar: will not over-write existing file "'alias.c'" else cat << \SHAR_EOF > 'alias.c' #include "uuconf.h" static char rcsid[] = "$Header: alias.c,v 3.0 86/03/14 12:04:41 sob RELEASE_3 $"; /*************************************************************************** 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. ***************************************************************************/ /* These routines based in part on the aliasing facility of MH Version 1.7 */ /* $Log: alias.c,v $ * Revision 3.0 86/03/14 12:04:41 sob * Release of 3/15/86 --- 3rd Release * * Revision 1.10 86/03/14 11:57:13 sob * updated copyright * * Revision 1.9 86/03/11 11:28:40 sob * Added Copyright Notice * * Revision 1.8 86/03/03 17:16:39 sob * Added fixes provided by desint!geoff. * Stan * * Revision 1.7 86/02/26 03:07:20 sob * This forward method seems to work. It is a bit awkward, but it does seem * to work. We will freeze the release here. * * Revision 1.6 86/02/24 12:46:31 sob * Fixed some problems with .forward. Still not completely correct, but better. * Stan * * Revision 1.5 86/02/23 23:48:50 sob * This version contains the first attempt to make .forwards work. * Stan * * Revision 1.4 86/02/23 23:01:12 sob * This version will correctly make note of programs that can have output * of uumail directly piped into (in place of mail or uux). * * Revision 1.3 86/02/18 01:56:12 sob * MH aliasing facility has been installed. Now comes time to test. * Stan * * Revision 1.2 86/02/17 18:42:47 sob * First update to add linked list of addresses. Real aliasing to be * added next. * * Revision 1.1 86/02/10 16:54:12 sob * Initial revision * * */ #ifdef NOALIAS char * alias() { return; } #else EXTERN struct mailname addrlist; #define GROUP "/etc/group" char *termptr; /* Conditional free -- perform a free call if the address passed * is in free storage; else NOP */ cndfree(addr) char *addr; { extern char end; if(addr >= &end) free(addr); } 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 == '.' || *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 * advance(ptr) register char *ptr; { return(termptr); } alias() { register char *cp, *pp; register struct mailname *lp; char line[256], pbuf[64]; FILE *a; if((a = fopen(AliasFile, "r")) == NULL) return; while(fgets(line, sizeof line, a)) { if(line[0] == ';' || line[0] == '\n') /* Comment Line */ continue; if((pp = parse(line, pbuf)) == NULL) { oops: fprintf(stderr, "Bad alias file %s\n", AliasFile); fprintf(stderr, "Line: %s", line); exit(EX_OSFILE); } for(lp = &addrlist; lp->m_next; lp = lp->m_next) { if(aleq(lp->m_next->m_name, pp)) { remove(lp); if(!(cp = advance(line)) || !(pp = parse(cp, pbuf))) goto oops; switch(*pp) { case '<': /* From file */ cp = advance(cp); if((pp = parse(cp, pbuf)) == NULL) goto oops; addfile(pp); break; case '=': /* UNIX group */ cp = advance(cp); if((pp = parse(cp, pbuf)) == NULL) goto oops; addgroup(pp); break; case '|': /* pipe through a program */ cp = advance(cp); if ((pp=parse(cp,pbuf)) == NULL) goto oops; addprgm(pp); break; default: /* Simple list */ for(;;) { insert(pp); if(!(cp = advance(line)) || !(pp = parse(cp, pbuf))) break; } } break; } } } } addfile(file) char *file; { register char *cp, *pp; char line[128], pbuf[64]; FILE *f; #ifdef DEBUG if (Debug >3) printf("addfile(%s)\n", file); #endif if((f = fopen(file, "r")) == NULL) { fprintf(stderr, "Can't open "); perror(file); exit(EX_OSFILE); } while(fgets(line, sizeof line, f)) { cp = line; while(pp = parse(cp, pbuf)) { insert(pp); cp = advance(cp); } } fclose(f); } addgroup(group) char *group; { register char *cp, *pp; int found = 0; char line[128], pbuf[64], *rindex(); FILE *f; #ifdef DEBUG if(Debug>3)printf("addgroup(%s)\n", group); #endif if((f = fopen(GROUP, "r")) == NULL) { fprintf(stderr, "Can't open "); perror(GROUP); exit(EX_OSFILE); } while(fgets(line, sizeof line, f)) { pp = parse(line, pbuf); if(strcmp(pp, group) == 0) { cp = rindex(line, ':'); while(pp = parse(cp, pbuf)) { insert(pp); cp = advance(cp); } found++; } } if(!found) { fprintf(stderr, "Group: %s non-existent\n", group); exit(EX_DATAERR); } fclose(f); } addprgm(name) char *name; { register struct mailname *mp; char * getcpy(); for(mp = &addrlist; mp->m_next; mp = mp->m_next) if(uleq(name, mp->m_next->m_name)) return; /* Don't insert existing name! */ mp->m_next = (struct mailname *) malloc(sizeof *mp->m_next); mp = mp->m_next; mp->m_next = 0; mp->m_name = getcpy(name); mp->m_pipe = 1; } remove(mp) /* Remove NEXT from argument node! */ register struct mailname *mp; { register struct mailname *rp; rp = mp->m_next; mp->m_next = rp->m_next; cndfree(rp->m_name); cndfree(rp); } insert(name) char *name; { register struct mailname *mp; char *getcpy(); #ifdef DEBUG if(Debug>3) printf("insert(%s)\n", name); #endif for(mp = &addrlist; mp->m_next; mp = mp->m_next) if(uleq(name, mp->m_next->m_name)) return; /* Don't insert existing name! */ mp->m_next = (struct mailname *) malloc(sizeof *mp->m_next); mp = mp->m_next; mp->m_next = 0; mp->m_pipe=0; mp->m_name = getcpy(name); } aleq(string, aliasent) register char *string, *aliasent; { register int c; while(c = *string++) if(*aliasent == '*') return 1; else if((c|040) != (*aliasent|040)) return(0); else aliasent++; return(*aliasent == 0 | *aliasent == '*'); } forward() { FILE * fp; struct passwd * pwd; struct mailname *lp; char forwardfile[BUFSIZ]; extern struct passwd * getpwnam (); for (lp = addrlist.m_next;lp;lp=lp->m_next){ if (index(lp->m_name,'!')) continue; /* not local */ if (index(lp->m_name,'@')) continue; /* ditto */ if (index(lp->m_name,'%')) continue; /* ditto */ if (index(lp->m_name,'/')) continue; /* filename */ if ((pwd = getpwnam(lp->m_name)) == NULL) continue; sprintf(forwardfile,"%s/.forward",pwd->pw_dir); if((fp=fopen(forwardfile,"r")) != NULL){ strcpy(lp->m_name,""); addfile(forwardfile); fclose(fp); } } } #endif /* add names to the address list */ 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_pipe = 0; mp->m_name = getcpy(name); } char *getcpy(str) { register char *cp; cp = (char *) malloc(strlen(str) + 1); strcpy(cp, str); return(cp); } SHAR_EOF if test 7875 -ne "`wc -c < 'alias.c'`" then echo shar: error transmitting "'alias.c'" '(should have been 7875 characters)' fi fi echo shar: extracting "'gethostnam.c'" '(1372 characters)' if test -f 'gethostnam.c' then echo shar: will not over-write existing file "'gethostnam.c'" else cat << \SHAR_EOF > 'gethostnam.c' #ifndef lint static char sccsid[] = "@(#)gethostnam.c 6.1 (down!honey) 85/01/21"; static char rcsid[] = "$Header: gethostnam.c,v 6.3 85/11/23 05:30:04 UUCP Exp $"; #endif lint #ifndef GETHOSTNAME #include "uuconf.h" void gethostname(name, len) char *name; { FILE *whoami, *fopen(), *popen(); char *ptr, *index(); #if defined(SYSIII) && !defined(SYSTEMNAME) struct utsname utsn; #endif *name = '\0'; #ifndef SYSTEMNAME #ifdef SYSIII if (uname(&utsn) != -1) { strcpy(name,utsn.nodename); len = strlen(name); return; } #endif #endif #ifdef SYSTEMNAME /* try /usr/lib/uucp/SYSTEMNAME */ if ((whoami = fopen("/usr/lib/uucp/SYSTEMNAME", "r")) != 0) { (void) fgets(name, len, whoami); (void) fclose(whoami); if ((ptr = index(name, '\n')) != 0) *ptr = '\0'; } if (*name) return; #endif /* try /usr/include/whoami.h */ if ((whoami = fopen("/usr/include/whoami.h", "r")) != 0) { while (!feof(whoami)) { char buf[100]; if (fgets(buf, 100, whoami) == 0) break; if (sscanf(buf, "#define sysname \"%[^\"]\"", name)) break; } (void) fclose(whoami); if (*name) return; } /* ask uucp */ if ((whoami = popen("uuname -l", "r")) != 0) { (void) fgets(name, len, whoami); (void) pclose(whoami); if ((ptr = index(name, '\n')) != 0) *ptr = '\0'; } if (*name) return; /* failure */ return; } #endif GETHOSTNAME SHAR_EOF if test 1372 -ne "`wc -c < 'gethostnam.c'`" then echo shar: error transmitting "'gethostnam.c'" '(should have been 1372 characters)' fi fi echo shar: extracting "'getpath.c'" '(8792 characters)' if test -f 'getpath.c' then echo shar: will not over-write existing file "'getpath.c'" else cat << \SHAR_EOF > 'getpath.c' /* * 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 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" #ifndef DBM #include #include #endif static char rcsid[] = "$Header: getpath.c,v 3.0 86/03/14 12:04:46 sob RELEASE_3 $"; extern char * index(); extern FILE * fopen (), *popen(); FILE * in; bool nghborflag; char neighbors[NEIGHBORS][NAMESIZ]; int getpath (sysname, pathname,pathfile) char *sysname, *pathname,*pathfile; { int retval,indx; #ifdef DBM datum lhs,rhs; #else struct stat st; time_t modtime; #ifdef SORTED int scomp(); long lo,hi; long cur; long last; static char buf[256]; #else char name[NAMESIZ],*p,t; #endif #endif #ifdef DEBUG if (Debug>2) printf("In getpath: Sysname = %s, Pathfile = %s\n",sysname,paths); #endif if(nghborflag !=TRUE) getneighbors(); indx = 0; while(neighbors[indx][0] != '\0'){ if(!strcmp(sysname,neighbors[indx])){ strcpy(pathname,neighbors[indx]); strcat(pathname,"!%s"); return(EX_OK); } indx++; } #ifdef DBM for (indx = 0; indx < 5; indx++) { if ((retval = dbminit (pathfile)) >= 0) break; #ifdef DEBUG if (Debug>2) fprintf (stderr, "Database unavailable. Sleeping.\n"); #endif sleep (TIMEOUT); } if (retval < 0) return(EX_NOINPUT); 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) 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) 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) fprintf (stderr, "Database unavailable. Sleeping.\n"); #endif sleep (TIMEOUT); } if (in == NULL) return(EX_NOINPUT); } else rewind(in); indx = 0; 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; fseek(in, cur, 0); fgets(buf, sizeof(buf), in); cur = ftell(in); fgets(buf, sizeof(buf), in); #ifdef DEBUG if (Debug > 4) printf("Found site %s\n", buf); #endif if (scomp(sysname, buf) < 0) hi = cur; else if (scomp(sysname, 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) { fseek(in, lo, 0); do { fgets(buf, sizeof(buf), in); lo = ftell(in); if (scomp(sysname, 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 */ return(EX_NOHOST); #else for (;;) { p = &name[0]; 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 = &name[0]; #ifdef DEBUG if (Debug>4) printf("Found %s\n",p); #endif if (strcmp (p,sysname) == 0) break; while ((getc (in) != '\n')); /* skip this path */ } p = pathname; /* save start loc of pathname */ while ((*pathname++ = getc (in)) != '\n'); *--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; nghborflag = TRUE; if ((ppntr = popen("uuname", "r")) != NULL) { #ifdef DEBUG if (Debug>2) fprintf(stderr,"Starting uuname\n"); #endif while((fgets(neighbors[x], NAMESIZ,ppntr)) != NULL){ if ((ptr = index(neighbors[x], '\n')) != NULL) *ptr = '\0'; #ifdef DEBUG if (Debug>4) fprintf(stderr,"Neighbor # %d: %s\n",x+1,neighbors[x]); #endif x++; } (void) pclose(ppntr); } strcpy(neighbors[x],Myname); } SHAR_EOF if test 8792 -ne "`wc -c < 'getpath.c'`" then echo shar: error transmitting "'getpath.c'" '(should have been 8792 characters)' fi fi echo shar: extracting "'opath.c'" '(6637 characters)' if test -f 'opath.c' then echo shar: will not over-write existing file "'opath.c'" else cat << \SHAR_EOF > 'opath.c' /* * opath.c - get an optimal uucp path from the path database, using an * RFC882-style address as input. The '%' character is properly translated, * and gateway-substitution is done to get mail onto other networks. * * * Eric Roskos, Perkin-Elmer Corp. SDC * Version 3.2 created 85/09/12 15:21:51 * $Log: opath.c,v $ * Revision 3.9 86/03/14 11:57:30 sob * * * Revision 3.8 86/02/17 02:55:28 sob * This version has the ability to optimize a uucp path in a manner * similiar to that used a GATech. The first hostname recognized * is used as the base for the path generation instead of the first * name in the path. * * Revision 3.7 85/11/14 20:22:16 sob * Added #ifdef DEBUG to allow compiliation without DEBUG * * Revision 3.6 85/11/08 03:05:22 sob * release version * * Revision 3.5 85/10/09 03:20:07 sob * Added strindex call to make striping the printf stuff more pleasing. * * Revision 3.4 85/09/30 02:49:12 sob * Updated to use getpath revised by Stan Barber * * Revision 3.3 85/09/16 18:32:26 sob * This version will use the getpath subroutine used by uupath/uumail * and is not dependant on whether it is DBM or not. * Also uses the uuconf include file. * * Revision 3.2 85/09/16 17:50:07 sob * Added to RCS * */ static char *opathsccsid = "@(#)opath.c 3.2 (peora) 15:21:51 - 85/09/12"; static char opathrcsid[] = "$Header: opath.c,v 3.9 86/03/14 11:57:30 sob Exp $"; #ifdef OPATH #include "uuconf.h" extern char * rindex(); /** ** User-configurable parameters **/ /** ** Global Variables **/ static char pval[150]; /* the path string is built here */ /* * the following are used to pass results by side-effect from the domain() * routine. */ static char prefix[80], suffix[80], fullsite[80]; /** ** Subroutines **/ /* * The Domain Table and its associated routines */ static struct domains { char dom[50]; char pre[50]; char suf[50]; char map[50]; } domtab[100]; /* Inline routine to copy a domain into the domain table */ #define DOMCPY(fld) { int i = 0; q=dp->fld; while (*p!=','&&*p!='\n'&&*p) \ {*q++ = *p++; if (i++>=48) break;} \ *q++ = '\0'; if (!*p) { \ fprintf(stderr,"opath: fld(s) missing in %s at %s\n", \ s, buf); \ dp++; continue;} p++; } /* Load the domain table from disk */ static int loaddomtab(s) char *s; { FILE *f; char buf[100]; register char *p,*q; struct domains *dp; f = fopen(s,"r"); if (f==NULL) { fprintf(stderr,"opath: can't open domain file '%s'\n",s); exit(1); } dp = domtab; while (fgets(buf,100,f)) { if (buf[0]=='#') continue; /* comments start with "#" */ p = buf; DOMCPY(dom); DOMCPY(pre); DOMCPY(suf); DOMCPY(map); if (dp->map[0] == '\0') { fprintf(stderr,"opath: bad route template in %s\n",s); strcpy(dp->map,"Invalid"); } dp++; } dp->map[0] = '\0'; /* mark end of table */ fclose(f); return(0); } /* Get a UUCP path from the pathalias database * and compensate for the format. * Typically the format is * site1!site2!site3!%s to be used in *printf statements. * We don't want the !%s, so we cut it off. * Pretty gross, but it works. */ static char * gpath(s) char *s; { static char path[100]; int getpath(),x; getpath(s,&path[0],paths); x=strindex(&path[0],"!%s"); if (x >0) path[x] = '\0'; #ifdef DEBUG if (Debug>1)fprintf(stderr,"Getpath returns: %s\n",&path[0]); #endif return(&path[0]); } /* returns location of tx in sx */ strindex(sx,tx) char * sx, *tx; { int i,n; n = strlen(tx); for (i=0;sx[i] != '\0'; i++) if (strncmp(sx+i,tx,n) ==0) return(i); return (-1); } /* String compare: entire first argument must match suffix of 2nd argument */ static int domcmp(ss,tt) char *ss, *tt; { char *s, *t; int cmp; s = ss + strlen(ss) - 1; t = tt + strlen(tt) - 1; do { if (*s - *t) break; s--; t--; } while (s >= ss); if (++s == ss) return(0); else return(1); } /* Look up a domain, and by side effect set prefix and suffix appropriately */ char *domain(s) char *s; { struct domains *d; char *p; static int loaded = 0; if (!loaded++) loaddomtab(ConfFile); if (*s!='.') /* default to UUCP domain */ { prefix[0]=suffix[0]='\0'; return("%R!%U"); } for (p=s; *p; p++) if (*p>='a' && *p<='z') *p -= 'a'-'A'; for (d = &domtab[0]; (int)d->map[0]; d++) { if (domcmp(d->dom,s)==0) break; } strcpy(prefix,(d->pre[0]=='>')? gpath(&d->pre[1]) : d->pre); strcpy(suffix,d->suf); return(d->map); } /* opath: generates a UUCP path from an RFC-822 address */ #define COPYON(s) {char *r; r=s; while (*r) *p++ = *r++; *p = '\0';} char * opath(s) char *s; { char user[50],site[50]; static char cm[150]; FILE *f; char *p, *q, *t; char *d; int i; int found; char *suf; for (p=user,q=s;(*p = *q)!='@'; p++,q++) if (*q=='\0') return(s); *p = '\0'; strcpy(fullsite,++q); for (p=site;(*p = *q)!='.'; p++,q++) if (*q=='\0') break; *p = '\0'; d = domain(q); if (d[0]=='\0') return(s); /* unknown domain - do nothing */ for (p=pval, q=d; *q; q++) { if (*q=='%') { switch(*++q) { case 'P': COPYON(prefix); break; case 'S': COPYON(suffix); break; case 'U': COPYON(user); break; case 'N': COPYON(site); break; case 'D': COPYON(fullsite); break; case 'R': COPYON(gpath(site)); break; case '%': *p++ = '%'; break; } } else *p++ = *q; } return(pval); } /* oupath: generates a uucp path from a (possibly disconnected) uucp path */ char *oupath(s) char *s; { char *p,*q; static char adr[100]; char first[100]; int found; #ifdef OPTIMIZE strcpy(first,s); if ((p = rindex(first,'!')) == NULL) return(opath(s)); /* this is an error or local */ *p = '\0'; /* cut off user id */ while ((q= rindex(first,'!')) != NULL) /* back up through bangs */ { if (getpath(q+1,adr,paths) == EX_OK) { found = strindex(adr,"!%s"); if (found >0) adr[found] = '\0'; found = strlen(first); strcpy(first,adr); strcat(first,(s+found)); return(first); } *q= '\0'; } strcpy(adr,gpath(first)); strcat(adr,rindex(s,'!')); return(adr); #else for (p=s,q=first,found=0; *p!='!' && *p!='\0'; p++) { if (*p=='.') found++; *q++ = *p; } if (*p=='\0') return (s); *q = '\0'; if (found) { strcpy(adr,++p); strcat(adr,"@"); strcat(adr,first); return(opath(adr)); } else { int i; strcpy(adr,gpath(first)); strcat(adr,/* ++ */p); return(adr); } #endif } opathlog(fmt,a,b,c,d) char *fmt; int a,b,c,d; { FILE *f; f = fopen(logfile,"a"); if (f==NULL) return; fprintf(f,fmt,a,b,c,d); fclose(f); } #endif SHAR_EOF if test 6637 -ne "`wc -c < 'opath.c'`" then echo shar: error transmitting "'opath.c'" '(should have been 6637 characters)' fi fi echo shar: extracting "'uuconf.h'" '(4925 characters)' if test -f 'uuconf.h' then echo shar: will not over-write existing file "'uuconf.h'" else cat << \SHAR_EOF > 'uuconf.h' /* $Header: uuconf.h,v 3.0 86/03/14 12:05:12 sob RELEASE_3 $ * Configuration for uumail and uupath utilities * Please see the header for makefile for changes you may * need to make there. *************************************************************************** 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. *************************************************************************** * $Log: uuconf.h,v $ * Revision 3.0 86/03/14 12:05:12 sob * Release of 3/15/86 --- 3rd Release * * Revision 1.8 86/03/14 11:58:00 sob * * * Revision 1.7 86/02/23 23:02:46 sob * updated to follow modifications to getpath * * Revision 1.6 85/12/30 17:00:55 sob * Removed include for setjump.h and added NULL definition * suggested by bug report * * Revision 1.5 85/12/10 20:42:30 sob * Added defines for new parts of getpath, SENTINAL and TIMEOUT * * Revision 1.4 85/10/02 02:16:21 sob * Added LOCALMAIL definition * * Revision 1.3 85/09/30 02:50:51 sob * Added pwd.h to list of include files * * Revision 1.2 85/07/11 19:29:34 sob * *** empty log message *** * * Revision 1.1 85/07/11 19:22:20 sob * Initial revision * */ #include #include #include #include /* * sysexits is a file of exit codes that are used in sendmail * and other programs ... */ #include /* if you don't have sysexits.h here are the useful parts */ #ifndef EX_OK # define EX_OK 0 /* successful termination */ # define EX_USAGE 64 /* command line usage error */ # define EX_DATAERR 65 /* data format error */ # define EX_NOINPUT 66 /* cannot open input */ # define EX_NOHOST 68 /* host name unknown */ # define EX_UNAVAILABLE 69 /* service unavailable */ # define EX_SOFTWARE 70 /* internal software error */ # define EX_OSERR 71 /* system error (e.g., can't fork) */ # define EX_OSFILE 72 /* critical OS file missing */ # define EX_CANTCREAT 73 /* can't create (user) output file */ # define EX_IOERR 74 /* input/output error */ # define EX_TEMPFAIL 75 /* temp failure; user should retry */ #endif typedef char bool; #ifdef DBM #include #endif #ifdef SYSIII #define index strchr #define rindex strrchr #include #endif #define NAMESIZ 32 /* system name size */ #define PATHSIZ 16*NAMESIZ /* path length */ #define NEIGHBORS BUFSIZ/NAMESIZ #define TRUE 1 #define FALSE 0 #ifndef TIMEOUT #define TIMEOUT ((unsigned) 180) #endif TIMEOUT #ifndef SENTINEL #define SENTINEL "@@@" #endif SENTINEL /* Does this solve the problem of null for dbm users? * problem reported by pluto!warren */ #ifndef NULL #define NULL ((char *) 0) #endif /* Here's where you should put in the the name of the file * in which the uucpmap data is kept. * For those using DBM, this will be the root filename for the database * (eg... file.pag and file.dir with root name file) */ #define DATABASE "/usr/lib/uucp/palias" #define CONFIGFILE "/usr/lib/uucp/domains" #define LOGFILE "/usr/adm/uumail.log" #define ALIASFILE "/usr/lib/uucp/Aliases" /* this needs to be a printf-like string to deliver LOCAL mail */ /* usually this is either /bin/mail or /bin/binmail */ #define LOCALMAIL "/bin/bellmail %s" #ifdef _DEFINE #define EXTERN #else #define EXTERN extern #endif /* The following structure is stolen from MH for use in a new aliasing and forwarding feature that will likely be stolen from MH. My thanks to the MH folks for making this stuff possible. */ struct mailname { struct mailname *m_next; char *m_name; int m_pipe; } ; EXTERN int Debug; EXTERN char *paths; EXTERN char *ConfFile; EXTERN char *AliasFile; EXTERN char Myname[NAMESIZ]; EXTERN char *logfile; EXTERN char OpMode; /* operation mode, see below */ /* These don't do anything yet.... maybe next time they will do something */ #define MD_DELIVER 'm' /* be a mail sender */ #define MD_ARPAFTP 'a' /* old-style arpanet protocols */ #define MD_SMTP 's' /* run SMTP on standard input */ #define MD_DAEMON 'd' /* run as a daemon */ #define MD_VERIFY 'v' /* verify: don't collect or deliver */ #define MD_TEST 't' /* test mode: resolve addrs only */ #define MD_INITALIAS 'i' /* initialize alias database */ #define MD_PRINT 'p' /* print the queue */ #define MD_FREEZE 'z' /* freeze the configuration file */ SHAR_EOF if test 4925 -ne "`wc -c < 'uuconf.h'`" then echo shar: error transmitting "'uuconf.h'" '(should have been 4925 characters)' fi fi echo shar: extracting "'uumail.c'" '(16528 characters)' if test -f 'uumail.c' then echo shar: will not over-write existing file "'uumail.c'" else cat << \SHAR_EOF > 'uumail.c' /* * 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 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. *************************************************************************** * $Log: uumail.c,v $ * 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" 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 char progname[12]; EXTERN char *paths; char templet[64]; char * from; struct mailname addrlist; /* list of addresses */ int local; static char Version[] ="$Header: uumail.c,v 3.0 86/03/14 12:05:00 sob RELEASE_3 $"; main(argc, argv) char **argv; { FILE *out, *tmpf; /* output to uux, temp file */ char lbuf[512]; /* for pipe to uux */ char sender[512]; /* accumulated path of sender */ char sys[64]; /* a system in path */ char cmd[2000]; char **av; int i, error = 0, bangcnt, hopcount = 30; char c, grade = 'C', name[20], /* The system name (if any) */ *fname, *path, /* uupath to the system */ *sysname, /* points to the system name */ *p, *q, *r, /* tmp pointer to argv's */ *rsys, *FullName; bool GrabTo,safecf,NoAlias,startuux,noheader,metoo; extern intsig(); struct mailname *lp; 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; gethostname(Myname,32); paths=DATABASE; logfile=LOGFILE; 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 'C': /* select configuration file */ ConfFile = &p[2]; safecf = FALSE; break; 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); 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 'w': /* just print the path */ uupath = TRUE; break; case 'h': /* don't add a From line */ noheader = TRUE; 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; } } if(*av==NULL && GrabTo!= TRUE) { fprintf(stderr,"Usage: %s [flags] address\n",progname); exit(EX_USAGE); } if (ConfFile == NULL) ConfFile = CONFIGFILE; if (AliasFile == NULL) AliasFile = ALIASFILE; /* 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 this is not uupath, then there must be a letter */ if (!uupath) { #ifdef DEBUG if (Debug) 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) printf("Temp file is %s\n",templet); #endif if((tmpf = fopen(templet, "w")) == NULL){ 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); fclose(tmpf); fclose(stdin); /* file now saved */ if((tmpf = fopen(templet, "r")) == NULL){ fprintf(stderr, "%s : can't open %s for reading\n", progname,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 = bangcnt = 0; q = p = lp->m_name; sysname = &name[0]; /* this is uupath command */ if (uupath) { (void) strcpy(sysname ,p); #ifdef OPATH if ((error = getpath (&name[0], path,paths)) != EX_OK) { if (error == EX_NOHOST) fprintf (stderr, "System %s not found in network map\n", &name[0]); if (error == EX_NOINPUT) fprintf(stderr,"Database %s could not be opened\n",paths); if (error == EX_TEMPFAIL) fprintf(stderr,"Database %s is being updated\nTry again later.\n",paths); exit(EX_NOHOST); } if (strcmp(path,"%s") == 0) local = 1; } else { /* check for pipe to another program output here */ if (lp->m_pipe == TRUE){ strcat(cmd,lp->m_name); goto pipeout; } #ifdef RFC976 if (index(p,'@') == NULL) strcpy(path,oupath(p)); else strcpy(path,opath(p)); #else if (index(p,'!') != NULL) strcpy(path,oupath(p)); else strcpy(path,opath(p)); #endif /* fix string to allow % to be untranslated by printf and * friends */ if ((r=index(path,'%')) != NULL) { char t[PATHSIZ]; strncpy(t,path,(r-path)); strcat(t,"%"); strcat(t,r); path = &t[0]; #ifdef DEBUG if (Debug>3) fprintf(stderr,"In percent fix, %s\n",t); #endif } #ifdef DEBUG if (Debug >1) fprintf(stderr,"Opath returns %s\n",path); #endif if (path[0] == '!') /* no match in pathalias database */ { deadletter(tmpf,local); unlink(templet); exit(EX_NOHOST); } if (strcmp(path,p) == 0 && index(path,'!') == NULL ) { strcpy(path,Myname); local = 1; } } /* end of else uupath */ #else } else { /* check and pipe to output if here */ do /* count bangs */ { while (((c = *p++) != '!') && (c != '\0')); if (c == '!') bangcnt++; } while (c != '\0' && bangcnt == 1); ; if (bangcnt >= 1) /* expand path */ { while ((*sysname++ = *q++) != '!'); *--sysname = '\0'; } /* insert code here to look at uucp neighbors & local host */ } if (bangcnt == 0) { strcpy(sysname,Myname); local = 1; } #ifdef DEBUG if (Debug>1) printf("sysname = %s\n",&name[0]); #endif if (local == 0 && (error = getpath (&name[0], path,paths)) != EX_OK) { if (error == EX_NOHOST) fprintf (stderr, "System %s not found in network map\n", &name[0]); if (error == EX_NOINPUT) fprintf(stderr,"Database %s could not be opened\n",paths); if (error == EX_TEMPFAIL) fprintf(stderr,"Database %s is being updated\nTry again later.\n",paths); exit(EX_NOHOST); } if (local!=0) path = "%s"; if (strcmp (path,"%s") == 0) local = 1; #endif #ifdef DEBUG if(Debug>1) printf("Path = %s\n",path); #endif p = q; /* save name */ for (i = 0; i < 1 && *p != '\0'; p++) if (*p == '/') i++; fname = &sender[0]; if (uupath) sprintf(fname,path,"username"); else sprintf(fname,path,q); p = fname; #ifdef DEBUG if (Debug> 4) printf("p = %s local = %d\n ",p,local); #endif rsys = &sys[0]; if (local == 0) { while((*rsys++ = *p++) != '!'); *--rsys = '\0'; } else /* local host, remove @ sign */ { strcpy(rsys,lp->m_name); q=rsys; if (index(rsys,'@') != NULL) { while (*q++ !='@'); *--q='\0'; } /* assume that if it has a bang in it uux will either reject it or know what to do with it */ /* this is a little gross */ if ((q = index(rsys,'!')) != NULL) { local=0; strcpy(&sys[0],rsys); sys[q-rsys]='\0'; p=q+1; } } if ((local==0 && *fname =='\0') || (local!=0 && &sys[0]=='\0')) { fprintf(stdout, "null name\n"); exit(EX_DATAERR); } #ifdef DEBUG if (Debug>3) printf("p = %s sys = %s fname = %s\n",p, &sys[0],fname); #endif if (uupath) { printf ("Path to %s: %s\n", lp->m_name, fname); continue; } else { if (local!= 0) sprintf(cmd, LOCALMAIL, &sys[0]); else { 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]; sprintf(work," -g%c",grade); strcat(cmd,work); } #endif if (index(p, '!')) { char work[100]; sprintf(work, " %s!rmail \\(%s\\)", &sys[0], p); strcat(cmd,work); } else { char work[100]; sprintf(work, " %s!rmail %s", &sys[0], p); strcat(cmd,work); } } pipeout: #ifdef DEBUG if (Debug) 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); */ if (!noheader) Putfrom(tmpf,out); while (fgets(lbuf, sizeof lbuf, tmpf)) fputs(lbuf, out); /* may not be needed */ if (local!=0) fprintf(out,"\n.\n"); #ifdef DEBUG if (Debug) i = fclose(out); else #endif i = pclose(out); if ((i & 0377) != 0) { fprintf(stderr, "pclose: status 0%o\n", i); deadletter(tmpf,local); #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; { fprintf(stderr,"%s\n",string); } /* make a unix type From line and send it out the stream */ Putfrom(into,outto) FILE *into, *outto; { char *asctime(); struct tm *bp, *localtime(); char *tp, *zp; int n,fromflag=0; char buf[128]; long iop; /* * 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);*/ sprintf(buf, "From %s %.16s %.4s", from, tp, tp+20); #ifdef UGLYUUCP if (local == 0){ strcat(buf," remote from "); strcat(buf,Myname); } #endif strcat(buf,"\n"); write(outto->_file,buf,strlen(buf)); fflush(outto); if (fgets(buf,sizeof(buf),into) != NULL) if((strncmp(&buf[0], "From ", 5) == 0 || strncmp(&buf[0], "From:", 5) == 0)) write(outto->_file,">",1); write(outto->_file,buf,strlen(buf)); } /* attempt to return dead letter */ /* we'll do better on this one next time */ deadletter(retlet, here) FILE *retlet; int here; { if(getlogin() != NULL) syserr("Letter failed....\n"); } /* 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) { fprintf(f,"%s: %s - %s\n",progname,atime,command); fclose(f); } } #endif SHAR_EOF if test 16528 -ne "`wc -c < 'uumail.c'`" then echo shar: error transmitting "'uumail.c'" '(should have been 16528 characters)' fi fi exit 0 # End of shell archive