1: /* send.c - send a composed message */ 2: 3: #include "../h/mh.h" 4: #include <stdio.h> 5: #include <signal.h> 6: #include <sys/types.h> 7: #include <sys/stat.h> 8: 9: /* */ 10: 11: static struct swit switches[] = { 12: #define ALIASW 0 13: "alias aliasfile", 0, 14: 15: #define DEBUGSW 1 16: "debug", -5, 17: 18: #define DRAFTSW 2 19: "draft", 0, 20: 21: #define DFOLDSW 3 22: "draftfolder +folder", 6, 23: #define DMSGSW 4 24: "draftmessage msg", 6, 25: #define NDFLDSW 5 26: "nodraftfolder", 0, 27: 28: #define ENCRSW 6 29: "encrypt", 30: #ifndef TMA 31: -7, 32: #else TMA 33: 0, 34: #endif TMA 35: #define NENCRSW 7 36: "noencrypt", 37: #ifndef TMA 38: -9, 39: #else TMA 40: 0, 41: #endif TMA 42: 43: #define FILTSW 8 44: "filter filterfile", 0, 45: #define NFILTSW 9 46: "nofilter", 0, 47: 48: #define FRMTSW 10 49: "format", 0, 50: #define NFRMTSW 11 51: "noformat", 0, 52: 53: #define FORWSW 12 54: "forward", 0, 55: #define NFORWSW 13 56: "noforward", 0, 57: 58: #define MSGDSW 14 59: "msgid", 0, 60: #define NMSGDSW 15 61: "nomsgid", 0, 62: 63: #define PUSHSW 16 64: "push", 0, 65: #define NPUSHSW 17 66: "nopush", 0, 67: 68: #define UNIQSW 18 69: "unique", -6, 70: #define NUNIQSW 19 71: "nounique", -8, 72: 73: #define VERBSW 20 74: "verbose", 0, 75: #define NVERBSW 21 76: "noverbose", 0, 77: 78: #define WATCSW 22 79: "watch", 0, 80: #define NWATCSW 23 81: "nowatch", 0, 82: 83: #define WIDTHSW 24 84: "width columns", 0, 85: 86: #define HELPSW 25 87: "help", 4, 88: 89: #define MAILSW 26 90: "mail", -4, 91: #define SAMLSW 27 92: "saml", -4, 93: #define SENDSW 28 94: "send", -4, 95: #define SOMLSW 29 96: "soml", -4, 97: 98: #define CLIESW 30 99: "client host", -6, 100: #define SERVSW 31 101: "server host", -6, 102: #define SNOOPSW 32 103: "snoop", -5, 104: 105: NULL, NULL 106: }; 107: 108: static struct swit anyl[] = { 109: #define NOSW 0 110: "no", 0, 111: #define YESW 1 112: "yes", 0, 113: #define LISTDSW 2 114: "list", 0, 115: 116: NULL, NULL 117: }; 118: 119: /* */ 120: 121: extern int debugsw; /* from sendsbr.c */ 122: extern int forwsw; 123: extern int inplace; 124: extern int pushsw; 125: extern int unique; 126: 127: extern char *altmsg; /* .. */ 128: extern char *annotext; 129: extern char *distfile; 130: 131: /* */ 132: 133: /* ARGSUSED */ 134: 135: main (argc, argv) 136: int argc; 137: char *argv[]; 138: { 139: int msgp = 0, 140: distsw = 0, 141: vecp = 1, 142: isdf = 0, 143: msgnum, 144: status; 145: char *cp, 146: *dfolder = NULL, 147: *maildir, 148: buf[100], 149: **ap, 150: **argp, 151: *arguments[MAXARGS], 152: *msgs[MAXARGS], 153: *vec[MAXARGS]; 154: struct msgs *mp; 155: struct stat st; 156: #ifdef UCI 157: FILE *fp; 158: #endif UCI 159: 160: invo_name = r1bindex (argv[0], '/'); 161: if ((cp = m_find (invo_name)) != NULL) { 162: ap = brkstring (cp = getcpy (cp), " ", "\n"); 163: ap = copyip (ap, arguments); 164: } 165: else 166: ap = arguments; 167: (void) copyip (argv + 1, ap); 168: argp = arguments; 169: 170: vec[vecp++] = "-library"; 171: vec[vecp++] = getcpy (m_maildir ("")); 172: 173: /* */ 174: 175: while (cp = *argp++) { 176: if (*cp == '-') 177: switch (smatch (++cp, switches)) { 178: case AMBIGSW: 179: ambigsw (cp, switches); 180: done (1); 181: case UNKWNSW: 182: adios (NULLCP, "-%s unknown\n", cp); 183: case HELPSW: 184: (void) sprintf (buf, "%s [file] [switches]", invo_name); 185: help (buf, switches); 186: done (1); /* thanks, phyl */ 187: 188: case DRAFTSW: 189: msgs[msgp++] = draft; 190: continue; 191: 192: case DFOLDSW: 193: if (dfolder) 194: adios (NULLCP, "only one draft folder at a time!"); 195: if (!(cp = *argp++) || *cp == '-') 196: adios (NULLCP, "missing argument to %s", argp[-2]); 197: dfolder = path (*cp == '+' || *cp == '@' ? cp + 1 : cp, 198: *cp != '@' ? TFOLDER : TSUBCWF); 199: continue; 200: case DMSGSW: 201: if (!(cp = *argp++) || *cp == '-') 202: adios (NULLCP, "missing argument to %s", argp[-2]); 203: msgs[msgp++] = cp; 204: continue; 205: case NDFLDSW: 206: dfolder = NULL; 207: isdf = NOTOK; 208: continue; 209: 210: case PUSHSW: 211: pushsw++; 212: continue; 213: case NPUSHSW: 214: pushsw = 0; 215: continue; 216: 217: case UNIQSW: 218: unique++; 219: continue; 220: case NUNIQSW: 221: unique = 0; 222: continue; 223: 224: case FORWSW: 225: forwsw++; 226: continue; 227: case NFORWSW: 228: forwsw = 0; 229: continue; 230: 231: case DEBUGSW: 232: debugsw++; /* fall */ 233: case NFILTSW: 234: case FRMTSW: 235: case NFRMTSW: 236: case MSGDSW: 237: case NMSGDSW: 238: case VERBSW: 239: case NVERBSW: 240: case WATCSW: 241: case NWATCSW: 242: case MAILSW: 243: case SAMLSW: 244: case SENDSW: 245: case SOMLSW: 246: case ENCRSW: 247: case NENCRSW: 248: case SNOOPSW: 249: vec[vecp++] = --cp; 250: continue; 251: 252: case ALIASW: 253: case FILTSW: 254: case WIDTHSW: 255: case CLIESW: 256: case SERVSW: 257: vec[vecp++] = --cp; 258: if (!(cp = *argp++) || *cp == '-') 259: adios (NULLCP, "missing argument to %s", argp[-2]); 260: vec[vecp++] = cp; 261: continue; 262: } 263: else 264: msgs[msgp++] = cp; 265: } 266: 267: /* */ 268: 269: if (dfolder == NULL) { 270: if (msgp == 0) { 271: #ifdef WHATNOW 272: if ((cp = getenv ("mhdraft")) && *cp) { 273: msgs[msgp++] = cp; 274: goto go_to_it; 275: } 276: #endif WHATNOW 277: msgs[msgp++] = getcpy (m_draft (NULLCP, NULLCP, 1, &isdf)); 278: if (stat (msgs[0], &st) == NOTOK) 279: adios (msgs[0], "unable to stat draft file"); 280: cp = concat ("Use \"", msgs[0], "\"? ", NULLCP); 281: for (status = LISTDSW; status != YESW;) { 282: if (!(argp = getans (cp, anyl))) 283: done (1); 284: switch (status = smatch (*argp, anyl)) { 285: case NOSW: 286: done (0); 287: case YESW: 288: break; 289: case LISTDSW: 290: (void) showfile (++argp, msgs[0]); 291: break; 292: default: 293: advise (NULLCP, "say what?"); 294: break; 295: } 296: } 297: } 298: else 299: for (msgnum = 0; msgnum < msgp; msgnum++) 300: msgs[msgnum] = getcpy (m_maildir (msgs[msgnum])); 301: } 302: else { 303: if (!m_find ("path")) 304: free (path ("./", TFOLDER)); 305: 306: if (!msgp) 307: msgs[msgp++] = "cur"; 308: maildir = m_maildir (dfolder); 309: 310: if (chdir (maildir) == NOTOK) 311: adios (maildir, "unable to change directory to"); 312: if (!(mp = m_gmsg (dfolder))) 313: adios (NULLCP, "unable to read folder %s", dfolder); 314: if (mp -> hghmsg == 0) 315: adios (NULLCP, "no messages in %s", dfolder); 316: 317: for (msgnum = 0; msgnum < msgp; msgnum++) 318: if (!m_convert (mp, msgs[msgnum])) 319: done (1); 320: m_setseq (mp); 321: 322: for (msgp = 0, msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) 323: if (mp -> msgstats[msgnum] & SELECTED) { 324: msgs[msgp++] = getcpy (m_name (msgnum)); 325: #ifdef notdef 326: mp -> msgstats[msgnum] |= DELETED; 327: #endif notdef 328: mp -> msgstats[msgnum] &= ~EXISTS; 329: } 330: mp -> msgflags |= SEQMOD; 331: 332: m_sync (mp); 333: } 334: #ifdef WHATNOW 335: go_to_it: ; 336: #endif WHATNOW 337: 338: /* */ 339: 340: #ifdef TMA 341: if ((cp = getenv ("KDS")) == NULL || *cp == NULL) 342: if ((cp = m_find ("kdsproc")) && *cp) 343: (void) putenv ("KDS", cp); 344: if ((cp = getenv ("TMADB")) == NULL || *cp == NULL) 345: if ((cp = m_find ("tmadb")) && *cp) 346: (void) putenv ("TMADB", m_maildir (cp)); 347: #endif TMA 348: 349: if ((cp = getenv ("SIGNATURE")) == NULL || *cp == NULL) 350: if ((cp = m_find ("signature")) && *cp) 351: (void) putenv ("SIGNATURE", cp); 352: #ifdef UCI 353: else { 354: (void) sprintf (buf, "%s/.signature", mypath); 355: if ((fp = fopen (buf, "r")) != NULL 356: && fgets (buf, sizeof buf, fp) != NULL) { 357: (void) fclose (fp); 358: if (cp = index (buf, '\n')) 359: *cp = NULL; 360: (void) putenv ("SIGNATURE", buf); 361: } 362: } 363: #endif UCI 364: 365: for (msgnum = 0; msgnum < msgp; msgnum++) 366: if (stat (msgs[msgnum], &st) == NOTOK) 367: adios (msgs[msgnum], "unable to stat draft file"); 368: 369: if ((annotext = getenv ("mhannotate")) == NULL || *annotext == NULL) 370: annotext = NULL; 371: if (annotext 372: && ((altmsg = getenv ("mhaltmsg")) == NULL || *altmsg == NULL)) 373: altmsg = NULL; 374: if (annotext && ((cp = getenv ("mhinplace")) != NULL && *cp != NULL)) 375: inplace = atoi (cp); 376: 377: if ((cp = getenv ("mhdist")) 378: && *cp 379: && (distsw = atoi (cp)) 380: && altmsg) { 381: vec[vecp++] = "-dist"; 382: distfile = getcpy (m_scratch (altmsg, invo_name)); 383: if (link (altmsg, distfile) == NOTOK) 384: adios (distfile, "unable to link %s to", altmsg); 385: } 386: else 387: distfile = NULL; 388: 389: if (altmsg == NULL || stat (altmsg, &st) == NOTOK) 390: st.st_mtime = 0, st.st_dev = 0, st.st_ino = 0; 391: if (pushsw) 392: push (); 393: 394: status = 0; 395: vec[0] = r1bindex (postproc, '/'); 396: closefds (3); 397: 398: for (msgnum = 0; msgnum < msgp; msgnum++) 399: switch (sendsbr (vec, vecp, msgs[msgnum], &st)) { 400: case DONE: 401: done (++status); 402: 403: case NOTOK: 404: status++; /* fall */ 405: case OK: 406: break; 407: } 408: 409: m_update (); 410: 411: done (status); 412: }