|
|
1.1 ! root 1: # include "defs.h" ! 2: /* ! 3: Mmail is a berkeley network internal command. ! 4: It is executed locally by the mwrite command, ! 5: and from a remote machine by the sendberkmail command. ! 6: Its purpose is to send mail to a user on this ! 7: machine using the system mail program. ! 8: ! 9: Archaic Usage: ! 10: ! 11: mmail [-commandsent -timesent] fromuser frommach touser ! 12: ! 13: Correct Usage: ! 14: mmail [-c commandsent] [-e timesent] [-f fromaddress] [-t toaddress] ! 15: [-h hopcnt] [-r rc] [-z] ! 16: ! 17: The mwrite command uses all the options. ! 18: The sendberkmail command does not use the commandsend, timesent and rc ! 19: options. ! 20: Timesent is time in seconds since 1901 in decimal, as returned by time(). ! 21: Frommach is a multi-character name, not a single letter. ! 22: Rc is the return code (exit code>>8) of the command. ! 23: ! 24: Assumptions about the system mail command: ! 25: 1. We assume there is an optional argument "-r" which can be added to mail. ! 26: Mail argument format (two choices): ! 27: ! 28: (ROPTION) ! 29: mail -f fromaddress toaddress ! 30: which becomes mail from "fromaddress" instead of "network". ! 31: ! 32: (ROPTION2) ! 33: mail -r frommach fromuser toaddress ! 34: which becomes mail from "fromach:fromuser" instead of "network". ! 35: ! 36: ROPTION is to be preferred. ! 37: ! 38: 2. We assume that mail accepts the "-h hopcnt" flag, and passes it thru ! 39: unchanged to the sendberkmail program. The hopcnt is incremented everytime ! 40: it passes thru mmail, so inifinite mail forwarding is detected. ! 41: Since both the from and to addresses cycle, it there is infinite looping ! 42: we simply mail to root to that effect and throw away the mail. ! 43: ! 44: ! 45: If this argument scheme looks flakey it is because I screwed up ! 46: in the argument design. With the network now up to 10 machines, ! 47: I can't add another parameter to the internal commands of the network ! 48: like mmail and mwrite. If I had used labeled parms instead of ! 49: positional parms, I would be able to add more options/info ! 50: without having to recompile all code... ! 51: ! 52: exit codes: ! 53: normally returns the exit code from the mail program ! 54: returns 101 if unable to exec the mail program ! 55: returns 102 if infinite mail forwarding loop is detected. ! 56: ! 57: NUID is the value returned from getuid for "network" account. ! 58: */ ! 59: main(argc,argv) ! 60: char **argv; { ! 61: int pip[2], n, ret, i, uid, roption = 0, hopcnt = 0, pid; ! 62: char *sargv[20], *cmdstr=NULL, buf[BUFSIZ], *timestr, fromaddress[BUFSIZ]; ! 63: char toaddress[BUFSIZ], src[20], snFrom[BUFSIZ], snto[BUFSIZ], mchFrom, mchto, ! 64: *sn, stemp[BUFSIZ], fisresponse = 0; ! 65: long timesent = TIMEBASE, el; ! 66: ! 67: debugflg = DBV; ! 68: src[0] = 0; ! 69: ! 70: /* parse old format positional parms */ ! 71: if(argv[1][0] == '-'){ ! 72: cmdstr = argv[1] + 1; ! 73: timesent = atol(argv[2] + 1); ! 74: sprintf(fromaddress,"%s:%s",argv[4],argv[3]); ! 75: strcpy(toaddress,argv[5]); ! 76: } ! 77: else { ! 78: sprintf(fromaddress,"%s:%s",argv[2],argv[1]); ! 79: strcpy(toaddress,argv[3]); ! 80: } ! 81: argv[argc] = 0; ! 82: ! 83: /* parse labeled parameters */ ! 84: /* prob because of -cmd in arg1 and arg2 */ ! 85: for(i = 1; i < argc; i++){ ! 86: if(argv[i][0] == '-' && argv[i][2] == 0) ! 87: switch(argv[i][1]){ ! 88: case 'f': ! 89: strcpy(fromaddress,argv[++i]); ! 90: break; ! 91: case 'c': ! 92: cmdstr = argv[++i]; ! 93: break; ! 94: case 'e': ! 95: timesent = atol(argv[++i]); ! 96: break; ! 97: case 't': ! 98: strcpy(toaddress,argv[++i]); ! 99: break; ! 100: case 'h': ! 101: hopcnt = atoi(argv[++i]); ! 102: break; ! 103: case 'r': ! 104: strcpy(src,argv[++i]); ! 105: break; ! 106: case 'z': ! 107: fisresponse++; ! 108: break; ! 109: /* it is important there be no error if an unknown ! 110: flag is encountered */ ! 111: } ! 112: } ! 113: mchFrom = MchSFromAddr(snFrom,fromaddress); ! 114: ! 115: /* compute time send */ ! 116: timestr = ctime(×ent); ! 117: timestr[strlen(timestr) - 6] = 0; ! 118: el = gettime() - timesent; ! 119: ! 120: # ifdef ROPTION ! 121: /* only use roption if super-user or "network" */ ! 122: /* ! 123: uid = getuid(); ! 124: uid = uidmask(uid); ! 125: if(uid == SUPERUSER || uid == NUID)roption++; ! 126: */ ! 127: /* or if mail is to the same user who is sending it */ ! 128: /* ! 129: sn = SnCurrent(); ! 130: if(sn != NULL){ ! 131: stemp[0] = 0; ! 132: mchfrom = MchSFromAddr(stemp,fromaddress); ! 133: if(strcmp(stemp,????) == 0)roption++; ! 134: } ! 135: uid = geteuid(); ! 136: uid = uidmask(uid); ! 137: if(uid == SUPERUSER || uid == NUID)roption++; ! 138: */ ! 139: roption++; ! 140: # endif ! 141: ! 142: # ifdef ROPTION2 ! 143: /* only use roption if super-user or "network" */ ! 144: uid = getuid(); ! 145: uid = uidmask(uid); ! 146: if(uid == SUPERUSER || uid == NUID)roption++; ! 147: /* or if mail is to the same user who is sending it */ ! 148: /* disabled since mail must accept this and it does not now */ ! 149: /* if(strcmp(SnCurrent(),argv[3]) == 0)roption++; */ ! 150: uid = geteuid(); ! 151: uid = uidmask(uid); ! 152: if(uid == SUPERUSER || uid == NUID)roption++; ! 153: # endif ! 154: ! 155: /* check the hopcnt */ ! 156: hopcnt++; ! 157: if(hopcnt > MAXHOPS)hopcnterr(toaddress, hopcnt); ! 158: ! 159: /* analyze the dest, if local, strip off mach name, otherwise ok */ ! 160: mchto = MchSFromAddr(snto,toaddress); ! 161: if(mchto == local)strcpy(toaddress,snto); ! 162: ! 163: /* add the hopcnt here */ ! 164: if(roption){ ! 165: sargv[1] = "-r"; ! 166: # ifdef ROPTION2 ! 167: sargv[2] = longname(mchFrom); ! 168: sargv[3] = snFrom; ! 169: sargv[4] = toaddress; ! 170: sargv[5] = 0; ! 171: # endif ! 172: # ifdef ROPTION ! 173: sargv[2] = fromaddress; ! 174: sargv[3] = toaddress; ! 175: sargv[4] = 0; ! 176: # endif ! 177: } ! 178: else { ! 179: sargv[1] = toaddress; ! 180: sargv[2] = 0; ! 181: } ! 182: sargv[0] = "mail"; ! 183: pipe(pip); ! 184: while((pid = fork()) == -1)sleep(2); ! 185: if(pid == 0){ ! 186: close(pip[1]); ! 187: close(0); ! 188: dup(pip[0]); ! 189: /* by convention, SYSMAIL1 may forward this mail ! 190: and response messages shouldn't be forwarded */ ! 191: if(!fisresponse) ! 192: execv(SYSMAIL1, sargv); ! 193: execv(SYSMAIL2, sargv); ! 194: execv(SYSMAIL3, sargv); ! 195: execv(SYSMAIL4, sargv); ! 196: exit(101); ! 197: /* mexecv is not used because it gives a diagnostic */ ! 198: } ! 199: close(pip[0]); ! 200: close(1); ! 201: dup(pip[1]); ! 202: if(!roption) ! 203: printf("(from %s)\n",fromaddress); ! 204: if(cmdstr != NULL){ ! 205: if(src[0] != 0)sprintf(stemp,", R: %s", src); ! 206: else stemp[0] = 0; ! 207: printf("(command: %s%s, sent %s, took %s)\n", ! 208: cmdstr,stemp,timestr,comptime(el)); ! 209: } ! 210: fflush(stdout); ! 211: while((n = read(0,buf,BUFSIZ)) > 0) ! 212: write(pip[1],buf,n); ! 213: close(pip[1]); ! 214: close(1); ! 215: wait(&ret); ! 216: ret >>= 8; ! 217: if(ret != 0) ! 218: fprintf(stderr, ! 219: "Non-zero return code (%d) from the mail program.\n",ret); ! 220: exit(ret); ! 221: } ! 222: /* ! 223: hopcnterr() ! 224: ! 225: there appears to be infinite mail forwarding - ! 226: as detected by the hop count. Mail to root and give up. ! 227: Both the from and to addresses are cycling, so mail ! 228: can't be sent there. ! 229: */ ! 230: hopcnterr(toaddress,hopcnt) ! 231: char *toaddress; ! 232: int hopcnt; ! 233: { ! 234: char cmdstr[BUFSIZ]; ! 235: int rcode; ! 236: sprintf(cmdstr,"echo infinite mail loop for %s hops %d | mail root", ! 237: toaddress,hopcnt); ! 238: rcode = system(cmdstr); ! 239: exit(102); ! 240: /*UNREACHED*/ ! 241: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.