|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 31264 (0x7a20) Types: TextFile Names: »mlist.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z« └─⟦e5a54fb17⟧ └─⟦this⟧ »pp-5.0/Tools/mlist/mlist.c«
/* mlist: list maintaining and viewing tool */ # ifndef lint static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Tools/mlist/RCS/mlist.c,v 5.0 90/09/20 16:27:43 pp Exp Locker: pp $"; # endif /* * $Header: /cs/research/pp/hubris/pp-beta/Tools/mlist/RCS/mlist.c,v 5.0 90/09/20 16:27:43 pp Exp Locker: pp $ * * $Log: mlist.c,v $ * Revision 5.0 90/09/20 16:27:43 pp * rcsforce : 5.0 public release * */ #include "head.h" #include "adr.h" #include "or.h" #include "dl.h" #include "alias.h" #include "chan.h" #include "retcode.h" #include "ap.h" #include <pwd.h> #include <sys/stat.h> #include <sys/file.h> #include <signal.h> int (*work_proc) (); int (*menu_proc) (); static int init(); static void user_init(); static int display(); static int display_menu(); static int modify(); static int modify_menu(); static int verifyList(); static int verifyUser(); static int inList(); static int addUser(); static int isPP(); static int removeUser(); static int findUser(); static void openpager(); static FILE *myopen(); static int myclose(); static void closepager(); static int m_createList(); static int m_alterInLine(); static int m_addReq(); static int m_delReq(); static int m_createListFile(); static int m_alterExpansion(); static int permission(); static void listLists(); static int isModerator(); static int listOnLocal(); static void master_modify(); static void restrict_modify(); static char *lowerfy (); extern int errno; extern Name *new_Name(); extern char *loc_dom_site, *loc_dom_mta, *loc_dist_prefix, *list_tbl_comment, *ad_getlocal(); extern char *tbldfldir; char *pager; FILE *out; char *list_table_file, *userAlias; int haveUid, userId; int superUser, curmode, menudriven, pipeopen = 0; typedef struct _desc { char *name; char *desc; } Desc; Desc *Descriptions = NULL; int noLists = 0; static void init_descs(); main (argc, argv) int argc; char **argv; { int i; init(argv[0]); superUser = FALSE; menudriven = TRUE; if (strcmp(argv[0], "malias") == 0) { work_proc = display; menu_proc = display_menu; } else { work_proc = modify; menu_proc = modify_menu; } i = 1; userAlias = NULLCP; haveUid = NOTOK; if (argc > 1 && lexequ(argv[1], "-help") == 0) { printf("%s [-user 'username'] [-uid 'user Id'] [listname ...]\n", argv[0]); exit(0); } if (argc >= 3) { if (lexequ(argv[1], "-user") == 0) { /* run as -user foo */ if (isPP() == NOTOK) { fprintf(stderr, "You are not a mail superuser and so cannot use the '%s' flag\n", argv[1]); exit(1); } userAlias = argv[2]; i = 3; } else if (lexequ(argv[1], "-uid") == 0) { /* run as -uid 6 */ if (isPP() == NOTOK) { fprintf(stderr, "You are not a mail superuser and so cannot use the '%s' flag\n", argv[1]); exit(1); } haveUid = OK; userId = atoi(argv[2]); i = 3; } } user_init(); if (i == argc) (*menu_proc)(); else { menudriven = FALSE; for (; i < argc; i++) (*work_proc) (argv[i]); } } /* \f */ /* initialisation routines */ static Table *List = NULLTBL; extern char *list_tbl; static int init(myname) char *myname; { char buf[BUFSIZ]; sys_init(myname); or_myinit(); if ((pager = getenv("PAGER")) == NULL) pager = "more"; if ((List = tb_nm2struct(list_tbl)) == NULLTBL) { fprintf(stderr, "Cannot initialise table 'list'\n"); exit(1); } if (List->tb_file[0] == '/') strcpy(buf, List->tb_file); else sprintf(buf,"%s/%s",tbldfldir,List->tb_file); list_table_file = strdup(buf); } struct passwd *pwd; ADDR *adr; extern char *postmaster, *pplogin; static int isPP() { RP_Buf rp; int uid; struct passwd *tmp; ADDR *tmpadr; if ((uid = getuid()) == 0) /* super user */ return OK; if ((tmp = getpwuid(uid)) == NULL) { fprintf(stderr, "Cannot get your passwd entry\n"); exit(1); } tmpadr = adr_new(tmp->pw_name, AD_ANY_TYPE, 0); if (rp_isbad(ad_parse(tmpadr, &rp, CH_UK_PREF))) { fprintf(stderr, "Cannot parse your mail address\nReason : %s\n", rp.rp_line); exit(1); } if ((strcmp(tmp->pw_name, pplogin) == 0) || (strcmp(tmpadr->ad_r822adr, postmaster) == 0)) { adr_free(tmpadr); return OK; } adr_free(tmpadr); return NOTOK; } static void user_init () { RP_Buf rp; if (userAlias != NULLCP) { if ((pwd = getpwnam(userAlias)) == NULL) { fprintf(stderr, "Cannot get passwd entry for user '%s'\n", userAlias); exit (1); } printf("Running as user '%s'\n", userAlias); } else if (haveUid == OK) { if ((pwd = getpwuid(userId)) == NULL) { fprintf (stderr, "Cannot get passwd entry for uid '%d'\n", userId); exit (1); } printf("Running as uid '%d'\n", userId); } else { if ((pwd = getpwuid(getuid())) == NULL) { fprintf(stderr, "Cannot get your passwd entry\n"); exit(1); } } adr = adr_new(pwd->pw_name, AD_ANY_TYPE, 0); if (rp_isbad(ad_parse(adr, &rp, CH_UK_PREF))) { fprintf(stderr, "Cannot parse your mail address\nReason : %s\n", rp.rp_line); exit(1); } if ((strcmp(pwd->pw_name, pplogin) == 0) || (strcmp(adr->ad_r822adr, postmaster) == 0)) { printf ("You are a mail super-user\n"); superUser = TRUE; } } /* \f */ /* display mode routines */ static char *getx400name(name) char *name; { OR_ptr or; char buf[BUFSIZ]; or = or_buildpn(name); or = or_default(or); or_or2std(or, buf, 0); or_free(or); return strdup(buf); } static dl *readList(name) char *name; { dl *list; char newname[BUFSIZ], *x400name, *local; if (tb_getdl(name,&list,OK) == OK) return list; /* try local variant of list */ if ((local = ad_getlocal(name,(name[0] == '/') ? AD_X400_TYPE : AD_822_TYPE)) != NULLCP) { if (tb_getdl(local, &list,OK) == OK) { free(local); return list; } free(local); } /* try various conversion on name */ /* with locdomsite */ sprintf(newname, "%s@%s",name,loc_dom_site); if (tb_getdl(newname,&list,OK) == OK) return list; /* with locdommta */ sprintf(newname, "%s@%s",name,loc_dom_mta); if (tb_getdl(newname,&list,OK) == OK) return list; /* x400 type address */ x400name = getx400name(name); if (tb_getdl(x400name, &list,OK) == OK) { free(x400name); return list; } free(x400name); return NULL; } static int writeList(list) dl *list; { Name *ix; openpager(); if (strncmp(list->dl_listname, loc_dist_prefix, strlen(loc_dist_prefix)) == 0) { char *ix2 = list->dl_listname + strlen(loc_dist_prefix); if (pipeopen) fprintf(out, "Local Expansion of List: %s\t%s\n-------------------------\n", ix2, list->dl_desc); } else { if (pipeopen) fprintf(out,"List: %s\t%s\n-----\n",list->dl_listname,list->dl_desc); } if (pipeopen) fprintf(out,"Moderator's mail address: %s\n", (list -> dl_moderator == NULL) ? postmaster : list -> dl_moderator); if (isModerator(list)) { if ((ix = list -> dl_uids) != NULL) { if (pipeopen) fprintf(out,"Moderator%s uids: ", (ix -> next == NULL) ? "" : "s"); while (ix != NULL) { if (pipeopen) fprintf(out,"%*s%s\n", (ix == list -> dl_uids) ? 0 : strlen("Moderators uids: "), "", ix -> name); ix = ix -> next; } } } ix = list -> dl_list; if (pipeopen) fprintf(out,"Expands to -> "); while (ix != NULL && pipeopen) { if (pipeopen) fprintf(out,"%*s%s\t%s\n", (ix == list -> dl_list) ? 0 : strlen("Expands to -> "), "", ix -> name, (ix -> file == NULL) ? "{inline-member}" : ""); ix = ix -> next; } if (pipeopen) fprintf(out,"\n"); closepager(); } static int display(name) char *name; { dl *list; char distList[BUFSIZ]; (void) sprintf(distList, "%s%s", loc_dist_prefix, name); if ((list = readList(name)) != NULL || (list = readList(distList)) != NULL) { if (permission(list) != SECRMODE) { writeList(list); dl_free(list); } else printf("You do not have permission to read this list\n"); } else printf("unknown list '%s'\n",name); } static int display_menu() { int quit = FALSE; char buf[BUFSIZ]; while (quit == FALSE) { printf("\n> "); fflush (stdout); if (gets (buf) == NULL) exit(OK); compress (buf, buf); if (buf[0] == NULL || strlen(buf) == 0) { printf("\nType 'h' or '?' for help\n"); continue; } if (strlen(buf) == 1) switch (buf[0]) { case '\0': case '\n': printf("\nType 'h' or '?' for help\n"); continue; case 'q': printf("\nBye...\n"); quit = TRUE; continue; case 'h': case '?': fprintf(stdout, "\nOptions are:\n'l' ist the lists,\n'q' uit,\n\nor the name of the list you wish to view\n"); continue; case 'l': listLists(); continue; default: break; } display(buf); } } /* \f */ /* modify mode routines */ static int modify(name) char *name; { dl *list; char distList[BUFSIZ]; struct stat statbuf; int fd; char buf[BUFSIZ], *inListname; (void) sprintf(distList, "%s%s", loc_dist_prefix, name); if ((list = readList(name)) == NULL && (list = readList(distList)) == NULL) { fprintf(stderr, "Unknown list '%s'\n",name); return NOTOK; } /* check in line or in file */ if (list->dl_file == NULLCP) { 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) m_alterInLine(list); dl_free(list); return NOTOK; } /* if (listOnLocal(list -> dl_listname, hostname) == FALSE) { printf("List '%s' is expanded on machine '%s'\n",name,hostname); if (isModerator(list) == TRUE) { if (confirm("do you wish to mail a request to change the expansion point ?") == TRUE) m_alterExpansion(list); } else printf("This tool can not modify remotely expanded lists\n"); dl_free(list); return NOTOK; }*/ if (stat(list->dl_file, &statbuf) < 0) { if (isModerator(list) == FALSE) { 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); if (confirm(buf) == TRUE) m_createListFile(list); dl_free(list); return NOTOK; } /* work out modes for creation of file */ printf("Creating file for list '%s'\n",name); printf("Do you want other users to be able to add / remove their own names ?"); if (confirm (NULLCP) == TRUE) { printf("Do you want them to be able to add / remove anyone else's name ?"); if (confirm(NULLCP) == TRUE) curmode = FREEMODE; else curmode = PUBMODE; } else { printf("Do you want others to be able to see who is on the list ?"); if (confirm (NULLCP)) curmode = PRIVMODE; else curmode = SECRMODE; } printf ("Creating file '%s' with list mode ", list->dl_file); switch (curmode) { case FREEMODE: printf("free\n"); break; case PUBMODE: printf("public\n"); break; case PRIVMODE: printf("private\n"); break; case SECRMODE: printf("secret\n"); break; } if ((fd = creat(list->dl_file, curmode)) < 0) { printf("Unable to create file '%s'\n",list->dl_file); dl_free(list); return NOTOK; } (void) fchmod(fd, curmode); } else { curmode = (int) statbuf.st_mode; curmode = curmode & 0777; if (!(isModerator(list) || curmode == PUBMODE || curmode == FREEMODE)) { printf ("list '%s' can only be updated by it's moderators\n",name); if (curmode != SECRMODE) { printf("Do you want to see who is on the list ? "); if (confirm (NULLCP)) display(name); } if (inList(pwd -> pw_name, list -> dl_list, &inListname) == TRUE) { printf("You (%s) are already in this list\nDo you wish to mail a request to be removed",inListname); if (confirm(NULLCP) == TRUE) m_delReq(list); } else { printf ("Do you wish to mail a request to be added"); if (confirm(NULLCP) == TRUE) m_addReq(list); } dl_free(list); return NOTOK; } } /* all prelimarys done */ printf("Modifying list '%s'\n",name); if (isModerator(list) || curmode == FREEMODE) master_modify(list); else restrict_modify(list); return OK; } static int modify_menu() { int quit = FALSE; char buf[BUFSIZ], *margv[20], ch; int margc; while (quit == FALSE) { printf("\n> "); fflush (stdout); if (gets (buf) == NULL) exit(OK); compress (buf, buf); if (buf[0] == NULL || strlen(buf) == 0) { printf("\nType 'h' or '?' for help\n"); continue; } margc = sstr2arg(buf, 20, margv, " \t"); if (strlen(margv[0]) > 1) ch = 'A'; else if (margv[0][0] == '?') ch = '?'; else ch = uptolow(margv[0][0]); switch (ch) { case '\0': case '\n': printf("\nType 'h' or '?' for help\n"); continue; case 'h': case '?': printf("\nOptions are:\n'l' ist the lists,\n'c' reate a list,\n"); printf("'p' rint 'listname' to view a list,\n'q' uit,\n\nor the name of the list you wish to modify\n"); continue; case 'q': printf("\nBye...\n"); quit = TRUE; continue; case 'l': listLists(); continue; case 'c': m_createList(); continue; case 'p': if (margc > 1) display(margv[1]); continue; default: break; } if (modify(margv[0]) == NOTOK) printf("\nType 'h' or '?' for help\n"); } } /* \f */ /* routines to send messages to postmaster or moderators */ char input[BUFSIZ]; static int getinput() { RP_Buf rp; fflush(stdout); if (gets (input) == NULL) { exit (1); } compress (input, input); if ((strlen(input) == 0) || ((strlen(input) == 1) && (input[0] == '\n'))) { printf("\t-> "); return getinput(); } return OK; } static int error_user() { RP_Buf rp; pps_end(NOTOK, &rp); } static int error_pps(rp) RP_Buf *rp; { fprintf(stderr, "pps_error: %s\n",rp->rp_line); fflush(stderr); } static int m_createList() { dl *list; RP_Buf rp; printf("Please wait while I initialise things ..."); fflush(stdout); if (pps_1adr("Distribution/mailing List creation request", postmaster, &rp) != OK) return error_pps(&rp); printf("done\n"); printf("Name of new list -> "); if (getinput() == NOTOK) return error_user(); if ((list = readList(input)) != NULL) { printf("'%s' list already exists ('%s')\n", input, list -> dl_listname); dl_free(list); return error_user(); } if (pps_txt("\nName of new list: ",&rp) != OK) return error_pps(&rp); if (pps_txt(input,&rp) != OK) return error_pps(&rp); printf("\nDescription of list (one line only) -> "); if (getinput() == NOTOK) return error_user(); if (pps_txt("\nFunction: ",&rp) != OK) return error_pps(&rp); if (pps_txt(input,&rp) != OK) return error_pps(&rp); printf("\nModerators login names (separated by , again one line only)\n\t-> "); if (getinput() == NOTOK) return error_user(); if (pps_txt("\nModerators: ",&rp) != OK) return error_pps(&rp); if (pps_txt(input,&rp) != OK) return error_pps(&rp); if (pps_txt("\n",&rp) != OK) return error_pps(&rp); printf("\nDo you want to pass this message on to the postmaster ?"); if (confirm (NULLCP) == FALSE) { pps_end(NOTOK,&rp); return 0; } printf("Please wait while I tidy things up ..."); fflush(stdout); if (pps_end(OK,&rp) != OK) return error_pps(&rp); printf("done\n"); fflush(stdout); printf ("Your request has been passed to an administrator\n"); printf ("You will be notified in a short time when the list has been created\n"); printf ("You can then use this program to enter names into the list\n\n"); fflush (stdout); return 0; } static int m_alterInLine(list) dl *list; { RP_Buf rp; printf("Sending message to postmaster..."); fflush(stdout); if (pps_1adr("Distribution/mailing list alteration request", postmaster, &rp) != OK) return error_pps(&rp); if (pps_txt("\nPlease could you change the list ",&rp) != OK) return error_pps(&rp); if (pps_txt(list->dl_listname,&rp) != OK) return error_pps(&rp); if (pps_txt("\nfrom being inline to being contained within a file\n\nThank you\n",&rp) != OK) return error_pps(&rp); if (pps_end(OK,&rp) != OK) return error_pps(&rp); printf("sent\n"); fflush(stdout); return 0; } static int m_addReq(list) dl *list; { RP_Buf rp; printf("Sending request message to moderator..."); fflush(stdout); if (pps_1adr("List addition request", (list -> dl_moderator == NULL) ? postmaster : list -> dl_moderator, &rp) != OK) return error_pps(&rp); if (pps_txt("\nPlease add me to the list ",&rp) != OK) return error_pps(&rp); if (pps_txt(list -> dl_listname,&rp) != OK) return error_pps(&rp); if (pps_txt("\n\nThank you.\n",&rp) != OK) return error_pps(&rp); if (pps_end(OK,&rp) != OK) return error_pps(&rp); printf("sent\n"); fflush(stdout); return 0; } static int m_delReq(list) dl *list; { RP_Buf rp; printf("Sending request message to moderator..."); fflush(stdout); if (pps_1adr("Deletion from list request", (list -> dl_moderator == NULL) ? postmaster : list -> dl_moderator, &rp) != OK) return error_pps(&rp); if (pps_txt("\nPlease remove me from the list ",&rp) != OK) return error_pps(&rp); if (pps_txt(list -> dl_listname,&rp) != OK) return error_pps(&rp); if (pps_txt("\n\nThank you.\n",&rp) != OK) return error_pps(&rp); if (pps_end(OK,&rp) != OK) return error_pps(&rp); printf("sent\n"); fflush(stdout); return 0; } static int m_createListFile(list) dl *list; { RP_Buf rp; printf("Sending request message to moderator..."); fflush(stdout); if (pps_1adr("List file creation request", (list -> dl_moderator == NULL) ? postmaster : list -> dl_moderator, &rp) != OK) return error_pps(&rp); if (pps_txt("Please create the file for the list ",&rp) != OK) return error_pps(&rp); if (pps_txt(list -> dl_listname,&rp) != OK) return error_pps(&rp); if (pps_txt("\n\nThank you.\n",&rp) != OK) return error_pps(&rp); if (pps_end(OK,&rp) != OK) return error_pps(&rp); printf("sent\n"); fflush(stdout); return 0; } static int m_alterExpansion(list) dl *list; { RP_Buf rp; printf("Please wait while I initialise things ..."); fflush(stdout); if (pps_1adr("List expansion alteration request", postmaster, &rp) != OK) return error_pps(&rp); if (pps_txt("\nPlease change the host the list ",&rp) != OK) return error_pps(&rp); if (pps_txt(list -> dl_listname,&rp) != OK) return error_pps(&rp); if (pps_txt(" is distributed from\nto ->",&rp) != OK) return error_pps(&rp); printf("done\n"); printf("Please input the host the list should be distrubuted from ->"); if (getinput() == NOTOK) return error_user(); if (pps_txt(input,&rp) != OK) return error_pps(&rp); if (pps_txt("\n\nThank you.\n",&rp) != OK) return error_pps(&rp); printf("Please wait while I tidy things up ..."); fflush(stdout); if (pps_end(OK,&rp) != OK) return error_pps(&rp); printf("done\n"); fflush(stdout); return 0; } /* \f */ /* general routines */ #define INC 3 static void init_descs() { int size = INC; char buf[BUFSIZ], *temp, *name, *ix; FILE *fd; if ((fd = fopen(list_table_file, "r")) == NULL) { fprintf(stderr, "Unable to open list of list file '%s' : %s\n", list_table_file, sys_errname (errno)); return; } Descriptions = (Desc *) calloc((unsigned int) size, sizeof(Desc)); while (fgets(buf, BUFSIZ, fd) != NULLCP) { temp = strdup(buf); if (temp[0] == '\n') { free(temp); continue; } if (temp[0] != '#') { if (strncmp(temp,loc_dist_prefix,strlen(loc_dist_prefix)) == 0) name = temp+strlen(loc_dist_prefix); else name = temp; ix = index(name, ':'); if (ix == NULL) { printf("unknown syntax line in list table '%s'\n",temp); free(temp); continue; } *ix++ = '\0'; ix = rindex(ix, ','); if (ix != NULL) ix++; } else { if (strncmp(&temp[1], list_tbl_comment, strlen(list_tbl_comment)) == 0) { name = temp+strlen(list_tbl_comment)+1; ix = NULL; } else continue; } if (noLists >= size) { size += INC; Descriptions = (Desc *) realloc((char *) Descriptions, (unsigned int)(size*sizeof(Desc))); } Descriptions[noLists].name = strdup(name); if (ix == NULLCP) Descriptions[noLists].desc = NULLCP; else Descriptions[noLists].desc = strdup(ix); noLists++; free(temp); } Descriptions = (Desc *) realloc((char *) Descriptions, (unsigned int) (noLists*sizeof(Desc))); } static void listLists() { int i; openpager(); if (Descriptions == NULL) init_descs(); for (i = 0; i < noLists && pipeopen; i++) { if (Descriptions[i].desc == NULLCP) fprintf(out, "%s", Descriptions[i].name); else fprintf(out, "%-30s: %s", Descriptions[i].name,Descriptions[i].desc); } closepager(); } /* \f */ /* pager routines */ SFP oldpipe; static void piped() { pipeopen = 0; } static void openpager() { oldpipe = signal(SIGPIPE, piped); if (isatty(1) == 0) out = stdout; else if ((out = popen(pager,"w")) == NULL) { fprintf(stderr, "unable to start pager '%s': %s\n", pager, sys_errname (errno)); out = stdout; } pipeopen = 1; } static void closepager() { if (out != stdout) { pclose(out); out = stdout; } pipeopen = 0; signal(SIGPIPE, oldpipe); } /*\f */ confirm (str) char *str; { register char c; if (str != NULL) { fputs (str, stdout); fflush(stdout); } printf (" [y/n] "); fflush (stdout); c = ttychar (); switch (c) { case 'Y': case 'y': printf ("yes\r\n"); fflush (stdout); return (TRUE); case 'N': case 'n': printf ("no\r\n"); fflush(stdout); return (FALSE); default: printf ("Type y or n\n"); fflush(stdout); return (confirm (NULLCP)); } } ttychar () { register int c; char buf[LINESIZE]; fflush (stdout); if (fgets (buf, LINESIZE, stdin) == NULL) exit (1); c = buf[0]; c = toascii (c); /* get rid of high bit */ if (c == '\r') c = '\n'; return (c); } /* \f */ static int permission(list) dl *list; { struct stat statbuf; int mode; if (isModerator(list) == TRUE) /* allowed to do anything */ return FREEMODE; if (list->dl_file == NULLCP || stat(list->dl_file, &statbuf) < 0) /* no file so can't do anything */ return TOPMODE; mode = (int) statbuf.st_mode; mode = mode & 0777; return mode; } /* \f */ static int listOnLocal(name, host) char *name, host[]; { char *p; if ((p = index(name, '@')) == NULL) { /* do x400 */ sprintf(host,"unknown"); return FALSE; } p++; sprintf(host,"%s",p); if (strcmp(p, loc_dom_mta) == 0 || strcmp(p, loc_dom_site) == 0) return TRUE; /* do x400 */ return FALSE; } static int isModerator(list) dl *list; { Name *ix = list -> dl_uids; if (superUser == TRUE) return TRUE; while (ix != NULL && (strcmp(ix -> name, pwd -> pw_name) != 0)) ix = ix -> next; return (ix == NULL) ? FALSE : TRUE; } /* \f */ /* main modify work routines */ static char *ix; static int getbufchar() { char ret = *ix; if (ret != 0) ix++; return (ret == 0) ? EOF : ret; } static void master_modify(list) dl *list; { FILE *curfp; int quit = FALSE, done; char tmpbuf[LINESIZE], buf[BUFSIZ], *adrstr, *orig_line, ch, *inListname; if ((curfp = flckopen(list->dl_file, "r+")) == NULL) { fprintf (stderr, "Can't open %s: %s\n", list -> dl_file, sys_errname (errno)); return; } flckclose(curfp); while (quit == FALSE) { fprintf(stdout, "\n%s%s", list->dl_listname, (menudriven == TRUE) ? ">> " : "> "); fflush(stdout); if (gets(tmpbuf) == NULL) { exit(0); } compress (tmpbuf, tmpbuf); if (tmpbuf[1] != '\0' && !isspace(tmpbuf[1])) { /* assume no command given */ ix = &(tmpbuf[0]); ch = 'A'; } else { /* get past command */ ix = &(tmpbuf[1]); while (isspace(*ix)) ix++; if (tmpbuf[0] == '?') ch = '?'; else ch = uptolow(tmpbuf[0]); } switch (ch) { case '\0': case '\n': printf("\nType 'h' or '?' for help\n"); continue; case 'p': display(list -> dl_listname); break; case 'v': verifyList(list); break; case 'h': case '?': fprintf(stdout, "\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"); if (menudriven == TRUE) fprintf(stdout, "'q' uit and return to top menu.\n\n"); else fprintf(stdout, "'q' uit.\n\n"); fprintf(stdout, "If the input is none of the above options,\nit is assumed to be a user name to be added\n"); fflush (stdout); break; case 'l': listLists(); break; case 'c': m_createList(); break; case 'q': quit = TRUE; break; case 'r': if (*ix == '\0') { printf ("give username to be removed (regex): "); if (gets(tmpbuf) == NULL) exit(0); compress (tmpbuf, tmpbuf); ix = &(tmpbuf[0]); } removeUser(ix, list); break; case 'f': if (*ix == '\0') { printf ("give username to search for (regex): "); if (gets(tmpbuf) == NULL) exit(0); compress (tmpbuf, tmpbuf); ix = &(tmpbuf[0]); } findUser(ix, list); break; case 'a': if (*ix == '\0') { printf("give username to be added: "); if (gets(tmpbuf) == NULL) exit(0); compress (tmpbuf, tmpbuf); ix = &(tmpbuf[0]); } default: done = FALSE; while (done == FALSE) { orig_line = ix; if (ap_pinit(getbufchar) == BADAP) { printf("Cannot parse '%s'\n", orig_line); done = FALSE; } else { switch (ap_1adr()) { case DONE: done = TRUE; break; case NOTOK: break; default: if (ap_t2s(ap_pstrt, &adrstr) != BADAP) { if (rp_isbad(verifyUser(adrstr, buf))) printf("Illegal address '%s'\n", adrstr); else { if (inList(adrstr, list -> dl_list, &inListname) == TRUE) { printf("User '%s' already in list", adrstr); if (lexequ(inListname, adrstr) != 0) printf(" as '%s'", inListname); printf("\n"); } else addUser(adrstr, list); ap_sqdelete(ap_pstrt, NULLAP); ap_free(ap_pstrt); ap_pstrt = NULLAP; } free(adrstr); } break; } } } break; } } if (menudriven == FALSE) printf("\nBye...\n"); } static void restrict_modify(list) dl *list; { char buf[LINESIZE], adr[BUFSIZ], *nameinlist; printf("Would you like to see who's in the list ?"); if (confirm(NULLCP) == TRUE) display(list -> dl_listname); if (!rp_isbad(verifyUser(pwd->pw_name, adr))) { if (inList(adr, list -> dl_list, &nameinlist) == TRUE) { printf("You (%s) are already in this list\nDo you wish to be removed ?",pwd -> pw_name); if (confirm(NULLCP) == TRUE) { sprintf(buf, "^%s$",adr); removeUser(buf, list); } else printf("You only have permission to add or remove yourself from this list\n"); } else { printf ("You (%s) are not in this list\nDo you wish to be added ?", pwd -> pw_name); if (confirm(NULLCP) == TRUE) addUser(adr, list); else printf("You only have permission to add or remove yourself from this list\n"); } } } /* \f */ /* checking routines */ static int verifyUser(name, addr) char *name, *addr; { RP_Buf rp; ADDR *temp; int ret, type; if (name[0] == '/') /* assume x400 address */ type = AD_X400_TYPE; else type = AD_ANY_TYPE; temp = adr_new(name, type, 0); if (rp_isbad(ret = ad_parse(temp, &rp, CH_UK_PREF))) fprintf(stderr, "Failed to parse '%s' (%s)\n", name, rp.rp_line); if (temp -> ad_r400adr != NULL && temp->ad_type == AD_X400_TYPE) sprintf(addr, temp->ad_r400adr); else if (temp -> ad_r822adr != NULL) sprintf(addr, temp->ad_r822adr); adr_free(temp); return ret; } static int verifyList(list) dl *list; { char *name, buf[BUFSIZ]; Name *ix = list -> dl_list; while (ix != NULL) { printf("Checking '%s'...",ix -> name); if (!rp_isbad(verifyUser(ix -> name, buf))) { printf("ok\n"); ix = ix -> next; } else { name = strdup(ix -> name); ix = ix -> next; removeUser(name,list); free(name); } /* if (temp != NULL) *temp = '@';*/ } } static int inList(name, list, plistname) char *name; Name *list; char **plistname; { while (list != NULL && ap_equ(list -> name, name) != TRUE) list = list -> next; if (list != NULL) *plistname = list->name; return (list != NULL) ? TRUE : FALSE; } /* \f */ /* list maintaince routines */ extern char *re_comp(); extern int re_exec(); static int findUser (name, list) char *name; dl *list; { char *diag; Name *ix; if ((diag = re_comp(name)) != 0) { fprintf(stderr, "re_comp error for '%s' [%s]\n", name, diag); return; } ix = list -> dl_list; openpager(); while (ix != NULL && pipeopen) { if (re_exec(lowerfy(ix -> name)) == 1) { fprintf(out, "%s\n", ix -> name); fflush(stdout); } ix = ix -> next; } closepager(); } static int removeUser(name, list) char *name; dl *list; { char *diag; Name *ix, *temp; char buf[BUFSIZ]; int len = 0, found; FILE *curfp; if ((diag = re_comp(name)) != 0) { fprintf (stderr, "re_comp error for '%s' [%s]\n",name,diag); return; } if ((curfp = flckopen (list->dl_file, "r+")) == NULL) { fprintf (stderr, "Can't open %s: %s\n", list -> dl_file, sys_errname (errno)); return; } rewind(curfp); ix = list -> dl_list; found = FALSE; while (ix != NULL) { temp = NULL; sprintf(buf, "Remove user '%s' ?", ix -> name); if (re_exec(lowerfy(ix -> name)) == 1 && confirm(buf) == TRUE) { /* remove from list -> dl_list */ if (ix -> file == NULL) printf("User '%s' specified in-line, cannot remove\n",ix->name); else { found = TRUE; temp = list -> dl_list; if (ix == list -> dl_list) { list -> dl_list = temp -> next; } else { while (temp -> next != ix) temp = temp -> next; temp -> next = ix -> next; temp = ix; } } } else if (ix -> file != NULL) { /* put it out again */ fputs (ix -> name, curfp); fputc('\n', curfp); len += strlen(ix -> name) + 1; } ix = ix -> next; if (temp != NULL) { temp -> next = NULL; name_free(temp); } } ftruncate(fileno(curfp), (off_t) len); flckclose(curfp); if (found == FALSE) printf("No matches\n"); } static int addUser(name, list) char *name; dl *list; { FILE *curfp; Name *temp, *ix; if ((curfp = flckopen(list->dl_file, "a")) == NULL) { fprintf (stderr, "Can't open file %s: %s\n", list -> dl_file, sys_errname (errno)); return; } printf ("adding user '%s'\n", name); fputs (name, curfp); fputc ('\n', curfp); flckclose (curfp); temp = new_Name(name, list->dl_file); if (list -> dl_list == NULL) list -> dl_list = temp; else { ix = list -> dl_list; while (ix -> next != NULL) ix = ix -> next; ix -> next = temp; } } static char *lowerfy (s) char *s; { static char buf[BUFSIZ]; char *cp; for (cp = buf; *s; s++) if (isascii (*s) && isupper (*s)) *cp++ = tolower (*s); else *cp ++ = *s; *cp = NULL; return buf; }