home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume22 / elm2.3 / part23 < prev    next >
Text File  |  1990-06-07  |  50KB  |  1,856 lines

  1. Subject:  v22i085:  ELM mail syste, release 2.3, Part23/26
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 0c166c91 0a54b00a 842e22a7 b9bf7105
  5.  
  6. Submitted-by: Syd Weinstein <syd@dsinc.dsi.com>
  7. Posting-number: Volume 22, Issue 85
  8. Archive-name: elm2.3/part23
  9.  
  10. #!/bin/sh
  11. # this is part 23 of a multipart archive
  12. # do not concatenate these parts, unpack them in order with /bin/sh
  13. # file src/syscall.c continued
  14. #
  15. CurArch=23
  16. if test ! -r s2_seq_.tmp
  17. then echo "Please unpack part 1 first!"
  18.      exit 1; fi
  19. ( read Scheck
  20.   if test "$Scheck" != $CurArch
  21.   then echo "Please unpack part $Scheck next!"
  22.        exit 1;
  23.   else exit 0; fi
  24. ) < s2_seq_.tmp || exit 1
  25. echo "x - Continuing file src/syscall.c"
  26. sed 's/^X//' << 'SHAR_EOF' >> src/syscall.c
  27. X    int  old_raw, helpful, ret;
  28. X
  29. X    helpful = (user_level == 0);
  30. X
  31. X    if (helpful)
  32. X      PutLine0(LINES-3,COLUMNS-40,"(Use the shell name for a shell.)");
  33. X    PutLine0(LINES-2,0,"Shell command: ");
  34. X    CleartoEOS();
  35. X    command[0] = '\0';
  36. X    (void) optionally_enter(command, LINES-2, 15, FALSE, FALSE);
  37. X    if (command[0] == 0) {
  38. X      if (helpful)
  39. X        MoveCursor(LINES-3,COLUMNS-40);
  40. X      else
  41. X        MoveCursor(LINES-2,0);
  42. X      CleartoEOS();
  43. X      return 0;
  44. X    }
  45. X
  46. X    MoveCursor(LINES,0);
  47. X    CleartoEOLN();
  48. X
  49. X    if ((old_raw = RawState()) == ON)
  50. X      Raw(OFF);
  51. X    softkeys_off();
  52. X    if (cursor_control)
  53. X      transmit_functions(OFF);
  54. X    
  55. X    umask(original_umask);    /* restore original umask so users new files are ok */
  56. X    ret = system_call(command, USER_SHELL, TRUE, TRUE);
  57. X    umask(077);        /* now put it back to private for mail files */
  58. X
  59. X    PutLine0(LINES, 0, "\n\nPress any key to return to ELM: ");
  60. X    Raw(ON);
  61. X    (void) getchar();
  62. X    if (old_raw == OFF)
  63. X      Raw(OFF);
  64. X    softkeys_on();
  65. X    if (cursor_control)
  66. X      transmit_functions(ON);
  67. X
  68. X    if (ret)
  69. X      error1("Return code was %d.", ret);
  70. X
  71. X    return 1;
  72. X}
  73. X
  74. X#endif /* ALLOW_SUBSHELL */
  75. X
  76. Xsystem_call(string, shell_type, allow_signals, allow_interrupt)
  77. Xchar *string;
  78. Xint   shell_type, allow_signals, allow_interrupt;
  79. X{
  80. X    /** execute 'string', setting uid to userid... **/
  81. X    /** if shell-type is "SH" /bin/sh is used regardless of the 
  82. X        users shell setting.  Otherwise, "USER_SHELL" is sent.
  83. X        If allow_signals is TRUE, then allow the executed
  84. X        command handle hangup, and optionally if allow_interrupt
  85. X        is also true handle interrupt in its own way.
  86. X        This is useful for executed programs with
  87. X        user interaction that handle those signals on their
  88. X        own terms. It is especially important for vi, so that
  89. X        a message being edited when a user connection is
  90. X        dropped is recovered by vi's expreserve program **/
  91. X
  92. X    int stat = 0, pid, w;
  93. X#if defined(BSD) && !defined(WEXITSTATUS)
  94. X    union wait status;
  95. X#else
  96. X    int status;
  97. X#endif
  98. X#ifdef VOIDSIG
  99. X    register void (*istat)(), (*qstat)();
  100. X# ifdef SIGTSTP
  101. X    register void (*oldstop)(), (*oldstart)();
  102. X# endif
  103. X#else
  104. X    register int (*istat)(), (*qstat)();
  105. X# ifdef SIGTSTP
  106. X    register int (*oldstop)(), (*oldstart)();
  107. X# endif 
  108. X#endif
  109. X    
  110. X    dprint(2, (debugfile,
  111. X        "System Call: %s\n\t%s\n", shell_type == SH? "/bin/sh" : shell,
  112. X        string));
  113. X
  114. X#ifdef VFORK
  115. X    if ((pid = vfork()) == 0)
  116. X#else
  117. X    if ((pid = fork()) == 0)
  118. X#endif
  119. X    {
  120. X      setgid(groupid);    /* and group id            */
  121. X      setuid(userid);    /* back to the normal user! */
  122. X
  123. X      if(allow_signals) {
  124. X        /* program to exec should handle interrupt, accidental hangup, and stop signals */
  125. X        (void)signal(SIGHUP, SIG_DFL);
  126. X        if (allow_interrupt)
  127. X          (void)signal(SIGINT, SIG_DFL);
  128. X        else
  129. X          (void)signal(SIGINT, SIG_IGN);
  130. X#ifdef SIGTSTP
  131. X        (void)signal(SIGTSTP, SIG_DFL);
  132. X        (void)signal(SIGCONT, SIG_DFL);
  133. X#endif
  134. X      } else {
  135. X        /* program to exec should ignore interrupt, accidental hangup, and stop signals */
  136. X        (void)signal(SIGHUP, SIG_IGN);
  137. X        (void)signal(SIGINT, SIG_IGN);
  138. X#ifdef SIGTSTP
  139. X        (void)signal(SIGTSTP, SIG_IGN);
  140. X        (void)signal(SIGCONT, SIG_IGN);
  141. X#endif
  142. X      }
  143. X
  144. X      if (strlen(shell) > 0 && shell_type == USER_SHELL) {
  145. X        execl(shell, argv_zero(shell), "-c", string, (char *) 0);
  146. X      }
  147. X      else 
  148. X        execl("/bin/sh", "sh", "-c", string, (char *) 0);
  149. X      _exit(127);
  150. X    }
  151. X
  152. X    istat = signal(SIGINT, SIG_IGN);
  153. X    qstat = signal(SIGQUIT, SIG_IGN);
  154. X#ifdef SIGTSTP
  155. X    oldstop = signal(SIGTSTP, SIG_DFL);
  156. X    oldstart = signal(SIGCONT, SIG_DFL);
  157. X#endif
  158. X
  159. X    while ((w = wait(&status)) != pid && w != -1)
  160. X        ;
  161. X
  162. X
  163. X    if (w == pid) {
  164. X#ifdef    WEXITSTATUS
  165. X      stat = WEXITSTATUS(status);
  166. X#else
  167. X# ifdef    BSD
  168. X      if (status.w_retcode != 0) stat = status.w_retcode;
  169. X# else
  170. X      stat = status;
  171. X# endif
  172. X#endif
  173. X    }
  174. X
  175. X    (void)signal(SIGINT, istat);
  176. X    (void)signal(SIGQUIT, qstat);
  177. X#ifdef SIGTSTP
  178. X    (void)signal(SIGTSTP, oldstop);
  179. X    (void)signal(SIGCONT, oldstart);
  180. X#endif
  181. X
  182. X    return(stat);
  183. X}
  184. X
  185. Xint
  186. Xdo_pipe()
  187. X{
  188. X    /** pipe the current message or tagged messages to
  189. X        the specified sequence.. **/
  190. X
  191. X    char command[SLEN], buffer[SLEN], message_list[SLEN];
  192. X    register int  ret, to_pipe;
  193. X    int    old_raw;
  194. X
  195. X    to_pipe = make_msg_list(message_list);
  196. X    sprintf(buffer, "Pipe message%s to: ", plural(to_pipe));
  197. X        PutLine0(LINES-2,0,buffer);
  198. X
  199. X    command[0] = '\0';
  200. X
  201. X    (void) optionally_enter(command, LINES-2, strlen(buffer), FALSE, FALSE);
  202. X    if (strlen(command) == 0) {
  203. X      MoveCursor(LINES-2,0);    CleartoEOLN();
  204. X      return(0);
  205. X    }
  206. X
  207. X    MoveCursor(LINES,0);     CleartoEOLN();
  208. X    if (( old_raw = RawState()) == ON)
  209. X      Raw(OFF);
  210. X
  211. X    if (cursor_control)  transmit_functions(OFF);
  212. X    
  213. X    sprintf(buffer, "%s -f %s -h %s | %s",
  214. X        readmsg,
  215. X        (folder_type == NON_SPOOL ? cur_folder : cur_tempfolder),
  216. X        message_list,
  217. X        command);
  218. X    
  219. X    ret = system_call(buffer, USER_SHELL, TRUE, TRUE);
  220. X
  221. X    PutLine0(LINES, 0, "\n\nPress any key to return to ELM.");
  222. X    if (old_raw == ON)
  223. X       Raw(ON);
  224. X    (void) getchar();
  225. X    if (cursor_control)  transmit_functions(ON);
  226. X
  227. X    if (ret != 0) error1("Return code was %d.", ret);
  228. X    return(1);
  229. X}
  230. X
  231. Xprint_msg()
  232. X{
  233. X    /** Print current message or tagged messages using 'printout' 
  234. X        variable.  Error message iff printout not defined! **/
  235. X
  236. X    char buffer[SLEN], filename[SLEN], printbuffer[SLEN];
  237. X    char message_list[SLEN];
  238. X    register int  retcode, to_print;
  239. X
  240. X    if (strlen(printout) == 0) {
  241. X      error("Don't know how to print - option \"printmail\" undefined!");
  242. X      return;
  243. X    }
  244. X    
  245. X    to_print = make_msg_list(message_list);
  246. X
  247. X    sprintf(filename,"%s%s%d", temp_dir, temp_print, getpid());
  248. X
  249. X    if (in_string(printout, "%s"))
  250. X      sprintf(printbuffer, printout, filename);
  251. X    else
  252. X      sprintf(printbuffer, "%s %s", printout, filename);
  253. X
  254. X    sprintf(buffer,"(%s -p -f %s%s > %s; %s 2>&1) > /dev/null",
  255. X        readmsg,
  256. X        (folder_type == NON_SPOOL ? cur_folder : cur_tempfolder),
  257. X        message_list, 
  258. X        filename,
  259. X        printbuffer);
  260. X    
  261. X    dprint(2, (debugfile, "Printing system call...\n"));
  262. X
  263. X      Centerline(LINES, "Queuing...");
  264. X
  265. X    if ((retcode = system_call(buffer, SH, FALSE, FALSE)) == 0) {
  266. X      sprintf(buffer, "Message%s queued up to print.", plural(to_print));
  267. X      Centerline(LINES, buffer);
  268. X    }
  269. X    else
  270. X      error1("Printout failed with return code %d.", retcode);
  271. X
  272. X    unlink(filename);    /* remove da temp file! */
  273. X}
  274. X
  275. Xmake_msg_list(message_list)
  276. Xchar *message_list;
  277. X{
  278. X    /** make a list of the tagged or just the current, if none tagged.
  279. X        check for overflow on messsage length
  280. X         **/
  281. X
  282. X    int i, msgs_selected = 0;
  283. X
  284. X    *message_list = '\0';    /* start with an empty list */
  285. X
  286. X    for (i=0; i < message_count; i++) 
  287. X      if (headers[i]->status & TAGGED) {
  288. X        if (strlen(message_list) + 6 >= SLEN) {
  289. X          error1("Too many messages selected, messages from %d on not used", i);
  290. X          return(msgs_selected);
  291. X          }
  292. X        sprintf(message_list, "%s %d", message_list, 
  293. X            headers[i]->index_number);
  294. X        msgs_selected++;
  295. X      }
  296. X
  297. X    if (! msgs_selected) {
  298. X      sprintf(message_list," %d", headers[current-1]->index_number);
  299. X      msgs_selected = 1;
  300. X    }
  301. X    
  302. X    return(msgs_selected);
  303. X}
  304. X
  305. Xlist_folders(numlines, helpmsg)
  306. Xunsigned numlines;
  307. Xchar *helpmsg;
  308. X{
  309. X    /** list the folders in the users FOLDERHOME directory.  This is
  310. X        simply a call to "ls -C"
  311. X        Numlines is the number of lines to scroll afterwards. This is
  312. X        useful when a portion of the screen needs to be cleared for
  313. X        subsequent prompts, but you don't want to overwrite the
  314. X        list of folders.
  315. X        Helpmsg is what should be printed before the listing if not NULL.
  316. X    **/
  317. X
  318. X    char buffer[SLEN];
  319. X
  320. X    Raw(OFF);
  321. X    ClearScreen();
  322. X    MoveCursor(LINES, 0);
  323. X    if(helpmsg)
  324. X      printf(helpmsg);
  325. X    sprintf(buffer, "cd %s;ls -C", folders);
  326. X    printf("\n\rContents of your folder directory:\n\r\n\r");
  327. X    system_call(buffer, SH, FALSE, FALSE); 
  328. X    while(numlines--)
  329. X        printf("\n\r");
  330. X    Raw(ON);
  331. X}
  332. SHAR_EOF
  333. echo "File src/syscall.c is complete"
  334. chmod 0444 src/syscall.c || echo "restore of src/syscall.c fails"
  335. echo "x - extracting src/utils.c (Text)"
  336. sed 's/^X//' << 'SHAR_EOF' > src/utils.c &&
  337. X
  338. Xstatic char rcsid[] = "@(#)$Id: utils.c,v 4.1 90/04/28 22:44:19 syd Exp $";
  339. X
  340. X/*******************************************************************************
  341. X *  The Elm Mail System  -  $Revision: 4.1 $   $State: Exp $
  342. X *
  343. X *             Copyright (c) 1986, 1987 Dave Taylor
  344. X *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  345. X *******************************************************************************
  346. X * Bug reports, patches, comments, suggestions should be sent to:
  347. X *
  348. X *    Syd Weinstein, Elm Coordinator
  349. X *    elm@DSI.COM            dsinc!elm
  350. X *
  351. X *******************************************************************************
  352. X * $Log:    utils.c,v $
  353. X * Revision 4.1  90/04/28  22:44:19  syd
  354. X * checkin of Elm 2.3 as of Release PL0
  355. X * 
  356. X *
  357. X ******************************************************************************/
  358. X
  359. X/** Utility routines for ELM
  360. X
  361. X**/
  362. X
  363. X#include "headers.h"
  364. X#include <sys/types.h>
  365. X#include <sys/stat.h>
  366. X#include <ctype.h>
  367. X#include <errno.h>
  368. X
  369. X#ifdef BSD
  370. X#undef tolower
  371. X#endif
  372. X
  373. X#include <signal.h>
  374. X
  375. Xextern int errno;
  376. X
  377. Xchar *error_name();
  378. Xvoid   exit();
  379. X
  380. Xcreate_new_folders()
  381. X{
  382. X    /* this creates a new folders directory */
  383. X
  384. X#ifdef MKDIR
  385. X    (void) mkdir(folders, 0700);
  386. X#else
  387. X    char com[SLEN];
  388. X
  389. X    /** Some systems don't have a mkdir call - how inconvienient! **/
  390. X
  391. X    sprintf(com, "mkdir %s", folders);
  392. X    system_call(com, SH, FALSE, FALSE);
  393. X    sprintf(com, "chmod 700 %s", folders);
  394. X    system_call(com, SH, FALSE, FALSE);
  395. X#endif /* MKDIR */
  396. X
  397. X    chown(folders, userid, groupid);
  398. X}
  399. X
  400. Xcreate_new_elmdir()
  401. X{
  402. X    /** this routine is just for allowing new users who don't have the
  403. X        old elm files to create a new .elm directory **/
  404. X
  405. X    char source[SLEN];
  406. X#ifdef MKDIR
  407. X    sprintf(source, "%s/.elm", home);
  408. X    (void) mkdir(source, 0700);
  409. X#else
  410. X    char com[SLEN];
  411. X
  412. X    /** Some systems don't have a mkdir call - how inconvienient! **/
  413. X
  414. X    sprintf(com, "mkdir %s/.elm", home);
  415. X    system_call(com, SH, FALSE, FALSE);
  416. X    sprintf(com, "chmod 700 %s/.elm", home);
  417. X    system_call(com, SH, FALSE, FALSE);
  418. X#endif /* MKDIR */
  419. X
  420. X    chown( source, userid, groupid);
  421. X}
  422. X
  423. Xmove_old_files_to_new()
  424. X{
  425. X    /** this routine is just for allowing people to transition from
  426. X        the old Elm, where things are all kept in their $HOME dir,
  427. X        to the new one where everything is in $HOME/.elm... **/
  428. X
  429. X    char source[SLEN], dest[SLEN], temp[SLEN];
  430. X    char com[SLEN];
  431. X
  432. X    /** simply go through all the files... **/
  433. X
  434. X    sprintf(source, "%s/.alias_text", home);
  435. X    if (access(source, ACCESS_EXISTS) != -1) {
  436. X      sprintf(dest,   "%s/%s", home, ALIAS_TEXT);
  437. X      printf("\n\rCopying from: %s\n\rCopying to:   %s\n\r", source, dest);
  438. X
  439. X      sprintf(temp, "/tmp/%d", getpid());
  440. X      sprintf(com, "%s -e 's/:/=/g' %s > %s\n", sed_cmd, source, temp);
  441. X      (void) system_call(com, SH, FALSE, FALSE);
  442. X      sprintf(com, "%s %s %s\n", move_cmd, temp, dest);
  443. X      (void) system_call(com, SH, FALSE, FALSE);
  444. X      (void) system_call("newalias", SH, FALSE, FALSE);
  445. X    }
  446. X
  447. X    sprintf(source, "%s/.elmheaders", home);
  448. X    if (access(source, ACCESS_EXISTS) != -1) {
  449. X      sprintf(dest,   "%s/%s", home, mailheaders);
  450. X      printf("\n\rCopying from: %s\n\rCopying to:   %s\n\r", source, dest);
  451. X      copy(source, dest);
  452. X    }
  453. X
  454. X    sprintf(source, "%s/.elmrc", home);
  455. X    if (access(source, ACCESS_EXISTS) != -1) {
  456. X      sprintf(dest,   "%s/%s", home, elmrcfile);
  457. X      printf("\n\rCopying from: %s\n\rCopying to:   %s\n\r", source, dest);
  458. X      copy(source, dest);
  459. X    }
  460. X
  461. X    printf(
  462. X    "\n\rWelcome to the new version of ELM!\n\n\rHit return to continue.");
  463. X    getchar();
  464. X}
  465. X
  466. Xemergency_exit()
  467. X{
  468. X    /** used in dramatic cases when we must leave without altering
  469. X        ANYTHING about the system... **/
  470. X    char *mk_lockname();
  471. X
  472. X    dprint(1, (debugfile,
  473. X     "\nERROR: Something dreadful is happening!  Taking emergency exit!!\n\n"));
  474. X    dprint(1, (debugfile,
  475. X         "  possibly leaving behind the following files;\n"));
  476. X    dprint(1, (debugfile,
  477. X         "     The mailbox tempfile : %s\n", cur_tempfolder));
  478. X    if(folder_type == SPOOL) dprint(1, (debugfile,
  479. X         "     The mailbox lock file: %s\n", mk_lockname(cur_folder)));
  480. X    dprint(1, (debugfile,
  481. X         "     The composition file : %s%s%d\n", temp_dir, temp_file, getpid()));
  482. X    dprint(1, (debugfile,
  483. X         "     The readmsg data file: %s/%s\n", home, readmsg_file));
  484. X
  485. X    Raw(OFF);
  486. X    if (cursor_control)  transmit_functions(OFF);
  487. X    if (hp_terminal)     softkeys_off();
  488. X
  489. X    if (cursor_control)
  490. X      MoveCursor(LINES, 0);
  491. X
  492. X    PutLine0(LINES,0,
  493. X        "\nEmergency exit taken! All temp files intact!\n\n");
  494. X
  495. X    exit(1);
  496. X}
  497. Xrm_temps_exit()
  498. X{
  499. X      char buffer[SLEN];
  500. X      PutLine0(LINES,0,
  501. X         "\nWrite to temp file failed, exiting leaving mailbox intact!\n\n");
  502. X      dprint(2, (debugfile, "\nrm_temps_exit, deleteing temp files\n"));
  503. X      Raw(OFF);
  504. X      if (cursor_control)  transmit_functions(OFF);
  505. X      if (hp_terminal)     softkeys_off();
  506. X      sprintf(buffer,"%s%d",temp_file, getpid());  /* editor buffer */
  507. X      (void) unlink(buffer);
  508. X      if (folder_type == SPOOL) {
  509. X        (void) unlink(cur_tempfolder);
  510. X      }
  511. X      sprintf(buffer,"%s/%s", home, readmsg_file);  /* readmsg temp */
  512. X      (void) unlink(buffer);
  513. X      unlock();                               /* remove lock file if any */
  514. X      if(!batch_only) {
  515. X        MoveCursor(LINES,0);
  516. X        NewLine();
  517. X      }
  518. X      exit(1);
  519. X}
  520. X
  521. X/*ARGSUSED*/
  522. X/*VARARGS0*/
  523. X
  524. Xleave(val)
  525. Xint val;    /* not used, placeholder for signal catching! */
  526. X{
  527. X    char buffer[SLEN];
  528. X
  529. X    dprint(2, (debugfile, "\nLeaving mailer normally (leave)\n"));
  530. X
  531. X    Raw(OFF);
  532. X    if (cursor_control)  transmit_functions(OFF);
  533. X    if (hp_terminal)     softkeys_off();
  534. X
  535. X    sprintf(buffer,"%s%s%d", temp_dir, temp_file, getpid());  /* editor buffer */
  536. X    (void) unlink(buffer);
  537. X
  538. X    if (folder_type == SPOOL) {
  539. X      (void) unlink(cur_tempfolder);
  540. X    }
  541. X
  542. X    sprintf(buffer,"%s/%s", home, readmsg_file);  /* readmsg temp */
  543. X    (void) unlink(buffer);
  544. X
  545. X    unlock();                /* remove lock file if any */
  546. X
  547. X    if(!batch_only) {
  548. X      MoveCursor(LINES,0);
  549. X      NewLine();
  550. X    }
  551. X
  552. X    exit(0);
  553. X}
  554. X
  555. Xsilently_exit()
  556. X{
  557. X    /** This is the same as 'leave', but it doesn't remove any non-pid
  558. X        files.  It's used when we notice that we're trying to create a
  559. X        temp mail file and one already exists!!
  560. X    **/
  561. X    char buffer[SLEN];
  562. X
  563. X    dprint(2, (debugfile, "\nLeaving mailer quietly (silently_exit)\n"));
  564. X
  565. X    Raw(OFF);
  566. X    if (cursor_control)  transmit_functions(OFF);
  567. X    if (hp_terminal)     softkeys_off();
  568. X
  569. X    sprintf(buffer,"%s%s%d", temp_dir, temp_file, getpid());  /* editor buffer */
  570. X    (void) unlink(buffer);
  571. X
  572. X    MoveCursor(LINES,0);
  573. X    NewLine();
  574. X
  575. X    exit(0);
  576. X}
  577. X
  578. X/*ARGSUSED0*/
  579. X
  580. X#ifndef REMOVE_AT_LAST
  581. Xleave_locked(val)
  582. Xint val;    /* not used, placeholder for signal catching! */
  583. X{
  584. X    /** same as leave routine, but don't disturb lock file **/
  585. X
  586. X    char buffer[SLEN];
  587. X
  588. X        dprint(3, (debugfile,
  589. X        "\nLeaving mailer due to presence of lock file (leave_locked)\n"));
  590. X
  591. X    Raw(OFF);
  592. X    if (cursor_control)  transmit_functions(OFF);
  593. X    if (hp_terminal)     softkeys_off();
  594. X
  595. X    sprintf(buffer,"%s%s%d", temp_dir, temp_file, getpid());  /* editor buffer */
  596. X    (void) unlink(buffer);
  597. X
  598. X    (void) unlink(cur_tempfolder);            /* temp mailbox */
  599. X
  600. X    MoveCursor(LINES,0);
  601. X    NewLine();
  602. X    exit(0);
  603. X}
  604. X#endif
  605. X
  606. Xint
  607. Xget_page(msg_pointer)
  608. Xint msg_pointer;
  609. X{
  610. X    /** Ensure that 'current' is on the displayed page,
  611. X        returning NEW_PAGE iff the page changed! **/
  612. X
  613. X    register int first_on_page, last_on_page;
  614. X
  615. X    first_on_page = (header_page * headers_per_page) + 1;
  616. X
  617. X    last_on_page = first_on_page + headers_per_page - 1;
  618. X
  619. X    if (selected)    /* but what is it on the SCREEN??? */
  620. X      msg_pointer = compute_visible(msg_pointer);
  621. X
  622. X    if (selected && msg_pointer > selected)
  623. X      return(SAME_PAGE);    /* too far - page can't change! */
  624. X
  625. X    if (msg_pointer > last_on_page) {
  626. X      header_page = (int) (msg_pointer-1)/ headers_per_page;
  627. X      return(NEW_PAGE);
  628. X    }
  629. X    else if (msg_pointer < first_on_page) {
  630. X      header_page = (int) (msg_pointer-1) / headers_per_page;
  631. X      return(NEW_PAGE);
  632. X    }
  633. X    else
  634. X      return(SAME_PAGE);
  635. X}
  636. X
  637. Xchar *nameof(filename)
  638. Xchar *filename;
  639. X{
  640. X    /** checks to see if 'filename' has any common prefixes, if
  641. X        so it returns a string that is the same filename, but
  642. X        with '=' as the folder directory, or '~' as the home
  643. X        directory..
  644. X    **/
  645. X
  646. X    static char buffer[STRING];
  647. X    register int i = 0, iindex = 0;
  648. X
  649. X    if (strncmp(filename, folders, strlen(folders)) == 0) {
  650. X      if (strlen(folders) > 0) {
  651. X        buffer[i++] = '=';
  652. X        iindex = strlen(folders);
  653. X        if(filename[iindex] == '/')
  654. X          iindex++;
  655. X      }
  656. X    }
  657. X    else if (strncmp(filename, home, strlen(home)) == 0) {
  658. X      if (strlen(home) > 1) {
  659. X        buffer[i++] = '~';
  660. X        iindex = strlen(home);
  661. X      }
  662. X    }
  663. X    else iindex = 0;
  664. X
  665. X    while (filename[iindex] != '\0')
  666. X      buffer[i++] = filename[iindex++];
  667. X    buffer[i] = '\0';
  668. X
  669. X    return( (char *) buffer);
  670. X}
  671. SHAR_EOF
  672. chmod 0444 src/utils.c || echo "restore of src/utils.c fails"
  673. echo "x - extracting src/validname.c (Text)"
  674. sed 's/^X//' << 'SHAR_EOF' > src/validname.c &&
  675. X
  676. Xstatic char rcsid[] = "@(#)$Id: validname.c,v 4.1 90/04/28 22:44:21 syd Exp $";
  677. X
  678. X/*******************************************************************************
  679. X *  The Elm Mail System  -  $Revision: 4.1 $   $State: Exp $
  680. X *
  681. X *             Copyright (c) 1986, 1987 Dave Taylor
  682. X *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  683. X *******************************************************************************
  684. X * Bug reports, patches, comments, suggestions should be sent to:
  685. X *
  686. X *    Syd Weinstein, Elm Coordinator
  687. X *    elm@DSI.COM            dsinc!elm
  688. X *
  689. X *******************************************************************************
  690. X * $Log:    validname.c,v $
  691. X * Revision 4.1  90/04/28  22:44:21  syd
  692. X * checkin of Elm 2.3 as of Release PL0
  693. X * 
  694. X *
  695. X ******************************************************************************/
  696. X
  697. X#include "defs.h"
  698. X
  699. X#include <stdio.h>
  700. X
  701. X#ifndef NOCHECK_VALIDNAME         /* Force a return of valid */
  702. X# ifdef PWDINSYS
  703. X#  include <sys/pwd.h>
  704. X# else
  705. X#  include <pwd.h>
  706. X# endif
  707. X#endif
  708. X
  709. Xint
  710. Xvalid_name(name)
  711. Xchar *name;
  712. X{
  713. X    /** Determine whether "name" is a valid logname on this system.
  714. X        It is valid if there is a password entry, or if there is
  715. X        a mail file in the mail spool directory for "name".
  716. X     **/
  717. X
  718. X#ifdef NOCHECK_VALIDNAME         /* Force a return of valid */
  719. X
  720. X    return(TRUE);
  721. X
  722. X#else
  723. X
  724. X    char filebuf[SLEN];
  725. X    struct passwd *getpwnam();
  726. X
  727. X    if(getpwnam(name) != NULL)
  728. X      return(TRUE);
  729. X
  730. X    sprintf(filebuf,"%s/%s", mailhome, name);
  731. X    if (access(filebuf, ACCESS_EXISTS) == 0)
  732. X      return(TRUE);
  733. X
  734. X    return(FALSE);
  735. X
  736. X#endif
  737. X}
  738. SHAR_EOF
  739. chmod 0444 src/validname.c || echo "restore of src/validname.c fails"
  740. echo "x - extracting test/test.empty (Text)"
  741. sed 's/^X//' << 'SHAR_EOF' > test/test.empty &&
  742. SHAR_EOF
  743. chmod 0444 test/test.empty || echo "restore of test/test.empty fails"
  744. echo "x - extracting test/test.mail (Text)"
  745. sed 's/^X//' << 'SHAR_EOF' > test/test.mail &&
  746. XFrom root Wed Oct 30 14:03:36 1985
  747. X>From srmmail Wed Oct 30 14:10:08 1985  remote from veeger
  748. X>From hplabs Wed Oct 30 14:00:16 1985 remote from hpcnof
  749. X>From hpl-opus!poulton  Wed Oct 30 02:06:16 1985 remote from hplabs
  750. XDate: Wed, 30 Oct 85 01:55:05 pst
  751. XFrom: <hplabs!hpl-opus!poulton>
  752. XReceived: by HP-VENUS id AA26352; Wed, 30 Oct 85 01:55:05 pst
  753. XMessage-Id: <8510300955.AA26352@HP-VENUS>
  754. XTo: hplabs!hpldat!taylor
  755. XSubject: Re: announce(1)
  756. X
  757. XThe announce I got was shar'd July 8.   NLEN was not defined in that
  758. Xsource, just used.  LONG_SLEN is not defined in the newmail(1)
  759. Xthat you sent me.  What system are you running on?
  760. XMy s500 doesn't have these def's.
  761. X
  762. X    -> Monday, January 3rd: Call your mother
  763. X
  764. XAs to announce --> newmail: why the switch?
  765. XSeems like both are useful, in different situations.
  766. X
  767. XKen Poulton
  768. XHPL
  769. X
  770. X
  771. X
  772. X
  773. XFrom root Wed Oct 30 14:03:39 1985
  774. X>From srmmail Wed Oct 30 14:10:12 1985  remote from veeger
  775. X>From hplabs Wed Oct 30 13:59:53 1985 remote from hpcnof
  776. X>From fowler  Wed Oct 30 12:57:11 1985 remote from hplabs
  777. XDate: Wed, 30 Oct 85 12:57:11 pst
  778. XFrom: Greg Fowler <hplabs!fowler>
  779. XReceived: by HP-VENUS id AA12562; Wed, 30 Oct 85 12:57:11 pst
  780. XMessage-Id: <8510302057.AA12562@HP-VENUS>
  781. XTo: mail-men@rochester
  782. XSubject: Re: Summary of Network Mail Headers
  783. XReferences: <36700044@hpcnof.UUCP>
  784. XPriority: Most Urgent
  785. X
  786. XI believe your introduction referred to the uucp network.  usenet is the network news
  787. Xsoftware mechanism and isn't a "network".
  788. X
  789. X    - > February 19, 1986
  790. X    -
  791. X    -    A longer test of the system
  792. X    -
  793. X
  794. X    Greg
  795. X
  796. X
  797. X
  798. XFrom root Wed Oct 30 14:13:23 1985
  799. X>From srmmail Wed Oct 30 14:20:08 1985  remote from veeger
  800. X>From root Wed Oct 30 14:01:57 1985 remote from hpcnof
  801. XTo: DCC@hplabs
  802. XSubject: Log of backup tape #1
  803. X
  804. XFull Backup starting at Wed Oct 30 12:45:14 MST 1985
  805. X
  806. X
  807. Xbacking up directories: 
  808. X    ./users/fh ./users/rmd ./users/vince ./users/roberts ./users/row ./users/dt ./lost+found ./users/lost+found ./users/scb ./users/kevin ./users/du
  809. X
  810. X
  811. X
  812. X
  813. X
  814. XFrom root Wed Oct 30 15:33:24 1985
  815. X>From srmmail Wed Oct 30 15:40:26 1985  remote from veeger
  816. X>From root Wed Oct 30 15:37:17 1985 remote from hpcnof
  817. XTo: root, uucp, taylor@hplabs.ARPA
  818. XSubject: Log of backup tape #2
  819. X
  820. Xbacking up directories: 
  821. X    ./users/fh ./users/rmd ./users/vince ./users/roberts ./users/row ./users/dt ./lost+found ./users/lost+found ./users/scb ./users/kevin ./users/du
  822. X
  823. X
  824. X
  825. X
  826. Xbacking up directories: 
  827. X    ./users/sbh ./users/ges ./users/cpb ./users/amy ./net ./users/root ./users/balza ./dev ./users/remple ./users/jr ./users/mwr ./users/larryf
  828. X
  829. X
  830. X
  831. X
  832. X
  833. XFrom root Sun Dec  8 22:50:18 1985
  834. X>From srmmail Mon Dec  9 00:50:05 1985 remote from veeger
  835. X>From root Mon Dec  9 00:41:15 1985 remote from hpcnof
  836. X>From JLarson.pa@Xerox.ARPA  Sun Dec  8 20:45:55 1985 remote from hplabs
  837. XDate: 8 Dec 85 20:36:36 PST (Sunday)
  838. XFrom: hplabs!JLarson.pa@Xerox.ARPA
  839. XSubject: How's it going, anyway?
  840. XTo: hpcnou!dat@HPLABS.ARPA (Dave Taylor)
  841. XCc: JLarson.pa@Xerox.ARPA
  842. X
  843. XHow are things with you?  Could you send me that paper we were talking
  844. Xabout?  
  845. X
  846. X    Thanks
  847. X
  848. XJohn Larson
  849. XXerox Palo Alto Research Center
  850. X3333 Coyote Hill Road
  851. XPalo Alto, Ca  94304
  852. X
  853. X
  854. X
  855. X
  856. XFrom To:host!root@hplabs.HP.COM Wed Aug  7 19:58:30 1985
  857. X#From uucp Wed Aug  7 19:55:12 1985  remote from veeger
  858. X#From hplabs Wed Aug  7 19:48:10 1985 remote from hpcnof
  859. X#From RICHER@SUMEX-AIM  Wed Aug  7 09:23:12 1985 remote from hplabs
  860. XReceived: by HP-VENUS id AA18269; Wed, 7 Aug 85 09:11:48 pdt
  861. XDate: Tue 6 Aug 85 09:12:37-PDT
  862. X#From: Mark Richer <hplabs!RICHER@SUMEX-AIM>
  863. XReceived: by HP-VENUS via CSNET; 7 Aug 1985 09:11:37-PDT (Wed)
  864. XReceived: from sumex-aim.arpa by csnet-relay.arpa id a015812; 6 Aug 85 12:14 EDT
  865. XTo: hpcnof!veeger!hpcnou!dat%hplabs.csnet@CSNET-RELAY
  866. XVia:  CSNet; 7 Aug 85 9:11-PDT
  867. XSubject: Re: AI in Education mailing list...
  868. XCc: RICHER@SUMEX-AIM
  869. XIn-Reply-To: <8508030243.AA27641@HP-VENUS>
  870. XMessage-Id: <12132987812.61.RICHER@SUMEX-AIM.ARPA>
  871. X
  872. XI added you to aied.  This message may be of interest to you:
  873. X
  874. XArtificial Intelligence in Education Meeting at IJCAI 85
  875. X---------- ------------ -- --------- ------- -- ----- --
  876. X
  877. XPlace: Math Sciences Auditorium (a.k.a. Math 4000A), UCLA campus
  878. XTime: 6:30 pm, Tuesday, Aug. 20, 1985  (length: 1 - 1 1/4 hr)
  879. X
  880. XAgenda:
  881. X    I have two speakers scheduled to make presentations that
  882. Xshould stimulate questions and discussions:
  883. X
  884. X    (1) Short Announcements
  885. X
  886. X    (2) Jeff Bonar, Research Scientist, Learning Research and
  887. X    Development Center (LRDC), University of Pittsburgh
  888. X
  889. X    --- on-going ICAI research projects at LRDC
  890. X    --- dissemination of ICAI technology in the form of software
  891. X    tools, workshops, written materials, and video tapes.
  892. X
  893. X    (3) Gary Fine, Product Engineering Manager, INTELLICORP,
  894. X    formerly with a company producing CAI products, also graduate
  895. X    work in ICAI  
  896. X
  897. X    --- bridging the gap between current ICAI technology and the
  898. X    real world
  899. X
  900. X[IJCAI-85, the 9th International Joint Conference on Artificial
  901. XIntelligence is being held at UCLA Campus, August 18-23, 1985.  This
  902. Xconference is co-sponsered by the American Association for Artificial
  903. XIntelligence (AAAI) this year, and I have been told by their office
  904. Xthat only walk-in registration is available at this time.  For more
  905. Xinformation, contact AAAI:  AAAI-OFFICE@SUMEX-AIM.ARPA
  906. X                AAAI, 445 Burgess Drive, Menlo Park, CA 94025
  907. X                or call (415) 328-3123]
  908. X
  909. XDirect questions on the AI in ED meeting (only) to Mark Richer,
  910. XRICHER@SUMEX-AIM.ARPA
  911. X-------
  912. X
  913. X
  914. X
  915. X
  916. XFrom root Tue Sep 24 09:53:24 1985
  917. X>From HPMAIL-gateway Tue Sep 24  9:46:47 1985  remote from veeger
  918. X>From Simon_CINTZ_/_HPD600/TR  Tue Sep 24  9:46:47 1985  remote from hpmail
  919. XDate:   Tue, 24 Sep 85  9:14:00 MDT
  920. XFrom:   Simon_CINTZ_/_HPD600/TR  (Simon Cintz)
  921. XSubject: ITF
  922. XFrom:   Simon_CINTZ_/_HPD600/TR  (Simon Cintz)
  923. XTo:     Dave_TAYLOR_/_HPF100/00
  924. X
  925. XDave -
  926. X
  927. XJust as one programming language doesn't suit the needs of
  928. Xall programmers, one authoring facility will probably not
  929. Xsuit the needs of all HP entities that require CBT -- at least
  930. Xnot in the near future.  Of course, this is my personal opinion
  931. Xand if I'm wrong, it won't be the first time.
  932. X
  933. XGood luck.
  934. X
  935. X
  936. X                                           - Simon
  937. X
  938. XFrom root Mon Oct 21 10:43:37 1985
  939. X>From srmmail Mon Oct 21 10:30:16 1985  remote from veeger
  940. X>From root Mon Oct 21 10:28:58 1985 remote from hpcnof
  941. X>From DLS.MDC%office-X.arpa@CSNET-RELAY  Mon Oct 21 01:57:05 1985 remote from hplabs
  942. XReceived: by HP-VENUS id AA17376; Mon, 21 Oct 85 01:57:05 pdt
  943. XDate: 21 Oct 85 01:02 EDT
  944. XFrom: Duane Stone / McDonnell Douglas / CSC-ASD <hplabs!DLS.MDC%office-1.arpa@CSNET-RELAY>
  945. XReceived: by HP-VENUS via CSNET; 21 Oct 1985 01:57:01-PDT (Mon)
  946. XReceived: from office-1.arpa by CSNET-RELAY.ARPA id a019220; 21 Oct 85 1:18 EDT
  947. XTo: Dave Taylor <hpcnou!dat%hplabs.csnet@CSNET-RELAY>
  948. XVia:  CSNet; 21 Oct 85 1:56-PDT
  949. XSubject: Re: More Mail Headers...
  950. XMessage-Id: <MDC-DLS-7W9CS@OFFICE-1>
  951. XComment: Dave -- this is the body of the message I previously 'sent' to you via
  952. X
  953. Xa Journal.
  954. X
  955. XI might suggest re-wording the para on Author -- my associates might object to 
  956. X'strange' -- something like:
  957. X
  958. X   This is used to credit the original author, or to give credit on article 
  959. X   excerpts (from Newspapers, magazines, books, etc).
  960. X
  961. XOne field which I forgot is:
  962. X
  963. X   Length:  This is computed when the message is sent and gives the recipients 
  964. X   an estimate of the number of pages in the document.
  965. X
  966. X   Example:
  967. X
  968. X      Length: 6 pages [estimate]
  969. X
  970. XAccess:
  971. X
  972. X   Used to declare whether a Journal item should be Public or Private (to those
  973. X   that are on the distribution list or Extended Access list)
  974. X
  975. X   Example:
  976. X
  977. X      Access: Unrestricted
  978. X
  979. XAcknowledge-Delivery:
  980. X
  981. X   Used to request the system mailer send back a message when it has 
  982. X   successfully delivered the item.
  983. X
  984. X   Example:
  985. X
  986. X      Acknowledge-Delivery: Requested
  987. X
  988. XAcknowledge-Receipt:
  989. X
  990. X   Used to to ask the recipient to acknowledge receipt of the message.
  991. X
  992. X   Example:
  993. X
  994. X   Acknowledge-Receipt: Requested
  995. X
  996. XAddendum-To:
  997. X
  998. X   A pointer to a previously submitted Journal item.
  999. X
  1000. X   Example:
  1001. X
  1002. X      Addendum-To: <ASD,1234,>
  1003. X
  1004. XDelivery-Timing:
  1005. X
  1006. X   Used by the sender to indicate when the message should be submitted to the 
  1007. X   mailer.
  1008. X
  1009. X      Examples:
  1010. X
  1011. X         Rush:       -   immediate
  1012. X
  1013. X         Soon:       -   as soon as possible
  1014. X
  1015. X         Defer:      -   overnight
  1016. X
  1017. X         Start-Delivery: DATE TIME
  1018. X
  1019. X         Stop-Delivery:  DATE TIME (if not yet delivered)
  1020. X
  1021. XDisposition-Code:
  1022. X
  1023. X   Used by the system to group Journal items into one of several classes for 
  1024. X   eventual archive to tape and as an indicator of how long the archive tapes 
  1025. X   should be retained.
  1026. X
  1027. X   Example:
  1028. X
  1029. X      Disposition-Code: Temporary (2 years)
  1030. X
  1031. XExtended-access:
  1032. X
  1033. X   Used with private Journal items to allow access by other than those on the 
  1034. X   distribution list.
  1035. X
  1036. X   Example:
  1037. X
  1038. X      Extended-access: ASD.MDC
  1039. X
  1040. XLocation:
  1041. X
  1042. X   Used to submit the message to the Journal.  The adressees receive a short 
  1043. X   citation with other header fields and a "Location:" field pointing to a file
  1044. X   in an electronic library.
  1045. X
  1046. X   Example:
  1047. X
  1048. X      Location: <MDC,1234,>
  1049. X
  1050. XPart-Of:
  1051. X
  1052. X   A pointer to a previously submitted Journal item.
  1053. X
  1054. X   Example:
  1055. X
  1056. X      Part-Of: <MDC,1234,>
  1057. X
  1058. XRoute-To:
  1059. X
  1060. X   Used to send a message "in-turn" to addressees in the "To:" field -- as 
  1061. X   opposed to the broadcast method of delivery where everyone gets the message 
  1062. X   "simultaneously".  Any addresses in the "Cc:" field receive a copy of the 
  1063. X   message each time it is passed from one adressee to the next in the "To:" 
  1064. X   field.
  1065. X
  1066. X   Example:
  1067. X
  1068. X      Routed-to: {addresses in To field}
  1069. X
  1070. XSigned:
  1071. X
  1072. X   Created when the user employs the Sign command; used to electronically sign 
  1073. X   a message.  It affixes a signature-block to a message.  A "Verify Signature"
  1074. X   command is available to recipients that lets them find out if anyone has 
  1075. X   changed the body of the message since the message was signed.
  1076. X
  1077. X   Example:
  1078. X
  1079. X          SIGNED
  1080. X      
  1081. X      Duane L. Stone
  1082. X      App. Dev. Mgr.
  1083. X
  1084. XSupersedes:
  1085. X
  1086. X   A pointer to a previously submitted Journal item.
  1087. X
  1088. X   Example:
  1089. X
  1090. X      Supersedes: <MDC,1234,>
  1091. X
  1092. X
  1093. X--- last line of the file --
  1094. SHAR_EOF
  1095. chmod 0444 test/test.mail || echo "restore of test/test.mail fails"
  1096. echo "x - extracting utils/Makefile.SH (Text)"
  1097. sed 's/^X//' << 'SHAR_EOF' > utils/Makefile.SH &&
  1098. Xcase $CONFIG in
  1099. X'')
  1100. X    if test ! -f config.sh; then
  1101. X    ln ../config.sh . || \
  1102. X    ln ../../config.sh . || \
  1103. X    ln ../../../config.sh . || \
  1104. X    (echo "Can't find config.sh."; exit 1)
  1105. X    fi
  1106. X    . ./config.sh
  1107. X    ;;
  1108. Xesac
  1109. Xcase "$0" in
  1110. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  1111. Xesac
  1112. X
  1113. Xecho "Extracting utils/Makefile (with variable substitutions)"
  1114. Xcat >Makefile <<!GROK!THIS!
  1115. X
  1116. X# @(#)$Id: Makefile.SH,v 4.1 90/04/28 22:44:26 syd Exp $
  1117. X#
  1118. X#  Makefile for the Elm system utilities
  1119. X#
  1120. X#    Copyright (c) 1986, 1987 Dave Taylor
  1121. X#    Copyright (c) 1988, 1989, 1990 USENET Community Trust
  1122. X#
  1123. X# Bug reports, patches, comments, suggestions should be sent to:
  1124. X#
  1125. X#    Syd Weinstein - elm@DSI.COM
  1126. X#            dsinc!elm
  1127. X#
  1128. X# $Log:    Makefile.SH,v $
  1129. X# Revision 4.1  90/04/28  22:44:26  syd
  1130. X# checkin of Elm 2.3 as of Release PL0
  1131. X# 
  1132. X#
  1133. X# Variables
  1134. X#    Variables established by Configure
  1135. XCC        =    $cc
  1136. XCCFLAGS        =    $ccflags $xencf
  1137. XCHMOD        =    $chmod
  1138. XCP        =    $cp
  1139. XDEST        =    $bin
  1140. XECHO        =    $echo
  1141. XLFLAGS        =    $ldflags $xenlf
  1142. XLIB        =    $lib
  1143. XLIB2        =     $libs
  1144. XLIBS        =    $termlib $dbm
  1145. XLINT        =    $lint
  1146. XLN        =    $ln
  1147. XMAKE        =    $make
  1148. XMV        =    $mv
  1149. XOPTIMIZE    =    $optimize
  1150. XRM        =     $rm -f
  1151. XTOUCH        =    $touch
  1152. X!GROK!THIS!
  1153. X
  1154. Xcat >>Makefile <<'!NO!SUBS!'
  1155. X#    Variables you may want to manually edit
  1156. X#        If you want debug logging then you'll
  1157. X#        want to uncomment the following.
  1158. X#DEBUG        =    -DDEBUG
  1159. X
  1160. X#    Other general variables
  1161. XBIN        =    ../bin
  1162. XCFLAGS        =    $(CCFLAGS) $(OPTIMIZE) -I$(INCLDIR) $(DEBUG) $(DACSNET) 
  1163. XINCLDIR        =    ../hdrs
  1164. XLINTFLAGS    =    -I$(INCLDIR)
  1165. XSHELL        =    /bin/sh
  1166. X
  1167. X#    Lists
  1168. X#        List of installed programs - excludes wnewmail, which is
  1169. X#        handled separately
  1170. XINSTALL_LIST    =    $(DEST)/answer        \
  1171. X            $(DEST)/arepdaemon    \
  1172. X            $(DEST)/autoreply    \
  1173. X            $(DEST)/checkalias    \
  1174. X            $(DEST)/fastmail    \
  1175. X            $(DEST)/frm        \
  1176. X            $(DEST)/listalias    \
  1177. X            $(DEST)/messages    \
  1178. X            $(DEST)/newalias    \
  1179. X            $(DEST)/newmail        \
  1180. X            $(DEST)/printmail    \
  1181. X            $(DEST)/readmsg
  1182. X
  1183. X#        List of remotely install programs
  1184. XREMOTE_LIST    =    $(REMOTE)$(DEST)/answer        \
  1185. X            $(REMOTE)$(DEST)/arepdaemon    \
  1186. X            $(REMOTE)$(DEST)/autoreply    \
  1187. X            $(REMOTE)$(DEST)/checkalias    \
  1188. X            $(REMOTE)$(DEST)/fastmail    \
  1189. X            $(REMOTE)$(DEST)/frm        \
  1190. X            $(REMOTE)$(DEST)/listalias    \
  1191. X            $(REMOTE)$(DEST)/messages    \
  1192. X            $(REMOTE)$(DEST)/newalias    \
  1193. X            $(REMOTE)$(DEST)/newmail    \
  1194. X            $(REMOTE)$(DEST)/printmail    \
  1195. X            $(REMOTE)$(DEST)/readmsg
  1196. X
  1197. X#        List of programs in bin directory
  1198. XBINARY_LIST    =    $(BIN)/answer        \
  1199. X            $(BIN)/arepdaemon    \
  1200. X            $(BIN)/autoreply    \
  1201. X            $(BIN)/checkalias    \
  1202. X            $(BIN)/fastmail        \
  1203. X            $(BIN)/frm        \
  1204. X            $(BIN)/listalias    \
  1205. X            $(BIN)/messages        \
  1206. X            $(BIN)/newalias        \
  1207. X            $(BIN)/newmail        \
  1208. X            $(BIN)/printmail    \
  1209. X            $(BIN)/readmsg
  1210. X
  1211. X#        List of programs to $(LINT) - only C programs
  1212. XLINT_LIST    =    answer_lint    \
  1213. X            arepdaemon_lint    \
  1214. X            autoreply_lint    \
  1215. X            fastmail_lint    \
  1216. X            frm_lint    \
  1217. X            listalias_lint    \
  1218. X            newalias_lint    \
  1219. X            newmail_lint    \
  1220. X            readmsg_lint
  1221. X
  1222. X#    List of all object files in all util programs (used in parallel makes)
  1223. XUTIL_OBJ    =    answer.o        \
  1224. X            arepdaem.o         \
  1225. X            autoreply.o        \
  1226. X            expand.o        \
  1227. X            fastmail.o        \
  1228. X            from.o            \
  1229. X            listalias.o        \
  1230. X            newalias.o        \
  1231. X            newmail.o        \
  1232. X            readmsg.o        \
  1233. X            ../src/opt_utils.o    \
  1234. X            ../src/string2.o    \
  1235. X            ../src/validname.o
  1236. X
  1237. X#    Lists of source and object files for each C program
  1238. XANSWER_SRC    =    answer.c ../src/opt_utils.c ../src/string2.c
  1239. XANSWER_OBJ    =    answer.o ../src/opt_utils.o ../src/string2.o
  1240. XAREPDAEMON_SRC    =    arepdaem.c ../src/opt_utils.c ../src/errno.c
  1241. XAREPDAEMON_OBJ    =    arepdaem.o ../src/opt_utils.o ../src/errno.o
  1242. XAUTOREPLY_SRC    =    autoreply.c ../src/opt_utils.c
  1243. XAUTOREPLY_OBJ    =    autoreply.o ../src/opt_utils.o
  1244. XFASTMAIL_SRC    =    fastmail.c ../src/opt_utils.c
  1245. XFASTMAIL_OBJ    =    fastmail.o ../src/opt_utils.o
  1246. XFRM_SRC        =    from.c expand.c ../src/opt_utils.c ../src/string2.c
  1247. XFRM_OBJ        =    from.o expand.o ../src/opt_utils.o ../src/string2.o
  1248. XLISTALIAS_SRC    =    listalias.c
  1249. XLISTALIAS_OBJ    =    listalias.o
  1250. XNEWALIAS_SRC    =    newalias.c ../src/validname.c ../src/opt_utils.c ../src/string2.c
  1251. XNEWALIAS_OBJ    =    newalias.o ../src/validname.o ../src/opt_utils.o ../src/string2.o
  1252. XNEWMAIL_SRC    =    newmail.c expand.c ../src/opt_utils.c ../src/string2.c
  1253. XNEWMAIL_OBJ    =    newmail.o expand.o ../src/opt_utils.o ../src/string2.o
  1254. XREADMSG_SRC    =    readmsg.c expand.c ../src/opt_utils.c ../src/string2.c
  1255. XREADMSG_OBJ    =    readmsg.o expand.o ../src/opt_utils.o ../src/string2.o
  1256. X
  1257. X# Standard targets
  1258. Xall:            objects $(BINARY_LIST)
  1259. X
  1260. X#    This unusual target enables highly efficial compilation of object files
  1261. X#    on systems that have the parallel make feature.
  1262. Xobjects:        $& $(UTIL_OBJ)
  1263. X
  1264. Xinstall:        $(INSTALL_LIST) $(DEST)/wnewmail
  1265. X
  1266. Xuninstall:        
  1267. X            $(RM) $(INSTALL_LIST) $(DEST)/wnewmail
  1268. X
  1269. X#    This is the only target that gets installed even if not out-of-date
  1270. X#    with respect the files from which it is installed.
  1271. Xrmt-install:        rmt-defined
  1272. X            -$(MV) $(DEST)/answer $(DEST)/answer.old
  1273. X            -$(MV) $(DEST)/arepdaemon $(DEST)/arepdaemon.old
  1274. X            -$(MV) $(DEST)/autoreply $(DEST)/autoreply.old
  1275. X            -$(MV) $(DEST)/checkalias $(DEST)/checkalias.old
  1276. X            -$(MV) $(DEST)/fastmail $(DEST)/fastmail.old
  1277. X            -$(MV) $(DEST)/frm $(DEST)/frm.old
  1278. X            -$(MV) $(DEST)/listalias $(DEST)/listalias.old
  1279. X            -$(MV) $(DEST)/messages $(DEST)/messages.old
  1280. X            -$(MV) $(DEST)/newalias $(DEST)/newalias.old
  1281. X            -$(MV) $(DEST)/newmail $(DEST)/newmail.old
  1282. X            -$(MV) $(DEST)/printmail $(DEST)/printmail.old
  1283. X            -$(MV) $(DEST)/readmsg $(DEST)/readmsg.old
  1284. X            -$(MV) $(DEST)/wnewmail $(DEST)/wnewmail.old
  1285. X            -$(RM) $(DEST)/answer.old
  1286. X            -$(RM) $(DEST)/arepdaemon.old
  1287. X            -$(RM) $(DEST)/autoreply.old
  1288. X            -$(RM) $(DEST)/checkalias.old
  1289. X            -$(RM) $(DEST)/fastmail.old
  1290. X            -$(RM) $(DEST)/frm.old
  1291. X            -$(RM) $(DEST)/listalias.old
  1292. X            -$(RM) $(DEST)/messages.old
  1293. X            -$(RM) $(DEST)/newalias.old
  1294. X            -$(RM) $(DEST)/newmail.old
  1295. X            -$(RM) $(DEST)/printmail.old
  1296. X            -$(RM) $(DEST)/readmsg.old
  1297. X            -$(RM) $(DEST)/wnewmail.old
  1298. X            $(CP) $(REMOTE_LIST) $(DEST)
  1299. X            $(LN) $(DEST)/newmail $(DEST)/wnewmail
  1300. X            $(CHMOD) a+rx $(INSTALL_LIST)
  1301. X
  1302. Xrmt-defined:
  1303. X    @(if [ "$(REMOTE)" = "" ];\
  1304. X      then\
  1305. X        $(ECHO) "You need to define 'REMOTE' as the remote file system";\
  1306. X        $(ECHO) "for this particular command. The easiest way to do this";\
  1307. X        $(ECHO) "to type:";\
  1308. X        $(ECHO) "        make REMOTE=<remote file system> rmt-install";\
  1309. X        exit 1;\
  1310. X      fi);
  1311. X
  1312. X#    This rule allows us to put lint output for each program on the
  1313. X#    same file, but make sure we start off fresh each time.
  1314. Xlint:            
  1315. X            $(RM) LINT.OUT; $(MAKE) -$(MAKEFLAGS) $(LINT_LIST)
  1316. X
  1317. Xclean:            
  1318. X            $(RM) $(UTIL_OBJ) $(BINARY_LIST)
  1319. X
  1320. X# Dependencies and rules
  1321. X#    Dependencies and rules for compiling and linting C programs
  1322. X.PRECIOUS:        $(INCLDIR)/defs.h $(INCLDIR)/elm.h $(INCLDIR)/headers.h
  1323. X
  1324. X$(BIN)/answer:        $(ANSWER_OBJ)
  1325. X            $(CC) $(LFLAGS) -o $@ $(ANSWER_OBJ) $(LIB2)
  1326. X
  1327. Xanswer_lint:        $(ANSWER_SRC)
  1328. X            $(LINT) $(LINTFLAGS) $(ANSWER_SRC) >> LINT.OUT
  1329. X
  1330. X$(BIN)/arepdaemon:    $(AREPDAEMON_OBJ)
  1331. X            $(CC) $(LFLAGS) -o $@ $(AREPDAEMON_OBJ) $(LIB2)
  1332. X
  1333. Xarepdaemon_lint:    $(AREPDAEMON_SRC)
  1334. X            $(LINT) $(LINTFLAGS) $(AREPDAEMON_SRC) >> LINT.OUT
  1335. X
  1336. X$(BIN)/autoreply:    $(AUTOREPLY_OBJ)
  1337. X            $(CC) $(LFLAGS) -o $@ $(AUTOREPLY_OBJ) $(LIB2)
  1338. X
  1339. Xautoreply_lint:        $(AUTOREPLY_SRC)
  1340. X            $(LINT) $(LINTFLAGS) $(AUTOREPLY_SRC) >> LINT.OUT
  1341. X
  1342. X$(BIN)/fastmail:    $(FASTMAIL_OBJ)
  1343. X            $(CC) $(LFLAGS) -o $@ $(FASTMAIL_OBJ) $(LIB2)
  1344. X
  1345. Xfastmail_lint:        $(FASTMAIL_SRC)
  1346. X            $(LINT) $(LINTFLAGS) $(FASTMAIL_SRC) >> LINT.OUT
  1347. X
  1348. X$(BIN)/frm:        $(FRM_OBJ)
  1349. X            $(CC) $(LFLAGS) -o $@ $(FRM_OBJ) $(LIB2)
  1350. X
  1351. Xfrm_lint:        $(FRM_SRC)
  1352. X            $(LINT) $(LINTFLAGS) $(FRM_SRC) >> LINT.OUT
  1353. X
  1354. X$(BIN)/listalias:    $(LISTALIAS_OBJ)
  1355. X            $(CC) $(LFLAGS) -o $@ $(LISTALIAS_OBJ) $(LIB2)
  1356. X
  1357. Xlistalias_lint:        $(LISTALIAS_SRC)
  1358. X            $(LINT) $(LINTFLAGS) $(LISTALIAS_SRC) >> LINT.OUT
  1359. X
  1360. X$(BIN)/newalias:    $(NEWALIAS_OBJ)
  1361. X            $(CC) $(LFLAGS) -o $@ $(NEWALIAS_OBJ) $(LIB2)
  1362. X
  1363. Xnewalias_lint:        $(NEWALIAS_SRC)
  1364. X            $(LINT) $(LINTFLAGS) $(NEWALIAS_SRC) >> LINT.OUT
  1365. X
  1366. X$(BIN)/newmail:        $(NEWMAIL_OBJ)
  1367. X            $(CC) $(LFLAGS) -o $@ $(NEWMAIL_OBJ) $(LIB2)
  1368. X
  1369. Xnewmail_lint:        $(NEWMAIL_SRC)
  1370. X            $(LINT) $(LINTFLAGS) $(NEWMAIL_SRC) >> LINT.OUT
  1371. X
  1372. X$(BIN)/readmsg:        $(READMSG_OBJ)
  1373. X            $(CC) $(LFLAGS) -o $@ $(READMSG_OBJ) $(LIB2)
  1374. X
  1375. Xreadmsg_lint:        $(READMSG_SRC)
  1376. X            $(LINT) $(LINTFLAGS) $(READMSG_SRC) >> LINT.OUT
  1377. X
  1378. X
  1379. X#    Rules to make shell scripts in bin directory
  1380. X$(BIN)/checkalias:    checkalias
  1381. X            $(CP) $? $@
  1382. X            $(CHMOD) u+w,a+rx $@
  1383. X
  1384. X$(BIN)/messages:    messages
  1385. X            $(CP) $? $@
  1386. X            $(CHMOD) u+w,a+rx $@
  1387. X
  1388. X$(BIN)/printmail:    printmail
  1389. X            $(CP) $? $@
  1390. X            $(CHMOD) u+w,a+rx $@
  1391. X
  1392. X#    Dependencies of header files upon other header files they include
  1393. X$(INCLDIR)/defs.h:    $(INCLDIR)/../config.h $(INCLDIR)/sysdefs.h
  1394. X            $(CHMOD) u+w $@
  1395. X            $(TOUCH) $@
  1396. X
  1397. X$(INCLDIR)/elm.h:    $(INCLDIR)/curses.h $(INCLDIR)/defs.h
  1398. X            $(CHMOD) u+w $@
  1399. X            $(TOUCH) $@
  1400. X
  1401. X$(INCLDIR)/headers.h:    $(INCLDIR)/curses.h $(INCLDIR)/defs.h
  1402. X            $(CHMOD) u+w $@
  1403. X            $(TOUCH) $@
  1404. X
  1405. X#    Rules to make objects from src directory
  1406. X../src/opt_utils.o:
  1407. X            cd ../src; $(MAKE) -$(MAKEFLAGS) opt_utils.o
  1408. X
  1409. X../src/string2.o:
  1410. X            cd ../src; $(MAKE) -$(MAKEFLAGS) string2.o
  1411. X
  1412. X../src/validname.o:
  1413. X            cd ../src; $(MAKE) -$(MAKEFLAGS) validname.o
  1414. X
  1415. X#    Dependencies of C object files
  1416. Xanswer.o:    $(INCLDIR)/defs.h
  1417. Xarepdaem.o:    $(INCLDIR)/defs.h
  1418. Xautoreply.o:    $(INCLDIR)/defs.h
  1419. Xexpand.o:    $(INCLDIR)/defs.h
  1420. Xfastmail.o:    $(INCLDIR)/defs.h $(INCLDIR)/patchlevel.h
  1421. Xfrom.o:        $(INCLDIR)/defs.h
  1422. Xlistalias.o:    $(INCLDIR)/defs.h $(INCLDIR)/sysdefs.h
  1423. Xnewalias.o:    $(INCLDIR)/defs.h $(INCLDIR)/sysdefs.h
  1424. Xnewmail.o:    $(INCLDIR)/defs.h
  1425. Xreadmsg.o:    $(INCLDIR)/defs.h
  1426. X
  1427. X#    Dependencies and rules for installing programs from bin directory
  1428. X$(DEST)/answer:        $(BIN)/answer
  1429. X            -$(MV) $@ $@.old
  1430. X            -$(RM) $@.old
  1431. X            $(CP) $? $@
  1432. X            $(CHMOD) a+x $@
  1433. X
  1434. X$(DEST)/arepdaemon:    $(BIN)/arepdaemon
  1435. X            -$(MV) $@ $@.old
  1436. X            -$(RM) $@.old
  1437. X            $(CP) $? $@
  1438. X            $(CHMOD) a+x $@
  1439. X
  1440. X$(DEST)/autoreply:    $(BIN)/autoreply
  1441. X            -$(MV) $@ $@.old
  1442. X            -$(RM) $@.old
  1443. X            $(CP) $? $@
  1444. X            $(CHMOD) a+x $@
  1445. X            $(CHMOD) u+s $@
  1446. X
  1447. X$(DEST)/checkalias:    $(BIN)/checkalias
  1448. X            -$(MV) $@ $@.old
  1449. X            -$(RM) $@.old
  1450. X            $(CP) $? $@
  1451. X            $(CHMOD) a+rx $@
  1452. X
  1453. X$(DEST)/fastmail:    $(BIN)/fastmail
  1454. X            -$(MV) $@ $@.old
  1455. X            -$(RM) $@.old
  1456. X            $(CP) $? $@
  1457. X            $(CHMOD) a+x $@
  1458. X
  1459. X$(DEST)/frm:        $(BIN)/frm
  1460. X            -$(MV) $@ $@.old
  1461. X            -$(RM) $@.old
  1462. X            $(CP) $? $@
  1463. X            $(CHMOD) a+x $@
  1464. X
  1465. X$(DEST)/listalias:    $(BIN)/listalias
  1466. X            -$(MV) $@ $@.old
  1467. X            -$(RM) $@.old
  1468. X            $(CP) $? $@
  1469. X            $(CHMOD) a+x $@
  1470. X
  1471. X$(DEST)/messages:    $(BIN)/messages
  1472. X            -$(MV) $@ $@.old
  1473. X            -$(RM) $@.old
  1474. X            $(CP) $? $@
  1475. X            $(CHMOD) a+rx $@
  1476. X
  1477. X$(DEST)/newalias:    $(BIN)/newalias
  1478. X            -$(MV) $@ $@.old
  1479. X            -$(RM) $@.old
  1480. X            $(CP) $? $@
  1481. X            $(CHMOD) a+x $@
  1482. X
  1483. X$(DEST)/newmail:    $(BIN)/newmail
  1484. X            -$(MV) $@ $@.old
  1485. X            -$(RM) $@.old
  1486. X            $(RM) $@
  1487. X            $(CP) $? $@
  1488. X            $(CHMOD) a+x $@
  1489. X
  1490. X$(DEST)/printmail:    $(BIN)/printmail
  1491. X            -$(MV) $@ $@.old
  1492. X            -$(RM) $@.old
  1493. X            $(CP) $? $@
  1494. X            $(CHMOD) a+rx $@
  1495. X
  1496. X$(DEST)/readmsg:    $(BIN)/readmsg
  1497. X            -$(MV) $@ $@.old
  1498. X            -$(RM) $@.old
  1499. X            $(CP) $? $@
  1500. X            $(CHMOD) a+x $@
  1501. X
  1502. X$(DEST)/wnewmail:    $(DEST)/newmail
  1503. X            -$(MV) $@ $@.old
  1504. X            -$(RM) $@.old
  1505. X            $(RM) $@
  1506. X            $(LN) $? $@
  1507. X
  1508. X!NO!SUBS!
  1509. SHAR_EOF
  1510. chmod 0444 utils/Makefile.SH || echo "restore of utils/Makefile.SH fails"
  1511. echo "x - extracting utils/answer.c (Text)"
  1512. sed 's/^X//' << 'SHAR_EOF' > utils/answer.c &&
  1513. X
  1514. Xstatic char rcsid[] = "@(#)$Id: answer.c,v 4.1 90/04/28 22:44:27 syd Exp $";
  1515. X
  1516. X/*******************************************************************************
  1517. X *  The Elm Mail System  -  $Revision: 4.1 $   $State: Exp $
  1518. X *
  1519. X *             Copyright (c) 1986, 1987 Dave Taylor
  1520. X *             Copyright (c) 1988, 1989, 1990 USENET Community Trust
  1521. X *******************************************************************************
  1522. X * Bug reports, patches, comments, suggestions should be sent to:
  1523. X *
  1524. X *    Syd Weinstein, Elm Coordinator
  1525. X *    elm@DSI.COM            dsinc!elm
  1526. X *
  1527. X *******************************************************************************
  1528. X * $Log:    answer.c,v $
  1529. X * Revision 4.1  90/04/28  22:44:27  syd
  1530. X * checkin of Elm 2.3 as of Release PL0
  1531. X * 
  1532. X *
  1533. X ******************************************************************************/
  1534. X
  1535. X/** This program is a phone message transcription system, and
  1536. X    is designed for secretaries and the like, to allow them to
  1537. X    painlessly generate electronic mail instead of paper forms.
  1538. X
  1539. X    Note: this program ONLY uses the local alias file, and does not
  1540. X      even read in the system alias file at all.
  1541. X
  1542. X**/
  1543. X
  1544. X#include <stdio.h>
  1545. X#include <fcntl.h>
  1546. X#include <ctype.h>
  1547. X
  1548. X#include "defs.h"            /* ELM system definitions      */
  1549. X
  1550. X#define  ELM        "elm"        /* where the elm program lives */
  1551. X
  1552. X#define  answer_temp_file    "/tmp/answer."
  1553. X
  1554. Xstatic char ident[] = { WHAT_STRING };
  1555. X
  1556. Xstruct alias_rec user_hash_table  [MAX_UALIASES];
  1557. X
  1558. Xint user_data;        /* fileno of user data file   */
  1559. X
  1560. Xchar *expand_group(), *get_alias_address(), *get_token(), *strip_parens(),
  1561. X    *shift_lower();
  1562. X
  1563. Xmain()
  1564. X{
  1565. X    FILE *fd;
  1566. X    char *address, buffer[LONG_STRING], tempfile[SLEN], *cp;
  1567. X    char  name[SLEN], user_name[SLEN];
  1568. X    int   msgnum = 0, eof;
  1569. X    
  1570. X    read_alias_files();
  1571. X
  1572. X    while (1) {
  1573. X      if (msgnum > 9999) msgnum = 0;
  1574. X    
  1575. X      printf("\n-------------------------------------------------------------------------------\n");
  1576. X
  1577. Xprompt:   printf("\nMessage to: ");
  1578. X      if (fgets(user_name, SLEN, stdin) == NULL) {
  1579. X        putchar('\n');
  1580. X        exit(0);
  1581. X      }
  1582. X      if(user_name[0] == '\0')
  1583. X        goto prompt;
  1584. X      
  1585. X      cp = &user_name[strlen(user_name)-1];
  1586. X      if(*cp == '\n') *cp = '\0';
  1587. X      if(user_name[0] == '\0')
  1588. X        goto prompt;
  1589. X
  1590. X      if ((strcmp(user_name,"quit") == 0) ||
  1591. X          (strcmp(user_name,"exit") == 0) ||
  1592. X          (strcmp(user_name,"done") == 0) ||
  1593. X          (strcmp(user_name,"bye")  == 0))
  1594. X         exit(0);
  1595. X
  1596. X      if (translate(user_name, name) == 0)
  1597. X        goto prompt;
  1598. X
  1599. X      address = get_alias_address(name, 1, 0);
  1600. X
  1601. X      printf("address '%s'\n", address);
  1602. X
  1603. X      if (address == NULL || strlen(address) == 0) {
  1604. X        printf("Sorry, could not find '%s' [%s] in list!\n", user_name, 
  1605. X           name);
  1606. X        goto prompt;
  1607. X      }
  1608. X
  1609. X      sprintf(tempfile, "%s%d", answer_temp_file, msgnum++);
  1610. X
  1611. X      if ((fd = fopen(tempfile,"w")) == NULL)
  1612. X        exit(printf("** Fatal Error: could not open %s to write\n",
  1613. X         tempfile));
  1614. X
  1615. X
  1616. X      printf("\nEnter message for %s ending with a blank line.\n\n", 
  1617. X         user_name);
  1618. X
  1619. X      fprintf(fd,"\n\n");
  1620. X
  1621. X      do {
  1622. X       printf("> ");
  1623. X       if (! (eof = (fgets(buffer, SLEN, stdin) == NULL))) 
  1624. X         fprintf(fd, "%s", buffer);
  1625. X      } while (! eof && strlen(buffer) > 1);
  1626. X    
  1627. X      fclose(fd);
  1628. X      sprintf(buffer, 
  1629. X         "((%s -s \"While You Were Out\" %s ; %s %s) & ) < %s > /dev/null",
  1630. X         ELM, strip_parens(address), remove_cmd, tempfile, tempfile);
  1631. X
  1632. X      system(buffer);
  1633. X    }
  1634. X}
  1635. X
  1636. Xint
  1637. Xtranslate(fullname, name)
  1638. Xchar *fullname, *name;
  1639. X{
  1640. X    /** translate fullname into name..
  1641. X           'first last'  translated to first_initial - underline - last
  1642. X           'initial last' translated to initial - underline - last
  1643. X        Return 0 if error.
  1644. X    **/
  1645. X    register int i, lastname = 0, len;
  1646. X
  1647. X    for (i=0, len = strlen(fullname); i < len; i++) {
  1648. X
  1649. X      if (isupper(fullname[i]))
  1650. X         fullname[i] = tolower(fullname[i]);
  1651. X
  1652. X      if (fullname[i] == ' ') 
  1653. X        if (lastname) {
  1654. X          printf(
  1655. X          "** Can't have more than 'FirstName LastName' as address!\n");
  1656. X          return(0);
  1657. X        }
  1658. X        else
  1659. X          lastname = i+1;
  1660. X    
  1661. X    }
  1662. X
  1663. X    if (lastname) 
  1664. X      sprintf(name, "%c_%s", fullname[0], (char *) fullname + lastname);
  1665. X    else
  1666. X      strcpy(name, fullname);
  1667. X
  1668. X    return(1);
  1669. X}
  1670. X
  1671. X        
  1672. Xread_alias_files()
  1673. X{
  1674. X    /** read the user alias file **/
  1675. X
  1676. X    char fname[SLEN];
  1677. X    int  hash;
  1678. X
  1679. X    sprintf(fname,  "%s/.elm/aliases.hash", getenv("HOME")); 
  1680. X
  1681. X    if ((hash = open(fname, O_RDONLY)) == -1) 
  1682. X      exit(printf("** Fatal Error: Could not open %s!\n", fname));
  1683. X
  1684. X    read(hash, user_hash_table, sizeof user_hash_table);
  1685. X    close(hash);
  1686. X
  1687. X    sprintf(fname,  "%s/.elm/aliases.data", getenv("HOME")); 
  1688. X
  1689. X    if ((user_data = open(fname, O_RDONLY)) == -1) 
  1690. X      return;
  1691. X}
  1692. X
  1693. Xchar *get_alias_address(name, mailing, depth)
  1694. Xchar *name;
  1695. Xint   mailing, depth;
  1696. X{
  1697. X    /** return the line from either datafile that corresponds 
  1698. X        to the specified name.  If 'mailing' specified, then
  1699. X        fully expand group names.  Returns NULL if not found.
  1700. X        Depth is the nesting depth, and varies according to the
  1701. X        nesting level of the routine.  **/
  1702. X
  1703. X    static char buffer[VERY_LONG_STRING];
  1704. X    int    loc;
  1705. X
  1706. X    name = shift_lower(name);
  1707. X    if ((loc = find(name, user_hash_table, MAX_UALIASES)) >= 0) {
  1708. X      lseek(user_data, ntohl(user_hash_table[loc].byte), 0L);
  1709. X      get_line(user_data, buffer);
  1710. X      if (buffer[0] == '!' && mailing)
  1711. X        return( (char *) expand_group(buffer, depth));
  1712. X      else
  1713. X        return( (char *) buffer);
  1714. X    }
  1715. X    
  1716. X    return( (char *) NULL);
  1717. X}
  1718. X
  1719. Xchar *expand_group(members, depth)
  1720. Xchar *members;
  1721. Xint   depth;
  1722. X{
  1723. X    /** given a group of names separated by commas, this routine
  1724. X        will return a string that is the full addresses of each
  1725. X        member separated by spaces.  Depth is the current recursion
  1726. X        depth of the expansion (for the 'get_token' routine) **/
  1727. X
  1728. X    char   buffer[VERY_LONG_STRING];
  1729. X    char   buf[LONG_STRING], *word, *address, *bufptr;
  1730. X
  1731. X    strcpy(buf, members);     /* parameter safety! */
  1732. X    buffer[0] = '\0';    /* nothing in yet!   */
  1733. X    bufptr = (char *) buf;    /* grab the address  */
  1734. X    depth++;        /* one more deeply into stack */
  1735. X
  1736. X    while ((word = (char *) get_token(bufptr, "!, ", depth)) != NULL) {
  1737. X      if ((address = (char *) get_alias_address(word, 1, depth)) == NULL) {
  1738. X        fprintf(stderr, "Alias %s not found for group expansion!", word);
  1739. X        return( (char *) NULL);
  1740. X      }
  1741. X      else if (strcmp(buffer,address) != 0) {
  1742. X        sprintf(buffer,"%s %s", buffer, address);
  1743. X      }
  1744. X
  1745. X      bufptr = NULL;
  1746. X    }
  1747. X
  1748. X    return( (char *) buffer);
  1749. X}
  1750. X
  1751. Xint
  1752. Xfind(word, table, size)
  1753. Xchar *word;
  1754. Xstruct alias_rec table[];
  1755. Xint size;
  1756. X{
  1757. X    /** find word and return loc, or -1 **/
  1758. X    register int loc;
  1759. X    
  1760. X    if (strlen(word) > 20)
  1761. X      exit(printf("Bad alias name: %s.  Too long.\n", word));
  1762. X
  1763. X    loc = hash_it(word, size);
  1764. X
  1765. X    while (strcmp(word, table[loc].name) != 0) {
  1766. X      if (table[loc].name[0] == '\0') 
  1767. X        return(-1);
  1768. X      loc = (loc + 1) % size; 
  1769. X    }
  1770. X
  1771. X    return(loc);
  1772. X}
  1773. X
  1774. Xint
  1775. Xhash_it(string, table_size)
  1776. Xchar *string;
  1777. Xint   table_size;
  1778. X{
  1779. X    /** compute the hash function of the string, returning
  1780. X        it (mod table_size) **/
  1781. X
  1782. X    register int i, sum = 0;
  1783. X    
  1784. X    for (i=0; string[i] != '\0'; i++)
  1785. X      sum += (int) string[i];
  1786. X
  1787. X    return(sum % table_size);
  1788. X}
  1789. X
  1790. Xget_line(fd, buffer)
  1791. Xint fd;
  1792. Xchar *buffer;
  1793. X{
  1794. X    /* read from file fd.  End read upon reading either 
  1795. X       EOF or '\n' character (this is where it differs 
  1796. X       from a straight 'read' command!) */
  1797. X
  1798. X    register int i= 0;
  1799. X    char     ch;
  1800. X
  1801. X    while (read(fd, &ch, 1) > 0)
  1802. X      if (ch == '\n' || ch == '\r') {
  1803. X        buffer[i] = 0;
  1804. X        return;
  1805. X      }
  1806. X      else
  1807. X        buffer[i++] = ch;
  1808. X}
  1809. X
  1810. Xprint_long(buffer, init_len)
  1811. Xchar *buffer;
  1812. Xint   init_len;
  1813. X{
  1814. X    /** print buffer out, 80 characters (or less) per line, for
  1815. X        as many lines as needed.  If 'init_len' is specified, 
  1816. X        it is the length that the first line can be.
  1817. X    **/
  1818. X
  1819. X    register int i, loc=0, space, length, len; 
  1820. X
  1821. X    /* In general, go to 80 characters beyond current character
  1822. X       being processed, and then work backwards until space found! */
  1823. X
  1824. X    length = init_len;
  1825. X
  1826. X    do {
  1827. X      if (strlen(buffer) > loc + length) {
  1828. X        space = loc + length;
  1829. X        while (buffer[space] != ' ' && space > loc + 50) space--;
  1830. X        for (i=loc;i <= space;i++)
  1831. X          putchar(buffer[i]);
  1832. X        putchar('\n');
  1833. X        loc = space;
  1834. X      }
  1835. X      else {
  1836. X        for (i=loc, len = strlen(buffer);i < len;i++)
  1837. X          putchar(buffer[i]);
  1838. X        putchar('\n');
  1839. X        loc = len;
  1840. X      }
  1841. X      length = 80;
  1842. X    } while (loc < strlen(buffer));
  1843. X}
  1844. X
  1845. X/****
  1846. X     The following is a newly chopped version of the 'strtok' routine
  1847. X  that can work in a recursive way (up to 20 levels of recursion) by
  1848. SHAR_EOF
  1849. echo "End of part 23"
  1850. echo "File utils/answer.c is continued in part 24"
  1851. echo "24" > s2_seq_.tmp
  1852. exit 0
  1853.