home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume9 / elm2 / part07 < prev    next >
Text File  |  1987-03-08  |  53KB  |  2,052 lines

  1. Subject:  v09i007:  ELM Mail System, Part07/19
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: Dave Taylor <hplabs!taylor>
  6. Mod.sources: Volume 9, Issue 7
  7. Archive-name: elm2/Part07
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If this archive is complete, you will see the message:
  13. #        "End of archive 7 (of 19)."
  14. # Contents:  src/aliasdb.c src/domains.c src/initialize.c
  15. #   utils/fastmail.c utils/newmail.c utils/wnewmail.c
  16. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  17. echo shar: Extracting \"src/aliasdb.c\" \(7752 characters\)
  18. if test -f src/aliasdb.c ; then 
  19.   echo shar: Will not over-write existing file \"src/aliasdb.c\"
  20. else
  21. sed "s/^X//" >src/aliasdb.c <<'END_OF_src/aliasdb.c'
  22. X/**            aliasdb.c            **/
  23. X
  24. X/** Alias database files...
  25. X
  26. X    (C) Copyright 1986 Dave Taylor
  27. X**/
  28. X
  29. X
  30. X#include "headers.h"
  31. X
  32. X#include <sys/types.h>
  33. X#include <sys/stat.h>
  34. X#include <errno.h>
  35. X
  36. Xextern int errno;
  37. X
  38. X#ifdef USE_DBM
  39. X# include <dbm.h>
  40. X#endif
  41. X
  42. X#define  absolute(x)        ((x) > 0 ? x : -(x))
  43. X
  44. Xchar *shift_lower(), *find_path_to(), *strcat(), *strcpy();
  45. Xunsigned long sleep();
  46. X
  47. Xint  findnode_has_been_initialized = FALSE;
  48. X
  49. Xfindnode(name, display_error)
  50. Xchar *name;
  51. Xint   display_error;
  52. X{
  53. X    /** break 'name' into machine!user or user@machine and then
  54. X        see if you can find 'machine' in the path database..
  55. X        If so, return name as the expanded address.  If not,
  56. X        return what was given to us!   If display_error, then
  57. X        do so...
  58. X    **/
  59. X
  60. X#ifndef DONT_TOUCH_ADDRESSES
  61. X    
  62. X    char   old_name[SLEN];
  63. X    char   address[SLEN];
  64. X
  65. X    if (strlen(name) == 0)
  66. X      return;
  67. X    
  68. X    if (! findnode_has_been_initialized) {
  69. X      if (! mail_only)
  70. X        error("initializing internal tables...");
  71. X#ifndef USE_DBM
  72. X      get_connections();
  73. X      open_domain_file();
  74. X#endif
  75. X      init_findnode();
  76. X      clear_error();
  77. X          findnode_has_been_initialized = TRUE;
  78. X    }
  79. X
  80. X    strcpy(old_name, name);        /* save what we were given */
  81. X
  82. X    if (expand_site(name, address) == -1) {
  83. X          if (display_error && name[0] != '!') {
  84. X        dprint2(2,"Couldn't expand host %s in address. (%s)\n",
  85. X                 name, "findnode");
  86. X        if (! check_only && warnings) {    /* be silent if just checking */
  87. X          if (mail_only)
  88. X            printf("Warning: couldn't expand %s...\n\r", name);
  89. X          else {
  90. X            error1("Warning: couldn't expand %s...", name);
  91. X            sleep(1);
  92. X          }
  93. X        }
  94. X      }
  95. X      strcpy(name, old_name);    /* and restore... */
  96. X    }
  97. X    else
  98. X      strcpy(name, address);
  99. X#endif
  100. X    return;
  101. X}
  102. X
  103. Xint
  104. Xexpand_site(cryptic, expanded)
  105. Xchar *cryptic, *expanded;
  106. X{
  107. X
  108. X    /** Given an address of the form 'xyz@site' or 'site!xyz'
  109. X        return an address of the form <expanded address for site>
  110. X            with 'xyz' embedded according to the path database entry.
  111. X        Note that 'xyz' can be eiher a simple address (as in "joe")
  112. X        or a complex address (as in "joe%xerox.parc@Xerox.ARPA")!
  113. X        0 = found, -1 return means unknown site code 
  114. X    
  115. X        Modified to strip out parenthetical comments...
  116. X    **/
  117. X
  118. X#ifdef ACSNET
  119. X
  120. X    strcpy(expanded, cryptic);    /* fast and simple */
  121. X    return(0);
  122. X
  123. X#else
  124. X# ifdef USE_DBM
  125. X    datum  key, contents;
  126. X# endif
  127. X
  128. X    char   name[VERY_LONG_STRING], sitename[VERY_LONG_STRING], 
  129. X               temp[VERY_LONG_STRING], old_name[VERY_LONG_STRING],
  130. X           comment[LONG_STRING];
  131. X    char   *expand_domain(), *addr;
  132. X    register int i = 0, j = 0, domain_name;
  133. X
  134. X    strcpy(old_name, cryptic);    /* remember what we were given */
  135. X
  136. X    /** break down **/
  137. X
  138. X    /** first, rip out the comment, if any **/
  139. X
  140. X    if ((i = chloc(cryptic, '(')) > -1) {
  141. X      comment[j++] = ' ';            /* leading space */
  142. X      for ( ;cryptic[i] != ')'; i++)
  143. X          comment[j++] = cryptic[i];
  144. X      comment[j++] = ')';
  145. X      comment[j] = '\0';
  146. X      /* and remove this from cryptic string too... */
  147. X      if (cryptic[(j = chloc(cryptic,'('))-1] == ' ')
  148. X        cryptic[j-1] = '\0';
  149. X      else
  150. X        cryptic[j] = '\0';
  151. X    }
  152. X    else
  153. X      comment[0] = '\0';
  154. X
  155. X    i = j = 0;    /* reset */
  156. X
  157. X    while (cryptic[i] != AT_SIGN && cryptic[i] != BANG && 
  158. X           cryptic[i] != '\0' && cryptic[i] != '(')
  159. X      sitename[j++] = cryptic[i++];
  160. X
  161. X    sitename[j++] = '\0';
  162. X
  163. X    j = 0;
  164. X    
  165. X    if (cryptic[i] == '\0') return(-1);    /* nothing to expand! */
  166. X
  167. X    domain_name = (cryptic[i] == AT_SIGN);
  168. X
  169. X    i++;
  170. X
  171. X    while (cryptic[i] != '\0' && cryptic[i] != '(' && 
  172. X               ! whitespace(cryptic[i]))
  173. X      name[j++] = cryptic[i++];
  174. X
  175. X    name[j] = '\0';
  176. X
  177. X    if (domain_name) {
  178. X      strcpy(temp, name);
  179. X      strcpy(name, sitename);
  180. X      strcpy(sitename, temp);
  181. X    }
  182. X
  183. X    dprint3(5,"\nBroke address into '%s' @ '%s' '%s'\n\n",
  184. X        name, sitename, comment);
  185. X
  186. X#ifdef USE_DBM
  187. X
  188. X    if (size_of_pathfd == 0)
  189. X      return(-1);
  190. X
  191. X    key.dptr  = sitename;
  192. X    key.dsize = strlen(sitename) + 1;
  193. X
  194. X    contents = fetch(key);
  195. X
  196. X    if (contents.dptr == 0) 
  197. X      return(-1);            /* can't find it! */
  198. X
  199. X    sprintf(expanded, contents.dptr, name);
  200. X    strcat(expanded, " ");            /* add a single space... */
  201. X    strcat(expanded, comment);        /*    ...and add comment */
  202. X    return(0);
  203. X#endif
  204. X
  205. X#ifndef LOOK_CLOSE_AFTER_SEARCH
  206. X
  207. X    if (talk_to(sitename)) {
  208. X      strcpy(expanded, old_name);    /* restore! */
  209. X      return(0);
  210. X    }
  211. X#endif
  212. X
  213. X    if ((addr = find_path_to(sitename, TRUE)) == NULL) {
  214. X
  215. X#ifdef LOOK_CLOSE_AFTER_SEARCH
  216. X
  217. X        if (talk_to(sitename)) {
  218. X          strcpy(expanded, old_name);    /* restore! */
  219. X          return(0);
  220. X        }
  221. X        else
  222. X#endif
  223. X        if ((addr = expand_domain(cryptic)) != NULL) {
  224. X           strcpy(expanded, addr);    /* into THIS buffer */
  225. X           strcat(expanded, comment);    /* patch in comment */
  226. X           return(0);
  227. X        }
  228. X        else  if (size_of_pathfd == 0) {    /* no path database! */
  229. X          strcpy(expanded, old_name);    /* restore! */
  230. X          return(0);
  231. X        }
  232. X        else {                 /* We just can't get there! */
  233. X          strcpy(expanded, old_name);    /* restore! */
  234. X          return(-1);
  235. X        }
  236. X    }
  237. X    else {            /* search succeeded */
  238. X       sprintf(expanded, addr, name);
  239. X       strcat(expanded, comment);        /* add comment */
  240. X       return(0);
  241. X    }
  242. X#endif
  243. X}
  244. X
  245. Xint
  246. Xbinary_search(name, address)
  247. Xchar *name, *address;
  248. X{
  249. X    /* binary search file for name.  Return 0 if found, -1 if not */
  250. X
  251. X    char machine[40];
  252. X    register long first = 0, last, middle;
  253. X    register int  compare;
  254. X
  255. X    address[0] = '\0';
  256. X
  257. X    last = size_of_pathfd;
  258. X
  259. X    do {
  260. X
  261. X      middle = (long) ((first+last) / 2);
  262. X
  263. X      get_entry(machine, address, pathfd, middle);
  264. X
  265. X      compare = strcmp(name, machine);
  266. X
  267. X      if (compare < 0) 
  268. X        last = middle - 1;
  269. X      else if (compare == 0) 
  270. X        return(0);
  271. X      else  /* greater */
  272. X        first = middle + 1; 
  273. X    } while (absolute(last) - absolute(first) > FIND_DELTA);
  274. X
  275. X    return(-1);
  276. X}
  277. X
  278. Xget_entry(machine, address, fileid, offset)
  279. Xchar *machine, *address;
  280. XFILE *fileid;
  281. Xlong offset;
  282. X{
  283. X    /** get entry...return machine and address immediately
  284. X        following given offset in fileid.  **/
  285. X
  286. X    fseek(fileid, offset, 0);
  287. X
  288. X    /* read until we hit an end-of-line */
  289. X
  290. X    while (getc(fileid) != '\n')
  291. X       ;
  292. X
  293. X    fscanf(fileid, "%s\t%s", machine, address);
  294. X}
  295. X
  296. Xinit_findnode()
  297. X{
  298. X    /** Initialize the FILE and 'size_of_file' values for the 
  299. X        findnode procedure **/
  300. X
  301. X    struct stat buffer;
  302. X
  303. X    if (stat(pathfile, &buffer) == -1) {
  304. X      dprint2(1, "Warning: No pathalias file [filename %s] found! (%s)\n", 
  305. X          pathfile, "init_findnode");
  306. X      size_of_pathfd = 0;
  307. X      return;
  308. X    }
  309. X
  310. X    size_of_pathfd = (long) buffer.st_size;
  311. X
  312. X#ifdef USE_DBM
  313. X    
  314. X    if (dbminit(pathfile) != 0) {
  315. X      dprint1(1, "Warning: couldn't initialize DBM database %s\n", 
  316. X             pathfile);
  317. X      dprint2(1, "** %s - %s **\n\n", error_name(errno),
  318. X             error_description(errno));
  319. X      size_of_pathfd = 0;    /* error flag, in this case */
  320. X      return;
  321. X    }
  322. X     
  323. X    return;
  324. X#else
  325. X
  326. X    if ((pathfd = fopen(pathfile,"r")) == NULL) {
  327. X      dprint2(1, "Warning: Can't read pathalias file [filename %s] (%s)\n", 
  328. X           pathfile, "init_findnode");
  329. X      size_of_pathfd = 0;
  330. X    }
  331. X    else
  332. X      dprint2(2, "\nOpened file '%s' as path alias database.  (%s)\n\n", 
  333. X          pathfile, "init_findnode");
  334. X#endif
  335. X}
  336. X
  337. Xchar *find_path_to(machine, printf_format)
  338. Xchar *machine;
  339. Xint   printf_format;
  340. X{
  341. X    /** Returns either the path to the specified machine or NULL if
  342. X        not found.  If "printf_format" is TRUE, then it leaves the
  343. X        '%s' intact, otherwise it assumes that the address is a uucp
  344. X        address for the domain expansion program and removes the
  345. X        last three characters of the expanded name ("!%s") since
  346. X        they're redundant with the expansion!
  347. X        **/
  348. X
  349. X    static char buffer[LONG_SLEN];    /* space for path */
  350. X
  351. X    if (size_of_pathfd > 0)
  352. X      if (binary_search(machine, buffer) != -1) {       /* found it! */
  353. X        if (! printf_format && strlen(buffer) > 3)
  354. X          buffer[strlen(buffer)-3] = '\0';
  355. X        return( (char *) buffer);
  356. X      }
  357. X
  358. X    return(NULL);                        /* failed if it's here! */
  359. X}
  360. END_OF_src/aliasdb.c
  361. if test 7752 -ne `wc -c <src/aliasdb.c`; then
  362.     echo shar: \"src/aliasdb.c\" unpacked with wrong size!?
  363. fi
  364. # end of overwriting check
  365. fi
  366. echo shar: Extracting \"src/domains.c\" \(7773 characters\)
  367. if test -f src/domains.c ; then 
  368.   echo shar: Will not over-write existing file \"src/domains.c\"
  369. else
  370. sed "s/^X//" >src/domains.c <<'END_OF_src/domains.c'
  371. X/**            domains.c            **/
  372. X
  373. X/** This file contains all the code dealing with the expansion of 
  374. X    domain based addresses in Elm.  It uses the file "domains" as
  375. X    defined in the sysdefs.h file.
  376. X
  377. X    (C) Copyright 1986 Dave Taylor
  378. X
  379. X    From a file format and idea in "uumail" - designed by Stan Barber.
  380. X**/
  381. X
  382. X#include <stdio.h>
  383. X#include <ctype.h>
  384. X
  385. X#include "headers.h"
  386. X
  387. X#ifdef BSD
  388. X# undef toupper
  389. X# undef tolower
  390. X#endif
  391. X
  392. X/** define the various characters that we can encounter after a "%" sign
  393. X    in the template file...
  394. X**/
  395. X
  396. X#define USERNAME    'U'    /* %U = the name of the remote user */
  397. X#define HOSTNAME    'N'    /* %N = the remote machine name     */
  398. X#define FULLNAME    'D'    /* %D = %N + domain info given      */
  399. X#define NPATH        'R'    /* %R = path to %N from pathalias   */
  400. X#define PPATH        'P'    /* %P = path to 'P' from pathalias  */
  401. X#define OBSOLETE    'S'    /* %S = (used to be suffix string)  */
  402. X
  403. X/** and finally some characters that are allowed in user/machine names **/
  404. X
  405. X#define okay_others(c)    (c == '-' || c == '^' || c == '$' || c == '_')
  406. X
  407. X/** and some allowed ONLY in the username field **/
  408. X
  409. X#define special_chars(c)    (c == '%' || c == ':')
  410. X
  411. Xchar *find_path_to(), *expand_domain(), *match_and_expand_domain();
  412. Xchar *strcpy(), *strcat(), *strtok();
  413. Xunsigned long sleep();
  414. Xvoid rewind();
  415. X          
  416. Xopen_domain_file()
  417. X{
  418. X    if ((domainfd = fopen(domains, "r")) == NULL) {
  419. X      dprint1(1, "Can't open file %s as domains file (open_domain_file)\n", 
  420. X          domains);
  421. X    }
  422. X    else {
  423. X      dprint1(2,
  424. X            "\nOpened '%s' as the domain database. (open_domain_file)\n\n", 
  425. X          domains);
  426. X    }
  427. X    
  428. X    /* if it fails it'll instantiate domainfd to NULL which is
  429. X       exactly what we want to have happen!! */
  430. X}
  431. X
  432. Xchar *expand_domain(buffer)
  433. Xchar *buffer;
  434. X{
  435. X    /** Expand the address 'buffer' based on the domain information, 
  436. X        if any.  Returns NULL if it can't expand it for any reason.
  437. X    **/
  438. X
  439. X    char name[2*NLEN], address[2*NLEN], domain[2*NLEN];
  440. X    char *match_and_expand_domain();
  441. X
  442. X    if (domainfd == NULL) return(NULL);    /* no file present! */
  443. X
  444. X    if (explode(buffer, name, address, domain)) 
  445. X      return( match_and_expand_domain(domain, name, address) );
  446. X    else {    /* invalid format - not "user@host.domain" */
  447. X      dprint1(3, 
  448. X         "Invalid format for domain expansion: %s (expand_domain)\n", 
  449. X           buffer);
  450. X      return(NULL);
  451. X    }
  452. X}    
  453. X
  454. Xint
  455. Xexplode(buffer, name, address, domain)
  456. Xchar *buffer, *name, *address, *domain;
  457. X{
  458. X    /** Break buffer, if in format name@machine.domain, into the
  459. X        component parts, otherwise return ZERO and don't worry
  460. X        about the values of the parameters!
  461. X    **/
  462. X    
  463. X    register int i, j = 0;
  464. X
  465. X    /** First get the name... **/
  466. X
  467. X    for (i=0; buffer[i] != '@'; i++) {
  468. X      if (! isalnum(buffer[i]) && ! okay_others(buffer[i]) && ! 
  469. X        special_chars(buffer[i]))
  470. X        return(0);            /* invalid character in string! */
  471. X      name[i] = buffer[i];
  472. X    }
  473. X
  474. X    name[i++] = '\0';
  475. X
  476. X    /** now let's get the machinename **/
  477. X
  478. X    while (buffer[i] != '.') {
  479. X      if (! isalnum(buffer[i]) && ! okay_others(buffer[i]))
  480. X         return(0);            /* invalid character in string! */
  481. X      address[j++] = buffer[i++];
  482. X    }
  483. X    address[j] = '\0';
  484. X
  485. X    j = 0;
  486. X
  487. X    /** finally let's get the domain information (there better be some!) **/
  488. X
  489. X    while (buffer[i] != '\0') {
  490. X      if (! isalnum(buffer[i]) && ! okay_others(buffer[i]) && 
  491. X            buffer[i] != '.')
  492. X        return(0);              /* an you fail again, bozo! */
  493. X      domain[j++] = toupper(buffer[i]);
  494. X      i++;
  495. X    }
  496. X
  497. X    domain[j] = '\0';
  498. X    
  499. X    return(j);        /* if j == 0 there's no domain info! */
  500. X}
  501. X        
  502. Xchar *match_and_expand_domain(domain, name, machine)
  503. Xchar *domain, *name, *machine;
  504. X{
  505. X    /** Given the domain, try to find it in the domain file and
  506. X           if found expand the entry and return the result as a 
  507. X        character string...
  508. X    **/
  509. X
  510. X    static char address[SLEN];
  511. X    char   buffer[SLEN], domainbuff[NLEN];
  512. X    char   field1[2*NLEN], field2[2*NLEN], field3[2*NLEN];
  513. X    char   *path, *template, *expanded, *mydomain, *strtok();
  514. X    int    matched = 0, in_percent = 0;
  515. X    register int i, j = 0;
  516. X
  517. X    address[j] = '\0';
  518. X
  519. X    domainbuff[0] = '\0';
  520. X    mydomain = (char *) domainbuff;            /* set up buffer etc */
  521. X
  522. X    do { 
  523. X      rewind(domainfd);                   /* back to ground zero! */
  524. X
  525. X      if (strlen(mydomain) > 0) {           /* already in a domain! */
  526. X        mydomain++;                       /* skip leading '.' */
  527. X        while (*mydomain != '.' && *mydomain != ',') 
  528. X          mydomain++;                   /* next character   */
  529. X        if (*mydomain == ',')
  530. X          return (NULL);                /* didn't find domain!  */
  531. X      }
  532. X      else
  533. X        sprintf(mydomain, "%s,", domain);        /* match ENTIRELY! */
  534. X
  535. X    /* whip through file looking for the entry, please... */
  536. X
  537. X    while (fgets(buffer, SLEN, domainfd) != NULL) {
  538. X      if (buffer[0] == '#')                  /* skip comments */
  539. X        continue;
  540. X      if (strncmp(buffer, mydomain, strlen(mydomain)) == 0) { /* match? */
  541. X         matched++;    /* Gotcha!  Remember this momentous event! */
  542. X         break;
  543. X      }
  544. X    }
  545. X
  546. X    if (! matched) 
  547. X       continue;        /* Nothing.  Not a sausage!  Step through! */
  548. X
  549. X    /** We've matched the domain! **/
  550. X
  551. X    no_ret(buffer);
  552. X
  553. X    (void) strtok(buffer, ",");    /* skip the domain info */
  554. X
  555. X    strcpy(field1, strtok(NULL, ","));    /* fun         */
  556. X    strcpy(field2, strtok(NULL, ","));    /*    stuff     */
  557. X    strcpy(field3, strtok(NULL, ","));    /*       eh?    */
  558. X    
  559. X    path = (char *) NULL;
  560. X
  561. X    /* now we merely need to figure out what permutation this is! */
  562. X
  563. X    if (field3 == NULL || strlen(field3) == 0)
  564. X      if (field2 == NULL || strlen(field2) == 0)
  565. X        template = (char *) field1;
  566. X      else {
  567. X        path     = (char *) field1;
  568. X        template = (char *) field2;
  569. X      }
  570. X    else {
  571. X      dprint1(2,"Domain info for %s from file broken into THREE fields!!\n",
  572. X           domain);
  573. X      dprint3(2, "-> %s\n-> %s\n-> %s\n", field1, field2, field3);
  574. X      error1("Warning: domain %s uses a defunct field!!", domain);
  575. X      sleep(2);
  576. X      path     = (char *) field1;
  577. X      template = (char *) field3;
  578. X    }
  579. X
  580. X    if (strlen(path) > 0 && path[0] == '>') 
  581. X       path++;    /* skip the '>' character, okay? */
  582. X
  583. X    j = 0;             /* address is zero, right now, right?? */
  584. X    address[j] = '\0';          /* make sure string is too! */
  585. X
  586. X    for (i=0; i < strlen(template); i++) {
  587. X      if (template[i] == '%') {
  588. X        if (! in_percent)               /* just hit a NEW percent! */
  589. X          in_percent = 1;
  590. X        else {          /* just another percent sign on the wall... */
  591. X          address[j++] = '%';
  592. X          address[j] = '\0';             /* ALWAYS NULL terminate */
  593. X          in_percent = 0;
  594. X        }
  595. X      }
  596. X      else if (in_percent) {           /* Hey! a real command string */
  597. X        in_percent = 0;
  598. X        switch (template[i]) {
  599. X          case USERNAME: strcat(address, name);        break;
  600. X          case HOSTNAME: strcat(address, machine);        break;
  601. X          case FULLNAME: strcat(address, machine);
  602. X                 strcat(address, domain);        break;
  603. X          case NPATH   : 
  604. X
  605. X         if ((expanded = find_path_to(machine, FALSE)) == NULL) {
  606. X            dprint2(3,"\nCouldn't expand system path '%s' (%s)\n\n",
  607. X                machine, "domains");
  608. X                error1("Couldn't find a path to %s!", machine);
  609. X                sleep(2);
  610. X                return(NULL);    /* failed!! */
  611. X             }
  612. X             strcat(address, expanded);    /* isn't this fun??? */
  613. X
  614. X             break;
  615. X
  616. X          case PPATH   : 
  617. X
  618. X         if ((expanded = find_path_to(path, FALSE)) == NULL) {
  619. X            dprint2(3,"\nCouldn't expand system path '%s' (%s)\n\n",
  620. X                path, "domains");
  621. X                error1("I Couldn't find a path to %s!", path);
  622. X                sleep(2);
  623. X                return(NULL);    /* failed!! */
  624. X             }
  625. X             strcat(address, expanded);    /* isn't this fun??? */
  626. X
  627. X             break;
  628. X
  629. X          case OBSOLETE:    /* fall through.. */
  630. X          default      : dprint2(1,
  631. X         "\nError: Bad sequence in template file for domain '%s': %%%c\n\n",
  632. X            domain, template[i]);
  633. X        }
  634. X        j = strlen(address);
  635. X      }
  636. X      else {
  637. X        address[j++] = template[i];
  638. X        address[j] = '\0';            /* null terminate */
  639. X      }
  640. X    }    
  641. X
  642. X    address[j] = '\0';
  643. X
  644. X    } while (strlen(address) < 1);
  645. X
  646. X    return( (char *) address);
  647. X}
  648. END_OF_src/domains.c
  649. if test 7773 -ne `wc -c <src/domains.c`; then
  650.     echo shar: \"src/domains.c\" unpacked with wrong size!?
  651. fi
  652. # end of overwriting check
  653. fi
  654. echo shar: Extracting \"src/initialize.c\" \(8292 characters\)
  655. if test -f src/initialize.c ; then 
  656.   echo shar: Will not over-write existing file \"src/initialize.c\"
  657. else
  658. sed "s/^X//" >src/initialize.c <<'END_OF_src/initialize.c'
  659. X/**        initialize.c        **/
  660. X
  661. X/***** Initialize - read in all the defaults etc etc 
  662. X       (C) Copyright 1985 Dave Taylor
  663. X*****/
  664. X
  665. X#include "headers.h"
  666. X
  667. X#ifdef BSD
  668. X#  include <sgtty.h>
  669. X#else
  670. X#  include <termio.h>
  671. X#endif
  672. X
  673. X#include <pwd.h>
  674. X
  675. X#ifdef BSD
  676. X#  include <sys/time.h>
  677. X#else
  678. X#  include <time.h>
  679. X#endif
  680. X
  681. X#include <signal.h>
  682. X#include <ctype.h>
  683. X#include <errno.h>
  684. X
  685. X#ifdef BSD
  686. X#undef toupper
  687. X#undef tolower
  688. X#endif
  689. X
  690. Xextern int errno;        /* system error number on failure */
  691. X
  692. Xchar *error_name(), *error_description();
  693. X
  694. Xchar *expand_logname(), *getenv(), *getlogin(), *strcpy(), *strcat();
  695. Xunsigned short getgid(), getuid(); 
  696. Xvoid exit();
  697. X
  698. Xstruct   header_rec *malloc();
  699. X
  700. Xinitialize(initscreen_too)
  701. Xint initscreen_too;
  702. X{
  703. X    /** initialize the whole ball of wax.   If "initscreen_too" then
  704. X        call init_screen where appropriate..
  705. X    **/
  706. X    struct passwd *pass, *getpwnam();
  707. X
  708. X    register int i, j; 
  709. X    int      quit_signal(), term_signal(), ill_signal(),
  710. X         fpe_signal(),  bus_signal(),  segv_signal(),
  711. X             alarm_signal(), pipe_signal();
  712. X    char     buffer[SLEN], *cp;
  713. X    
  714. X
  715. X    userid  = getuid();
  716. X    groupid = getgid();    
  717. X
  718. X    strcpy(home,((cp = getenv("HOME")) == NULL)? "" : cp);
  719. X    strcpy(shell,((cp = getenv("SHELL")) == NULL)? "" : cp);
  720. X    strcpy(pager,((cp = getenv("PAGER")) == NULL)? default_pager : cp);
  721. X
  722. X    if (debug) {        /* setup for dprintf statements! */
  723. X      char newfname[SLEN], filename[SLEN];
  724. X
  725. X      sprintf(filename, "%s/%s", home, DEBUG);
  726. X      if (access(filename, ACCESS_EXISTS) == 0) {    /* already one! */
  727. X        sprintf(newfname,"%s/%s", home, OLDEBUG);
  728. X        (void) link(filename, newfname);
  729. X      }
  730. X
  731. X      /* Note what we just did up there: we always save the old
  732. X         version of the debug file as OLDEBUG, so users can mail
  733. X         copies of bug files without trashing 'em by starting up
  734. X         the mailer.  Dumb, subtle, but easy enough to do!
  735. X       */
  736. X
  737. X      if ((debugfile = fopen(filename, "w")) == NULL) {
  738. X        debug = 0;    /* otherwise 'leave' will try to log! */
  739. X        leave(fprintf(stderr,"Could not open file %s for debug output!\n",
  740. X          filename));
  741. X      }
  742. X      chown(filename, userid, groupid); /* file owned by user */
  743. X
  744. X      fprintf(debugfile, "Debug output of the ELM program.  Version %s\n\n",
  745. X          VERSION);
  746. X    }
  747. X
  748. X    if (initscreen_too)    /* don't set up unless we need to! */
  749. X      InitScreen();
  750. X
  751. X    if (debug < 2) {    /* otherwise let the system trap 'em! */
  752. X      signal(SIGINT,  SIG_IGN);
  753. X      signal(SIGQUIT, quit_signal);        /* Quit signal                 */
  754. X      signal(SIGTERM, term_signal);     /* Terminate signal         */
  755. X      signal(SIGILL,  ill_signal);        /* Illegal instruction      */
  756. X      signal(SIGFPE,  fpe_signal);        /* Floating point exception */
  757. X      signal(SIGBUS,  bus_signal);        /* Bus error              */
  758. X      signal(SIGSEGV, segv_signal);        /* Segmentation Violation   */
  759. X    }
  760. X    
  761. X    signal(SIGALRM, alarm_signal);        /* Process Timer Alarm        */
  762. X    signal(SIGPIPE, pipe_signal);        /* Illegal Pipe Operation   */
  763. X
  764. X    get_term_chars();
  765. X    
  766. X    gethostname(hostname, sizeof(hostname));
  767. X
  768. X#ifdef BSD
  769. X    if ((cp = getenv("USER")) == NULL)
  770. X#else
  771. X    if ((cp = getenv("LOGNAME")) == NULL)
  772. X#endif
  773. X      if ((cp = getlogin()) == NULL)
  774. X        cuserid(username);
  775. X      else
  776. X        strcpy(username, cp);
  777. X    else
  778. X      strcpy(username, cp);
  779. X
  780. X    /* now let's get the full username.. */
  781. X
  782. X    if ((pass = getpwnam(username)) == NULL) {
  783. X      error("Couldn't read password entry??");
  784. X      strcpy(full_username, username);
  785. X    }
  786. X    else {
  787. X      /* fix for this section from Don Joslyn of Nova University */
  788. X      for (i=0,j=0; pass->pw_gecos[i] != '\0' && pass->pw_gecos[i] != ',';
  789. X           i++)
  790. X          if (pass->pw_gecos[i] == '&') {
  791. X            full_username[j] = '\0';
  792. X            strcat(full_username, expand_logname());
  793. X            j = strlen(full_username);
  794. X          }
  795. X          else
  796. X            full_username[j++] = pass->pw_gecos[i];
  797. X      full_username[j] = '\0'; 
  798. X    }
  799. X
  800. X    if ((cp = getenv("EDITOR")) == NULL)
  801. X      strcpy(editor,default_editor);
  802. X    else
  803. X      strcpy(editor, cp);
  804. X    strcpy(alternative_editor, editor);    /* this one can't be changed! */
  805. X
  806. X    if (! mail_only) {
  807. X      mailbox[0] = '\0';
  808. X      strcpy(prefixchars, "> ");     /* default message prefix */
  809. X      sprintf(calendar_file, "%s/%s", home, dflt_calendar_file);
  810. X    }
  811. X
  812. X    local_signature[0] = remote_signature[0] = '\0';    /* NULL! */
  813. X
  814. X    read_rc_file();        /* reading the .elmrc next... */
  815. X
  816. X    /** now try to expand the specified filename... **/
  817. X
  818. X    if (strlen(infile) > 0) {
  819. X      (void) expand_filename(infile);
  820. X      if ((errno = can_access(infile, READ_ACCESS))) {
  821. X        dprint2(1,"Error: given file %s as mailbox - unreadable (%s)!\n", 
  822. X             infile, error_name(errno));
  823. X        fprintf(stderr,"Can't open mailbox '%s' for reading!\n", infile);
  824. X        exit(1);
  825. X      }
  826. X    }
  827. X
  828. X    /** check to see if the user has defined a LINES or COLUMNS
  829. X        value different to that in the termcap entry (for
  830. X        windowing systems, of course!) **/
  831. X
  832. X    ScreenSize(&LINES, &COLUMNS);
  833. X
  834. X    if ((cp = getenv("LINES")) != NULL && isdigit(*cp)) {
  835. X      sscanf(cp, "%d", &LINES);
  836. X      LINES -= 1;    /* kludge for HP Window system? ... */
  837. X    }
  838. X
  839. X    if ((cp = getenv("COLUMNS")) != NULL && isdigit(*cp))
  840. X      sscanf(cp, "%d", &COLUMNS);
  841. X
  842. X    /** fix the shell if needed **/
  843. X
  844. X    if (shell[0] != '/') {
  845. X       sprintf(buffer, "/bin/%s", shell);
  846. X       strcpy(shell, buffer);
  847. X    }
  848. X
  849. X    if (! mail_only) {
  850. X      mailbox_defined = (mailbox[0] != '\0'); 
  851. X
  852. X      /* get the cursor control keys... */
  853. X
  854. X      cursor_control = FALSE;
  855. X
  856. X      if ((cp = return_value_of("ku")) != NULL)
  857. X       if (strlen(cp) == 2) {
  858. X        strcpy(up, cp);
  859. X        if ((cp = return_value_of("kd")) == NULL)
  860. X          cursor_control = FALSE;
  861. X        else if (strlen(cp) != 2)
  862. X          cursor_control = FALSE;
  863. X        else {
  864. X          strcpy(down, cp);
  865. X          cursor_control = TRUE;
  866. X          transmit_functions(ON);
  867. X        }
  868. X      }
  869. X
  870. X      strcpy(start_highlight, "->");
  871. X      end_highlight[0] = '\0';
  872. X
  873. X      if (!arrow_cursor) {    /* try to use inverse bar instead */
  874. X        if ((cp = return_value_of("so")) != NULL) {
  875. X          strcpy(start_highlight, cp);
  876. X          if ((cp = return_value_of("se")) == NULL)
  877. X            strcpy(start_highlight, "->");
  878. X          else {
  879. X            strcpy(end_highlight, cp);
  880. X            has_highlighting = TRUE;
  881. X          }
  882. X        }
  883. X      }
  884. X    }
  885. X
  886. X    /** allocate the first KLICK headers... **/
  887. X
  888. X    if ((header_table = malloc(KLICK*sizeof(struct header_rec))) == NULL) {
  889. X       fprintf(stderr,"\n\r\n\rCouldn't allocate initial headers!\n\r\n");
  890. X       leave();
  891. X    }
  892. X    max_headers = KLICK;        /* we have those preallocated */
  893. X
  894. X    /** now cruise along... **/
  895. X
  896. X    if (! mail_only) {
  897. X      if (mini_menu)
  898. X        headers_per_page = LINES - 13;
  899. X      else
  900. X        headers_per_page = LINES -  8;    /* 5 more headers! */
  901. X
  902. X      newmbox(1,FALSE, TRUE);    /* read in the mailbox! */
  903. X    }
  904. X
  905. X    dprint0(2,"\n-- end of initialization phase --\n");
  906. X
  907. X    dprint3(2,"\thostname = %s\n\tusername = %s\n\tfull_username = \"%s\"\n",
  908. X             hostname, username, full_username);
  909. X
  910. X    dprint3(2,"\thome = %s\n\teditor = %s\n\tmailbox = %s\n",
  911. X         home, editor, mailbox);
  912. X
  913. X    dprint3(2,"\tinfile = %s\n\tfolder-dir = %s\n\tprintout = \"%s\"\n",
  914. X         infile, folders, printout);
  915. X    
  916. X    dprint3(2,"\tsavefile = %s\n\tprefix = \"%s\"\n\tshell = %s\n",
  917. X        savefile, prefixchars, shell);
  918. X    
  919. X    if (signature)
  920. X      dprint2(2,"\tlocal-signature = %s\n\tremote-signature = %s\n",
  921. X            local_signature, remote_signature);
  922. X
  923. X    dprint0(1,"-- beginning execution phase --\n\n");
  924. X}
  925. X
  926. Xget_term_chars()
  927. X{
  928. X    /** This routine sucks out the special terminal characters
  929. X        ERASE and KILL for use in the input routine.  The meaning 
  930. X            of the characters are (dare I say it?) fairly obvious... **/
  931. X
  932. X#ifdef BSD
  933. X    struct sgttyb term_buffer;
  934. X
  935. X# define TCGETA    TIOCGETP
  936. X
  937. X#else 
  938. X    struct termio term_buffer;
  939. X#endif
  940. X
  941. X    if (ioctl(STANDARD_INPUT, TCGETA, &term_buffer) == -1) {
  942. X      dprint1(1,"Error: %s encountered on ioctl call (get_term_chars)\n", 
  943. X           error_name(errno));
  944. X      /* set to defaults for terminal driver */
  945. X      backspace = BACKSPACE;
  946. X      kill_line = ctrl('U');
  947. X    }
  948. X    else {
  949. X#ifdef BSD
  950. X      backspace = term_buffer.sg_erase;
  951. X      kill_line = term_buffer.sg_kill;
  952. X#else
  953. X      backspace = term_buffer.c_cc[VERASE];
  954. X      kill_line = term_buffer.c_cc[VKILL];
  955. X#endif
  956. X    }
  957. X}
  958. X
  959. Xchar *expand_logname()
  960. X{
  961. X    /** Return logname in a nice format (for expanding "&" in the
  962. X        /etc/passwd file) **/
  963. X
  964. X    static char buffer[SLEN];
  965. X    register int i;
  966. X
  967. X    if (strlen(username) == 0)
  968. X      buffer[0] = '\0';
  969. X    else {
  970. X      buffer[0] = toupper(username[0]);
  971. X
  972. X      for (i=1; username[i] != '\0'; i++)
  973. X        buffer[i] = tolower(username[i]);
  974. X
  975. X      buffer[i] = '\0';
  976. X    }
  977. X
  978. X    return( (char *) buffer);    
  979. X}
  980. END_OF_src/initialize.c
  981. if test 8292 -ne `wc -c <src/initialize.c`; then
  982.     echo shar: \"src/initialize.c\" unpacked with wrong size!?
  983. fi
  984. # end of overwriting check
  985. fi
  986. echo shar: Extracting \"utils/fastmail.c\" \(8167 characters\)
  987. if test -f utils/fastmail.c ; then 
  988.   echo shar: Will not over-write existing file \"utils/fastmail.c\"
  989. else
  990. sed "s/^X//" >utils/fastmail.c <<'END_OF_utils/fastmail.c'
  991. X/**            fastmail.c            **/
  992. X
  993. X/** This program is specifically written for group mailing lists and
  994. X    such batch type mail processing.  It does NOT use aliases at all,
  995. X    it does NOT read the /etc/password file to find the From: name
  996. X    of the user and does NOT expand any addresses.  It is meant 
  997. X    purely as a front-end for either /bin/mail or /usr/lib/sendmail
  998. X    (according to what is available on the current system).
  999. X
  1000. X         **** This program should be used with CAUTION *****
  1001. X
  1002. X    (C) Copyright 1985 Dave Taylor
  1003. X**/
  1004. X
  1005. X/** The calling sequence for this program is:
  1006. X
  1007. X    fastmail {args}  filename full-email-address 
  1008. X
  1009. X   where args could be any (or all) of;
  1010. X
  1011. X       -b bcc-list        (Blind carbon copies to)
  1012. X       -c cc-list        (carbon copies to)
  1013. X       -d            (debug on)
  1014. X       -f from         (from name)
  1015. X       -r reply-to-address     (Reply-To:)
  1016. X       -s subject         (subject of message)
  1017. X**/
  1018. X
  1019. X#include <stdio.h>
  1020. X
  1021. X#ifdef BSD
  1022. X# ifdef BSD4.1
  1023. X#   include <time.h>
  1024. X#   include <sys/types.h>
  1025. X#   include <sys/timeb.h>
  1026. X# else
  1027. X#   include <sys/time.h>
  1028. X# endif
  1029. X#else
  1030. X#  include <time.h>
  1031. X#endif
  1032. X
  1033. X#include "defs.h"
  1034. X
  1035. Xstatic char ident[] = { WHAT_STRING };
  1036. X
  1037. X#define  binrmail    "/bin/rmail"
  1038. X#define  temphome    "/tmp/fastmail."
  1039. X
  1040. X#define DONE        0
  1041. X#define ERROR        -1
  1042. X
  1043. Xchar *optional_arg;            /* optional argument as we go */
  1044. Xint   opt_index;            /* argnum + 1 when we leave   */
  1045. X
  1046. Xchar *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
  1047. X          "Fri", "Sat", "" };
  1048. X
  1049. Xchar *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  1050. X          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
  1051. X
  1052. Xchar *get_arpa_date();
  1053. X
  1054. X#ifdef BSD
  1055. X  char *timezone();
  1056. X#else
  1057. X  extern char *tzname[];
  1058. X#endif
  1059. X
  1060. Xmain(argc, argv)
  1061. Xint argc;
  1062. Xchar *argv[];
  1063. X{
  1064. X
  1065. X    FILE *tempfile;
  1066. X    char hostname[NLEN], username[NLEN], from_string[SLEN], subject[SLEN];
  1067. X    char filename[SLEN], tempfilename[SLEN], command_buffer[256];
  1068. X    char replyto[SLEN], cc_list[SLEN], bcc_list[SLEN], to_list[SLEN];
  1069. X    int  c, sendmail_available, debug = 0;
  1070. X
  1071. X    replyto[0] = '\0';
  1072. X    cc_list[0] = '\0';
  1073. X    bcc_list[0] = '\0';
  1074. X
  1075. X    while ((c = get_options(argc, argv, "b:c:df:r:s:")) > 0) {
  1076. X      switch (c) {
  1077. X        case 'b' : strcpy(bcc_list, optional_arg);        break;
  1078. X        case 'c' : strcpy(cc_list, optional_arg);        break;
  1079. X        case 'd' : debug++;                    break;    
  1080. X        case 'f' : strcpy(from_string, optional_arg);    break;
  1081. X        case 'r' : strcpy(replyto, optional_arg);        break;
  1082. X        case 's' : strcpy(subject, optional_arg);        break;
  1083. X       }
  1084. X    }    
  1085. X
  1086. X    if (c == ERROR) {
  1087. X      fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
  1088. X      fprintf(stderr, "   where {args} can be;\n");
  1089. X      fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n");
  1090. X      fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
  1091. X      exit(1);
  1092. X    }
  1093. X
  1094. X    if (opt_index > argc) {
  1095. X      fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
  1096. X      fprintf(stderr, "   where {args} can be;\n");
  1097. X      fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n");
  1098. X      fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
  1099. X      exit(1);
  1100. X    }
  1101. X
  1102. X    strcpy(filename, argv[opt_index++]);
  1103. X
  1104. X    if (opt_index > argc) {
  1105. X      fprintf(stderr,"Usage: fastmail {args} filename address(es)\n");
  1106. X      fprintf(stderr, "   where {args} can be;\n");
  1107. X      fprintf(stderr,"\t-b bcc-list\n\t-c cc-list\n\t-d\n\t-f from-name\n");
  1108. X      fprintf(stderr, "\t-r reply-to\n\t-s subject\n\n");
  1109. X      exit(1);
  1110. X    }
  1111. X
  1112. X    gethostname(hostname, sizeof(hostname));
  1113. X    strcpy(username, getlogin());
  1114. X    if (strlen(username) == 0)
  1115. X      cuserid(username);
  1116. X
  1117. X    if (access(filename, READ_ACCESS) == -1)
  1118. X      exit(fprintf(stderr, "Error: can't find file %s!\n", filename));
  1119. X
  1120. X    sprintf(tempfilename, "%s%d", temphome, getpid());
  1121. X
  1122. X    if ((tempfile = fopen(tempfilename, "w")) == NULL)
  1123. X      exit(fprintf(stderr, "Couldn't open temp file %s\n", tempfilename));
  1124. X
  1125. X    if (strlen(from_string) > 0)
  1126. X      fprintf(tempfile, "From: %s!%s (%s)\n", 
  1127. X          hostname, username, from_string);
  1128. X    else
  1129. X      fprintf(tempfile, "From: %s!%s\n", hostname, username);
  1130. X
  1131. X    fprintf(tempfile, "Date: %s\n", get_arpa_date());
  1132. X
  1133. X    if (strlen(subject) > 0)
  1134. X      fprintf(tempfile, "Subject: %s\n", subject);
  1135. X
  1136. X    if (strlen(replyto) > 0)
  1137. X      fprintf(tempfile, "Reply-To: %s\n", replyto);
  1138. X
  1139. X    while (opt_index < argc) 
  1140. X          sprintf(to_list, "%s%s%s", to_list, (strlen(to_list) > 0? ", ":""), 
  1141. X          argv[opt_index++]);
  1142. X    
  1143. X    fprintf(tempfile, "To: %s\n", to_list);
  1144. X
  1145. X    if (strlen(cc_list) > 0)
  1146. X      fprintf(tempfile, "Cc: %s\n", cc_list);
  1147. X
  1148. X    if (strlen(bcc_list) > 0)
  1149. X      fprintf(tempfile, "Bcc: %s\n", bcc_list);    /* trust xport */
  1150. X
  1151. X    fprintf(tempfile, "X-Mailer: fastmail [version %s]\n", VERSION);
  1152. X    fprintf(tempfile, "\n");
  1153. X
  1154. X    fclose(tempfile);
  1155. X
  1156. X    /** now we'll cat both files to /bin/rmail or sendmail... **/
  1157. X
  1158. X    sendmail_available = (access(sendmail, EXECUTE_ACCESS) != -1);
  1159. X
  1160. X    printf("Mailing to %s%s%s%s%s [via %s]\n", to_list,
  1161. X        (strlen(cc_list) > 0 ? " ":""), cc_list,
  1162. X        (strlen(bcc_list) > 0 ? " ":""), bcc_list,
  1163. X        sendmail_available? "sendmail" : "rmail");
  1164. X
  1165. X    sprintf(command_buffer, "cat %s %s | %s '%s %s %s'", 
  1166. X        tempfilename, filename, 
  1167. X            sendmail_available? sendmail : mailer,
  1168. X        to_list, cc_list, bcc_list);
  1169. X
  1170. X    if (debug)
  1171. X      printf("%s\n", command_buffer);
  1172. X
  1173. X    system(command_buffer);
  1174. X
  1175. X    unlink(tempfilename);
  1176. X}
  1177. X
  1178. X
  1179. Xchar *get_arpa_date()
  1180. X{
  1181. X    /** returns an ARPA standard date.  The format for the date
  1182. X        according to DARPA document RFC-822 is exemplified by;
  1183. X
  1184. X                     Mon, 12 Aug 85 6:29:08 MST
  1185. X
  1186. X    **/
  1187. X
  1188. X    static char buffer[SLEN];    /* static character buffer       */
  1189. X    struct tm *the_time,        /* Time structure, see CTIME(3C) */
  1190. X          *localtime();
  1191. X    long       junk;        /* time in seconds....         */
  1192. X#ifdef BSD
  1193. X#  ifdef BSD4.1
  1194. X    struct timeb loc_time;    /* of course this is different! */
  1195. X#  else
  1196. X    struct  timeval  time_val;        
  1197. X    struct  timezone time_zone;
  1198. X#  endif
  1199. X#endif
  1200. X
  1201. X#ifdef BSD
  1202. X#  ifdef BSD4.1
  1203. X    junk = (long) time((long *) 0);
  1204. X    ftime(&loc_time);
  1205. X#  else
  1206. X    gettimeofday(&time_val, &time_zone);
  1207. X    junk = time_val.tv_sec;
  1208. X#  endif
  1209. X#else
  1210. X    junk = time(0);    /* this must be here for it to work! */
  1211. X#endif
  1212. X    the_time = localtime(&junk);
  1213. X
  1214. X    sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
  1215. X      arpa_dayname[the_time->tm_wday],
  1216. X      the_time->tm_mday % 32,
  1217. X      arpa_monname[the_time->tm_mon],
  1218. X      the_time->tm_year % 100,
  1219. X      the_time->tm_hour % 24,
  1220. X      the_time->tm_min  % 61,
  1221. X      the_time->tm_sec  % 61,
  1222. X#ifdef BSD
  1223. X#  ifdef BSD4.1
  1224. X      timezone(loc_time.time_zone, the_time->tz_isdst));
  1225. X#  else
  1226. X      timezone(time_zone.tz_minuteswest, time_zone.tz_dsttime));
  1227. X#  endif
  1228. X#else
  1229. X      tzname[the_time->tm_isdst]);
  1230. X#endif
  1231. X    
  1232. X    return( (char *) buffer);
  1233. X}
  1234. X
  1235. X/** Starting argument parsing routine.   
  1236. X
  1237. X    Called as "get_options(argc, argv, options)" where options is a string
  1238. X    of the form "abc:d" indicating that 'a' 'b' and 'd' are flags and
  1239. X    'c' is a flag with a trailing argument.   Optional arguments are
  1240. X    returned in the external char * variable "optional_arg", and the
  1241. X    external int "opt_index" is set to the first entry in the argv list
  1242. X    that wasn't processed (ie after the flags). 
  1243. X
  1244. X    For example, the C compiler would have something of the form 
  1245. X    getopt(argc, argv, "Oo:l:") to allow "cc -O -o output -l lib file.c"
  1246. X
  1247. X    (C) Copyright 1986, Dave Taylor
  1248. X**/
  1249. X
  1250. Xint  _indx = 1, _argnum = 1;
  1251. X
  1252. Xint
  1253. Xget_options(argc, argv, options)
  1254. Xint argc;
  1255. Xchar *argv[], *options;
  1256. X{
  1257. X    /** Returns the character argument next, and optionally instantiates 
  1258. X        "argument" to the argument associated with the particular option 
  1259. X    **/
  1260. X    
  1261. X    char       *word, *strchr();
  1262. X
  1263. X    if (_indx >= strlen(argv[_argnum])) {
  1264. X      _argnum++;
  1265. X      _indx = 1;        /* zeroeth char is '-' */
  1266. X    }
  1267. X
  1268. X    if (_argnum >= argc) {
  1269. X      opt_index = argc;
  1270. X      return(DONE);
  1271. X    }
  1272. X    
  1273. X    if (argv[_argnum][0] != '-') {
  1274. X      opt_index = _argnum;
  1275. X      return(DONE);
  1276. X    }
  1277. X
  1278. X        word = strchr(options, argv[_argnum][_indx++]);
  1279. X
  1280. X    if (strlen(word) == 0) 
  1281. X      return(ERROR);
  1282. X    
  1283. X    if (word[1] == ':') {
  1284. X
  1285. X      /** Two possibilities - either tailing end of this argument or the 
  1286. X          next argument in the list **/
  1287. X
  1288. X      if (_indx < strlen(argv[_argnum])) { /* first possibility */
  1289. X        optional_arg = (char *) (argv[_argnum] + _indx);
  1290. X        _argnum++;
  1291. X        _indx = 1;
  1292. X      }
  1293. X      else {                /* second choice     */
  1294. X        if (++_argnum >= argc) 
  1295. X          return(ERROR);            /* no argument!!     */
  1296. X
  1297. X        optional_arg = (char *) argv[_argnum++];
  1298. X        _indx = 1;
  1299. X      }
  1300. X    }
  1301. X
  1302. X    return((int) word[0]);
  1303. X}
  1304. END_OF_utils/fastmail.c
  1305. if test 8167 -ne `wc -c <utils/fastmail.c`; then
  1306.     echo shar: \"utils/fastmail.c\" unpacked with wrong size!?
  1307. fi
  1308. # end of overwriting check
  1309. fi
  1310. echo shar: Extracting \"utils/newmail.c\" \(7989 characters\)
  1311. if test -f utils/newmail.c ; then 
  1312.   echo shar: Will not over-write existing file \"utils/newmail.c\"
  1313. else
  1314. sed "s/^X//" >utils/newmail.c <<'END_OF_utils/newmail.c'
  1315. X/**            newmail.c            **/
  1316. X
  1317. X/** Keep track of the mail for the current user...if new mail
  1318. X    arrives, output a line of the form;
  1319. X
  1320. X       New mail from <name> - <subject>
  1321. X
  1322. X    where <name> is either the persons full name, or machine!login.
  1323. X    If there is no subject, it will say.
  1324. X
  1325. X    Added: you can specify a file other than the mailbox to keep
  1326. X    track of - if an argument is given, the program will try
  1327. X    to use it as a filename...
  1328. X
  1329. X    Also, the program will quit when you log off of the machine.
  1330. X
  1331. X    (C) Copyright 1986, Dave Taylor
  1332. X**/
  1333. X
  1334. X#include <stdio.h>
  1335. X#include <sys/types.h>
  1336. X#include <sys/stat.h>
  1337. X
  1338. X#include "defs.h"
  1339. X
  1340. X#ifdef AUTO_BACKGROUND
  1341. X#include <signal.h>    /* background jobs ignore some signals... */
  1342. X#endif
  1343. X
  1344. Xstatic char ident[] = { WHAT_STRING };
  1345. X
  1346. X#define LINEFEED    (char) 10
  1347. X#define BEGINNING    0            /* seek fseek(3S) */
  1348. X#define SLEEP_TIME    60        
  1349. X
  1350. X#define NO_SUBJECT    "(No Subject Specified)"
  1351. X
  1352. XFILE *mailfile;
  1353. X
  1354. Xlong  bytes();
  1355. X
  1356. Xmain(argc, argv)
  1357. Xint argc;
  1358. Xchar *argv[];
  1359. X{
  1360. X    char filename[LONG_SLEN];
  1361. X    long size, newsize;
  1362. X
  1363. X    if (argc > 2) 
  1364. X      fprintf(stderr, "Usage: %s [filename] &\n", argv[0]);
  1365. X    else if (argc == 2) {
  1366. X      strcpy(filename, argv[1]);
  1367. X      if (access(filename, ACCESS_EXISTS) == -1) {
  1368. X        fprintf(stderr,"%s: Can't open file %s to keep track of!\n",
  1369. X            argv[0], filename);
  1370. X        exit(1);
  1371. X      }
  1372. X    }
  1373. X    else
  1374. X      sprintf(filename,"%s%s",mailhome, getlogin());
  1375. X
  1376. X#ifdef AUTO_BACKGROUND
  1377. X    if (fork())        /* automatically puts this task in background! */
  1378. X      exit(0);
  1379. X
  1380. X    signal(SIGINT, SIG_IGN);
  1381. X    signal(SIGQUIT, SIG_IGN);
  1382. X    signal(SIGHUP,  SIG_DFL);    /* so we exit when logged out */
  1383. X#endif
  1384. X
  1385. X    size = bytes(filename);
  1386. X
  1387. X    mailfile = (FILE *) NULL;
  1388. X
  1389. X    while (1) {
  1390. X    
  1391. X#ifndef AUTO_BACKGROUND        /* won't work if we're nested this deep! */
  1392. X      if (getppid() == 1)     /* we've lost our shell! */
  1393. X        exit();
  1394. X#endif
  1395. X    if (! isatty(1))    /* we're not sending output to a tty any more */
  1396. X       exit();
  1397. X    
  1398. X    /** Note the lack of error checking on the fopen() (Philip Peake
  1399. X        did!) - this is okay since if it fails we don't have any 
  1400. X        mail and we can sleep(60) and try again later... 
  1401. X    **/
  1402. X
  1403. X      if (mailfile == (FILE *) NULL) 
  1404. X        mailfile = fopen(filename,"r");
  1405. X
  1406. X      if ((newsize = bytes(filename)) > size) {    /* new mail */
  1407. X        fseek(mailfile, size, BEGINNING); /* skip all current mail */
  1408. X        size = newsize;
  1409. X        printf("\n\r");    /* blank lines surrounding message */
  1410. X        read_headers();
  1411. X        printf("\n\r");
  1412. X      }
  1413. X      else if (newsize != size) {
  1414. X        size = newsize;         /* mail's been removed... */
  1415. X        (void) fclose(mailfile);    /* close it and ...       */
  1416. X        mailfile = (FILE *) NULL;    /* let's reopen the file  */
  1417. X      }
  1418. X
  1419. X      sleep(SLEEP_TIME);
  1420. X    }
  1421. X}
  1422. X
  1423. Xint
  1424. Xread_headers()
  1425. X{
  1426. X    /** read the headers, output as found **/
  1427. X
  1428. X    char buffer[LONG_SLEN], from_whom[SLEN], subject[SLEN];
  1429. X    register int subj = 0, in_header = 1, count = 0, priority=0;
  1430. X
  1431. X    while (fgets(buffer, LONG_SLEN, mailfile) != NULL) {
  1432. X      if (first_word(buffer,"From ")) {
  1433. X        if (real_from(buffer, from_whom)) {
  1434. X          subj = 0;
  1435. X          in_header = 1;
  1436. X        }
  1437. X      }
  1438. X      else if (in_header) {
  1439. X        if (first_word(buffer,">From")) 
  1440. X          forwarded(buffer, from_whom); /* return address */
  1441. X        else if (first_word(buffer,"Subject:") ||
  1442. X             first_word(buffer,"Re:")) {
  1443. X          if (! subj++) {
  1444. X            remove_first_word(buffer);
  1445. X        strcpy(subject, buffer);
  1446. X          }
  1447. X        }
  1448. X        else if (first_word(buffer,"Priority:")) 
  1449. X          priority++;
  1450. X        else if (first_word(buffer,"From:")) 
  1451. X          parse_arpa_from(buffer, from_whom);
  1452. X        else if (buffer[0] == LINEFEED) {
  1453. X          in_header = 0;    /* in body of message! */
  1454. X          show_header(priority, from_whom, subject);
  1455. X          from_whom[0] = 0;
  1456. X          subject[0] = 0;
  1457. X          count++;
  1458. X        }
  1459. X      }
  1460. X    }
  1461. X    return(count);
  1462. X}
  1463. X
  1464. Xint
  1465. Xreal_from(buffer, who)
  1466. Xchar *buffer, *who;
  1467. X{
  1468. X    /***** returns true iff 's' has the seven 'from' fields,
  1469. X           initializing the who to the sender *****/
  1470. X
  1471. X    char junk[80];
  1472. X
  1473. X    junk[0] = '\0';
  1474. X    sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
  1475. X                who, junk);
  1476. X    return(junk[0] != '\0');
  1477. X}
  1478. X
  1479. Xforwarded(buffer, who)
  1480. Xchar *buffer, *who;
  1481. X{
  1482. X    /** change 'from' and date fields to reflect the ORIGINATOR of 
  1483. X        the message by iteratively parsing the >From fields... **/
  1484. X
  1485. X    char machine[80], buff[80];
  1486. X
  1487. X    machine[0] = '\0';
  1488. X    sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
  1489. X                who, machine);
  1490. X
  1491. X    if (machine[0] == '\0') /* try for srm address */
  1492. X      sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
  1493. X                who, machine);
  1494. X
  1495. X    if (machine[0] == '\0')
  1496. X      sprintf(buff,"anonymous");
  1497. X    else
  1498. X      sprintf(buff,"%s!%s", machine, who);
  1499. X
  1500. X    strncpy(who, buff, 80);
  1501. X}
  1502. X
  1503. X
  1504. Xremove_first_word(string)
  1505. Xchar *string;
  1506. X{    /** removes first word of string, ie up to first non-white space
  1507. X        following a white space! **/
  1508. X
  1509. X    register int loc;
  1510. X
  1511. X    for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++) 
  1512. X        ;
  1513. X
  1514. X    while (string[loc] == ' ' || string[loc] == '\t')
  1515. X      loc++;
  1516. X    
  1517. X    move_left(string, loc);
  1518. X}
  1519. X
  1520. Xmove_left(string, chars)
  1521. Xchar string[];
  1522. Xint  chars;
  1523. X{
  1524. X    /** moves string chars characters to the left DESTRUCTIVELY **/
  1525. X
  1526. X    register int i;
  1527. X
  1528. X    chars--; /* index starting at zero! */
  1529. X
  1530. X    for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
  1531. X      string[i-chars] = string[i];
  1532. X
  1533. X    string[i-chars] = '\0';
  1534. X}
  1535. X
  1536. Xshow_header(priority, from, subject)
  1537. Xint   priority;
  1538. Xchar *from, *subject;
  1539. X{
  1540. X    /** output header in clean format, including abbreviation
  1541. X        of return address if more than one machine name is
  1542. X        contained within it! **/
  1543. X    char buffer[SLEN];
  1544. X    int  loc, i=0, exc=0;
  1545. X
  1546. X#ifdef PREFER_UUCP
  1547. X
  1548. X    if (chloc(from, '!') != -1 && in_string(from, BOGUS_INTERNET))
  1549. X      from[strlen(from) - strlen(BOGUS_INTERNET)] = '\0';
  1550. X
  1551. X#endif
  1552. X
  1553. X    loc = strlen(from);
  1554. X
  1555. X    while (exc < 2 && loc > 0)
  1556. X      if (from[--loc] == '!')
  1557. X        exc++;
  1558. X
  1559. X    if (exc == 2) { /* lots of machine names!  Get last one */
  1560. X      loc++;
  1561. X      while (loc < strlen(from) && loc < SLEN)
  1562. X        buffer[i++] = from[loc++];
  1563. X      buffer[i] = '\0';
  1564. X      strcpy(from, buffer);
  1565. X    }
  1566. X
  1567. X    if (strlen(subject) < 2)
  1568. X      strcpy(subject, NO_SUBJECT);
  1569. X    
  1570. X      printf(">> %s mail from %s - %s\n\r", 
  1571. X        priority? "PRIORITY" : "New", from, subject);
  1572. X}    
  1573. X
  1574. Xparse_arpa_from(buffer, newfrom)
  1575. Xchar *buffer, *newfrom;
  1576. X{
  1577. X    /** try to parse the 'From:' line given... It can be in one of
  1578. X        two formats:
  1579. X        From: Dave Taylor <hpcnou!dat>
  1580. X        or  From: hpcnou!dat (Dave Taylor)
  1581. X        Change 'newfrom' ONLY if sucessfully parsed this entry and
  1582. X        the resulting name is non-null! 
  1583. X    **/
  1584. X
  1585. X    char temp_buffer[SLEN], *temp;
  1586. X    register int i, j = 0;
  1587. X
  1588. X    temp = (char *) temp_buffer;
  1589. X    temp[0] = '\0';
  1590. X
  1591. X    no_ret(buffer);        /* blow away '\n' char! */
  1592. X
  1593. X    if (lastch(buffer) == '>') {
  1594. X      for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
  1595. X           buffer[i] != '('; i++)
  1596. X        temp[j++] = buffer[i];
  1597. X      temp[j] = '\0';
  1598. X    }
  1599. X    else if (lastch(buffer) == ')') {
  1600. X      for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
  1601. X           buffer[i] != '<'; i--)
  1602. X        temp[j++] = buffer[i];
  1603. X      temp[j] = '\0';
  1604. X      reverse(temp);
  1605. X    }
  1606. X      
  1607. X    if (strlen(temp) > 0) {        /* mess with buffer... */
  1608. X
  1609. X      /* remove leading spaces... */
  1610. X
  1611. X      while (whitespace(temp[0]))
  1612. X        temp = (char *) (temp + 1);        /* increment address! */
  1613. X
  1614. X      /* remove trailing spaces... */
  1615. X
  1616. X      i = strlen(temp) - 1;
  1617. X
  1618. X      while (whitespace(temp[i]))
  1619. X       temp[i--] = '\0';
  1620. X
  1621. X      /* if anything is left, let's change 'from' value! */
  1622. X
  1623. X      if (strlen(temp) > 0)
  1624. X        strcpy(newfrom, temp);
  1625. X    }
  1626. X}
  1627. X
  1628. Xreverse(string)
  1629. Xchar *string;
  1630. X{
  1631. X    /** reverse string... pretty trivial routine, actually! **/
  1632. X
  1633. X    char buffer[SLEN];
  1634. X    register int i, j = 0;
  1635. X
  1636. X    for (i = strlen(string)-1; i >= 0; i--)
  1637. X      buffer[j++] = string[i];
  1638. X
  1639. X    buffer[j] = '\0';
  1640. X
  1641. X    strcpy(string, buffer);
  1642. X}
  1643. X
  1644. Xlong
  1645. Xbytes(name)
  1646. Xchar *name;
  1647. X{
  1648. X    /** return the number of bytes in the specified file.  This
  1649. X        is to check to see if new mail has arrived....  **/
  1650. X
  1651. X    int ok = 1;
  1652. X    extern int errno;    /* system error number! */
  1653. X    struct stat buffer;
  1654. X
  1655. X    if (stat(name, &buffer) != 0)
  1656. X      if (errno != 2)
  1657. X       exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
  1658. X      else
  1659. X        ok = 0;
  1660. X    
  1661. X    return(ok ? buffer.st_size : 0);
  1662. X}
  1663. END_OF_utils/newmail.c
  1664. if test 7989 -ne `wc -c <utils/newmail.c`; then
  1665.     echo shar: \"utils/newmail.c\" unpacked with wrong size!?
  1666. fi
  1667. # end of overwriting check
  1668. fi
  1669. echo shar: Extracting \"utils/wnewmail.c\" \(8080 characters\)
  1670. if test -f utils/wnewmail.c ; then 
  1671.   echo shar: Will not over-write existing file \"utils/wnewmail.c\"
  1672. else
  1673. sed "s/^X//" >utils/wnewmail.c <<'END_OF_utils/wnewmail.c'
  1674. X/**            wnewmail.c            **/
  1675. X
  1676. X/** Same as newmail.c but for a windowing system...
  1677. X    
  1678. X    (C) Copyright 1986, Dave Taylor
  1679. X**/
  1680. X
  1681. X#include <stdio.h>
  1682. X#include <sys/types.h>
  1683. X#include <sys/stat.h>
  1684. X
  1685. X#include "defs.h"
  1686. X
  1687. X#ifdef AUTO_BACKGROUND
  1688. X#include <signal.h>    /* background jobs ignore some signals... */
  1689. X#endif
  1690. X
  1691. Xstatic char ident[] = { WHAT_STRING };
  1692. X
  1693. X#define LINEFEED    (char) 10
  1694. X#define BEGINNING    0            /* seek fseek(3S) */
  1695. X#define SLEEP_TIME    10        
  1696. X
  1697. X#define NO_SUBJECT    "(No Subject Specified)"
  1698. X
  1699. XFILE *mailfile;
  1700. X
  1701. Xlong  bytes();
  1702. Xchar  *getusername();
  1703. X
  1704. Xmain(argc, argv)
  1705. Xint argc;
  1706. Xchar *argv[];
  1707. X{
  1708. X    char filename[LONG_SLEN];
  1709. X    long size, newsize;
  1710. X
  1711. X    if (argc > 2) 
  1712. X      fprintf(stderr, "Usage: %s [filename] &\n", argv[0]);
  1713. X    else if (argc == 2) {
  1714. X      strcpy(filename, argv[1]);
  1715. X      if (access(filename, ACCESS_EXISTS) == -1) {
  1716. X        fprintf(stderr,
  1717. X           "%s: Can't open file %s to keep track of incoming mail.\n",
  1718. X            argv[0], filename);
  1719. X        exit(1);
  1720. X      }
  1721. X    }
  1722. X    else
  1723. X      sprintf(filename,"%s%s",mailhome, getusername());
  1724. X
  1725. X#ifdef AUTO_BACKGROUND
  1726. X    if (fork())        /* automatically puts this task in background! */
  1727. X      exit(0);
  1728. X
  1729. X    signal(SIGINT, SIG_IGN);
  1730. X    signal(SIGQUIT, SIG_IGN);
  1731. X    signal(SIGHUP,  SIG_DFL);    /* so we exit when logged out */
  1732. X#endif
  1733. X
  1734. X    size = bytes(filename);
  1735. X
  1736. X    mailfile = (FILE *) NULL;
  1737. X
  1738. X    printf("Incoming Mail;\n");
  1739. X
  1740. X    while (1) {
  1741. X    
  1742. X#ifndef AUTO_BACKGROUND        /* won't work if we're nested this deep! */
  1743. X      if (getppid() == 1)     /* we've lost our shell! */
  1744. X        exit();
  1745. X#endif
  1746. X    if (! isatty(1))     /* we're not talking to the screen any more */
  1747. X       exit();
  1748. X    
  1749. X    /** Note the lack of error checking on the fopen() (Philip Peake
  1750. X        did!) - this is okay since if it fails we don't have any 
  1751. X        mail and we can sleep(60) and try again later... 
  1752. X    **/
  1753. X
  1754. X      if (mailfile == (FILE *) NULL) 
  1755. X        mailfile = fopen(filename,"r");
  1756. X
  1757. X      if ((newsize = bytes(filename)) > size) {    /* new mail */
  1758. X        fseek(mailfile, size, BEGINNING); /* skip all current mail */
  1759. X        size = newsize;
  1760. X        printf("%c", 007);    /* beep for new mail! */
  1761. X        read_headers();
  1762. X      }
  1763. X      else if (newsize != size) {
  1764. X        size = newsize;         /* mail's been removed... */
  1765. X        (void) fclose(mailfile);    /* close it and ...       */
  1766. X        mailfile = (FILE *) NULL;    /* let's reopen the file  */
  1767. X      }
  1768. X
  1769. X      sleep(SLEEP_TIME);
  1770. X    }
  1771. X}
  1772. X
  1773. Xint
  1774. Xread_headers()
  1775. X{
  1776. X    /** read the headers, output as found **/
  1777. X
  1778. X    char buffer[LONG_SLEN], from_whom[SLEN], subject[SLEN];
  1779. X    register int subj = 0, in_header = 1, count = 0, priority = 0;
  1780. X
  1781. X    while (fgets(buffer, LONG_SLEN, mailfile) != NULL) {
  1782. X      if (first_word(buffer,"From ")) {
  1783. X        if (real_from(buffer, from_whom)) {
  1784. X          subj = 0;
  1785. X          priority = 0;
  1786. X          in_header = 1;
  1787. X        }
  1788. X      }
  1789. X      else if (in_header) {
  1790. X        if (first_word(buffer,">From")) 
  1791. X          forwarded(buffer, from_whom); /* return address */
  1792. X        else if (first_word(buffer,"Subject:") ||
  1793. X             first_word(buffer,"Re:")) {
  1794. X          if (! subj++) {
  1795. X            remove_first_word(buffer);
  1796. X        strcpy(subject, buffer);
  1797. X          }
  1798. X        }
  1799. X        else if (first_word(buffer,"From:")) 
  1800. X          parse_arpa_from(buffer, from_whom);
  1801. X        else if (first_word(buffer, "Priority:"))
  1802. X          priority++;
  1803. X        else if (buffer[0] == LINEFEED) {
  1804. X          in_header = 0;    /* in body of message! */
  1805. X          show_header(priority, from_whom, subject);
  1806. X          from_whom[0] = 0;
  1807. X          subject[0] = 0;
  1808. X          count++;
  1809. X        }
  1810. X      }
  1811. X    }
  1812. X    return(count);
  1813. X}
  1814. X
  1815. Xint
  1816. Xreal_from(buffer, who)
  1817. Xchar *buffer, *who;
  1818. X{
  1819. X    /***** returns true iff 's' has the seven 'from' fields,
  1820. X           initializing the who to the sender *****/
  1821. X
  1822. X    char junk[80];
  1823. X
  1824. X    junk[0] = '\0';
  1825. X    sscanf(buffer, "%*s %s %*s %*s %*s %*s %s",
  1826. X                who, junk);
  1827. X    return(junk[0] != '\0');
  1828. X}
  1829. X
  1830. Xforwarded(buffer, who)
  1831. Xchar *buffer, *who;
  1832. X{
  1833. X    /** change 'from' and date fields to reflect the ORIGINATOR of 
  1834. X        the message by iteratively parsing the >From fields... **/
  1835. X
  1836. X    char machine[80], buff[80];
  1837. X
  1838. X    machine[0] = '\0';
  1839. X    sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s",
  1840. X                who, machine);
  1841. X
  1842. X    if (machine[0] == '\0') /* try for srm address */
  1843. X      sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s",
  1844. X                who, machine);
  1845. X
  1846. X    if (machine[0] == '\0')
  1847. X      sprintf(buff,"anonymous");
  1848. X    else
  1849. X      sprintf(buff,"%s!%s", machine, who);
  1850. X
  1851. X    strncpy(who, buff, 80);
  1852. X}
  1853. X
  1854. X
  1855. Xremove_first_word(string)
  1856. Xchar *string;
  1857. X{    /** removes first word of string, ie up to first non-white space
  1858. X        following a white space! **/
  1859. X
  1860. X    register int loc;
  1861. X
  1862. X    for (loc = 0; string[loc] != ' ' && string[loc] != '\0'; loc++) 
  1863. X        ;
  1864. X
  1865. X    while (string[loc] == ' ' || string[loc] == '\t')
  1866. X      loc++;
  1867. X    
  1868. X    move_left(string, loc);
  1869. X}
  1870. X
  1871. Xmove_left(string, chars)
  1872. Xchar string[];
  1873. Xint  chars;
  1874. X{
  1875. X    /** moves string chars characters to the left DESTRUCTIVELY **/
  1876. X
  1877. X    register int i;
  1878. X
  1879. X    chars--; /* index starting at zero! */
  1880. X
  1881. X    for (i=chars; string[i] != '\0' && string[i] != '\n'; i++)
  1882. X      string[i-chars] = string[i];
  1883. X
  1884. X    string[i-chars] = '\0';
  1885. X}
  1886. X
  1887. Xshow_header(priority, from, subject)
  1888. Xint   priority;
  1889. Xchar *from, *subject;
  1890. X{
  1891. X    /** Output header in clean format, including abbreviation
  1892. X        of return address if more than one machine name is
  1893. X        contained within it! **/
  1894. X
  1895. X    char buffer[SLEN];
  1896. X    int  loc, i=0, exc=0;
  1897. X
  1898. X#ifdef PREFER_UUCP
  1899. X    
  1900. X    if (chloc(from,'!') != -1 && in_string(from, BOGUS_INTERNET))
  1901. X      from[strlen(from) - strlen(BOGUS_INTERNET)] = '\0';
  1902. X
  1903. X#endif
  1904. X
  1905. X    loc = strlen(from);
  1906. X
  1907. X    while (exc < 2 && loc > 0)
  1908. X      if (from[--loc] == '!')
  1909. X        exc++;
  1910. X
  1911. X    if (exc == 2) { /* lots of machine names!  Get last one */
  1912. X      loc++;
  1913. X      while (loc < strlen(from) && loc < SLEN)
  1914. X        buffer[i++] = from[loc++];
  1915. X      buffer[i] = '\0';
  1916. X      strcpy(from, buffer);
  1917. X    }
  1918. X
  1919. X    if (strlen(subject) < 2)
  1920. X      strcpy(subject, NO_SUBJECT);
  1921. X    
  1922. X      if (strlen(from) > 0)    /* last final check... */
  1923. X        printf("%sMail from %s -- %s\n", 
  1924. X           priority? "PRIORITY ": "", from, subject);
  1925. X}    
  1926. X
  1927. Xparse_arpa_from(buffer, newfrom)
  1928. Xchar *buffer, *newfrom;
  1929. X{
  1930. X    /** Try to parse the 'From:' line given... It can be in one of
  1931. X        two formats:
  1932. X        From: Dave Taylor <hpcnou!dat>
  1933. X        or  From: hpcnou!dat (Dave Taylor)
  1934. X        Change 'newfrom' ONLY if sucessfully parsed this entry and
  1935. X        the resulting name is non-null! 
  1936. X    **/
  1937. X
  1938. X    char temp_buffer[SLEN], *temp;
  1939. X    register int i, j = 0;
  1940. X
  1941. X    temp = (char *) temp_buffer;
  1942. X    temp[0] = '\0';
  1943. X
  1944. X    no_ret(buffer);        /* blow away '\n' char! */
  1945. X
  1946. X    if (lastch(buffer) == '>') {
  1947. X      for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
  1948. X           buffer[i] != '('; i++)
  1949. X        temp[j++] = buffer[i];
  1950. X      temp[j] = '\0';
  1951. X    }
  1952. X    else if (lastch(buffer) == ')') {
  1953. X      for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
  1954. X           buffer[i] != '<'; i--)
  1955. X        temp[j++] = buffer[i];
  1956. X      temp[j] = '\0';
  1957. X      reverse(temp);
  1958. X    }
  1959. X      
  1960. X    if (strlen(temp) > 0) {        /* mess with buffer... */
  1961. X
  1962. X      /* remove leading spaces... */
  1963. X
  1964. X      while (whitespace(temp[0]))
  1965. X        temp = (char *) (temp + 1);        /* increment address! */
  1966. X
  1967. X      /* remove trailing spaces... */
  1968. X
  1969. X      i = strlen(temp) - 1;
  1970. X
  1971. X      while (whitespace(temp[i]))
  1972. X       temp[i--] = '\0';
  1973. X
  1974. X      /* if anything is left, let's change 'from' value! */
  1975. X
  1976. X      if (strlen(temp) > 0)
  1977. X        strcpy(newfrom, temp);
  1978. X    }
  1979. X}
  1980. X
  1981. Xreverse(string)
  1982. Xchar *string;
  1983. X{
  1984. X    /** reverse string... pretty trivial routine, actually! **/
  1985. X
  1986. X    char buffer[SLEN];
  1987. X    register int i, j = 0;
  1988. X
  1989. X    for (i = strlen(string)-1; i >= 0; i--)
  1990. X      buffer[j++] = string[i];
  1991. X
  1992. X    buffer[j] = '\0';
  1993. X
  1994. X    strcpy(string, buffer);
  1995. X}
  1996. X
  1997. Xlong
  1998. Xbytes(name)
  1999. Xchar *name;
  2000. X{
  2001. X    /** return the number of bytes in the specified file.  This
  2002. X        is to check to see if new mail has arrived....  **/
  2003. X
  2004. X    int ok = 1;
  2005. X    extern int errno;    /* system error number! */
  2006. X    struct stat buffer;
  2007. X
  2008. X    if (stat(name, &buffer) != 0)
  2009. X      if (errno != 2)
  2010. X       exit(fprintf(stderr,"Error %d attempting fstat on %s", errno, name));
  2011. X      else
  2012. X        ok = 0;
  2013. X    
  2014. X    return(ok ? (long) buffer.st_size : 0L);
  2015. X}
  2016. X
  2017. Xchar  *getusername()
  2018. X{
  2019. X    /** Getting the username on some systems is a real pain, so...
  2020. X       This routine is guaranteed to return a usable username **/
  2021. X
  2022. X    char *return_value, *cuserid(), *getlogin();
  2023. X
  2024. X    if ((return_value = cuserid(NULL)) == NULL)
  2025. X      if ((return_value = getlogin()) == NULL)
  2026. X        exit(printf("Newmail: I can't get username!\n"));
  2027. X
  2028. X    return( (char *) return_value);
  2029. X}
  2030. END_OF_utils/wnewmail.c
  2031. if test 8080 -ne `wc -c <utils/wnewmail.c`; then
  2032.     echo shar: \"utils/wnewmail.c\" unpacked with wrong size!?
  2033. fi
  2034. # end of overwriting check
  2035. fi
  2036. echo shar: End of archive 7 \(of 19\).
  2037. cp /dev/null ark7isdone
  2038. DONE=true
  2039. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  2040.     if test ! -f ark${I}isdone ; then
  2041.     echo shar: You still need to run archive ${I}.
  2042.     DONE=false
  2043.     fi
  2044. done
  2045. if test "$DONE" = "true" ; then
  2046.     echo You have unpacked all 19 archives.
  2047.     echo "See the Instructions file"
  2048.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2049. fi
  2050. ##  End of shell archive.
  2051. exit 0
  2052.