home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Tools / mlist / mlist.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  33.9 KB  |  1,622 lines

  1. /* mlist: list maintaining and viewing tool */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Tools/mlist/RCS/mlist.c,v 6.0 1991/12/18 20:31:28 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Tools/mlist/RCS/mlist.c,v 6.0 1991/12/18 20:31:28 jpo Rel $
  9.  *
  10.  * $Log: mlist.c,v $
  11.  * Revision 6.0  1991/12/18  20:31:28  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include    "head.h"
  19. #include    "adr.h"
  20. #include    "or.h"
  21. #include    "dl.h"
  22. #include     "alias.h"
  23. #include    "chan.h"
  24. #include     "retcode.h"
  25. #include    "ap.h"
  26. #include    <pwd.h>
  27. #include    <sys/stat.h>
  28. #include    "sys.file.h"
  29. #include    <signal.h>
  30. #include    <isode/cmd_srch.h>
  31.  
  32. int (*work_proc) ();
  33. int (*menu_proc) ();
  34.  
  35. static int init();
  36. static void user_init();
  37. static int display();
  38. static int display_menu();
  39. static int modify();
  40. static int modify_menu();
  41. static int verifyList();
  42. static int verifyUser();
  43. static int inList();
  44. static int addUser();
  45. static int isPP();
  46. static int removeUser();
  47. static int findUser();
  48. static void openpager();
  49. static void closepager();
  50. static void changeAdrType();
  51. static int m_createList();
  52. static int m_alterInLine();
  53. static int m_addReq();
  54. static int m_delReq();
  55. static int m_createListFile();
  56. static int m_alterExpansion();
  57. static int permission();
  58. static void listLists();
  59. static int isModerator();
  60. static int listOnLocal();
  61. static void master_modify();
  62. static void restrict_modify();
  63. static char *lowerfy ();
  64. extern int errno;
  65. extern char *compress();
  66.  
  67. /* copied from Lib/tai/tai_chan.c */
  68. static CMD_TABLE   chtbl_ad_order[] = {
  69.     "usa",            CH_USA_ONLY,
  70.     "us",            CH_USA_ONLY,
  71.     "uk",            CH_UK_ONLY,
  72.     "usapref",        CH_USA_PREF,
  73.     "uspref",        CH_USA_PREF,
  74.     "ukpref",        CH_UK_PREF,
  75.     0,            -1
  76.     };
  77.  
  78.  
  79. extern Name    *new_Name();
  80. extern char    *loc_dom_site,
  81.         *loc_dom_mta,
  82.         *loc_dist_prefix,
  83.         *list_tbl_comment,
  84.         *ad_getlocal();
  85. extern char    *tbldfldir;
  86. char    *pager;
  87. FILE    *out;
  88. char    *list_table_file, *userAlias;
  89. int    haveUid, userId;
  90. int    superUser,
  91.     curmode,
  92.     menudriven,
  93. #ifdef UKORDER
  94.     dmnorder = CH_UK_PREF,
  95. #else
  96.     dmnorder = CH_USA_ONLY,
  97. #endif
  98.     pipeopen = 0,
  99.     adrType = AD_822_TYPE;
  100.  
  101. typedef    struct _desc {
  102.     char    *name;
  103.     char    *desc;
  104. } Desc;
  105.  
  106. Desc    *Descriptions = NULL;
  107. int    noLists = 0;
  108. static void init_descs();
  109.  
  110. main (argc, argv)
  111. int    argc;
  112. char    **argv;
  113. {
  114.     int i, args;
  115.  
  116.     init(argv[0]);
  117.  
  118.     superUser = FALSE;
  119.     menudriven = TRUE;
  120.  
  121.     if (strcmp(argv[0], "malias") == 0) {
  122.         work_proc = display;
  123.         menu_proc = display_menu;
  124.     } else {
  125.         work_proc = modify;
  126.         menu_proc = modify_menu;
  127.     }
  128.     i = 1;
  129.     userAlias = NULLCP;
  130.     haveUid = NOTOK;
  131.     args = TRUE;
  132.  
  133.     while (args == TRUE && i < argc) {
  134.         if (lexequ(argv[i], "-help") == 0) {
  135.             printf("%s [-order 'domain_order'] [-user 'username'] [-uid 'user Id'] [-x] [-r] [listname ...]\n",
  136.                    argv[0]);
  137.             exit(0);
  138.         } else if (lexequ(argv[i], "-x") == 0) {
  139.             adrType = AD_X400_TYPE;
  140.         } else if (lexequ(argv[i], "-r") == 0) {
  141.             adrType = AD_822_TYPE;
  142.         } else if (lexequ(argv[i], "-user") == 0) {
  143.             /* run as -user foo */
  144.             if (isPP() == NOTOK) {
  145.                 fprintf(stderr,
  146.                     "You are not a mail superuser and so cannot use the '%s' flag\n",
  147.                     argv[i]);
  148.                 exit(1);
  149.             }
  150.             if (i+1 < argc) 
  151.                 userAlias = argv[++i];
  152.             else {
  153.                 fprintf(stderr,
  154.                     "No user name given with flag '%s'\n",
  155.                     argv[i]);
  156.                 exit (0);
  157.             }
  158.         } else if (lexequ(argv[i], "-uid") == 0) {
  159.             /* run as -uid 6 */
  160.             if (isPP() == NOTOK) {
  161.                 fprintf(stderr,
  162.                     "You are not a mail superuser and so cannot use the '%s' flag\n",
  163.                     argv[i]);
  164.                 exit(1);
  165.             }
  166.             if (i+1 < argc) {
  167.                 haveUid = OK;
  168.                 userId = atoi(argv[++i]);
  169.             } else {
  170.                 fprintf (stderr,
  171.                      "No user id given with flag '%s'\n",
  172.                      argv[i]);
  173.                 exit (0);
  174.             }
  175.         } else if (lexequ(argv[i], "-order") == 0) {
  176.             if (i+1 < argc) {
  177.                 if ((dmnorder = cmd_srch(argv[++i], 
  178.                              chtbl_ad_order)) == NOTOK) {
  179.                     fprintf(stderr,
  180.                         "Unknown domain ordering '%s'\n",
  181.                         argv[i]);
  182.                     exit (0);
  183.                 }
  184.             } else {
  185.                 fprintf(stderr,
  186.                     "No domain ordering given with flag '%s'\n",
  187.                     argv[i]);
  188.                 exit (0);
  189.             }
  190.         } else
  191.             args = FALSE;
  192.         if (args == TRUE)
  193.             i++;
  194.     }
  195.                     
  196.     user_init();
  197.         
  198.     if (i == argc)
  199.         (*menu_proc)();
  200.     else {
  201.         menudriven = FALSE;
  202.         for (; i < argc; i++)
  203.             (*work_proc) (argv[i]);
  204.     }
  205. }
  206.  
  207. /*   */
  208. /* initialisation routines */
  209. static Table    *List = NULLTBL;
  210.  
  211. extern    char    *list_tbl;
  212.  
  213. static int init(myname)
  214. char    *myname;
  215. {
  216.     char    buf[BUFSIZ];
  217.     sys_init(myname);
  218.     or_myinit();
  219.     if ((pager = getenv("PAGER")) == NULL)
  220.         pager = "more";
  221.     if ((List = tb_nm2struct(list_tbl)) == NULLTBL) {
  222.         fprintf(stderr, "Cannot initialise table 'list'\n");
  223.         exit(1);
  224.     }
  225.     if (List->tb_file[0] == '/')
  226.         strcpy(buf, List->tb_file);
  227.     else
  228.         sprintf(buf,"%s/%s",tbldfldir,List->tb_file);
  229.     list_table_file = strdup(buf);
  230. }
  231.  
  232. struct passwd    *pwd;
  233. ADDR        *adr;
  234. extern char    *postmaster,
  235.         *pplogin;
  236.  
  237.  
  238. static int isPP()
  239. {
  240.     RP_Buf    rp;
  241.     int    uid;
  242.     struct passwd    *tmp;
  243.     ADDR    *tmpadr;
  244.  
  245.     if ((uid = getuid()) == 0)
  246.         /* super user */
  247.         return OK;
  248.     if ((tmp = getpwuid(uid)) == NULL) {
  249.         fprintf(stderr, "Cannot get your passwd entry\n");
  250.         exit(1);
  251.     }
  252.     tmpadr = adr_new(tmp->pw_name, AD_ANY_TYPE, 0);
  253.  
  254.     if (rp_isbad(ad_parse(tmpadr, &rp, dmnorder))) {
  255.         fprintf(stderr,
  256.             "Cannot parse your mail address\nReason : %s\n",
  257.             rp.rp_line);
  258.         exit(1);
  259.     }
  260.  
  261.     if ((strcmp(tmp->pw_name, pplogin) == 0)
  262.         || (strcmp(tmpadr->ad_r822adr, postmaster) == 0)) {
  263.         adr_free(tmpadr);
  264.         return OK;
  265.     }
  266.     adr_free(tmpadr);
  267.     return NOTOK;
  268. }
  269.     
  270. static void user_init ()
  271. {
  272.     RP_Buf    rp;
  273.     if (userAlias != NULLCP) {
  274.         if ((pwd = getpwnam(userAlias)) == NULL) {
  275.             fprintf(stderr,
  276.                 "Cannot get passwd entry for user '%s'\n",
  277.                 userAlias);
  278.             exit (1);
  279.         }
  280.         printf("Running as user '%s'\n", userAlias);
  281.     } else if (haveUid == OK) {
  282.         if ((pwd = getpwuid(userId)) == NULL) {
  283.             fprintf (stderr,
  284.                  "Cannot get passwd entry for uid '%d'\n",
  285.                  userId);
  286.             exit (1);
  287.         }
  288.         printf("Running as uid '%d'\n", userId);
  289.     } else {
  290.         if ((pwd = getpwuid(getuid())) == NULL) {
  291.             fprintf(stderr, "Cannot get your passwd entry\n");
  292.             exit(1);
  293.         }
  294.     }
  295.     adr = adr_new(pwd->pw_name, AD_ANY_TYPE, 0);
  296.  
  297.     if (rp_isbad(ad_parse(adr, &rp, dmnorder))) {
  298.         fprintf(stderr,
  299.             "Cannot parse your mail address\nReason : %s\n",
  300.             rp.rp_line);
  301.         exit(1);
  302.     }
  303.     if ((strcmp(pwd->pw_name, pplogin) == 0)
  304.         || (strcmp(adr->ad_r822adr, postmaster) == 0)) {
  305.         printf ("You are a mail super-user\n");
  306.         superUser = TRUE;
  307.     }
  308. }
  309.     
  310. /*   */
  311. /* display mode routines */
  312.  
  313. static char *getx400name(name)
  314. char    *name;
  315. {
  316.     OR_ptr    or;
  317.     char    buf[BUFSIZ];
  318.  
  319.     or = or_buildpn(name);
  320.     or = or_default(or);
  321.     or_or2std(or, buf, 0);
  322.     or_free(or);
  323.     return strdup(buf);
  324. }
  325.  
  326. static dl *readList(name)
  327. char    *name;
  328. {
  329.     dl *list;
  330.     char    newname[BUFSIZ], *x400name, *local;
  331.     
  332.     if (tb_getdl(name,&list,OK) == OK
  333.         || list != NULL)
  334.         return list;
  335.  
  336.     /* try local variant of list */
  337.     if ((local = ad_getlocal(name,(name[0] == '/') ? AD_X400_TYPE : AD_822_TYPE)) != NULLCP) {
  338.         if (tb_getdl(local, &list,OK) == OK
  339.             || list != NULL) {
  340.             free(local);
  341.             return list;
  342.         }
  343.         free(local);
  344.     }
  345.  
  346.     /* try various conversion on name */
  347.  
  348.     /* with locdomsite */
  349.     sprintf(newname, "%s@%s",name,loc_dom_site);
  350.     if (tb_getdl(newname,&list,OK) == OK
  351.         || list != NULL)
  352.         return list;
  353.  
  354.     /* with locdommta */
  355.     sprintf(newname, "%s@%s",name,loc_dom_mta);
  356.     if (tb_getdl(newname,&list,OK) == OK
  357.         || list != NULL)
  358.         return list;
  359.  
  360.     /* x400 type address */
  361.     x400name = getx400name(name);
  362.     if (tb_getdl(x400name, &list,OK) == OK
  363.         || list != NULL) {
  364.         free(x400name);
  365.         return list;
  366.     }
  367.     free(x400name);
  368.     return NULL;
  369. }
  370.  
  371. static int writeList(list)
  372. dl    *list;
  373. {
  374.     Name    *ix;
  375.  
  376.     openpager();
  377.  
  378.     if (strncmp(list->dl_listname, loc_dist_prefix, strlen(loc_dist_prefix)) == 0) {
  379.         char    *ix2 = list->dl_listname + strlen(loc_dist_prefix);
  380.         if (pipeopen)
  381.             fprintf(out, "Local Expansion of List: %s\t%s\n-------------------------\n",
  382.                 ix2, list->dl_desc);
  383.     } else {
  384.         if (pipeopen)
  385.             fprintf(out,"List: %s\t%s\n-----\n",list->dl_listname,list->dl_desc);
  386.     }
  387.     if (pipeopen)
  388.         fprintf(out,"Moderator's mail address: %s\n",
  389.             (list -> dl_moderator == NULL) ? postmaster : list -> dl_moderator);
  390.     if (isModerator(list)) {
  391.         if ((ix = list -> dl_uids) != NULL) {
  392.             if (pipeopen)
  393.                 fprintf(out,"Moderator%s uids: ",
  394.                     (ix -> next == NULL) ? "" : "s");
  395.             while (ix != NULL) {
  396.                 if (pipeopen)
  397.                     fprintf(out,"%*s%s\n",
  398.                         (ix == list -> dl_uids) ? 0 : strlen("Moderators uids: "),
  399.                         "",
  400.                         ix -> name);
  401.                 ix = ix -> next;
  402.             }
  403.         }
  404.     }
  405.  
  406.     ix = list -> dl_list;
  407.     if (pipeopen)
  408.         fprintf(out,"Expands to -> ");
  409.     while (ix != NULL && pipeopen) {
  410.         if (pipeopen)
  411.             fprintf(out,"%*s%s\t%s\n",
  412.                 (ix == list -> dl_list) ? 0 : strlen("Expands to -> "),
  413.                 "",
  414.                 ix -> name,
  415.                 (ix -> file == NULL) ? "{inline-member}" : "");
  416.         ix = ix -> next;
  417.     }
  418.     if (pipeopen)
  419.         fprintf(out,"\n");
  420.     closepager();
  421. }
  422.         
  423. static int display(name)
  424. char    *name;
  425. {
  426.     dl    *list;
  427.     char    distList[BUFSIZ];
  428.  
  429.     (void) sprintf(distList, "%s%s", loc_dist_prefix, name);
  430.  
  431.     if ((list = readList(name)) != NULL
  432.         || (list = readList(distList)) != NULL) {
  433.         if (permission(list) != SECRMODE) {
  434.             writeList(list);
  435.             dl_free(list);
  436.         } else
  437.             printf("You do not have permission to read this list\n");
  438.     } else
  439.         printf("unknown list '%s'\n",name);
  440. }
  441.  
  442. static int display_menu()
  443. {
  444.     int    quit = FALSE;
  445.     char    buf[BUFSIZ], *tix;
  446.  
  447.     while (quit == FALSE) {
  448.         printf("\n> ");
  449.         fflush (stdout);
  450.         if (gets (buf) == NULL)
  451.             exit(OK);
  452.         (void) compress (buf, buf);
  453.         if (buf[0] == NULL || strlen(buf) == 0) {
  454.             printf("\nType 'h' or '?' for help\n");
  455.             continue;
  456.         }
  457.         if (strlen(buf) == 1)
  458.             switch (buf[0])
  459.             {
  460.                 case '\0':
  461.                 case '\n':
  462.                 printf("\nType 'h' or '?' for help\n");
  463.                 continue;
  464.                 case 'q':
  465.                 case 'Q':
  466.                 printf("\nBye...\n");
  467.                 quit = TRUE;
  468.                 continue;
  469.                 case 't':
  470.                 case 'T':
  471.                 tix = &(buf[0]);
  472.                 while (*tix != '\0'
  473.                        && !isspace(*tix))
  474.                     tix ++;
  475.                 while (*tix != '\0'
  476.                        && isspace(*tix))
  477.                     tix++;
  478.                 if (tix == buf)
  479.                     tix++;
  480.                 changeAdrType(tix);
  481.                 continue;
  482.                 case 'h':
  483.                 case 'H':
  484.                 case '?':
  485.                 fprintf(stdout,
  486.                     "\nOptions are:\n'l' ist the lists,\n'q' uit,\n't'ype - change type of addresses you're inputing,\n\nor the name of the list you wish to view\n");
  487.                 continue;
  488.                 case 'l':
  489.                 case 'L':
  490.                 listLists();
  491.                 continue;
  492.                 default:
  493.                 break;
  494.             }
  495.         display(buf);
  496.     }
  497. }
  498.  
  499. /*   */
  500. /* modify mode routines */
  501.  
  502. static int modify(name)
  503. char    *name;
  504. {
  505.     dl        *list;
  506.     char        distList[BUFSIZ];
  507.     struct stat    statbuf;
  508.     int         fd;
  509.     char    buf[BUFSIZ], *inListname;
  510.  
  511.     (void) sprintf(distList, "%s%s", loc_dist_prefix, name);
  512.     if ((list = readList(name)) == NULL
  513.         && (list = readList(distList)) == NULL) {
  514.         fprintf(stderr, "Unknown list '%s'\n",name);
  515.         return NOTOK;
  516.     }
  517.     
  518.     /* check in line or in file */
  519.     if (list->dl_file == NULLCP) {
  520.         if (confirm("This list is an in-line list\nThis program is unable to modify in-line lists\nDo you want to send a request to change this ?") == TRUE)
  521.             m_alterInLine(list);
  522.         dl_free(list);
  523.         return NOTOK;
  524.     }
  525.  
  526. /*    if (listOnLocal(list -> dl_listname, hostname) == FALSE) {
  527.         printf("List '%s' is expanded on machine '%s'\n",name,hostname);
  528.         if (isModerator(list) == TRUE) {
  529.             if (confirm("do you wish to mail a request to change the expansion point ?") == TRUE)
  530.                 m_alterExpansion(list);
  531.         } else
  532.             printf("This tool can not modify remotely expanded lists\n");
  533.         dl_free(list);
  534.         return NOTOK;
  535.     }*/
  536.  
  537.     if (stat(list->dl_file, &statbuf) < 0) {
  538.         if (isModerator(list) == FALSE) {
  539.             sprintf(buf, "File for list '%s' can only be created by a moderator\nDo you wish to send a message to the list moderator ?",name);
  540.             if (confirm(buf) == TRUE)
  541.                 m_createListFile(list);
  542.             dl_free(list);
  543.             return NOTOK;
  544.         }
  545.         
  546.         /* work out modes for creation of file */
  547.         printf("Creating file for list '%s'\n",name);
  548.         printf("Do you want other users to be able to add / remove their own names ?");
  549.         if (confirm (NULLCP) == TRUE) {
  550.             printf("Do you want them to be able to add / remove anyone else's name ?");
  551.             if (confirm(NULLCP) == TRUE)
  552.                 curmode = FREEMODE;
  553.             else
  554.                 curmode = PUBMODE;
  555.         } else {
  556.             printf("Do you want others to be able to see who is on the list ?");
  557.             if (confirm (NULLCP))
  558.                 curmode = PRIVMODE;
  559.             else
  560.                 curmode = SECRMODE;
  561.         }
  562.         
  563.         printf ("Creating file '%s' with list mode ", list->dl_file);
  564.         switch (curmode) {
  565.             case FREEMODE:
  566.             printf("free\n");
  567.             break;
  568.             case PUBMODE:
  569.             printf("public\n");
  570.             break;
  571.             case PRIVMODE:
  572.             printf("private\n");
  573.             break;
  574.             case SECRMODE:
  575.             printf("secret\n");
  576.             break;
  577.         }
  578.         if ((fd = creat(list->dl_file, curmode)) < 0) {
  579.             printf("Unable to create file '%s'\n",list->dl_file);
  580.             dl_free(list);
  581.             return NOTOK;
  582.         }
  583.         (void) fchmod(fd, curmode);
  584.         
  585.     } else {
  586.         curmode = (int) statbuf.st_mode;
  587.         curmode = curmode & 0777;
  588.         
  589.         if (!(isModerator(list)
  590.               || curmode == PUBMODE
  591.               || curmode == FREEMODE)) {
  592.             printf ("list '%s' can only be updated by it's moderators\n",name);
  593.             if (curmode != SECRMODE) {
  594.                 printf("Do you want to see who is on the list ? ");
  595.                 if (confirm (NULLCP)) 
  596.                     display(name);
  597.             }
  598.             
  599.             if (inList(pwd -> pw_name, list -> dl_list, &inListname) == TRUE) {
  600.                 printf("You (%s) are already in this list\nDo you wish to mail a request to be removed",inListname);
  601.                 if (confirm(NULLCP) == TRUE)
  602.                     m_delReq(list);
  603.             } else {
  604.                 printf ("Do you wish to mail a request to be added");
  605.                 if (confirm(NULLCP) == TRUE)
  606.                     m_addReq(list);
  607.             }
  608.             dl_free(list);
  609.             return NOTOK;
  610.         }
  611.     }
  612.  
  613.     /* all prelimarys done */
  614.     printf("Modifying list '%s'\n",name);
  615.     if (isModerator(list) || curmode == FREEMODE)
  616.         master_modify(list);
  617.     else
  618.         restrict_modify(list);
  619.     return OK;
  620. }
  621.                 
  622. static int modify_menu()
  623. {
  624.     int    quit = FALSE;
  625.     char    buf[BUFSIZ],
  626.     *margv[20],
  627.     ch;
  628.     int    margc;
  629.  
  630.     while (quit == FALSE) {
  631.         printf("\n> ");
  632.         fflush (stdout);
  633.         if (gets (buf) == NULL)
  634.             exit(OK);
  635.         compress (buf, buf);
  636.         if (buf[0] == NULL || strlen(buf) == 0) {
  637.             printf("\nType 'h' or '?' for help\n");
  638.             continue;
  639.         }
  640.         margc = sstr2arg(buf, 20, margv, " \t");
  641.         if ((int)strlen(margv[0]) > 1)
  642.             ch = 'A';
  643.         else if (margv[0][0] == '?')
  644.             ch = '?';
  645.         else
  646.             ch = uptolow(margv[0][0]);
  647.         switch (ch)
  648.         {
  649.             case '\0':
  650.             case '\n':
  651.             printf("\nType 'h' or '?' for help\n");
  652.             continue;
  653.             case 'h':
  654.             case '?':
  655.             printf("\nOptions are:\n'l' ist the lists,\n'c' reate a list,\n");
  656.             printf("'p' rint 'listname' to view a list,\n'q' uit,\n't'ype - change type of addresses you're inputing,\n\nor the name of the list you wish to modify\n");
  657.             continue;
  658.             case 'q':
  659.             printf("\nBye...\n");
  660.             quit = TRUE;
  661.             continue;
  662.             case 't':
  663.             changeAdrType(margv[1]);
  664.             continue;
  665.             case 'l':
  666.             listLists();
  667.             continue;
  668.             case 'c':
  669.             m_createList();
  670.             continue;
  671.             case 'p':
  672.             if (margc > 1)
  673.                 display(margv[1]);
  674.             continue;
  675.             default:
  676.             break;
  677.         }
  678.         if (modify(margv[0]) == NOTOK)
  679.             printf("\nType 'h' or '?' for help\n");
  680.     }
  681.  
  682. }
  683.  
  684. /*   */
  685. /* routines to send messages to postmaster or moderators */
  686.  
  687. char    input[BUFSIZ];
  688.  
  689. static int getinput()
  690. {
  691.     fflush(stdout);
  692.     if (gets (input) == NULL) {
  693.         exit (1);
  694.     }
  695.     compress (input, input);
  696.     if ((strlen(input) == 0)
  697.         || ((strlen(input) == 1) && (input[0] == '\n'))) {
  698.         printf("\t-> ");
  699.         return getinput();
  700.     }
  701.     return OK;
  702. }
  703.  
  704. static int error_user()
  705. {
  706.     RP_Buf    rp;
  707.     pps_end(NOTOK, &rp);
  708. }
  709.  
  710. static int error_pps(rp)
  711. RP_Buf    *rp;
  712. {
  713.     fprintf(stderr, "pps_error: %s\n",rp->rp_line);
  714.     fflush(stderr);
  715. }
  716.  
  717. static int m_createList()
  718. {
  719.     dl    *list;
  720.     RP_Buf    rp;
  721.     printf("Please wait while I initialise things ...");
  722.     fflush(stdout);
  723.     
  724.     if (pps_1adr("Distribution/mailing List creation request",
  725.              postmaster,
  726.              &rp) != OK)
  727.         return error_pps(&rp);
  728.     printf("done\n");
  729.     printf("Name of new list -> ");
  730.     if (getinput() == NOTOK)
  731.         return error_user();
  732.     if ((list = readList(input)) != NULL) {
  733.         printf("'%s' list already exists ('%s')\n",
  734.                input,
  735.                list -> dl_listname);
  736.         dl_free(list);
  737.         return error_user();
  738.     }
  739.     if (pps_txt("\nName of new list: ",&rp) != OK)
  740.         return error_pps(&rp);
  741.     if (pps_txt(input,&rp) != OK)
  742.         return error_pps(&rp);
  743.     printf("\nDescription of list (one line only) -> ");
  744.     if (getinput() == NOTOK)
  745.         return error_user();
  746.     if (pps_txt("\nFunction: ",&rp) != OK)
  747.         return error_pps(&rp);
  748.     if (pps_txt(input,&rp) != OK)
  749.         return error_pps(&rp);
  750.     printf("\nModerators login names (separated by , again one line only)\n\t-> ");
  751.     if (getinput() == NOTOK)
  752.         return error_user();
  753.     if (pps_txt("\nModerators: ",&rp) != OK)
  754.         return error_pps(&rp);
  755.     if (pps_txt(input,&rp) != OK)
  756.         return error_pps(&rp);
  757.     if (pps_txt("\n",&rp) != OK)
  758.         return error_pps(&rp);
  759.  
  760.     printf("\nDo you want to pass this message on to the postmaster ?");
  761.     if (confirm (NULLCP) == FALSE) {
  762.         pps_end(NOTOK,&rp);
  763.         return 0;
  764.     }
  765.     printf("Please wait while I tidy things up ...");
  766.     fflush(stdout);
  767.     if (pps_end(OK,&rp) != OK)
  768.         return error_pps(&rp);
  769.     printf("done\n");
  770.     fflush(stdout);
  771.     printf ("Your request has been passed to an administrator\n");
  772.     printf ("You will be notified in a short time when the list has been created\n");
  773.     printf ("You can then use this program to enter names into the list\n\n");
  774.     fflush (stdout);
  775.     return 0;
  776. }
  777.  
  778. static int m_alterInLine(list)
  779. dl    *list;
  780. {
  781.     RP_Buf    rp;
  782.     printf("Sending message to postmaster...");
  783.     fflush(stdout);
  784.     if (pps_1adr("Distribution/mailing list alteration request",
  785.              postmaster,
  786.              &rp) != OK)
  787.         return error_pps(&rp);
  788.     if (pps_txt("\nPlease could you change the list ",&rp) != OK)
  789.         return error_pps(&rp);
  790.     if (pps_txt(list->dl_listname,&rp) != OK)
  791.         return error_pps(&rp);
  792.     if (pps_txt("\nfrom being inline to being contained within a file\n\nThank you\n",&rp) != OK)
  793.         return error_pps(&rp);
  794.     if (pps_end(OK,&rp) != OK)
  795.         return error_pps(&rp);
  796.     printf("sent\n");
  797.     fflush(stdout);
  798.     return 0;
  799. }
  800.  
  801. static int m_addReq(list)
  802. dl    *list;
  803. {
  804.     RP_Buf    rp;
  805.     printf("Sending request message to moderator...");
  806.     fflush(stdout);
  807.     if (pps_1adr("List addition request",
  808.              (list -> dl_moderator == NULL) ? postmaster : list -> dl_moderator,
  809.              &rp) != OK) 
  810.         return error_pps(&rp);
  811.  
  812.     if (pps_txt("\nPlease add me to the list ",&rp) != OK) 
  813.         return error_pps(&rp);
  814.     if (pps_txt(list -> dl_listname,&rp) != OK)
  815.         return error_pps(&rp);
  816.     if (pps_txt("\n\nThank you.\n",&rp) != OK)
  817.         return error_pps(&rp);
  818.     if (pps_end(OK,&rp) != OK)
  819.         return error_pps(&rp);
  820.     printf("sent\n");
  821.     fflush(stdout);
  822.     return 0;
  823. }
  824.  
  825. static int m_delReq(list)
  826. dl    *list;
  827. {
  828.     RP_Buf    rp;
  829.     printf("Sending request message to moderator...");
  830.     fflush(stdout);
  831.     if (pps_1adr("Deletion from list request",
  832.              (list -> dl_moderator == NULL) ? postmaster : list -> dl_moderator,
  833.              &rp) != OK) 
  834.         return error_pps(&rp);
  835.  
  836.     if (pps_txt("\nPlease remove me from the list ",&rp) != OK) 
  837.         return error_pps(&rp);
  838.     if (pps_txt(list -> dl_listname,&rp) != OK)
  839.         return error_pps(&rp);
  840.     if (pps_txt("\n\nThank you.\n",&rp) != OK)
  841.         return error_pps(&rp);
  842.     if (pps_end(OK,&rp) != OK)
  843.         return error_pps(&rp);
  844.     printf("sent\n");
  845.     fflush(stdout);
  846.     return 0;
  847. }
  848.  
  849. static int m_createListFile(list)
  850. dl    *list;
  851. {
  852.     RP_Buf    rp;
  853.     printf("Sending request message to moderator...");
  854.     fflush(stdout);
  855.     if (pps_1adr("List file creation request",
  856.              (list -> dl_moderator == NULL) ? postmaster : list -> dl_moderator,
  857.              &rp) != OK) 
  858.         return error_pps(&rp);
  859.  
  860.     if (pps_txt("Please create the file for the list ",&rp) != OK) 
  861.         return error_pps(&rp);
  862.     if (pps_txt(list -> dl_listname,&rp) != OK)
  863.         return error_pps(&rp);
  864.     if (pps_txt("\n\nThank you.\n",&rp) != OK)
  865.         return error_pps(&rp);
  866.     if (pps_end(OK,&rp) != OK)
  867.         return error_pps(&rp);
  868.     printf("sent\n");
  869.     fflush(stdout);
  870.     return 0;
  871. }
  872.  
  873. static int m_alterExpansion(list)
  874. dl    *list;
  875. {
  876.     RP_Buf    rp;
  877.     printf("Please wait while I initialise things ...");
  878.     fflush(stdout);
  879.     if (pps_1adr("List expansion alteration request",
  880.              postmaster,
  881.              &rp) != OK)
  882.         return error_pps(&rp);
  883.  
  884.     if (pps_txt("\nPlease change the host the list ",&rp) != OK) 
  885.         return error_pps(&rp);
  886.     if (pps_txt(list -> dl_listname,&rp) != OK)
  887.         return error_pps(&rp);
  888.     if (pps_txt(" is distributed from\nto ->",&rp) != OK)
  889.         return error_pps(&rp);
  890.     printf("done\n");
  891.     printf("Please input the host the list should be distrubuted from ->");
  892.     if (getinput() == NOTOK)
  893.         return error_user();
  894.     if (pps_txt(input,&rp) != OK)
  895.         return error_pps(&rp);
  896.     if (pps_txt("\n\nThank you.\n",&rp) != OK)
  897.         return error_pps(&rp);
  898.  
  899.     printf("Please wait while I tidy things up ...");
  900.     fflush(stdout);
  901.     if (pps_end(OK,&rp) != OK)
  902.         return error_pps(&rp);
  903.     printf("done\n");
  904.     fflush(stdout);
  905.     return 0; 
  906. }
  907.  
  908. /*   */
  909. /* general routines */
  910. #define    INC    3
  911.  
  912. static void init_descs()
  913. {
  914.     int    size = INC;
  915.     char    buf[BUFSIZ],
  916.         *temp,
  917.         *name,
  918.         *ix;
  919.     FILE    *fd;
  920.  
  921.     if ((fd = fopen(list_table_file, "r")) == NULL) {
  922.         fprintf(stderr,
  923.             "Unable to open list of list file '%s' : %s\n",
  924.             list_table_file, sys_errname (errno));
  925.         return;
  926.     }
  927.  
  928.     Descriptions = (Desc *) calloc((unsigned int) size, sizeof(Desc));
  929.     
  930.     while (fgets(buf, BUFSIZ, fd) != NULLCP) {
  931.         temp = strdup(buf);
  932.         if (temp[0] == '\n') {
  933.             free(temp);
  934.             continue;
  935.         }
  936.         
  937.         if (temp[0] != '#') {
  938.             if (strncmp(temp,loc_dist_prefix,strlen(loc_dist_prefix)) == 0)
  939.                 name = temp+strlen(loc_dist_prefix);
  940.             else
  941.                 name = temp;
  942.             ix = index(name, ':');
  943.             if (ix == NULL) {
  944.                 printf("unknown syntax line in list table '%s'\n",temp);
  945.                 free(temp);
  946.                 continue;
  947.             }
  948.             *ix++ = '\0';
  949.             ix = rindex(ix, ',');
  950.             if (ix != NULL)
  951.                 ix++;
  952.         } else {
  953.             if (strncmp(&temp[1], 
  954.                     list_tbl_comment, 
  955.                     strlen(list_tbl_comment)) == 0) {
  956.                 name = temp+strlen(list_tbl_comment)+1;
  957.                 ix = NULL;
  958.             } else
  959.                 continue;
  960.         }
  961.         if (noLists >= size) {
  962.             size += INC;
  963.             Descriptions = (Desc *) realloc((char *) Descriptions, 
  964.                             (unsigned int)(size*sizeof(Desc)));
  965.         }
  966.  
  967.         Descriptions[noLists].name = strdup(name);
  968.         if (ix == NULLCP)
  969.             Descriptions[noLists].desc = NULLCP;
  970.         else
  971.             Descriptions[noLists].desc = strdup(ix);
  972.         noLists++;
  973.         free(temp);
  974.     }
  975.     Descriptions = (Desc *) realloc((char *) Descriptions,
  976.                     (unsigned int) (noLists*sizeof(Desc)));
  977. }
  978.  
  979. static void listLists()
  980. {
  981.     int    i;
  982.  
  983.     openpager();
  984.     
  985.     if (Descriptions == NULL)
  986.         init_descs();
  987.     for (i = 0; i < noLists && pipeopen; i++) {    
  988.         if (Descriptions[i].desc == NULLCP)
  989.             fprintf(out, "%s", Descriptions[i].name);
  990.         else
  991.             fprintf(out, "%-30s: %s",
  992.                 Descriptions[i].name,Descriptions[i].desc);
  993.     }
  994.     closepager();
  995. }
  996.  
  997. /*   */
  998. /* pager routines */
  999.  
  1000. SFP    oldpipe;
  1001.  
  1002. static SFD piped(sig)
  1003. int sig;
  1004. {
  1005.     pipeopen = 0;
  1006. }
  1007.  
  1008. static void openpager()
  1009. {
  1010.     oldpipe = signal(SIGPIPE, piped);
  1011.     if (isatty(1) == 0)
  1012.         out = stdout;
  1013.     else if ((out = popen(pager,"w")) == NULL) {
  1014.         fprintf(stderr, "unable to start pager '%s': %s\n",
  1015.             pager, sys_errname (errno));
  1016.         out = stdout;
  1017.     }
  1018.     pipeopen = 1;
  1019. }    
  1020.  
  1021. static void closepager()
  1022. {
  1023.     if (out != stdout) {
  1024.         pclose(out);
  1025.         out = stdout;
  1026.     }
  1027.     pipeopen = 0;
  1028.     signal(SIGPIPE, oldpipe);
  1029. }
  1030.  
  1031. /* */
  1032.  
  1033. confirm (str)
  1034. char    *str;
  1035. {
  1036.     register char   c;
  1037.  
  1038.     if (str != NULL) {
  1039.         fputs (str, stdout);
  1040.         fflush(stdout);
  1041.     }
  1042.     printf (" [y/n] ");
  1043.     fflush (stdout);
  1044.  
  1045.     c = ttychar ();
  1046.  
  1047.     switch (c)
  1048.     {
  1049.     case 'Y':
  1050.     case 'y':
  1051.         printf ("yes\r\n");
  1052.         fflush (stdout);
  1053.         return (TRUE);
  1054.  
  1055.     case 'N':
  1056.     case 'n':
  1057.         printf ("no\r\n");
  1058.         fflush(stdout);
  1059.         return (FALSE);
  1060.     default:
  1061.         printf ("Type y or n\n");
  1062.         fflush(stdout);
  1063.         return (confirm (NULLCP));
  1064.     }
  1065. }
  1066.  
  1067.  
  1068. ttychar ()
  1069. {
  1070.     register int    c;
  1071.     char        buf[LINESIZE];
  1072.  
  1073.     fflush (stdout);
  1074.     if (fgets (buf, LINESIZE,  stdin) == NULL)
  1075.         exit (1);
  1076.     c = buf[0];
  1077.  
  1078.     c = toascii (c);    /* get rid of high bit */
  1079.  
  1080.     if (c == '\r')
  1081.     c = '\n';
  1082.  
  1083.     return (c);
  1084. }
  1085.  
  1086. /*   */
  1087. static int permission(list)
  1088. dl *list;
  1089. {
  1090.     struct stat    statbuf;
  1091.     int        mode;
  1092.  
  1093.     if (isModerator(list) == TRUE)
  1094.         /* allowed to do anything */
  1095.         return FREEMODE;
  1096.     if (list->dl_file == NULLCP
  1097.         || stat(list->dl_file, &statbuf) < 0)
  1098.         /* no file so can't do anything */
  1099.         return TOPMODE;
  1100.  
  1101.     mode = (int) statbuf.st_mode;
  1102.     mode = mode & 0777;
  1103.  
  1104.     return mode;
  1105. }
  1106.  
  1107. /*   */
  1108. static int listOnLocal(name, host)
  1109. char    *name,
  1110.     host[];
  1111. {
  1112.     char    *p;
  1113.  
  1114.     if ((p = index(name, '@')) == NULL) {
  1115.         /* do x400 */
  1116.         sprintf(host,"unknown");
  1117.         return FALSE;
  1118.     }
  1119.     p++;
  1120.     sprintf(host,"%s",p);
  1121.     if (strcmp(p, loc_dom_mta) == 0
  1122.         || strcmp(p, loc_dom_site) == 0)
  1123.         return TRUE;
  1124.  
  1125.     /* do x400 */
  1126.     return FALSE;
  1127. }
  1128.         
  1129. static int isModerator(list)
  1130. dl    *list;
  1131. {
  1132.     Name    *ix = list -> dl_uids;
  1133.  
  1134.     if (superUser == TRUE)
  1135.         return TRUE;
  1136.  
  1137.     while (ix != NULL && (strcmp(ix -> name, pwd -> pw_name) != 0))
  1138.         ix = ix -> next;
  1139.  
  1140.     return (ix == NULL) ? FALSE : TRUE;
  1141. }
  1142.  
  1143. /*   */
  1144. /* main modify work routines */
  1145. static char    *ix;
  1146.  
  1147. static int    getbufchar()
  1148. {
  1149.     char    ret = *ix;
  1150.     if (ret != 0) ix++;
  1151.     return (ret == 0) ? EOF : ret;
  1152. }
  1153.  
  1154. static void master_modify(list)
  1155. dl    *list;
  1156. {
  1157.     FILE    *curfp;
  1158.     int    quit = FALSE,
  1159.         done;
  1160.     char    tmpbuf[LINESIZE], *tix,
  1161.         buf[BUFSIZ],
  1162.         *adrstr, *orig_line, *inListname;
  1163.  
  1164.     if ((curfp = flckopen(list->dl_file, "r+")) == NULL) {
  1165.         fprintf (stderr, "Can't open %s: %s\n",
  1166.              list -> dl_file, sys_errname (errno));
  1167.         return;
  1168.     }
  1169.     
  1170.     flckclose(curfp);
  1171.  
  1172.     while (quit == FALSE) {
  1173.         fprintf(stdout, "\n%s%s", 
  1174.             list->dl_listname,    
  1175.             (menudriven == TRUE) ? ">> " : "> ");
  1176.         fflush(stdout);
  1177.         if (gets(tmpbuf) == NULL) {
  1178.             exit(0);
  1179.         }
  1180.         compress (tmpbuf, tmpbuf);
  1181.  
  1182.         ix = &(tmpbuf[0]);
  1183.         switch (tmpbuf[0])
  1184.         {
  1185.             case '\0':
  1186.             case '\n':
  1187.             printf("\nType 'h' or '?' for help\n");
  1188.             continue;
  1189.  
  1190.             case 't':
  1191.             case 'T':
  1192.             tix = &(tmpbuf[0]);
  1193.             while (*tix != '\0'
  1194.                    && !isspace(*tix))
  1195.                 tix ++;
  1196.             while (*tix != '\0'
  1197.                    && isspace(*tix))
  1198.                 tix++;
  1199.             if (tix == tmpbuf)
  1200.                 tix++;
  1201.             changeAdrType(tix);
  1202.             continue;
  1203.  
  1204.             case 'p':
  1205.             case 'P':
  1206.             if (tmpbuf[1] == '\0'
  1207.                 || isspace(tmpbuf[1])) {
  1208.                 ix = &(tmpbuf[1]);
  1209.                 while (*ix != '\0'
  1210.                        && isspace(*ix)) ix++;
  1211.                 display(list -> dl_listname);
  1212.                 continue;
  1213.             }
  1214.             case 'v':
  1215.             case 'V':
  1216.             if (tmpbuf[1] == '\0'
  1217.                 || isspace(tmpbuf[1])) {
  1218.                 ix = &(tmpbuf[1]);
  1219.                 while (*ix != '\0'
  1220.                        && isspace(*ix)) ix ++;
  1221.                 verifyList(list);
  1222.                 continue;
  1223.             }
  1224.             
  1225.             case 'h':
  1226.             case 'H':
  1227.             case '?':
  1228.             if (tmpbuf[1] == '\0'
  1229.                 || isspace(tmpbuf[1])) {
  1230.                 fprintf(stdout,
  1231.                     "\nOptions are:\n'p' rint list,\n'v' erify list,\n'a' dd user,\n'f' ind user,\n'r' emove users,\n'l' ist the lists,\n'c' reate a new list,\n't'ype - change type of addresses you're inputting,\n");
  1232.                 if (menudriven == TRUE)
  1233.                     fprintf(stdout, "'q' uit and return to top menu.\n\n");
  1234.                 else
  1235.                     fprintf(stdout, "'q' uit.\n\n");
  1236.                 fprintf(stdout, "If the input is none of the above options,\nit is assumed to be a user name to be added\n");
  1237.                 fflush (stdout);
  1238.                 continue;
  1239.             }
  1240.  
  1241.             case 'l':
  1242.             case 'L':
  1243.             if (tmpbuf[1] == '\0'
  1244.                 || isspace(tmpbuf[1])) {
  1245.                 listLists();
  1246.                 continue;
  1247.             }
  1248.             
  1249.             case 'c':
  1250.             case 'C':
  1251.             if (tmpbuf[1] == '\0'
  1252.                 || isspace(tmpbuf[1])) {
  1253.                 ix = &(tmpbuf[1]);
  1254.                 while (*ix != '\0' &&
  1255.                        isspace(*ix)) ix++;
  1256.                 m_createList();
  1257.                 continue;
  1258.             }
  1259.             case 'q':
  1260.             case 'Q':
  1261.             if (tmpbuf[1] == '\0'
  1262.                 || isspace(tmpbuf[1])) {
  1263.                 ix = &(tmpbuf[1]);
  1264.                 while (*ix != '\0'
  1265.                        && isspace(*ix)) ix ++;
  1266.                 if (*ix == '\0') {
  1267.                     quit = TRUE;
  1268.                     continue;
  1269.                 }
  1270.                 ix = &(tmpbuf[0]);
  1271.                 break;
  1272.             }
  1273.             case 'r':
  1274.             case 'R':
  1275.             if (tmpbuf[1] == '\0'
  1276.                 || isspace(tmpbuf[1])) {
  1277.                 ix = &(tmpbuf[1]);
  1278.                 while (*ix != '\0'
  1279.                        && isspace(*ix)) ix++;
  1280.                 if (*ix == '\0') {
  1281.                     printf ("give username to be removed (regex): ");
  1282.                     (void) fflush (stdout);
  1283.                     if (gets(tmpbuf) == NULL) 
  1284.                         exit(0);
  1285.                     compress (tmpbuf, tmpbuf);
  1286.                     ix = &(tmpbuf[0]);
  1287.                 }
  1288.                 removeUser(ix, list);
  1289.                 continue;
  1290.             }
  1291.  
  1292.             case 'f':
  1293.             case 'F':
  1294.             if (tmpbuf[1] == '\0'
  1295.                 || isspace(tmpbuf[1])) {
  1296.                 ix = &(tmpbuf[1]);
  1297.                 while (*ix != '\0'
  1298.                        && isspace(*ix)) ix++;
  1299.  
  1300.                 if (*ix == '\0') {
  1301.                     printf ("give username to search for (regex): ");
  1302.                     if (gets(tmpbuf) == NULL) 
  1303.                         exit(0);
  1304.                     compress (tmpbuf, tmpbuf);
  1305.                     ix = &(tmpbuf[0]);
  1306.                 } 
  1307.  
  1308.             
  1309.                 findUser(ix, list);
  1310.                 continue;
  1311.             }
  1312.             case 'a':
  1313.             case 'A':
  1314.             if (tmpbuf[1] == '\0'
  1315.                 || isspace(tmpbuf[1])) {
  1316.                 ix = &(tmpbuf[1]);
  1317.                 while (*ix != '\0'
  1318.                        && isspace (*ix)) ix++;
  1319.  
  1320.                 if (*ix == '\0') {
  1321.                     printf("give username to be added: ");
  1322.                     if (gets(tmpbuf) == NULL)
  1323.                         exit(0);
  1324.                     compress (tmpbuf, tmpbuf);
  1325.                     ix = &(tmpbuf[0]);
  1326.                 } 
  1327.             }
  1328.  
  1329.             default:
  1330.             break;
  1331.         }
  1332.         done = FALSE;
  1333.  
  1334.         while (done == FALSE) {
  1335.             orig_line = ix;
  1336.             if (ap_pinit(getbufchar) == BADAP) {
  1337.                 printf("Cannot parse '%s'\n",
  1338.                        orig_line);
  1339.                 done = FALSE;
  1340.             } else {
  1341.                 switch (ap_1adr()) {
  1342.                     case DONE:
  1343.                     done = TRUE;
  1344.                     break;
  1345.                     case NOTOK:
  1346.                     break;
  1347.                     default:
  1348.                     if (ap_t2s(ap_pstrt, &adrstr) != BADAP) {
  1349.                         if (rp_isbad(verifyUser(adrstr, buf)))
  1350.                             printf("Illegal address '%s'\n",
  1351.                                    adrstr);
  1352.                         else {
  1353.                             if (inList(adrstr, list -> dl_list, &inListname) == TRUE) {
  1354.                                 printf("User '%s' already in list",
  1355.                                        adrstr);
  1356.                                 if (lexequ(inListname, adrstr) != 0) 
  1357.                                     printf(" as '%s'", inListname);
  1358.                                 printf("\n");
  1359.                             } else 
  1360.                                 addUser(adrstr, list);
  1361.                         }
  1362.                         free(adrstr);
  1363.                         ap_pstrt = NULLAP;
  1364.                     }
  1365.                     break;
  1366.                 }
  1367.             }
  1368.         }
  1369.  
  1370.     }
  1371.     if (menudriven == FALSE) 
  1372.         printf("\nBye...\n");
  1373.         
  1374. }
  1375.  
  1376. static void restrict_modify(list)
  1377. dl    *list;
  1378. {
  1379.     char    buf[LINESIZE],
  1380.         adr[BUFSIZ],
  1381.         *nameinlist;
  1382.  
  1383.     printf("Would you like to see who's in the list ?");
  1384.     if (confirm(NULLCP) == TRUE) 
  1385.         display(list -> dl_listname);
  1386.     if (!rp_isbad(verifyUser(pwd->pw_name, adr))) {
  1387.         if (inList(adr, list -> dl_list, &nameinlist) == TRUE) {
  1388.        
  1389.             printf("You (%s) are already in this list\nDo you wish to be removed ?",pwd -> pw_name);
  1390.             if (confirm(NULLCP) == TRUE) {
  1391.                 sprintf(buf, "^%s$",adr);
  1392.                 removeUser(buf, list);
  1393.             } else 
  1394.                 printf("You only have permission to add or remove yourself from this list\n");
  1395.         } else {
  1396.             printf ("You (%s) are not in this list\nDo you wish to be added ?", pwd -> pw_name);
  1397.             if (confirm(NULLCP) == TRUE)
  1398.                 addUser(adr, list);
  1399.             else
  1400.                 printf("You only have permission to add or remove yourself from this list\n");
  1401.         }
  1402.     }
  1403.             
  1404. }
  1405.  
  1406. /*   */
  1407. /* checking routines */
  1408.  
  1409. static int verifyUser(name, addr)
  1410. char    *name,
  1411.     *addr;
  1412. {
  1413.     RP_Buf    rp;
  1414.     ADDR    *temp;
  1415.     int    ret,
  1416.         type;
  1417.     
  1418.     temp = adr_new(name, adrType, 0);
  1419.     
  1420.     if (rp_isbad(ret = ad_parse(temp, &rp, dmnorder)))
  1421.         fprintf(stderr, "Failed to parse '%s' (%s)\n",
  1422.             name,
  1423.             rp.rp_line);
  1424.     if (temp -> ad_r400adr != NULL 
  1425.         && temp->ad_type == AD_X400_TYPE)
  1426.         sprintf(addr, "%s", temp->ad_r400adr);
  1427.     else if (temp -> ad_r822adr != NULL)
  1428.         sprintf(addr, "%s", temp->ad_r822adr);
  1429.     adr_free(temp);
  1430.     
  1431.     return ret;
  1432. }
  1433.  
  1434. static int verifyList(list)
  1435. dl    *list;
  1436. {
  1437.     char    *name,
  1438.         buf[BUFSIZ];
  1439.  
  1440.     
  1441.     Name    *ix = list -> dl_list;
  1442.     while (ix != NULL) {
  1443.         printf("Checking '%s'...",ix -> name);
  1444.         if (!rp_isbad(verifyUser(ix -> name, buf))) {
  1445.             printf("ok\n");
  1446.             ix = ix -> next;
  1447.         } else {
  1448.             name = strdup(ix -> name);
  1449.             ix = ix -> next;
  1450.             removeUser(name,list);
  1451.             free(name);
  1452.         }
  1453. /*        if (temp != NULL) *temp = '@';*/
  1454.     }
  1455. }
  1456.  
  1457. static int inList(name, list, plistname)
  1458. char    *name;
  1459. Name    *list;
  1460. char    **plistname;
  1461. {
  1462.     while (list != NULL 
  1463.            && ap_equ(list -> name, name) != TRUE)
  1464.         list = list -> next;
  1465.     if (list != NULL)
  1466.         *plistname = list->name;
  1467.     return (list != NULL) ? TRUE : FALSE;
  1468. }
  1469.  
  1470. /*   */
  1471. /* list maintaince routines */
  1472. extern char *re_comp();
  1473. extern int re_exec();
  1474.  
  1475. static int findUser  (name, list)
  1476. char    *name;
  1477. dl    *list;
  1478. {
  1479.     char    *diag;
  1480.     Name    *ix;
  1481.  
  1482.     if ((diag = re_comp(name)) != 0) {
  1483.         fprintf(stderr,
  1484.             "re_comp error for '%s' [%s]\n", name, diag);
  1485.         return;
  1486.     }
  1487.     ix = list -> dl_list;
  1488.     openpager();
  1489.     while (ix != NULL && pipeopen) {
  1490.         if (re_exec(lowerfy(ix -> name)) == 1) {
  1491.             fprintf(out, "%s\n", ix -> name);
  1492.             fflush(stdout);
  1493.         }
  1494.         ix = ix -> next;
  1495.     }
  1496.      closepager();
  1497. }
  1498.     
  1499. static int removeUser(name, list)
  1500. char    *name;
  1501. dl    *list;
  1502. {
  1503.     char       *diag;
  1504.     Name    *ix,
  1505.         *temp;
  1506.     char    buf[BUFSIZ];
  1507.     int    len = 0,
  1508.         found;
  1509.     FILE    *curfp;
  1510.  
  1511.     if ((diag = re_comp(name)) != 0) {
  1512.         fprintf (stderr,
  1513.              "re_comp error for '%s' [%s]\n",name,diag);
  1514.         return;
  1515.     }
  1516.     if ((curfp = flckopen (list->dl_file, "r+")) == NULL) {
  1517.         fprintf (stderr, "Can't open %s: %s\n",
  1518.              list -> dl_file, sys_errname (errno));
  1519.         return;
  1520.     }
  1521.  
  1522.     rewind(curfp);
  1523.     ix = list -> dl_list;
  1524.     found = FALSE;
  1525.     while (ix != NULL) {
  1526.         temp = NULL;
  1527.         sprintf(buf, "Remove user '%s' ?", ix -> name);
  1528.         if (re_exec(lowerfy(ix -> name)) == 1 
  1529.             && confirm(buf) == TRUE) {
  1530.             /* remove from list -> dl_list */
  1531.             if (ix -> file == NULL) 
  1532.                 printf("User '%s' specified in-line, cannot remove\n",ix->name);
  1533.             else {
  1534.                 found = TRUE;
  1535.                 temp = list -> dl_list;
  1536.                 if (ix == list -> dl_list) {
  1537.                     list -> dl_list = temp -> next;
  1538.                 } else {
  1539.                     while (temp -> next != ix)
  1540.                         temp = temp -> next;
  1541.                     temp -> next = ix -> next;
  1542.                     temp = ix;
  1543.                 }
  1544.             }
  1545.         } else if (ix -> file != NULL) {
  1546.             /* put it out again */
  1547.             fputs (ix -> name, curfp);
  1548.             fputc('\n', curfp);
  1549.             len += strlen(ix -> name) + 1;
  1550.         }
  1551.         ix = ix -> next;
  1552.         if (temp != NULL) {
  1553.             temp -> next = NULL;
  1554.             name_free(temp);
  1555.         }
  1556.     }
  1557.     ftruncate(fileno(curfp), (off_t) len);
  1558.     flckclose(curfp);
  1559.     if (found == FALSE)
  1560.         printf("No matches\n");
  1561. }
  1562.  
  1563. static int addUser(name, list)
  1564. char    *name;
  1565. dl    *list;
  1566. {
  1567.     FILE    *curfp;
  1568.     Name    *temp,
  1569.         *ix;
  1570.  
  1571.     if ((curfp = flckopen(list->dl_file, "a")) == NULL) {
  1572.         fprintf (stderr, "Can't open file %s: %s\n",
  1573.              list -> dl_file, sys_errname (errno));
  1574.         return;
  1575.     }
  1576.     
  1577.     printf ("adding user '%s'\n", name);
  1578.     fputs (name, curfp);
  1579.     fputc ('\n', curfp);
  1580.     flckclose (curfp);
  1581.     temp = new_Name(name, list->dl_file);
  1582.     if (list -> dl_list == NULL)
  1583.         list -> dl_list = temp;
  1584.     else {
  1585.         ix = list -> dl_list;
  1586.  
  1587.         while (ix -> next != NULL)
  1588.             ix = ix -> next;
  1589.         ix -> next = temp;
  1590.     }
  1591. }
  1592.  
  1593. static char *lowerfy (s)
  1594. char    *s;
  1595. {
  1596.     static char    buf[BUFSIZ];
  1597.     char    *cp;
  1598.  
  1599.     for (cp = buf; *s; s++)
  1600.         if (isascii (*s) && isupper (*s))
  1601.             *cp++ = tolower (*s);
  1602.         else
  1603.             *cp ++ = *s;
  1604.     *cp = NULL;
  1605.     return buf;
  1606. }
  1607.  
  1608. static void changeAdrType(buf)
  1609. char    *buf;
  1610. {
  1611.     if (buf[0] == '\0')
  1612.         printf ("Currently inputing %s style addresses\n",
  1613.             (adrType == AD_X400_TYPE) ? "x400" : "rfc822");
  1614.     else if (lexnequ(buf, "x400", strlen("x400")) == 0)
  1615.         adrType = AD_X400_TYPE;
  1616.     else if (lexnequ(buf, "rfc822", strlen("rfc822")) == 0)
  1617.         adrType = AD_822_TYPE;
  1618.     else
  1619.         printf("Unknown address type '%s' - try %s or %s",
  1620.                buf, "x400", "rfc822");
  1621. }
  1622.