1: static char sccsid[] = "@(#)mmail.c 4.1 (Berkeley) 9/12/82"; 2: 3: # include "defs.h" 4: /* sccs id variable */ 5: static char *mmail_sid = "@(#)mmail.c 1.2"; 6: 7: /* 8: Mmail is a berkeley network internal command. 9: It is executed locally by the mwrite command, 10: and from a remote machine by the sendberkmail command. 11: Its purpose is to send mail to a user on this 12: machine using the system mail program. 13: 14: Archaic Usage: 15: 16: mmail [-commandsent -timesent] fromuser frommach touser 17: 18: Correct Usage: 19: mmail [-c commandsent] [-e timesent] [-f fromaddress] [-t toaddress] 20: [-h hopcnt] [-r rc] [-z] 21: 22: The mwrite command uses all the options. 23: The sendberkmail command does not use the commandsend, timesent and rc 24: options. 25: Timesent is time in seconds since 1901 in decimal, as returned by time(). 26: Frommach is a multi-character name, not a single letter. 27: Rc is the return code (exit code>>8) of the command. 28: 29: Assumptions about the system mail command: 30: 1. We assume there is an optional argument "-r" which can be added to mail. 31: Mail argument format (two choices): 32: 33: mail -r fromaddress toaddress 34: 35: which becomes mail from "fromaddress" instead of "network". 36: 37: 2. We assume that mail accepts the "-h hopcnt" flag, and passes it thru 38: unchanged to the sendberkmail program. The hopcnt is incremented everytime 39: it passes thru mmail, so inifinite mail forwarding is detected. 40: Since both the from and to addresses cycle, it there is infinite looping 41: we simply mail to root to that effect and throw away the mail. 42: 43: 44: If this argument scheme looks flakey it is because I screwed up 45: in the argument design. With the network now up to 10 machines, 46: I can't add another parameter to the internal commands of the network 47: like mmail and mwrite. If I had used labeled parms instead of 48: positional parms, I would be able to add more options/info 49: without having to recompile all code... 50: 51: exit codes: 52: normally returns the exit code from the mail program 53: 54: */ 55: main(argc,argv) 56: char **argv; { 57: int n, ret, i, hopcnt = 0, pid; 58: char *sargv[20], *cmdstr=NULL, buf[BUFSIZ], *timestr, 59: fromaddress[BUFSIZ]; 60: char toaddress[BUFSIZ], src[20], snFrom[BUFSIZ], snto[BUFSIZ], 61: mchFrom, mchto, stemp[BUFSIZ], fisresponse = 0; 62: long timesent = TIMEBASE, el; 63: FILE *fdm; 64: 65: debugflg = DBV; 66: src[0] = 0; 67: 68: /* parse old format positional parms */ 69: if(argv[1][0] == '-'){ 70: cmdstr = argv[1] + 1; 71: timesent = atol(argv[2] + 1); 72: sprintf(fromaddress,"%s:%s",argv[4],argv[3]); 73: strcpy(toaddress,argv[5]); 74: } 75: else { 76: sprintf(fromaddress,"%s:%s",argv[2],argv[1]); 77: strcpy(toaddress,argv[3]); 78: } 79: argv[argc] = 0; 80: 81: /* parse labeled parameters */ 82: /* prob because of -cmd in arg1 and arg2 */ 83: for(i = 1; i < argc; i++){ 84: if(argv[i][0] == '-' && argv[i][2] == 0) 85: switch(argv[i][1]){ 86: case 'f': 87: strcpy(fromaddress,argv[++i]); 88: break; 89: case 'c': 90: cmdstr = argv[++i]; 91: break; 92: case 'e': 93: timesent = atol(argv[++i]); 94: break; 95: case 't': 96: strcpy(toaddress,argv[++i]); 97: break; 98: case 'h': 99: hopcnt = atoi(argv[++i]); 100: break; 101: case 'r': 102: strcpy(src,argv[++i]); 103: break; 104: case 'z': 105: fisresponse++; 106: break; 107: /* it is important there be no error if an unknown 108: flag is encountered */ 109: } 110: } 111: mchFrom = MchSFromAddr(snFrom,fromaddress); 112: 113: /* compute time send */ 114: timestr = ctime(×ent); 115: timestr[strlen(timestr) - 6] = 0; 116: el = gettime() - timesent; 117: 118: /* check the hopcnt */ 119: hopcnt++; 120: if(hopcnt > MAXHOPS)hopcnterr(toaddress, hopcnt); 121: 122: /* analyze the dest, if local, strip off mach name, otherwise ok */ 123: mchto = MchSFromAddr(snto,toaddress); 124: if(mchto == local)strcpy(toaddress,snto); 125: 126: /* it is important to realize that mmail is executed 127: either as root, network, or the USER! 128: So the -r option must be accepted (and possibly ignored) 129: by the mail program if the user is a reandom user. 130: */ 131: /* now we fork off a mail command. if fisresponse, then 132: we are "cautious" and don't use mail forwarders */ 133: 134: fdm = mailopen(toaddress, fromaddress, fisresponse, hopcnt); 135: if(cmdstr != NULL){ 136: if(src[0] != 0)sprintf(stemp,", R: %s", src); 137: else stemp[0] = 0; 138: fprintf(fdm,"Subject: \"%s\"%s, sent %s, took %s\n", 139: cmdstr,stemp,timestr,comptime(el)); 140: } 141: while((n = fread(buf,1,BUFSIZ,stdin)) > 0) 142: fwrite(buf,1,n,fdm); 143: ret = mailclose(fdm); 144: ret >>= 8; 145: if(ret != 0) 146: fprintf(stderr, 147: "Non-zero return code (%d) from the mail program.\n",ret); 148: exit(ret); 149: } 150: /* 151: hopcnterr() 152: 153: there appears to be infinite mail forwarding - 154: as detected by the hop count. Mail to root and give up. 155: Both the from and to addresses are cycling, so mail 156: can't be sent there. 157: */ 158: hopcnterr(toaddress,hopcnt) 159: char *toaddress; 160: int hopcnt; 161: { 162: char cmdstr[BUFSIZ]; 163: int rcode; 164: sprintf(cmdstr,"echo infinite mail loop for %s hops %d | mail root", 165: toaddress,hopcnt); 166: rcode = system(cmdstr); 167: exit(EX_OSERR); 168: /*UNREACHED*/ 169: }