home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume18 / mush / part12 < prev    next >
Internet Message Format  |  1991-04-22  |  51KB

  1. From: argv@zipcode.com (Dan Heller)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i069:  mush - Mail User's Shell, Part12/22
  4. Message-ID: <1991Apr22.000412.18858@sparky.IMD.Sterling.COM>
  5. Date: 22 Apr 91 00:04:12 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: e46a1855 4e24d409 846c84c5 a349d102
  8.  
  9. Submitted-by: Dan Heller <argv@zipcode.com>
  10. Posting-number: Volume 18, Issue 69
  11. Archive-name: mush/part12
  12. Supersedes: mush: Volume 12, Issue 28-47
  13.  
  14. #!/bin/sh
  15. # do not concatenate these parts, unpack them in order with /bin/sh
  16. # file mail.c continued
  17. #
  18. if test ! -r _shar_seq_.tmp; then
  19.     echo 'Please unpack part 1 first!'
  20.     exit 1
  21. fi
  22. (read Scheck
  23.  if test "$Scheck" != 12; then
  24.     echo Please unpack part "$Scheck" next!
  25.     exit 1
  26.  else
  27.     exit 0
  28.  fi
  29. ) < _shar_seq_.tmp || exit 1
  30. if test ! -f _shar_wnt_.tmp; then
  31.     echo 'x - still skipping mail.c'
  32. else
  33. echo 'x - continuing file mail.c'
  34. sed 's/^X//' << 'SHAR_EOF' >> 'mail.c' &&
  35. X    case 'x':
  36. X        /* don't save dead.letter -- simulate normal rm_edfile() call */
  37. X        rm_edfile(0);
  38. X        return -1;
  39. X        /* break; (not specified for lint) */
  40. X    default:
  41. X        if (line[1] == *escape) {
  42. X        (void) fputs(&line[1], ed_fp);
  43. X        (void) fputc('\n', ed_fp);
  44. X        (void) fflush(ed_fp);
  45. X        return 1;
  46. X        } else if (line[1] == '?') {
  47. X        register int x;
  48. X        (void) do_pager(NULL, TRUE); /* start pager */
  49. X        for (x = 0; tilde_commands[x]; x++) {
  50. X            if (ison(flags, EDIT_HDRS) && TC_EDIT(x))
  51. X            continue;
  52. X            (void) sprintf(buf, "%s%s\n", escape, tilde_commands[x]);
  53. X            if (do_pager(buf, FALSE) == EOF)
  54. X            break;
  55. X        }
  56. X        if (tilde_commands[x] == NULL) {
  57. X            (void) sprintf(buf,
  58. X            "%s%s\t\tBegin a line with a single %s\n",
  59. X            escape, escape, escape);
  60. X            (void) do_pager(buf, FALSE);
  61. X        }
  62. X        (void) do_pager(NULL, FALSE); /* end pager */
  63. X        } else
  64. X        print("`%c': unknown %c escape. Use %c? for help.\n",
  65. X            line[1], *escape, *escape);
  66. X        return 1;
  67. X    }
  68. X    if (ed_fp)
  69. X    (void) fseek(ed_fp, 0L, 2);
  70. X    if (!istool)
  71. X    wprint("(continue editing letter)\n");
  72. X    return 1;
  73. }
  74. X
  75. /*
  76. X * finish up the letter. ask for the cc line, if verify is set, ask to
  77. X * verify sending, continue editing, or to dump the whole idea.
  78. X * Then check for signature and fortune.  Finally, pass it to send_it()
  79. X * to actually send it off.
  80. X * Return 0 on success, -1 on failure.
  81. X */
  82. static int
  83. finish_up_letter()
  84. {
  85. X    register char *p;
  86. X    int c;
  87. X    char buf[MAXPATHLEN];
  88. X
  89. X    /* forwarded mail has no additional personalized text */
  90. X    if (ison(flags, FORWARD)) {
  91. X    if (send_it() == -1) {
  92. X        wprint("Message not sent!\n");
  93. X        return -1;
  94. X    }
  95. X    turnoff(glob_flags, IS_GETTING);
  96. X    return 0;
  97. X    }
  98. X
  99. X    /* REDIRECT should never be on here, but just in case */
  100. X    if (isoff(glob_flags, REDIRECT)) {
  101. X    if (!istool) {
  102. X        if (isoff(flags, EDIT_HDRS) && do_set(set_options, "askcc")) {
  103. X        if (p = set_header("Cc: ", Cc, 1))
  104. X            (void) strcpy(Cc, p);
  105. X        }
  106. X    }
  107. X    /* ~v on the Cc line asks for verification, first initialize p! */
  108. X    p = NULL;
  109. X    if (!strncmp(Cc, "~v", 2) ||
  110. X        /* Flashy test for $verify either empty or set to "mail" */
  111. X        glob(p = do_set(set_options, "verify"),
  112. X                        "{,{,*[ \\,]}mail{,[ \\,]*}}")) {
  113. X        if (!p) /* so we don't Cc to ~v! */
  114. X        *Cc = 0;
  115. X        for (;;) {
  116. #ifdef SUNTOOL
  117. X        if (istool)
  118. X            c = (ask("Send Message?") == TRUE)? 's' : 'c';
  119. X        else
  120. #endif /* SUNTOOL */
  121. X        {
  122. X            print("send, continue editing, discard [s,c,d]? ");
  123. X            c = Getstr(buf, sizeof(buf), 0);
  124. X            if (c < 0)
  125. X            putchar('\n');
  126. X            else if (!istool)
  127. X            c = lower(*buf);
  128. X        }
  129. X        if (c == 'd') {
  130. X            rm_edfile(-2);
  131. X            return 0;
  132. X        } else if (c == 'c') {
  133. X            wprint("(continue editing letter)\n");
  134. X            return -1;
  135. X        } else if (c == 's')
  136. X            break;
  137. X        }
  138. X    }
  139. X    }
  140. X
  141. X    if (send_it() == -1) {
  142. X    if (isoff(flags, SEND_NOW))
  143. X        wprint("(continue)\n");
  144. X    return -1;
  145. X    }
  146. X    return 0;
  147. }
  148. X
  149. /*
  150. X * actually send the letter.
  151. X * 1. reset all the signals because of fork.
  152. X * 2. determine recipients (users, address, files, programs)
  153. X * 3. determine mailer, fork and return (if not verbose).
  154. X * 4. popen mailer, $record, and other files specified in step 1.
  155. X * 5. make the headers; this includes To: line, and user set headers, etc...
  156. X * 6. copy the letter right into the array of file pointers (step 1).
  157. X * 7. close the mailer and other files (step 1) and remove the edit-file.
  158. X * return -1 if mail wasn't sent.  could be user error, could be the system.
  159. X * allow user to try again or to save message to file and abort message.
  160. X * return 0 if successful.
  161. X */
  162. static int
  163. send_it()
  164. {
  165. X    register char *p, *b, *addr_list;
  166. #ifdef MAXFILES
  167. X    register int size = MAXFILES - 1;
  168. X    FILE *files[MAXFILES];
  169. X    char *names[MAXFILES];
  170. #else
  171. X    register int size = getdtablesize() - 1;
  172. X    FILE *files[30];  /* 30 should be sufficiently large enough */
  173. X    char *names[30];
  174. #endif /* MAXFILES */
  175. #if defined(VERBOSE_ARG)
  176. X    SIGRET (*oldchld)();
  177. #endif /* VERBOSE_ARG */
  178. X    int next_file = 1; /* reserve files[0] for the mail delivery program */
  179. X    int log_file = -1; /* the index into the files array for mail logging */
  180. X    char buf[3*HDRSIZ];
  181. X    char *orig_to, *orig_cc, *orig_bcc; /* save originals to restore on error */
  182. X    char expand = !do_set(set_options, "no_expand");
  183. X    int fork_pid;
  184. X
  185. X    names[0] = names[1] = NULL; /* for free_vec() */
  186. X    /* If edit_hdrs, make sure the correct headers exist and are intact
  187. X     * before bothering to continue.
  188. X     */
  189. X    if (ison(flags, EDIT_HDRS)) {
  190. X    /* fool header_field into thinking that the file is the folder */
  191. X    FILE *save_tmpf = tmpf;
  192. X    long old_offset = msg[msg_cnt].m_offset;
  193. X
  194. X    if (!ed_fp) {
  195. X        wprint("No file for headers!\n");
  196. X        return -1;
  197. X    }
  198. X    Debug("Getting headers from file ... ");
  199. X
  200. X    tmpf = ed_fp;
  201. X    msg[msg_cnt].m_offset = 0L;
  202. X    if (p = header_field(msg_cnt, "to")) {
  203. X        (void) strcpy(To, p);
  204. X        Cc[0] = Bcc[0] = 0;
  205. X        if (p = header_field(msg_cnt, "cc"))
  206. X        (void) strcpy(Cc, p);
  207. X        if (p = header_field(msg_cnt, "bcc"))
  208. X        (void) strcpy(Bcc, p);
  209. X        if (p = header_field(msg_cnt, "fcc"))
  210. X        next_file += find_files(p, names+next_file, size-next_file, 1);
  211. X    } else
  212. X        *To = 0; /* Error caught below */
  213. X    msg[msg_cnt].m_offset = old_offset;
  214. X    tmpf = save_tmpf;
  215. X    Debug("\n");
  216. X    }
  217. X    if (!*To) {
  218. X    wprint("You must have a To: recipient to send mail.\n");
  219. X    if (!istool) {
  220. X        (void) signal(SIGINT, oldint);
  221. X        (void) signal(SIGQUIT, oldquit);
  222. X        (void) signal(SIGTERM, oldterm);
  223. X    }
  224. X    free_vec(&names[1]);
  225. X    return -1;
  226. X    }
  227. X
  228. X    if (!(p = do_set(set_options, "sendmail")))
  229. X    p = MAIL_DELIVERY;
  230. X
  231. #ifdef VERBOSE_ARG
  232. X    /* Tool mode can't do verbosity -- no window for the MTA output */
  233. X    if (!istool && (ison(flags, VERBOSE) || do_set(set_options, "verbose"))) {
  234. X    turnon(flags, VERBOSE); /* prevent fork when "verbose" has changed */
  235. X    oldchld = signal(SIGCHLD, SIG_DFL); /* let pclose() do the wait() */
  236. #ifdef MMDF
  237. X    b = &buf[strlen(sprintf(buf, "%s%s", p, VERBOSE_ARG))];
  238. #else /* MMDF */
  239. X    b = &buf[strlen(sprintf(buf, "%s %s", p, VERBOSE_ARG))];
  240. #endif /* MMDF */
  241. X    } else
  242. #endif /* VERBOSE_ARG */
  243. X    b = buf + Strcpy(buf, p);
  244. #ifdef METOO_ARG
  245. X    if (!strcmp(p, MAIL_DELIVERY) && do_set(set_options, "metoo"))
  246. X    b += strlen(sprintf(b, " %s", METOO_ARG));
  247. #endif /* METOO_ARG */
  248. X    *b++ = ' ', *b = 0; /* strcat(b, " "); */
  249. X    addr_list = b; /* save this position to check for addresses later */
  250. X
  251. X    /* save original list.  If alias expansion fails, replace address lists
  252. X     * with what was originally typed so user can fix it.  This isn't necessary
  253. X     * if the lists are already in the file the user is editing (edit_hdrs).
  254. X     */
  255. X    if (isoff(flags, EDIT_HDRS))
  256. X    orig_to = savestr(To);
  257. X    /*
  258. X     * Build the address lines to give to the mail transfer system.  This
  259. X     * address line cannot contain comment fields!  First, expand aliases
  260. X     * since they may contain comment fields within addresses. Copy this
  261. X     * result back into the Buffer since this will go into the header ...
  262. X     * Next, remove all comments so the buffer contains ONLY valid addresses.
  263. X     * Next, strip off any filenames/programs which might occur in the list.
  264. X     * Finally, add this information to the command line buffer (buf).
  265. X     * Remove commas if necessary (see ifdefs).  In the event of errors,
  266. X     * force a dead letter by rm_edfile(-1).
  267. X     */
  268. X    if (!(p = alias_to_address(To))) {
  269. X    print("address expansion failed for To: list.\n");
  270. X    free_vec(&names[1]);
  271. X    if (isoff(flags, EDIT_HDRS))
  272. X        strcpy(To, orig_to), xfree(orig_to);
  273. X    return -1;
  274. X    } else {
  275. X    next_file += find_files(p, names+next_file, size-next_file, 0);
  276. X    if (expand)
  277. X        (void) strcpy(To, p);
  278. X    rm_cmts_in_addr(p);
  279. X    skipspaces(0);
  280. X    b += Strcpy(b, p);
  281. X    }
  282. X    if (isoff(flags, EDIT_HDRS))
  283. X    orig_cc = savestr(Cc);
  284. X    if (*Cc) {
  285. X    if (!(p = alias_to_address(Cc))) {
  286. X        wprint("address expansion failed for Cc: list.\n");
  287. X        free_vec(&names[1]);
  288. X        if (isoff(flags, EDIT_HDRS)) {
  289. X        strcpy(To, orig_to), xfree(orig_to);
  290. X        strcpy(Cc, orig_cc), xfree(orig_cc);
  291. X        }
  292. X        return -1;
  293. X    } else {
  294. X        next_file += find_files(p, names+next_file, size-next_file, 0);
  295. X        if (expand)
  296. X        (void) strcpy(Cc, p);
  297. X        rm_cmts_in_addr(p);
  298. X        skipspaces(0);
  299. X        if (*p) {
  300. X        *b++ = ',', *b++ = ' ';
  301. X        b += Strcpy(b, p);
  302. X        }
  303. X    }
  304. X    }
  305. X
  306. X    /* expand Bcc addrs, but don't add to list yet.  sign letter first */
  307. X    if (isoff(flags, EDIT_HDRS))
  308. X    orig_bcc = savestr(Bcc);
  309. X    if (*Bcc) {
  310. X    if (p = alias_to_address(Bcc))
  311. X        p = strcpy(Bcc, p);
  312. X    else {
  313. X        wprint("address expansion failed for Bcc: list.\n");
  314. X        free_vec(&names[1]);
  315. X        /* rm_edfile(-1); */
  316. X        if (isoff(flags, EDIT_HDRS)) {
  317. X        strcpy(To, orig_to), xfree(orig_to);
  318. X        strcpy(Cc, orig_cc), xfree(orig_cc);
  319. X        strcpy(Bcc, orig_bcc), xfree(orig_bcc);
  320. X        }
  321. X        return -1;
  322. X    }
  323. X    } else
  324. X    p = NULL;
  325. X
  326. X    /* Sign the letter before adding the Bcc list since they aren't
  327. X     * considered when adding a signature.
  328. X     */
  329. X    if (*addr_list && ison(flags, SIGN|DO_FORTUNE) &&
  330. X        isoff(glob_flags, REDIRECT) && isoff(flags, FORWARD))
  331. X    sign_letter(addr_list, flags, ed_fp);
  332. X
  333. X    if (p) { /* p still points to expanded Bcc list */
  334. X    next_file += find_files(p, names+next_file, size-next_file, 0);
  335. X    rm_cmts_in_addr(p);
  336. X    skipspaces(0);
  337. X    if (*p) {
  338. X        *b++ = ',', *b++ = ' ';
  339. X        b += Strcpy(b, p);
  340. X    }
  341. X    }
  342. X    if (!*addr_list && next_file == 1) {
  343. X    wprint("There must be at least 1 legal recipient.\n");
  344. X    if (isoff(flags, EDIT_HDRS)) {
  345. X        strcpy(To, orig_to), xfree(orig_to);
  346. X        strcpy(Cc, orig_cc), xfree(orig_cc);
  347. X        strcpy(Bcc, orig_bcc), xfree(orig_bcc);
  348. X    }
  349. X    return -1;
  350. X    }
  351. X
  352. #ifdef NO_COMMAS
  353. X    for (p = buf; p = index(p, ','); p++)
  354. X    *p = ' ';
  355. #endif /* NO_COMMAS */
  356. X
  357. X    Debug("mail command: %s\n", buf);
  358. X
  359. X    if (isoff(flags, VERBOSE) && debug < 3)
  360. X    switch (fork_pid = fork()) {
  361. X        case  0:  /* the child will send the letter. ignore signals */
  362. #if defined(SYSV) && !defined(AUX)
  363. X        if (setpgrp() == -1)
  364. #else /* !SYSV || AUX */
  365. X        if (setpgrp(0, getpid()) == -1)
  366. #endif /* SYSV && !AUX */
  367. X            error("setpgrp");
  368. X        /* NOTE: No special case needed for tool here because
  369. X         * this is the sending child -- it's going to pclose()
  370. X         * and then exit(), so who cares about the notifier?
  371. X         */
  372. X        (void) signal(SIGCHLD, SIG_DFL);
  373. X        (void) signal(SIGTERM, SIG_IGN);
  374. X        (void) signal(SIGINT, SIG_IGN);
  375. X        (void) signal(SIGHUP, SIG_IGN);
  376. X        (void) signal(SIGQUIT, SIG_IGN);
  377. #ifdef SIGTTIN
  378. X        (void) signal(SIGTTOU, SIG_IGN);
  379. X        (void) signal(SIGTTIN, SIG_IGN);
  380. #endif /* SIGTTIN */
  381. #ifdef SIGCONT
  382. X        (void) signal(SIGCONT, SIG_IGN);
  383. X        (void) signal(SIGTSTP, SIG_IGN);
  384. #endif /* SIGCONT */
  385. X        turnon(glob_flags, IGN_SIGS);
  386. X        when -1:
  387. X        error("fork failed trying to send mail");
  388. X        if (isoff(flags, EDIT_HDRS)) {
  389. X            strcpy(To, orig_to);
  390. X            strcpy(Cc, orig_cc);
  391. X            strcpy(Bcc, orig_bcc);
  392. X        }
  393. X        /* fall thru */
  394. X        default:
  395. X        if (fork_pid > 0) {
  396. #ifdef SUNTOOL
  397. X            /* If we're a tool, we have to register a handler
  398. X             * for the fork_pid.  Otherwise, it's used only as
  399. X             * an error indicator, so reset it to zero.
  400. X             */
  401. X            if (istool)
  402. X            notify_set_wait3_func(mfprint_sw, my_wait3, fork_pid);
  403. #endif /* SUNTOOL */
  404. X            fork_pid = 0;
  405. X        }
  406. X        /* istool doesn't need ed_fp, so don't keep it around */
  407. X        if (istool || !fork_pid && isoff(glob_flags, REDIRECT))
  408. X            (void) fclose(ed_fp), ed_fp = NULL_FILE;
  409. X        free_vec(&names[1]);
  410. X        if (isoff(flags, EDIT_HDRS))
  411. X            xfree(orig_to), xfree(orig_cc), xfree(orig_bcc);
  412. X        if (!istool) {
  413. X            (void) signal(SIGINT, oldint);
  414. X            (void) signal(SIGQUIT, oldquit);
  415. X            (void) signal(SIGTERM, oldterm);
  416. X        }
  417. X        return fork_pid;
  418. X    }
  419. X
  420. #ifdef MMDF
  421. X    *(addr_list-1) = '\0';
  422. #endif /* MMDF */
  423. X    if (debug > 2) {
  424. X    files[0] = stdout;
  425. X    if (!*addr_list)
  426. X        addr_list = "[no recipients]";
  427. X    } else if (*addr_list) {
  428. X    if (!(files[0] = open_file(buf, TRUE, FALSE))) {
  429. X        rm_edfile(-1); /* force saving of undeliverable mail */
  430. X        if (isoff(flags, VERBOSE) && debug < 3)
  431. X        exit(-1);
  432. X        else
  433. X        return 0;
  434. X    }
  435. X    } else
  436. X    files[0] = NULL_FILE;
  437. X
  438. X    if (ison(flags, VERBOSE))
  439. X    wprint("Sending letter ... "), (void) fflush(stdout);
  440. #ifdef MMDF
  441. X    /* give address list to submit */
  442. X    for (p = addr_list; *p && (p = any(p, ",<")); p++)
  443. X    if (*p == ',')
  444. X        *p = '\n';
  445. X    else
  446. X        p = index(p, '>');
  447. X    if (*addr_list)
  448. X    (void) fprintf(files[0], "%s\n\n", addr_list);
  449. #endif /* MMDF */
  450. X
  451. X    /* see if log is set.  This is just to add message headers. No msg body. */
  452. X    if (p = do_set(set_options, "logfile")) {
  453. X    if (!*p)
  454. X        p = "~/mail.log";
  455. X    if (!index("~|/+", *p))
  456. X        (void) sprintf(buf, "%s/%s", do_set(set_options, "cwd"), p);
  457. X    else
  458. X        (void) strcpy(buf, p);
  459. X    log_file = next_file;
  460. X    next_file += find_files(buf, names+next_file, size-next_file, 0);
  461. X    if (log_file == next_file)
  462. X        log_file = -1;
  463. X    }
  464. X
  465. X    /* see if record is set.  If so, open that file for appending and add
  466. X     * the letter in a format such that mail can be read from it
  467. X     */
  468. X    if (p = do_set(set_options, "record")) {
  469. X    if (!*p)
  470. X        p = "~/record";
  471. X    if (!index("~|/+", *p))
  472. X        (void) sprintf(buf, "%s/%s", do_set(set_options, "cwd"), p);
  473. X    else
  474. X        (void) strcpy(buf, p);
  475. X    next_file += find_files(buf, names+next_file, size-next_file, 0);
  476. X    }
  477. X
  478. X    /* Don't need to open names[0] as files[0], so skip those */
  479. X    next_file = 1 + open_list(names + 1, files + 1, next_file - 1);
  480. X
  481. X    /* First, put the message separator in... */
  482. X    for (size = 1; size < next_file; size++)
  483. #ifndef MSG_SEPARATOR
  484. X    {
  485. X        time_t t;
  486. X        (void) time(&t);
  487. X        (void) fprintf(files[size], "From %s %s", login, ctime(&t));
  488. X    }
  489. #else /* MSG_SEPARATOR */
  490. #ifdef MMDF
  491. X    (void) fputs(MSG_SEPARATOR, files[size]);
  492. #else /* MMDF */
  493. X    (void) fprintf(files[size], "%s\n", MSG_SEPARATOR);
  494. #endif /* MMDF */
  495. #endif /* MSG_SEPARATOR */
  496. X
  497. X    /* if redirection, ed_fp = stdin, else rewind the file just made */
  498. X    if (isoff(glob_flags, REDIRECT))
  499. X    rewind(ed_fp);
  500. X    else
  501. X    ed_fp = stdin;
  502. X
  503. #ifndef MSG_SEPARATOR
  504. X    /* If forwarding or reading a draft, skip the leading From_ line.
  505. X     * This is done for drafts so that messages saved by dead_letter()
  506. X     * can be read back in as a draft; in other cases, this isn't done
  507. X     * for edit_hdrs because FORWARD wouldn't be set.
  508. X     */
  509. X    if (ison(flags, FORWARD|SEND_NOW) && fgets(buf, sizeof buf, ed_fp) &&
  510. X    strncmp(buf, "From ", 5) != 0)
  511. X    rewind(ed_fp); /* No From_ line (should never happen) */
  512. #endif /* MSG_SEPARATOR */
  513. X    {
  514. X    long offset = add_headers(ed_fp, files, next_file, flags);
  515. X    if (offset == -1)
  516. X        offset = 0L;
  517. X    (void) fseek(ed_fp, offset, L_SET);
  518. X    }
  519. X
  520. X    /* Read from stdin or the edfile till EOF and send it all to the mailer
  521. X     * and other open files/folders/programs. Check for "From " at the
  522. X     * beginnings of these lines to prevent creating new messages in folders.
  523. X     */
  524. X    while (fgets(buf, sizeof buf, ed_fp))
  525. X    for (size = 0; size < next_file; size++) {
  526. X        if (!files[size]) /* files[0] will be NULL if not calling MTA */
  527. X        continue;
  528. X        if (size == log_file)
  529. X        continue;
  530. #ifndef MSG_SEPARATOR
  531. X        if (!strncmp(buf, "From ", 5))
  532. X        (void) fputc('>', files[size]);
  533. #endif /* MSG_SEPARATOR */
  534. X        if (fputs(buf, files[size]) == EOF) {
  535. X        if (size == 0) {
  536. X            error("Lost connection to MTA");
  537. X            dead_letter(-1);
  538. X            break;
  539. X        } else {
  540. X            /* Drop this file, but continue writing others */
  541. X            if (names[size]) {
  542. X            error("Write failed: %s", names[size]);
  543. X            (void) close_lock(names[size], files[size]);
  544. X            xfree(names[size]);
  545. X            } else
  546. X            error("Write failed");
  547. X            if (size < --next_file) {
  548. X            names[size] = names[next_file];
  549. X            files[size--] = files[next_file];
  550. X            }
  551. X            files[next_file] = NULL_FILE;
  552. X            names[next_file] = NULL;
  553. X        }
  554. X        }
  555. X    }
  556. X
  557. X    /* loop thru the open files (except for the first: the mail delivery agent)
  558. X     * and append a blank line so that ucb-mail can read these folders.
  559. X     * Then close the files.
  560. X     */
  561. X    for (size = 1; size < next_file; size++) {
  562. #ifdef END_MSG_SEP
  563. X    (void) fputs(END_MSG_SEP, files[size]);
  564. #endif /* END_MSG_SEP */
  565. X    if (names[size]) {
  566. #ifndef END_MSG_SEP
  567. X        (void) fputc('\n', files[size]);
  568. #endif /* !END_MSG_SEP */
  569. X        if (close_lock(names[size], files[size]) == EOF) {
  570. X        error("Warning: Close failed: %s", names[size]);
  571. X        }
  572. X        xfree(names[size]);
  573. X    } else {
  574. X        if (debug < 3)
  575. X        (void) fclose(files[size]); /* Don't mess with pclose() */
  576. X        else
  577. X        (void) pclose(files[size]); /* unless we never forked */
  578. X    }
  579. X    }
  580. X
  581. X    if (debug < 3) {
  582. X    int reply_code = files[0]? pclose(files[0]) : (MTA_EXIT << 8);
  583. X    Debug("pclose reply_code = %d\n", reply_code);
  584. X    rm_edfile((reply_code == (MTA_EXIT << 8))? 0 : -1);
  585. X    } else
  586. X    rm_edfile(0);
  587. X
  588. #ifdef VERBOSE_ARG
  589. X    if (!istool && ison(flags, VERBOSE))
  590. X    (void) signal(SIGCHLD, oldchld);
  591. #endif /* VERBOSE_ARG */
  592. X
  593. X    if (ison(flags, VERBOSE) || debug > 2) {
  594. X    if (isoff(glob_flags, REDIRECT))
  595. X        wprint("sent.\n");
  596. X    if (!istool) {
  597. X        (void) signal(SIGINT, oldint);
  598. X        (void) signal(SIGQUIT, oldquit);
  599. X        (void) signal(SIGTERM, oldterm);
  600. X    }
  601. X    } else
  602. X    exit(0); /* not a user exit -- a child exit */
  603. X    return 0;
  604. }
  605. X
  606. /*
  607. X * Add the necessary headers to make a file a legitimate mail message.
  608. X * This could be for a file which the user will edit (via edit_hdrs) or
  609. X * for delivery to an MTA.
  610. X * Make folders conform to RFC-822 by adding From: and Date: headers.
  611. X * Prefix certain header with the "Resent-" prefix when forwarding.
  612. X * Return offset of fp if we're parsing it for headers (for delivery to MTA).
  613. X */
  614. static long
  615. add_headers(fp, files, size, flags)
  616. FILE *fp, *files[];
  617. int size;
  618. u_long flags;
  619. {
  620. X    char buf[BUFSIZ], From_buf[256], *pF = From_buf, date_str[64];
  621. X    char *host = NULL, *p, *subj = NULL, *own_from = NULL; /* See WARNING */
  622. X    int i, for_editor = (fp == NULL_FILE);
  623. X    int got_date = for_editor, got_from = for_editor;
  624. X    struct options *opts;
  625. X
  626. X    if (for_editor && hfile) {
  627. X    i = file_to_fp(hfile, files[0], "r");
  628. X    xfree(hfile), hfile = NULL;
  629. X    return (i < 0 ? -1 : TRUE);
  630. X    }
  631. X
  632. X    buf[0] = 0;
  633. X    if (ourname)
  634. X    host = ourname[0];
  635. X    if (for_editor)
  636. X    turnoff(flags,FORWARD); /* forwarded messages must not be edited */
  637. X
  638. X    /* [Re]create a From: header -- check first to see if the user has
  639. X     * created a From: header with the my_hdr command (the own_hdrs list).
  640. X     * If his is not legitimate, warn user and use the other header.
  641. X     */
  642. X    if ((for_editor || isoff(flags, EDIT_HDRS)) &&
  643. X        own_hdrs && !do_set(set_options, "no_hdrs")) {
  644. X    for (opts = own_hdrs; opts; opts = opts->next)
  645. X        if (!strcmp(opts->option, "From:")) {
  646. X        p = opts->value;
  647. X        skipspaces(0);
  648. X        sprintf(buf, "%sFrom: %s\n",
  649. X                ison(flags, FORWARD)? "Resent-" : "", p);
  650. X        own_from = buf;
  651. X        /* WARNING: the above depends on the following facts:
  652. X         * 1. If for_editor, own_from will be output immediately,
  653. X         *    so buf will not be overwritten;
  654. X         * 2. If !for_editor but EDIT_HDRS, the "real" from line
  655. X         *    will be read from the file so own_from isn't needed;
  656. X         * 3. If neither, From: is the first line output, so
  657. X         *    buf will not be overwritten.
  658. X         * Any change in the above means a new buffer for own_from
  659. X         * may be needed.  Check carefully.
  660. X         */
  661. X        }
  662. X    }
  663. X    if (ison(flags, FORWARD))
  664. X    pF += Strcpy(From_buf, "Resent-");
  665. X    pF += Strcpy(pF, "From: ");
  666. #ifdef UUCP
  667. X    if (host && *host)
  668. X    pF += strlen(sprintf(pF, "%s!", host));
  669. #endif /* UUCP */
  670. X    pF += Strcpy(pF, login);
  671. #ifndef UUCP
  672. X    if (host && *host)
  673. X    pF += strlen(sprintf(pF, "@%s", host));
  674. #endif /* UUCP */
  675. X    if ((p = do_set(set_options, "realname")) ||
  676. X    (p = do_set(set_options, "name")))
  677. X    pF += strlen(sprintf(pF, " (%s)", p));
  678. X    *pF++ = '\n', *pF++ = 0;
  679. X
  680. X    /* First print From, Date, In-Reply-To */
  681. X    for (i = 0; i < size; i++) {
  682. X    if (!files[i])
  683. X        continue;
  684. X    if (for_editor)
  685. X        if (own_from)
  686. X        (void) fputs(own_from, files[i]);
  687. X        else
  688. X        (void) fputs(From_buf, files[i]);
  689. X    else if (isoff(flags, EDIT_HDRS)) {
  690. #ifdef PICKY_MAILER
  691. X        if (i > 0)
  692. #endif /* PICKY_MAILER */
  693. X        if (own_from)
  694. X        (void) fputs(own_from, files[i]);
  695. X        else
  696. X        (void) fputs(From_buf, files[i]);
  697. X        got_from = TRUE;
  698. X    }
  699. X    if (for_editor || isoff(flags, EDIT_HDRS)) {
  700. #ifdef PICKY_MAILER
  701. X        if (i > 0 && !for_editor)
  702. #endif /* PICKY_MAILER */
  703. X        (void) fprintf(files[i], "%sDate: %s\n",
  704. X        ison(flags, FORWARD) ? "Resent-" : "", rfc_date(date_str));
  705. X        got_date = TRUE;
  706. X        if (*in_reply_to)
  707. X        fprintf(files[i], "In-Reply-To: %s\n", in_reply_to);
  708. X    }
  709. X    }
  710. X    if (own_from)
  711. X    *own_from = 0; /* buf[0] must be 0 below */
  712. X    /* next print user's own message headers */
  713. X    if (for_editor || isoff(flags, EDIT_HDRS))
  714. X    if (own_hdrs && !do_set(set_options, "no_hdrs")) {
  715. X        for (opts = own_hdrs; opts; opts = opts->next) {
  716. X        if (!strcmp(opts->option, "From:"))
  717. X            continue;
  718. X        for (i = 0; i < size; i++) {
  719. X            if (!files[i])
  720. X            continue;
  721. X            p = opts->value;
  722. X            skipspaces(0);
  723. X            fprintf(files[i], "%s %s\n", opts->option, p);
  724. X        }
  725. X        }
  726. X    }
  727. X
  728. X    /*
  729. X     * Now either prepare to put the rest of the headers into the file
  730. X     * or (when sending edited headers) copy them back out of the file
  731. X     */
  732. X    if (for_editor) {
  733. X    char *orig = NULL;
  734. X    /* for edit_hdrs, print the headers followed by a blank line */
  735. X    if (To[0]) {
  736. X        orig = savestr(To);
  737. X        if (!(p = alias_to_address(To))) {
  738. X        wprint("To: list unmodified.\n");
  739. X        p = orig;
  740. X        }
  741. X        (void) strcpy(To, p);
  742. X    }
  743. X    if (Cc[0]) {
  744. X        strdup(orig, Cc);
  745. X        if (!(p = alias_to_address(Cc))) {
  746. X        wprint("Cc: list unmodified.\n");
  747. X        p = orig;
  748. X        }
  749. X        (void) strcpy(Cc, p);
  750. X    }
  751. X    if (Bcc[0]) {
  752. X        strdup(orig, Bcc);
  753. X        if (!(p = alias_to_address(Bcc))) {
  754. X        wprint("Bcc: list unmodified.\n");
  755. X        p = orig;
  756. X        }
  757. X        (void) strcpy(Bcc, p);
  758. X    }
  759. X    xfree(orig);
  760. X    } else if (ison(flags, EDIT_HDRS)) {
  761. X    /* copy the headers of the message removing special headers */
  762. X    int print_hdr = FALSE;
  763. X    if (isoff(flags, SEND_NOW))
  764. X        rewind(fp); /* Drafts may have had fp positioned */
  765. X    while (fgets(buf, sizeof(buf), fp)) {
  766. X        (void) no_newln(buf);
  767. X        if (!buf[0])
  768. X        break;
  769. X        /* if the first char is NOT a space, it MUST be a new header.
  770. X         * Otherwise, it is considered part of the message body.
  771. X         */
  772. X        if (!isspace(buf[0])) {
  773. X        print_hdr = TRUE;
  774. X        if (!(p = any(buf, " \t:")) || isspace(*p))
  775. X            break; /* this is not a legitimate header */
  776. X        skipspaces(1);
  777. X        if (!*p)
  778. X            print_hdr = FALSE; /* blank headers are not allowed */
  779. X        p = buf;
  780. X        if (!lcase_strncmp(buf, "resent-", 7)) {
  781. X            if (ison(flags, EDIT_HDRS))
  782. X        wprint("You can't use \"Resent-\" headers in edited messages.\n");
  783. X            p += 7;
  784. X        }
  785. X        if (!lcase_strncmp(p, "to:", 3) ||
  786. X            !lcase_strncmp(p, "cc:", 3) ||
  787. X            !lcase_strncmp(p, "bcc:", 4) ||
  788. X            !lcase_strncmp(p, "fcc:", 4) ||
  789. X            !lcase_strncmp(p, "x-mailer:", 9) ||
  790. X            !lcase_strncmp(p, "status:", 7))
  791. X            print_hdr = FALSE;
  792. X        else if (!lcase_strncmp(p, "date:", 5))
  793. X            if (got_date)
  794. X            wprint("You can't change or add date headers.\n");
  795. X            else {
  796. X            got_date = TRUE;
  797. X            (void) sprintf(buf, "Date: %s", rfc_date(date_str));
  798. X            p = buf;
  799. X            }
  800. X        else if (!lcase_strncmp(p, "subject:", 8))
  801. X            (print_hdr = FALSE), strdup(subj, p);
  802. X        else if (!lcase_strncmp(p, "from:", 5)) {
  803. X            char not_me[BUFSIZ];
  804. X            (void) strcpy(not_me, buf + 5);
  805. X            take_me_off(not_me);
  806. X            if (*not_me) {
  807. X            /* Ignore bogus From: if we have a good one */
  808. X            if (got_from)
  809. X                print_hdr = FALSE;
  810. X            /* otherwise, output a good one */
  811. X            else {
  812. X                (void) strcpy(buf, From_buf);
  813. X                (void) no_newln(buf);
  814. X            }
  815. X            }
  816. X            got_from = TRUE;
  817. #ifdef PICKY_MAILER
  818. X            /* don't send From: to mta -- fool "for loop" below
  819. X             * by initializing the loop at files[1], not files[0]
  820. X             */
  821. X            if (!for_editor)
  822. X            print_hdr = 2;
  823. #endif /* PICKY_MAILER */
  824. X        }
  825. X        }
  826. X        if (print_hdr)
  827. X        /* print_hdr may be 2 for From: header */
  828. X        for (i = print_hdr-1; i < size; i++)
  829. X            if (files[i]) {
  830. X            (void) fputs(buf, files[i]);
  831. X            (void) fputc('\n', files[i]);
  832. X            }
  833. X    }
  834. X    }
  835. X    /* Finally, do the required (or changed) headers (Date, To, Cc) */
  836. X    (void) wrap_addrs(To, 80);
  837. X    (void) wrap_addrs(Cc, 80);
  838. X    (void) wrap_addrs(Bcc, 80);
  839. X    for (i = 0; i < size; i++) {
  840. X    if (!files[i])
  841. X        continue;
  842. #ifdef PICKY_MAILER
  843. X    if (i > 0) {
  844. #endif /* PICKY_MAILER */
  845. X    if (!got_from)
  846. X        (void) fputs(From_buf, files[i]);
  847. X    if (!got_date)
  848. X        (void) fprintf(files[i], "%sDate: %s\n",
  849. X        ison(flags, FORWARD) ? "Resent-" : "", rfc_date(date_str));
  850. #ifdef PICKY_MAILER
  851. X    }
  852. #endif /* PICKY_MAILER */
  853. X    (void) fprintf(files[i], "X-Mailer: %s\n", check_internal("version"));
  854. X    (void) fprintf(files[i], "%sTo: %s\n",
  855. X        ison(flags, FORWARD) ? "Resent-" : "", To);
  856. X    if (for_editor || isoff(flags, EDIT_HDRS)) {
  857. X        if (isoff(flags, FORWARD) &&
  858. X            (*Subject || for_editor && (do_set(set_options, "ask") ||
  859. X                        do_set(set_options, "asksub"))))
  860. X        (void) fprintf(files[i], "Subject: %s\n", Subject);
  861. X    } else if (subj && *subj && strlen(subj) > 9)
  862. X        (void) (fputs(subj, files[i]), fputc('\n', files[i]));
  863. X    if (*Cc || for_editor && do_set(set_options, "askcc"))
  864. X        (void) fprintf(files[i], "%sCc: %s\n",
  865. X        ison(flags, FORWARD) ? "Resent-" : "", Cc);
  866. X    if (i > 0 || for_editor)
  867. X        /* Do not send these to mail transfer agent */
  868. X        if (*Bcc)
  869. X        (void) fprintf(files[i], "%sBcc: %s\n",
  870. X            ison(flags, FORWARD) ? "Resent-" : "", Bcc);
  871. X    if (i > 0)
  872. X        (void) fprintf(files[i], "Status: OR\n");
  873. X    }
  874. X    for (i = 0; i < size; i++)
  875. X    if (files[i])
  876. X        (void) fflush(files[i]);
  877. X    if (buf[0]) /* last attempted header read was a line of msg text */
  878. X    for (i = 0; i < size; i++) {
  879. X        if (files[i]) {
  880. X        (void) fputs(buf, files[i]);
  881. X        (void) fputc('\n', files[i]);
  882. X        (void) fflush(files[i]);
  883. X        }
  884. X    }
  885. X    else
  886. X    if (isoff(flags, FORWARD))
  887. X        for (i = 0; i < size; i++)
  888. X        if (files[i]) {
  889. X            (void) fputc('\n', files[i]);
  890. X            (void) fflush(files[i]);
  891. X        }
  892. X    return fp? ftell(fp) : (long)TRUE;
  893. }
  894. X
  895. /* ARGSUSED */
  896. SIGRET
  897. rm_edfile(sig)
  898. {
  899. X    if (sig > 0) {
  900. X    char *fix;
  901. X    if (ison(glob_flags, IGN_SIGS))
  902. X        return;
  903. X    /* wrapcolumn may have been trashed -- restore it */
  904. X    if ((fix = do_set(set_options, "wrapcolumn")) && *fix)
  905. X        wrapcolumn = atoi(fix);
  906. X    mac_flush(); /* abort pending macros */
  907. X    }
  908. X    /* now check whether we should abort the letter */
  909. X    if (sig > 0 && !killme && ison(glob_flags, IS_GETTING)) {
  910. X    if (!istool)
  911. X        (void) signal(sig, rm_edfile);
  912. X    killme = 1;
  913. X    print("\n** interrupt -- one more to kill letter **\n");
  914. X    longjmp(cntrl_c_buf, 1);
  915. X    }
  916. X    killme = 0;
  917. X    /* if sig == -1, force a save into dead.letter.
  918. X     * else, check for nosave not being set and save anyway if it's not set
  919. X     * sig == 0 indicates normal exit (or ~x), so don't save a dead letter.
  920. X     */
  921. X    if (sig == -1 || sig != 0 && !do_set(set_options, "nosave"))
  922. X    dead_letter(sig);
  923. X    if (isoff(glob_flags, REDIRECT) && ed_fp) /* ed_fp may be null in toolmode*/
  924. X    (void) fclose(ed_fp), ed_fp = NULL_FILE;
  925. X    (void) unlink(edfile);
  926. X
  927. X    turnoff(glob_flags, IS_GETTING);
  928. X    if (sig == -1)
  929. X    return;
  930. X
  931. X    if (sig == SIGHUP)
  932. X    cleanup(0);
  933. X    if (!istool) {
  934. X    (void) signal(SIGINT, oldint);
  935. X    (void) signal(SIGQUIT, oldquit);
  936. X    (void) signal(SIGTERM, oldterm);
  937. X    }
  938. X
  939. X    if (sig == 0 || sig == -2 || istool) /* make sure sigchld is reset first */
  940. X    return;
  941. X
  942. X    if (isoff(glob_flags, DO_SHELL)) {  /* If we're not in a shell, exit */
  943. X    puts("exiting");
  944. X    echo_on();
  945. X    exit(1);
  946. X    }
  947. X    longjmp(jmpbuf, 1);
  948. }
  949. X
  950. /* save letter into dead letter */
  951. dead_letter(sig)
  952. int sig;    /* signal passed to rm_edfile() or 0 */
  953. {
  954. X    char     *p, buf[BUFSIZ];
  955. X    long     t;
  956. X    FILE     *dead;
  957. X
  958. X    if (ison(glob_flags, REDIRECT)) {
  959. X    print("input redirected -- can't save dead letter.\n");
  960. X    return;
  961. X    }
  962. X    /* If the file doesn't exist, get outta here. File may not exist if
  963. X     * user generated a ^C from a promptable header and catch sent us here.
  964. X     */
  965. X    if (!ed_fp && Access(edfile, R_OK) != 0)
  966. X    return;
  967. X    /* User may have killed mush via a signal while he was in an editor.
  968. X     * ed_fp will be NULL in this case.  Since the file does exist (above),
  969. X     * open it so we can copy it to dead letter.
  970. X     */
  971. X    if (!ed_fp && !(ed_fp = fopen(edfile, "r"))) {
  972. X    error("can't save dead letter from %s", edfile);
  973. X    return;
  974. X    }
  975. X    /* don't save a dead letter if there's nothing to save. */
  976. X    if (fseek(ed_fp, 0L, 2) || ftell(ed_fp) <= 1L)
  977. X    return;
  978. X    if (!(p = do_set(set_options, "dead")))
  979. X    p = "~/dead.letter";
  980. X    if (!(dead = open_file(p + (*p == '|'), (*p == '|'), TRUE)))
  981. X    return;
  982. X    (void) time (&t);
  983. X    (void) fflush(ed_fp);
  984. X    rewind(ed_fp);
  985. #ifdef MSG_SEPARATOR
  986. X    (void) fputs(MSG_SEPARATOR, dead);
  987. #ifndef MMDF
  988. X    (void) fputc('\n', dead);
  989. #endif /* MMDF */
  990. #else /* MSG_SEPARATOR */
  991. X    (void) fprintf(dead, "From %s %s", login, ctime(&t));
  992. #endif /* MSG_SEPARATOR */
  993. X    (void) fprintf(dead, "From: %s\nTo: %s\nSubject: %s\n", login, To, Subject);
  994. X    (void) fprintf(dead, "Date: %s\n", rfc_date(buf));
  995. X    if (*Cc)
  996. X    (void) fprintf(dead, "Cc: %s\n", Cc);
  997. X    if (*Bcc)
  998. X    (void) fprintf(dead, "Bcc: %s\n", Bcc);
  999. X    (void) fputc('\n', dead);
  1000. X    while (fgets(buf, sizeof(buf), ed_fp))
  1001. X    (void) fputs(buf, dead);
  1002. X    (void) fputc('\n', dead);
  1003. #ifdef END_MSG_SEP
  1004. X    (void) fputs(END_MSG_SEP, dead);
  1005. #endif /* END_MSG_SEP */
  1006. X    if (*p != '|')
  1007. X    (void) close_lock(p, dead);
  1008. X    else
  1009. X    (void) pclose(dead);
  1010. X    wprint("Saved%s letter in %s.\n", sig > 0? " unfinished" : "", p);
  1011. }
  1012. SHAR_EOF
  1013. echo 'File mail.c is complete' &&
  1014. chmod 0644 mail.c ||
  1015. echo 'restore of mail.c failed'
  1016. Wc_c="`wc -c < 'mail.c'`"
  1017. test 57669 -eq "$Wc_c" ||
  1018.     echo 'mail.c: original size 57669, current size' "$Wc_c"
  1019. rm -f _shar_wnt_.tmp
  1020. fi
  1021. # ============= mail.icon.1 ==============
  1022. if test -f 'mail.icon.1' -a X"$1" != X"-c"; then
  1023.     echo 'x - skipping mail.icon.1 (File already exists)'
  1024.     rm -f _shar_wnt_.tmp
  1025. else
  1026. > _shar_wnt_.tmp
  1027. echo 'x - extracting mail.icon.1 (Text)'
  1028. sed 's/^X//' << 'SHAR_EOF' > 'mail.icon.1' &&
  1029. /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
  1030. X */
  1031. X    0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0000,0x0001,
  1032. X    0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  1033. X    0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  1034. X    0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001,
  1035. X    0x8000,0x0000,0x0000,0x0001,0x8000,0x1FFF,0xFFFF,0xFE01,
  1036. X    0x8000,0xFE00,0x0000,0x0181,0x8007,0x01C0,0x0000,0x0061,
  1037. X    0x8018,0x0030,0x0000,0x0011,0x8020,0x7008,0x0000,0x0011,
  1038. X    0x80C1,0xFC06,0x0000,0x0009,0x8101,0xFC01,0x0000,0x0009,
  1039. X    0x8103,0xFE01,0x0000,0x0005,0x8203,0xFE00,0x8000,0x0005,
  1040. X    0x8403,0xFE00,0x4000,0x0005,0x8401,0xFC00,0x4000,0x0005,
  1041. X    0x8801,0xFC00,0x2000,0x0005,0x8800,0x7000,0x2000,0x0005,
  1042. X    0x8800,0x0000,0x3000,0x0005,0x9000,0x0000,0x1000,0x0005,
  1043. X    0x9000,0x0000,0x1000,0x0005,0x93FF,0xFFFF,0x9000,0x0025,
  1044. X    0xA200,0x0000,0x9000,0x00E5,0xA200,0x0000,0x9000,0x03A5,
  1045. X    0xA200,0x0000,0x9000,0x0625,0xA3FF,0xFFFF,0x9000,0x1C25,
  1046. X    0xA000,0x0000,0x1000,0x3425,0xA000,0x0000,0x1000,0xC425,
  1047. X    0xA000,0x0000,0x1003,0x8425,0xA000,0x0000,0x1006,0x0425,
  1048. X    0xA000,0x0000,0x101C,0x0425,0xA000,0x0000,0x11F0,0x0425,
  1049. X    0xA000,0x0000,0x13E0,0x0445,0xA000,0x0000,0x13E0,0x0585,
  1050. X    0xA000,0x0000,0x13E0,0x0605,0xA000,0x0000,0x11C0,0x0405,
  1051. X    0xA000,0x0000,0x1000,0x000D,0xA000,0x0000,0x1000,0x0011,
  1052. X    0xA000,0x0000,0x1000,0x0021,0xA000,0x0000,0x1000,0x00C1,
  1053. X    0xA000,0x0000,0x1000,0x0101,0xA000,0x0000,0x1000,0x0601,
  1054. X    0xA000,0x0000,0x1000,0x0801,0xA000,0x0000,0x1000,0x3801,
  1055. X    0xA000,0x0000,0x1000,0x4801,0xA000,0x0000,0x1000,0x8801,
  1056. X    0xA000,0x0000,0x1003,0x0801,0xA000,0x0000,0x1004,0x0801,
  1057. X    0xA000,0x0000,0x101C,0x0801,0xA000,0x0000,0x1024,0x0801,
  1058. X    0xA000,0x0000,0x1044,0x0801,0xA000,0x0000,0x1184,0x0801,
  1059. X    0xA000,0x0000,0x1204,0x0801,0xA000,0x0000,0x1404,0x0801,
  1060. X    0xBFFF,0xFFFF,0xF804,0x0801,0x8000,0x0000,0x0004,0x0801,
  1061. X    0x8000,0x0000,0x0004,0x0801,0x8000,0x0000,0x0004,0x0801,
  1062. X    0x8000,0x0000,0x0004,0x0801,0xFFFF,0xFFFF,0xFFFF,0xFFFF
  1063. SHAR_EOF
  1064. chmod 0644 mail.icon.1 ||
  1065. echo 'restore of mail.icon.1 failed'
  1066. Wc_c="`wc -c < 'mail.icon.1'`"
  1067. test 1933 -eq "$Wc_c" ||
  1068.     echo 'mail.icon.1: original size 1933, current size' "$Wc_c"
  1069. rm -f _shar_wnt_.tmp
  1070. fi
  1071. # ============= mail.icon.2 ==============
  1072. if test -f 'mail.icon.2' -a X"$1" != X"-c"; then
  1073.     echo 'x - skipping mail.icon.2 (File already exists)'
  1074.     rm -f _shar_wnt_.tmp
  1075. else
  1076. > _shar_wnt_.tmp
  1077. echo 'x - extracting mail.icon.2 (Text)'
  1078. sed 's/^X//' << 'SHAR_EOF' > 'mail.icon.2' &&
  1079. /* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16
  1080. X */
  1081. X    0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0000,0x0001,
  1082. X    0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x00E0,0x0001,
  1083. X    0x8000,0x0000,0x00DE,0x0001,0x8000,0x0000,0x00C1,0xE001,
  1084. X    0x8000,0x0000,0x00C0,0x1801,0x8000,0x0000,0x00C0,0x0801,
  1085. X    0x8000,0x0000,0x00C0,0x0801,0x8000,0x1FFF,0xFFC0,0x0E01,
  1086. X    0x8000,0xFE00,0x00C0,0x0981,0x8007,0x01C0,0x00C0,0x0861,
  1087. X    0x8018,0x0030,0x00C0,0x0811,0x8020,0x7008,0x00C0,0x0811,
  1088. X    0x80C1,0xFC06,0x00C0,0x1809,0x8101,0xBC01,0x00C0,0x6009,
  1089. X    0x8103,0x1E01,0x00C1,0x8005,0x8202,0x0E00,0x80C6,0x0005,
  1090. X    0x8404,0x0400,0x40D8,0x0005,0x8408,0x0200,0x40E0,0x0005,
  1091. X    0x8810,0x0100,0x20C0,0x0005,0x8820,0x6080,0x20C0,0x0005,
  1092. X    0x8840,0x4040,0x30C0,0x0005,0x9081,0x3020,0x10C0,0x0005,
  1093. X    0x9041,0x9C10,0x10C0,0x0005,0x93E0,0x8A0F,0x90C0,0x0005,
  1094. X    0xA210,0x6404,0x90C0,0x0005,0xA208,0x3002,0x90C0,0x0005,
  1095. X    0xA204,0x1401,0x90C0,0x0005,0xA3FF,0xFFFF,0x90C0,0x0005,
  1096. X    0xA000,0x0000,0x10C0,0x0005,0xA000,0x0000,0x10C0,0x0005,
  1097. X    0xA000,0x0000,0x10C0,0x0005,0xA000,0x0000,0x10C0,0x0005,
  1098. X    0xA000,0x0000,0x10C0,0x0005,0xA000,0x0000,0x11C0,0x0005,
  1099. X    0xA000,0x0000,0x13E0,0x0005,0xA000,0x0000,0x13E0,0x0005,
  1100. X    0xA000,0x0000,0x13E0,0x0005,0xA000,0x0000,0x11C0,0x0005,
  1101. X    0xA000,0x0000,0x1000,0x000D,0xA000,0x0000,0x1000,0x0011,
  1102. X    0xA000,0x0000,0x1000,0x0021,0xA000,0x0000,0x1000,0x00C1,
  1103. X    0xA000,0x0000,0x1000,0x0101,0xA000,0x0000,0x1000,0x0601,
  1104. X    0xA000,0x0000,0x1000,0x0801,0xA000,0x0000,0x1000,0x3001,
  1105. X    0xA000,0x0000,0x1000,0x4001,0xA000,0x0000,0x1000,0x8001,
  1106. X    0xA000,0x0000,0x1003,0x8001,0xA000,0x0000,0x1004,0x8001,
  1107. X    0xA000,0x0000,0x1018,0x8001,0xA000,0x0000,0x1020,0x8001,
  1108. X    0xA000,0x0000,0x1060,0x8001,0xA000,0x0000,0x1180,0x8001,
  1109. X    0xA000,0x0000,0x1280,0x8001,0xA000,0x0000,0x1480,0x8001,
  1110. X    0xBFFF,0xFFFF,0xFC80,0x8001,0x8000,0x0000,0x0080,0x8001,
  1111. X    0x8000,0x0000,0x0080,0x8001,0x8000,0x0000,0x0080,0x8001,
  1112. X    0x8000,0x0000,0x0080,0x8001,0xFFFF,0xFFFF,0xFFFF,0xFFFF
  1113. SHAR_EOF
  1114. chmod 0644 mail.icon.2 ||
  1115. echo 'restore of mail.icon.2 failed'
  1116. Wc_c="`wc -c < 'mail.icon.2'`"
  1117. test 1933 -eq "$Wc_c" ||
  1118.     echo 'mail.icon.2: original size 1933, current size' "$Wc_c"
  1119. rm -f _shar_wnt_.tmp
  1120. fi
  1121. # ============= main.c ==============
  1122. if test -f 'main.c' -a X"$1" != X"-c"; then
  1123.     echo 'x - skipping main.c (File already exists)'
  1124.     rm -f _shar_wnt_.tmp
  1125. else
  1126. > _shar_wnt_.tmp
  1127. echo 'x - extracting main.c (Text)'
  1128. sed 's/^X//' << 'SHAR_EOF' > 'main.c' &&
  1129. /* @(#)main.c    (c) copyright 10/18/86 (Dan Heller) */
  1130. X
  1131. #include "mush.h"
  1132. #include "options.h"
  1133. X
  1134. #if defined(sun) && defined(M_DEBUG)
  1135. cpu()
  1136. {
  1137. X    print("CPU time limit exceeded!\n");
  1138. }
  1139. #endif /* sun && DEBUG */
  1140. X
  1141. #ifdef LCKDFLDIR
  1142. extern char *lckdfldir;
  1143. #endif /* LCKDFLDIR */
  1144. X
  1145. #ifdef DOT_LOCK
  1146. int sgid;
  1147. #ifdef BSD
  1148. int rgid;
  1149. #endif /* BSD */
  1150. #endif /* DOT_LOCK */
  1151. X
  1152. /*ARGSUSED*/   /* we ignore envp */
  1153. main(argc, argv)
  1154. int argc;
  1155. char *argv[];
  1156. {
  1157. X    int              n;
  1158. X    char           buf[MAXPATHLEN];
  1159. X    register char    *p;
  1160. X    struct mush_flags Flags;
  1161. X
  1162. #ifndef INTERNAL_MALLOC
  1163. X    extern char *stackbottom;    /* used by xfree() */
  1164. X
  1165. X    stackbottom = (char *) &argc;
  1166. #endif /* INTERNAL_MALLOC */
  1167. X
  1168. #ifdef AUX
  1169. X    set42sig();        /* Use 4.2 BSD signal handling conventions */
  1170. #endif /* AUX */
  1171. X
  1172. #ifdef LCKDFLDIR
  1173. X    lckdfldir = LCKDFLDIR;
  1174. #endif /* LCKDFLDIR */
  1175. X    prog_name = basename(*argv);
  1176. X
  1177. X    (void) signal(SIGBUS,  bus_n_seg);
  1178. X    (void) signal(SIGSEGV, bus_n_seg);
  1179. X    (void) signal(SIGPIPE, SIG_IGN); /* if pager is terminated before end */
  1180. X
  1181. #if defined(sun) && defined(M_DEBUG)
  1182. X    (void) signal(SIGXCPU, cpu);
  1183. X
  1184. X    if (p = getenv("MALLOC_DEBUG"))
  1185. X    malloc_debug(atoi(p));
  1186. X    else
  1187. X    malloc_debug(0);
  1188. #endif /* sun && debug */
  1189. X
  1190. X    if (!isatty(0))
  1191. X    turnon(glob_flags, REDIRECT);
  1192. X    else
  1193. X    (void) setbuf(stdin, NULL);
  1194. X
  1195. X    init(); /* must be done before checking mail since "login" is set here */
  1196. X    mailfile = "";
  1197. #ifdef HOMEMAIL
  1198. X    {
  1199. X    char *home = do_set(set_options, "home");
  1200. X    if (!home)
  1201. X        home = ALTERNATE_HOME;
  1202. X    strdup(spoolfile, sprintf(buf, "%s/%s", home, MAILFILE));
  1203. X    }
  1204. #else /* HOMEMAIL */
  1205. X    strdup(spoolfile, sprintf(buf, "%s/%s", MAILDIR, login));
  1206. #endif /* HOMEMAIL */
  1207. X
  1208. X    n = preparse_opts(&argc,argv);
  1209. X
  1210. X    /* check for any mail at all and exit if we're not continuing */
  1211. X    if (!n) {
  1212. X    struct stat statb;
  1213. X    if (stat(spoolfile, &statb) || statb.st_size == 0) {
  1214. X        (void) printf("No mail for %s.\n", login);
  1215. X        exit(0);
  1216. X    }
  1217. X    }
  1218. X
  1219. #ifdef DOT_LOCK
  1220. X    sgid = getegid();
  1221. #ifdef BSD
  1222. X    rgid = getgid();
  1223. X    setregid(sgid, rgid);
  1224. #else
  1225. X    setgid(getgid());
  1226. #endif /* BSD */
  1227. #endif /* DOT_LOCK */
  1228. X
  1229. X    parse_options(&argv, &Flags);
  1230. X
  1231. X    (void) cmd_line(strcpy(buf, "set cmd_help"), NULL);
  1232. #ifdef SUNTOOL
  1233. X    if (istool)
  1234. X    (void) cmd_line(strcpy(buf, "set tool_help"), NULL);
  1235. #endif /* SUNTOOL */
  1236. X
  1237. X    set_cwd();
  1238. X
  1239. X    if (Flags.init_file)
  1240. X    (void) cmd_line(sprintf(buf, "source %s", Flags.init_file), msg_list);
  1241. X    if (Flags.source_rc > 0) {
  1242. X    /* use cmd_line() in case DEFAULT_RC has expandable chars */
  1243. X    (void) cmd_line(sprintf(buf, "source %s", DEFAULT_RC), msg_list);
  1244. X    }
  1245. X    if (Flags.source_rc > -1)
  1246. X    (void) source(0, DUBL_NULL);
  1247. X    mailfile = Flags.folder;
  1248. X
  1249. X    if (*spoolfile != '/') {
  1250. X    n = 1;
  1251. X    p = getpath(spoolfile, &n);
  1252. X    if (n == -1)
  1253. X        (void) fputs(p, stderr), exit(1);
  1254. X    else if (n)
  1255. X        (void) fprintf(stderr, "\"%s\" is a directory.\n", p), exit(1);
  1256. X    else if (*p != '/') {
  1257. X        /* if it still isn't a full path, make it one */
  1258. X        char *wd = do_set(set_options, "cwd");
  1259. X        if (*wd) {
  1260. X        (void) sprintf(buf, "%s/%s", wd, p);
  1261. X        strdup(spoolfile, buf);
  1262. X        } else
  1263. X        strdup(spoolfile, p);
  1264. X    } else
  1265. X        strdup(spoolfile, p);
  1266. X    }
  1267. X
  1268. #ifdef SUNTOOL
  1269. X    if (istool) {
  1270. X    make_tool();
  1271. X    turnon(glob_flags, DO_SHELL);
  1272. X    turnoff(glob_flags, REDIRECT); /* -- SunOS-4.0 has a problem here */
  1273. X    }
  1274. #endif /* SUNTOOL */
  1275. X
  1276. X    /* now we're ready for I/O */
  1277. X    if (isoff(glob_flags, REDIRECT)) {
  1278. X    /* make sure we can always recover from no echo mode */
  1279. X    (void) signal(SIGINT, catch);
  1280. X    (void) signal(SIGQUIT, catch);
  1281. X    (void) signal(SIGHUP, catch);
  1282. X    if (istool)
  1283. X        turnon(glob_flags, ECHO_FLAG);
  1284. X    tty_settings();
  1285. #ifdef SIGCONT
  1286. X    (void) signal(SIGTSTP, stop_start); /* this will take care of SIGCONT */
  1287. #endif /* SIGCONT */
  1288. X    /* echo_off() checks to see if echo_flg is set, so don't worry */
  1289. X    echo_off();
  1290. X    }
  1291. X
  1292. X    if (!istool && ison(glob_flags, IS_SENDING)) {
  1293. X    char recipients[BUFSIZ], *mailv[16];
  1294. X    (void) argv_to_string(recipients, argv);
  1295. X    fix_up_addr(recipients);
  1296. X    mailv[0] = "mail";
  1297. X    n = 1;
  1298. X    if (ison(Flags.flg, VERBOSE))
  1299. X        mailv[n++] = "-v";
  1300. X    if (Flags.Subj && *(Flags.Subj)) {
  1301. X        mailv[n++] = "-s";
  1302. X        mailv[n++] = Flags.Subj;
  1303. X    }
  1304. X    if (Flags.Cc && *(Flags.Cc)) {
  1305. X        fix_up_addr(Flags.Cc);
  1306. X        mailv[n++] = "-c";
  1307. X        mailv[n++] = Flags.Cc;
  1308. X    }
  1309. X    if (Flags.Bcc && *(Flags.Bcc)) {
  1310. X        fix_up_addr(Flags.Bcc);
  1311. X        mailv[n++] = "-b";
  1312. X        mailv[n++] = Flags.Bcc;
  1313. X    }
  1314. X    if (ison(Flags.flg, NO_SIGN))
  1315. X        mailv[n++] = "-u";
  1316. X    if (ison(Flags.flg, SEND_NOW))
  1317. X        mailv[n++] = "-U";
  1318. X    if (Flags.draft) {
  1319. X        if (isoff(Flags.flg, SEND_NOW))
  1320. X        mailv[n++] = "-E";
  1321. X        mailv[n++] = "-h";
  1322. X        mailv[n++] = Flags.draft;
  1323. X    }
  1324. X    mailv[n++] = recipients;
  1325. X    mailv[n] = NULL;
  1326. X    /* set now in case user is not running shell, but is running debug */
  1327. X    if (!istool)
  1328. X        (void) signal(SIGCHLD, sigchldcatcher);
  1329. X    if (!setjmp(jmpbuf))
  1330. X        (void) do_mail(n, mailv, msg_list);
  1331. X    /* do shell set from above: "mush -S user" perhaps */
  1332. X    if (isoff(glob_flags, DO_SHELL) && !*mailfile) {
  1333. X        if (isoff(glob_flags, REDIRECT))
  1334. X        echo_on();
  1335. X        exit(0);
  1336. X    }
  1337. X    }
  1338. X    turnoff(glob_flags, IS_SENDING); /* no longer sending mail; running shell */
  1339. X
  1340. X    if (ison(glob_flags, REDIRECT)
  1341. X        && (!Flags.src_file || !Flags.src_n_exit)) {
  1342. X    puts("You can't redirect input unless you're sending mail.");
  1343. X    puts("If you want to run a shell with redirection, use \"-i\"");
  1344. X    cleanup(0);
  1345. X    }
  1346. X    if (!*mailfile) {
  1347. X    strdup(mailfile, spoolfile);
  1348. X    if (!mail_size() && isoff(glob_flags, DO_SHELL)) {
  1349. X        /* we know it's not the spool file here */
  1350. X        (void) printf("No mail in %s.\n", mailfile);
  1351. X        echo_on(), exit(0);
  1352. X    }
  1353. X    }
  1354. X
  1355. X    if (!hdrs_only) {
  1356. X    /* catch will test DO_SHELL and try to longjmp if set.  this is a
  1357. X     * transition state from no-shell to do-shell to ignore sigs to
  1358. X     * avoid a longjmp botch.  Note setjmp isn't called until do_loop().
  1359. X     */
  1360. X    turnon(glob_flags, IGN_SIGS);
  1361. #ifdef CURSES
  1362. X    if (ison(glob_flags, PRE_CURSES))
  1363. X        (void) curses_init(0, DUBL_NULL);
  1364. X    turnoff(glob_flags, PRE_CURSES);
  1365. #endif /* CURSES */
  1366. X    }
  1367. X
  1368. X    /* find a free tmpfile */
  1369. X    if (!(p = getdir(do_set(set_options, "tmpdir"))))
  1370. alted:
  1371. X    p = ALTERNATE_HOME;
  1372. X    {
  1373. X    int pid = getpid();
  1374. X    while (!Access(sprintf(tempfile, "%s/.%s%d", p, prog_name, pid++), F_OK))
  1375. X    ;
  1376. X    }
  1377. X    /* just create the file, make sure it's empty.  It'll close later and
  1378. X     * be reopened for reading only.
  1379. X     */
  1380. X    if (!(tmpf = mask_fopen(tempfile, "w"))) {
  1381. X    if (strcmp(p, ALTERNATE_HOME))
  1382. X        goto alted;
  1383. X    error("Can't create tempfile %s", tempfile);
  1384. X    cleanup(0);
  1385. X    }
  1386. X
  1387. X    /* do pseudo-intelligent stuff with certain signals */
  1388. X    (void) signal(SIGINT,  catch);
  1389. X    (void) signal(SIGQUIT, catch);
  1390. X    (void) signal(SIGHUP,  catch);
  1391. X
  1392. X    if (!hdrs_only && !istool && (!Flags.src_file || !Flags.src_n_exit) &&
  1393. X    !glob(do_set(set_options, "quiet"), "{,{,*[ \\,]}startup{,[ \\,]*}}"))
  1394. X    (void) printf("%s: Type '?' for help.\n", check_internal("version"));
  1395. X
  1396. X    (void) sprintf(buf, "folder %s %s", Flags.f_flags, mailfile);
  1397. X    if ((argv = mk_argv(buf, &argc, TRUE)) && argc > 0) {
  1398. X    if (folder(argc, argv, NULL) == -1 && isoff(glob_flags, DO_SHELL)) {
  1399. X        if (iscurses)
  1400. X        putchar('\n');
  1401. X        turnoff(glob_flags, IGN_SIGS), cleanup(0);
  1402. X    }
  1403. #ifdef CURSES
  1404. X    if (iscurses)
  1405. X        (void) curses_help_msg(TRUE);
  1406. #endif /* CURSES */
  1407. X    free_vec(argv);
  1408. X    }
  1409. X
  1410. X    if (hdrs_only) {
  1411. X    (void) sprintf(buf, "headers %s", hdrs_only);
  1412. X    if (argv = make_command(buf, TRPL_NULL, &argc))
  1413. X        (void) do_hdrs(argc, argv, NULL);
  1414. X    cleanup(0);
  1415. X    }
  1416. X
  1417. X    turnon(glob_flags, DO_SHELL);
  1418. X
  1419. X    /* finally, if the user wanted to source a file to execute, do it now */
  1420. X    if (Flags.src_file) {
  1421. X    char *s_argv[2];
  1422. X    s_argv[1] = Flags.src_file;
  1423. X    (void) source(2, s_argv);
  1424. X    if (!istool && Flags.src_n_exit)
  1425. X        cleanup(0);
  1426. X    }
  1427. X
  1428. #ifdef SUNTOOL
  1429. X    if (istool) {
  1430. X    char buf[16];
  1431. X    n = 0;
  1432. X    if (time_out < 30)
  1433. X        time_out = 30;
  1434. X    turnoff(glob_flags, IGN_SIGS);
  1435. X    (void) do_hdrs(0, DUBL_NULL, NULL);
  1436. X    timerclear(&(mail_timer.it_interval));
  1437. X    timerclear(&(mail_timer.it_value));
  1438. X
  1439. X    /*  Reload time with value of timeout upon timer expiration. */
  1440. X    mail_timer.it_interval.tv_sec = time_out;
  1441. X
  1442. X    mail_timer.it_value.tv_sec = time_out;
  1443. X    (void) notify_set_itimer_func(tool, do_check,
  1444. X        ITIMER_REAL, &mail_timer, (struct itimerval *) 0);
  1445. X    timeout_cursors(FALSE);
  1446. X    window_main_loop(tool);
  1447. X    cleanup(0);
  1448. X    }
  1449. #endif /* SUNTOOL */
  1450. X    do_loop();
  1451. }
  1452. X
  1453. do_version()
  1454. {
  1455. X    print("%s\n", check_internal("version"));
  1456. X    return -1;
  1457. }
  1458. X
  1459. /* set the current working directory */
  1460. set_cwd()
  1461. {
  1462. X    char cwd[MAXPATHLEN];
  1463. X
  1464. X    if (GetCwd(cwd, MAXPATHLEN) == NULL) {
  1465. X    error("set_cwd: %s", cwd);
  1466. X    (void) un_set(&set_options, "cwd");
  1467. X    } else {
  1468. X    char *argv[4];
  1469. X    argv[0] = "cwd";
  1470. X    argv[1] = "=";
  1471. X    argv[2] = cwd;
  1472. X    argv[3] = NULL;
  1473. X    (void) add_option(&set_options, argv);
  1474. X    }
  1475. }
  1476. SHAR_EOF
  1477. chmod 0644 main.c ||
  1478. echo 'restore of main.c failed'
  1479. Wc_c="`wc -c < 'main.c'`"
  1480. test 8757 -eq "$Wc_c" ||
  1481.     echo 'main.c: original size 8757, current size' "$Wc_c"
  1482. rm -f _shar_wnt_.tmp
  1483. fi
  1484. # ============= makefile.bsd ==============
  1485. if test -f 'makefile.bsd' -a X"$1" != X"-c"; then
  1486.     echo 'x - skipping makefile.bsd (File already exists)'
  1487.     rm -f _shar_wnt_.tmp
  1488. else
  1489. > _shar_wnt_.tmp
  1490. echo 'x - extracting makefile.bsd (Text)'
  1491. sed 's/^X//' << 'SHAR_EOF' > 'makefile.bsd' &&
  1492. # makefile.bsd    (c) copyright 1991    (Dan Heller)
  1493. # SunOS users should add -DSUN_3_5, -DSUN_4_0, or -DSUN_4_1 to CFLAGS.
  1494. #
  1495. HDRS= mush.h config.h-dist strings.h bindings.h options.h version.h glob.h
  1496. X
  1497. SRCS= main.c init.c misc.c mail.c hdrs.c execute.c commands.c print.c dates.c \
  1498. X      signals.c setopts.c msgs.c pick.c sort.c expr.c folders.c \
  1499. X      loop.c viewopts.c curses.c curs_io.c bind.c file.c strings.c \
  1500. X      lock.c macros.c options.c addrs.c malloc.c glob.c command2.c
  1501. OBJS= main.o init.o misc.o mail.o hdrs.o execute.o commands.o print.o file.o \
  1502. X      signals.o setopts.o msgs.o pick.o sort.o expr.o strings.o \
  1503. X      folders.o dates.o loop.o viewopts.o curses.o curs_io.o bind.o \
  1504. X      lock.o macros.o options.o addrs.o malloc.o glob.o command2.o
  1505. X
  1506. HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 mush.1 \
  1507. X    cmd_help Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
  1508. X
  1509. MAKES= makefile.bsd makefile.xenix makefile.sys.v makefile.hpux makefile.sun
  1510. X
  1511. # See the README for changes needed to compile under Ultrix.
  1512. # In particular, you may need -DSIGRET=void and/or -ltermcap.
  1513. CFLAGS= -O -DCURSES -DBSD
  1514. LDFLAGS=
  1515. LINTFLAGS= -bxah -Dlint -DCURSES -DBSD
  1516. LIBES= -lcurses -ltermlib
  1517. OTHERLIBS=
  1518. # Use some variant of this one if you #define MMDF in config.h
  1519. #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
  1520. X
  1521. mush: $(OBJS)
  1522. X    @echo loading...
  1523. X    @cc $(LDFLAGS) $(OBJS) $(LIBES) $(OTHERLIBS) -o mush
  1524. X
  1525. $(OBJS): config.h mush.h
  1526. loop.o: version.h
  1527. X
  1528. tape:
  1529. X    @tar cv $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES)
  1530. X
  1531. tar:
  1532. X    @tar fcv MUSH $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES)
  1533. X
  1534. tarmail:
  1535. X    tar fcv - $(MAKES) $(HDRS) $(SRCS) $(HELP_FILES) | \
  1536. X    compress | btoa > mush.tarmail
  1537. X
  1538. lint:
  1539. X    lint $(LINTFLAGS) $(SRCS)
  1540. X
  1541. clean:
  1542. X    rm -f *.o core mush
  1543. X
  1544. BINDIR= /usr/local/bin
  1545. LIBDIR= /usr/local/lib
  1546. MRCDIR= /usr/lib
  1547. MANDIR= /usr/local/man/man1
  1548. MANEXT= 1
  1549. X
  1550. install: mush
  1551. X    mv mush $(BINDIR)
  1552. X    strip $(BINDIR)/mush
  1553. X    chmod 0755 $(BINDIR)/mush
  1554. X    cp mush.1 $(MANDIR)/mush.$(MANEXT)
  1555. X    chmod 0644 $(MANDIR)/mush.$(MANEXT)
  1556. X    cp cmd_help $(LIBDIR)
  1557. X    chmod 0644 $(LIBDIR)/cmd_help
  1558. X    cp Mushrc $(MRCDIR)/Mushrc
  1559. X    chmod 0644 $(MRCDIR)/Mushrc
  1560. SHAR_EOF
  1561. chmod 0644 makefile.bsd ||
  1562. echo 'restore of makefile.bsd failed'
  1563. Wc_c="`wc -c < 'makefile.bsd'`"
  1564. test 2096 -eq "$Wc_c" ||
  1565.     echo 'makefile.bsd: original size 2096, current size' "$Wc_c"
  1566. rm -f _shar_wnt_.tmp
  1567. fi
  1568. # ============= makefile.hpux ==============
  1569. if test -f 'makefile.hpux' -a X"$1" != X"-c"; then
  1570.     echo 'x - skipping makefile.hpux (File already exists)'
  1571.     rm -f _shar_wnt_.tmp
  1572. else
  1573. > _shar_wnt_.tmp
  1574. echo 'x - extracting makefile.hpux (Text)'
  1575. sed 's/^X//' << 'SHAR_EOF' > 'makefile.hpux' &&
  1576. # Mush makefile for HP/UX.
  1577. #
  1578. HDRS1= mush.h config.h
  1579. HDRS2= strings.h options.h
  1580. HDRS3= bindings.h glob.h
  1581. HDRS4= version.h
  1582. SRCS1= commands.c dates.c execute.c expr.c folders.c \
  1583. X    hdrs.c init.c loop.c mail.c main.c misc.c msgs.c pick.c \
  1584. X    print.c setopts.c signals.c sort.c viewopts.c options.c lock.c
  1585. SRCS2= bind.c curs_io.c curses.c file.c strings.c macros.c \
  1586. X    addrs.c malloc.c glob.c command2.c
  1587. X
  1588. OBJS1= commands.o dates.o execute.o expr.o folders.o \
  1589. X    hdrs.o init.o loop.o mail.o main.o misc.o msgs.o pick.o \
  1590. X    print.o setopts.o signals.o sort.o viewopts.o options.o lock.o
  1591. OBJS2= bind.o curs_io.o curses.o file.o strings.o macros.o \
  1592. X    addrs.o malloc.o glob.o command2.o
  1593. X
  1594. HELP_FILES= README README-7.0 README-7.1 README-7.2.0 README-7.2.2 mush.1 \
  1595. X    cmd_help Mushrc Mailrc Gnurc sample.mushrc advanced.mushrc digestify
  1596. X
  1597. # If your HP-UX version is older than 6.5, you will need remove -DDIRECTORY
  1598. X
  1599. HPFLAGS=    -DHPUX -DSELECT -DDIRECTORY
  1600. CFLAGS=     -O -DSYSV -DUSG -DCURSES -DREGCMP -DSIGRET=void $(HPFLAGS)
  1601. LDFLAGS=
  1602. LIBS=         -lcurses -lPW -lmalloc
  1603. OTHERLIBS=
  1604. # Use some variant of this one if you #define MMDF in config.h
  1605. #OTHERLIBS=/usr/src/mmdf/lib/libmmdf.a
  1606. PROG=        mush
  1607. X
  1608. $(PROG): $(OBJS1) $(OBJS2)
  1609. X    @echo loading...
  1610. X    @$(CC) $(LDFLAGS) $(OBJS1) $(OBJS2) -o $(PROG) $(LIBS) $(OTHERLIBS)
  1611. X
  1612. $(OBJS1): $(HDRS1) $(HDRS2)
  1613. $(OBJS2): $(HDRS1) $(HDRS2) $(HDRS3)
  1614. loop.o: version.h
  1615. X
  1616. BINDIR= /usr/local/bin
  1617. LIBDIR= /usr/local/lib
  1618. MRCDIR= /usr/lib
  1619. MANDIR= /usr/local/man/man1
  1620. MANEXT= 1
  1621. X
  1622. install: mush
  1623. X    cp mush $(BINDIR)
  1624. X    strip $(BINDIR)/mush
  1625. X    chmod 0755 $(BINDIR)/mush
  1626. X    cp mush.1 $(MANDIR)/mush.$(MANEXT)
  1627. X    chmod 0644 $(MANDIR)/mush.$(MANEXT)
  1628. X    cp cmd_help $(LIBDIR)
  1629. X    chmod 0644 $(LIBDIR)/cmd_help
  1630. X    cp Mushrc $(MRCDIR)/Mushrc
  1631. X    chmod 0644 $(MRCDIR)/Mushrc
  1632. SHAR_EOF
  1633. chmod 0644 makefile.hpux ||
  1634. echo 'restore of makefile.hpux failed'
  1635. Wc_c="`wc -c < 'makefile.hpux'`"
  1636. test 1735 -eq "$Wc_c" ||
  1637.     echo 'makefile.hpux: original size 1735, current size' "$Wc_c"
  1638. rm -f _shar_wnt_.tmp
  1639. fi
  1640. # ============= makefile.sun ==============
  1641. if test -f 'makefile.sun' -a X"$1" != X"-c"; then
  1642.     echo 'x - skipping makefile.sun (File already exists)'
  1643.     rm -f _shar_wnt_.tmp
  1644. else
  1645. > _shar_wnt_.tmp
  1646. echo 'x - extracting makefile.sun (Text)'
  1647. sed 's/^X//' << 'SHAR_EOF' > 'makefile.sun' &&
  1648. # makefile.sun    (c) copyright 1986    (Dan Heller)
  1649. SHAR_EOF
  1650. true || echo 'restore of makefile.sun failed'
  1651. fi
  1652. echo 'End of  part 12'
  1653. echo 'File makefile.sun is continued in part 13'
  1654. echo 13 > _shar_seq_.tmp
  1655. exit 0
  1656. exit 0 # Just in case...
  1657. -- 
  1658. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1659. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1660. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1661. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1662.