tim (06/18/82)
/* * * TITLE : nmail * * PURPOSE : To pre-process network addresses finding the shortest * path through the network * * PROGRAMMER : Timothy W. Curry at University of Central Florida * * DATE : April 7, 1982 * * ENTRY PTS. : main * * PARAMETERS : addresses of the form: name or site!name or name@arpa_site * */ /* include the headers to work with standard I/O; isdigit; nmailer defines */ #include <stdio.h> #include <ctype.h> #include "nmail.h" main(argc,argv) int argc; char *argv[]; { /* * Variable Usage: * net - the input file descriptor name for the network topology file * site_name - a storage buffer to hold the name of a site * plen,psrc,pdest - pointer variables used to build the list of site * names. plen holds the length of the site name; psrc holds * the current character position in the source buffer; pdest * in the destination buffer * dest - holds the name of the site we are trying to reach * addr - holds both the name of the destination site and name of the * user to receive the message * i,k,j,l,m,n - integer counters * ppos - keeps track of the current character position in paths * ptr - index into the list of site links * used - an array to hold the sites already visited while finding * the shortest path * pstk - the stack onto which the breadth first search places values */ FILE *net,*fopen(); char site_name[SITENAMELEN]; char *plen,*psrc,*pdest; char paths[256],dest[14],addr[30]; int i,j,k,l,m,n,ppos; short int *ptr,used[MAXSITES],pstk[MAXSITES][2]; if (argc == 1) { fprintf(stderr,"nmail: no addresses given.\n"); nmailusage(); } if ((net = fopen(NETFILE,"r")) == NULL) { fprintf(stderr,"nmail: can't open network configuration file.\n"); exit(1); } /* the SITES buffer will consist of a byte with the length of the site name in it followed by the site name */ *SITES = '\0'; pdest = SITES; for (NUMSITES=1; ; NUMSITES++) { if ((pdest-SITES+SITENAMELEN) > SITEBUFSZ) { fprintf(stderr,"SITES buffer overflowed\n"); exit(1); } fscanf(net,"%s",site_name); if (isdigit(*site_name)) break; for (plen=pdest,psrc=site_name; *++pdest = *psrc++; (*plen)++); } /* LINKS will be an array of numbers indicating which sites are connected to which. LINDEX is used to index into the LINKS array. */ LINKS[1] = (short int) atoi(site_name); LINDEX[1] = &LINKS[1]; for (i=2,j=1; i<=NUMSITES+1 ; i++) { while (LINKS[j] != 0) { fscanf(net,"%d",&k); j++; LINKS[j] = (short int) k; } LINDEX[i] = &LINKS[j]; j--; } /* the last number was the value for the local site */ Local = LINKS[j]; /* initialize the buffer to mail */ strcpy(paths,"mail "); ppos = 5; for (i=1; i<argc ;i++) { addr[0] = '\0'; /* if its a local address, then no need to process it */ if (!(index(argv[i],'@')) && !(index(argv[i],'!'))) { strcat(paths,argv[i]); strcat(paths," "); ppos += strlen(argv[i]) + 1; } /* otherwise a path must be found ! */ else { if (index(argv[i],'@') && !(index(argv[i],'!'))) strcpy(addr,ARPA); strcat(addr,argv[i]); strcat(addr," "); /* set dest = name of destination site */ for (j=0; addr[j] != '!' ;j++) { dest[j] = addr[j]; dest[j+1] = '\0'; if (dest[j] == '\0') { fprintf(stderr,"nmail: improperly formed address.\n"); nmailusage(); } } /* find the numeric index of dest for LINDEX to use */ for (j=0,k=1,m = strlen(dest); k<NUMSITES ;k++) { l = SITES[j]; if (l == m) { for (j++,l+=j,n=0; j<l ; j++,n++) if (SITES[j] != dest[n]) break; if (j == l) break; j = l; } else j += l + 1; } if (k == NUMSITES) { fprintf(stderr,"nmail: site %s is not in the network.\n",dest); exit(1); } /* do a breadth first search to find a path from source to sink */ if (k != Local) { for (j=0,l=1,m=0,used[0] = k; k!=Local ;k=pstk[m++][1]) { for (ptr=LINDEX[k]; ptr<LINDEX[k+1] ;ptr++) { for (n=0; n<l ;n++) if (used[n] == *ptr) break; if (n==l) { used[l] = *ptr; l++; pstk[j][0] = k; pstk[j][1] = *ptr; j++; } } } /* convert the numeric site values to thier character names and place them in the paths buffer */ k = pstk[m-1][0]; while (k != pstk[0][0]) { for (j=0,l=0; j<k-1 ;j++) l += SITES[l] + 1; n = SITES[l]; for (j=0,l++; j<n ;j++,l++,ppos++) paths[ppos] = SITES[l]; paths[ppos++] = '!'; for ( ; pstk[m][1] != k ;m--); k = pstk[m][0]; } paths[ppos] = '\0'; } strcat(paths,addr); ppos += strlen(addr); } } /* when all the paths are resolved, pass control over to mail */ printf("%s\n",paths); execl("/usr/ucb/mail","mail",paths,0); } nmailusage() { fprintf(stderr,"usage: nmail addr {addr} \nWhere addr = site!name for "); fprintf(stderr,"uucp-address or name@site for ARPANET-address.\n"); exit(1); }