/* * * Copyright (C) 1989 by the Massachusetts Institute of Technology * Developed by the MIT Student Information Processing Board (SIPB). * For copying information, see the file mit-copyright.h in this release. * */ /* * addmtg () -- * The add_meeting command in discuss. This request adds a * meeting to the user's list of meetings. There are several * ways that this can occur -- the user could put the meeting * on the command line, in the form of host:pathname. * * Or the user could put some transaction specifiers on the * command line, in which case they are used as meeting announcements. * * $Id: addmtg.c,v 1.34 2006-03-10 07:11:30 ghudson Exp $ * */ #ifndef lint static char rcsid_addmtg_c[] = "$Id: addmtg.c,v 1.34 2006-03-10 07:11:30 ghudson Exp $"; #endif /* lint */ #include #include #include #include #include #if HAVE_FCNTL_H #include #endif #include #include "globals.h" #include extern tfile unix_tfile(); static int add_mtg_it(); static int mtgs_added; static del_the_mtg(); name_blk *set; int num; add_mtg(argc, argv) int argc; char **argv; { int i, *used; name_blk nb; int code,have_names; char *user,*realm,cerror[80],*pathp,*hostp; char auser_id[BUFSIZ]; trn_info t_info; selection_list *trn_list,*trn_temp; used = (int *)calloc(argc+1, sizeof(int)); user = ""; realm = user; set = NULL; dsc_expand_mtg_set(user_id, "*", &set, &num, &code); i = 1; have_names = 0; /* If we're attending a meeting, try to interpret the arguments as transaction specifiers for the current meeting. If no arguments are given, then we default to the current transaction */ if (dsc_public.attending) { dsc_destroy_mtg_info(&dsc_public.m_info); dsc_get_mtg_info(&dsc_public.nb, &dsc_public.m_info,&code); /* get mtg info for trn mapping */ if (code) { (void) ss_perror(sci_idx, code, "Can't get meeting info for current meeting"); goto punt; } dsc_get_trn_info(&dsc_public.nb, dsc_public.current, &t_info, &code); if (code) t_info.current = 0; dsc_destroy_trn_info (&t_info); if (argc == 1) { trn_list = trn_select(&t_info, "current", (selection_list *)NULL, &code); if (code) { ss_perror(sci_idx, code, ""); sl_free(trn_list); goto punt; } used[1] = 1; } else { trn_list = (selection_list *)NULL; for (;icurrent); ss_perror(sci_idx, *codep, cerror); *codep = 0; return; } parse_mtg_info (&dsc_public.nb, t_infop->current, &nb, codep); if (*codep != 0) { if (*codep == DISC_NOT_ANNOUNCEMENT) { sprintf (cerror, "Transaction [%04d] is not a properly formatted meeting announcement", t_infop->current); ss_perror (sci_idx, 0, cerror); } else { sprintf (cerror, "Transaction [%04d]", t_infop->current); ss_perror(sci_idx, *codep, cerror); } return; } add_the_mtg (&nb, codep); if (*codep != 0 && *codep != DISC_ACTION_NOT_PERFORMED) { sprintf (cerror, "Error adding meeting in transaction [%04d]", t_infop->current); ss_perror(sci_idx, *codep, cerror); } else if (*codep != DISC_ACTION_NOT_PERFORMED) printf ("Transaction [%04d] Meeting %s (%s) added.\n", t_infop->current, nb.aliases[0], nb.aliases[1]); dsc_destroy_name_blk (&nb); *codep = 0; return; } parse_mtg_info(mtg_nbp, trn_no, result_nbp, code) name_blk *mtg_nbp; int trn_no; name_blk *result_nbp; int *code; { int fd,dummy; char tempbfr[256],host[100]; tfile tf; FILE *fp; *code = 0; /* initialize puntable state */ fp = NULL; unlink(temp_file); fd = open(temp_file,O_WRONLY|O_CREAT,0700); tf = unix_tfile(fd); dsc_get_trn(mtg_nbp,trn_no,tf,code); close(fd); tclose(tf,&dummy); tdestroy(tf); if (*code) return; fp = fopen(temp_file,"r"); if (!fp) goto not_ann; if (!fgets(tempbfr,256,fp)) goto not_ann; if (strncmp(tempbfr," Meeting Name: ",17)) goto not_ann; if (!fgets(tempbfr,256,fp)) goto not_ann; if (strncmp(tempbfr," Host: ",17)) goto not_ann; tempbfr[strlen(tempbfr)-1] = '\0'; strcpy(host,tempbfr+17); if (!fgets(tempbfr,256,fp)) goto not_ann; if (strncmp(tempbfr," Pathname: ",17)) goto not_ann; fclose(fp); fp = NULL; tempbfr[strlen(tempbfr)-1] = '\0'; hostpath_to_nb (host, &tempbfr[17], result_nbp, code); goto punt; not_ann: *code = DISC_NOT_ANNOUNCEMENT; punt: if (fp != NULL) fclose(fp); return; } hostpath_to_nb (host, path, nbp, code) char *host, *path; name_blk *nbp; int *code; { struct hostent *hp; mtg_info m_info; char *short_name; nbp -> hostname = nbp -> pathname = nbp -> user_id = nbp -> spare = NULL; nbp -> date_attended = nbp -> last = nbp -> status = 0; hp = gethostbyname (host); if (hp != NULL) host = hp -> h_name; /* use canonical if possible */ nbp -> hostname = malloc((unsigned)strlen(host)+1); strcpy(nbp -> hostname,host); nbp -> pathname = malloc((unsigned)strlen(path)+1); strcpy(nbp -> pathname, path); nbp -> user_id = malloc((unsigned)strlen(user_id)+1); strcpy(nbp -> user_id, user_id); nbp -> aliases = (char **)NULL; dsc_get_mtg_info(nbp, &m_info, code); if (*code) { if (*code == NO_ACCESS) { *code = CANT_ATTEND; /* friendlier error msg */ } goto punt; } short_name = strrchr(path,'/'); if (!short_name) short_name = strrchr(path,':'); nbp -> aliases = (char **)calloc(3, sizeof(char *)); nbp -> aliases[0] = malloc(strlen(m_info.long_name)+1); strcpy(nbp -> aliases[0], m_info.long_name); nbp -> aliases[1] = malloc(strlen(short_name)); strcpy(nbp -> aliases[1],short_name+1); nbp -> aliases[2] = (char *)NULL; *(nbp->spare = malloc(1)) = '\0'; free(m_info.location); free(m_info.chairman); free(m_info.long_name); return; punt: dsc_destroy_name_blk (nbp); return; } add_the_mtg(new_nbp,code) name_blk *new_nbp; int *code; { name_blk *nbp,temp_nb; const char *prompt = "Meeting %s already exists.\nDo you wish to delete the old one and add the new one? "; char *question = NULL; int j; /* see if we're already attending... */ for (j = 0,nbp = set; j < num; j++,nbp++) { if (!namcmp (nbp ->hostname, new_nbp->hostname) && !strcmp(nbp->pathname, new_nbp->pathname)) { *code = DISC_DUPLICATE_MTG; return; } } for (j = 0; new_nbp->aliases[j] != NULL; j++) { dsc_get_mtg (user_id, new_nbp->aliases[j], &temp_nb, code); if (*code == 0) { /* already exists */ question = malloc(strlen(prompt) - 2 + strlen(new_nbp -> aliases[j]) + 1); if (! question) { fprintf(stderr, "Couldn't malloc. Too bad..."); return; } sprintf (question, prompt, new_nbp -> aliases[j]); if (!command_query (question)) { printf ("Meeting not added.\n"); dsc_destroy_name_blk (&temp_nb); *code = DISC_ACTION_NOT_PERFORMED; free(question); return; } free(question); del_the_mtg (&temp_nb, code); if (*code != 0) { dsc_destroy_name_blk (&temp_nb); return; } dsc_destroy_name_blk(&temp_nb); } } dsc_update_mtg_set(user_id, new_nbp, 1, code); if (*code) { return; } return; } del_mtg(argc, argv) int argc; char **argv; { int i, *used; name_blk nb; int code,have_names; char *user,*realm; char auser_id[BUFSIZ]; used = (int *)calloc(argc, sizeof(int)); user = ""; realm = user; have_names = 0; for (i=1; ialiases[0], dsc_public.nb.aliases[0])) leave_mtg(); nbp->status |= DSC_ST_DELETED; dsc_update_mtg_set(user_id, nbp, 1, code); } /* * * command_query () -- * Routine to ask the user a question, and return TRUE/FALSE depending * on whether it is 'yes'/'no' * */ command_query (question) char *question; { int result; char answer [20]; printf ("%s", question); fflush (stdout); if (fgets (answer, 10, stdin) == NULL) return(FALSE); return (answer [0] == 'Y' || answer [0] == 'y'); }