/* * U T I L I T I E S . C -- User frendly interface to OS9 facilities * * * Written: Clive A Stubbings * Image Recognition Systems * 720 Birchwood Boulevard * Birchwood Science Park * Warrington * Cheshire * WA3 7PX * * Copyright (c) and intellectual property rights Image Recognition Systems * * Date: 5th October 1986 * * Modifications * * 22 Sep 1994 JimP Fixed getspec, getclass not to bash the * disc continuously. * 4 May 1992 Joanne separated classifier/species by seat, * cur_species.1 and cur_species.2 * 31 Jan 1992 Joanne Added getspecies(), getclassifier(), * getspec() and getcurclass() to file to * give the option to change species and * classifier type * 28 Feb 1990 dcb Fork off gamma for gamma correction in utilities * 23 Oct 1989 dcb Don't invoke date in new user password line * 3 Sep 1989 dcb OD and tape archiving as options * 1 Jun 1989 CAS Def errno for v2.2 * 8 May 1989 dcb Add check for legal username chars. * 23 Jul 1989 CAS Extra param to remove * 19 Jan 1989 CAs Fork washline with ddgsptr instead of fstype * 26 Jul 1988 CAS Undevel kmrcmenu + washline * 15 Jul 1988 CAS kmr 3 => kmr for password file * 6 Jul 1988 CAS Tidy cmmd's * 1 Jul 1988 CAS Add hook to washline + kmrcmenu * 30 Jun 1988 CAS Fix tape option cmmd's to not delete option number * 25 Apr 1988 CAS Only present transfer stuff if its initialised * 23 Mar 1988 CAS Case summary report writer * 22 Mar 1988 CAS Options for transfer case to remote computer * 25 Jan 1988 CAS Mods for new cmdsys * */ #include #include #include #include #include #include #include #include #include #define PASSWORD_FILE "/dd/sys/password" #define USER_ROOT "/dd/usr" #define MIN_USER_NO 100 /* Desired attributes for making directories */ #define DIR_ATTR S_IREAD | S_IWRITE | S_IEXEC | S_IOREAD | S_IOWRITE | S_IOEXEC | S_IFDIR extern int errno; extern FILE *debug_channel; extern struct allkontr *alc; char workingfile[40]; /* Used in menus to display file being processed */ static char legal_username_chars[] = "0123456789_ABCDEFGHIHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; extern int show_dir(), setdir(), setcase(), setslide(), dirsort(), tape_menu(), od_archive_menu(), transfer(), /* Transfer case data to remote computer */ report(), /* Case report generator */ iscyto(), nowfork(); static int add_user(), del_user(), del_menu(), del_metfile(), del_cellfile(), del_case(), del_slide(), go_shell(), getspecies(), getclassifier(), casereport(); char *getspec(), *getcurclass(); /* * U T I L I T E S -- General user house keeping utilities * Primarilly to save the user from having to * interact directly with OS9 * */ utilities() { char dirbuf[DIRSIZ+20], casename[CASELENGTH+1]; char washopts[20], userkmrcopts[OPERLENGTH+4], gammaopts[20], *fstype; int (*linkerbug)(); int Exit_cmd; workingfile[0] = '\0'; dirbuf[0] = '\0'; strcpy(casename,alc->nameids.case); /* * switch (alc->ddgschannel->type) { * case FS_VIRTUOSO: fstype = "I"; break; case FS_VIRTUOSO_INVERT: fstype = "V"; break; default: fstype = ""; * } * sprintf(washopts,"-s%s%d",fstype,alc->ddgschannel->devno+1); */ sprintf(washopts,"-s %d",alc->ddgschannel); sprintf(userkmrcopts,"-su %s",alc->user); sprintf(gammaopts, "-s %d", alc); newmenu("utilities"); linkerbug = setdir; cmmd ("set working directory;%?s%-s%f",dirbuf,alc->dir,linkerbug); if (alc->arch_type & TAPE_ARCH) { cmmd ("tape archive operations;%f",tape_menu); mouse(MIDBT); } if (alc->arch_type & OD_ARCH) { cmmd ("od archive operations;%f",od_archive_menu); mouse(LONGMB); } cmmd ("delete;%f",del_menu); cmmd ("change species (human/mouse/chinham);%f",getspecies); if (alc->trans) { linkerbug = transfer; cmmd ("transfer case;:k30%?+s%x%-s%f",casename,alc->dir,workingfile,linkerbug); } linkerbug = casereport; cmmd ("print case report;:k30%?+s%x%-s%f",casename,alc->dir,workingfile,linkerbug); linkerbug = nowfork; cmmd ("composite karyotype;%x%x%f","washline",washopts,linkerbug); cmmd ("user configuration;%x%x%f","kmrcmenu",userkmrcopts,linkerbug); cmmd ("gamma correction;%x%x%f","gamma",gammaopts,linkerbug); mouse(RIGHTBT); if ((getuid() & 0xFFFF0000) == 0) { /* Only allow if super user */ cmmd ("system configuration;%x%x%f","kmrcmenu","-s",linkerbug); cmmd ("add new user;%g",add_user); /* cmmd ("remove user not done;%g",del_user); */ } if (alc->debug || alc->devel) cmmd ("OS9 commands\n;%g",go_shell); Exit_cmd = cmmd("exit"); mouse(LONGLB); while (thismu() && (nncmd != Exit_cmd)) strcpy(casename,alc->nameids.case); } /* * D E L _ M E N U * */ del_menu() { static int confirm = 1; char workbuf[40]; int (*linkerbug)(); struct cyto_file *cfp; workbuf[0] = '\0'; cfp = &alc->nameids; newmenu ("delete options"); linkerbug = setcase; cmmd("case ID;:k30%+s%-17s%f",workbuf,cfp->case,linkerbug); linkerbug = setslide; cmmd("slide;:k30%+s%-5s%f",workbuf,cfp->slide,linkerbug); cmmd("cell number;:k30%d",&cfp->cellno); cmmd ("confirm each file;:k30%T",&confirm); linkerbug = show_dir; cmmd ("show working directory;:k30%-+s%f",alc->dir,linkerbug); cmmd ("delete metaphase list;%-+d%f",&confirm,del_metfile); cmmd ("delete cell (and karyotype);%-+d%+i%f",&confirm,0,del_cellfile); cmmd ("delete slide;%-+d%f",&confirm,del_slide); cmmd ("delete case;%-+d%f",&confirm,del_case); while (thismu()) ; } /* * D E L _ C A S E * */ del_case(confirm) int *confirm; { delthings(confirm,1); } /* * D E L _ S L I D E * */ del_slide(confirm) int *confirm; { delthings(confirm,2); } /* * state = 1 if whole case * 2 if whole slide */ static delthings(confirm,state) int *confirm, state; { int dp, size, typ; struct dirent *wmem, *nptr; struct cyto_file cur_file, *cfp; cfp = &alc->nameids; if ((dp = open(alc->dir,0x81)) == -1) { return(0); } size = _gs_size(dp); if ((wmem = (struct dirent *) Malloc(size)) == NULL) return(0); read(dp,wmem,size); close(dp); qsort (wmem, size/32, 32, dirsort); for (nptr=wmem; nptr < wmem+(size/32); nptr++) { if (alc->debug) fprintf(debug_channel,"Dir file: %s",nptr->dir_name); if (typ = iscyto(nptr->dir_name,&cur_file)) { if (strcasecmp(cur_file.case,cfp->case) == 0) { if ((state == 1) || ((state == 2) && (strcasecmp(cur_file.slide,cfp->slide) == 0))) { alc_case(&cur_file); switch (cur_file.type) { case METFILE: del_metfile(confirm); break; case CELLFILE: del_cellfile(confirm,1); break; case KARYFILE: del_cellfile(confirm,2); break; } } } } } Free(wmem); } static alc_case(cur_file) struct cyto_file *cur_file; { struct cyto_file *cfp; cfp = &alc->nameids; strncpy(cfp->case,cur_file->case,CASELENGTH); strncpy(cfp->patnam,cur_file->patnam,PATLENGTH); strncpy(cfp->slide,cur_file->slide,SLIDELENGTH); cfp->cellno = cur_file->cellno; } /* * D E L _ M E T F I L E * */ del_metfile(confirm) int *confirm; { char fbuf[40]; struct cyto_file *cfp; cfp = &alc->nameids; cfp->type = METFILE; makefilename(fbuf, cfp); if (fileexists(alc->dir,fbuf)) { if (*confirm) { screengo(ENDLINE,0); printf("delete %s %s metaphase list? : ",cfp->case,cfp->slide); if (tryboth(1)) remove(alc->dir,fbuf); } else remove(alc->dir,fbuf); } } /* * D E L _ C E L L F I L E -- delete cellfile (+ karyotype) * * typ determines whether it deletes cell, karyotype or both * * typ 0 - both * 1 - cell * 2 - karyotype */ del_cellfile(confirm,typ) int *confirm,typ; { char fbuf[40]; struct cyto_file *cfp; cfp = &alc->nameids; if ((typ == 0) || (typ == 1)) { cfp->type = CELLFILE; makefilename(fbuf,cfp); if (fileexists(alc->dir,fbuf)) { if (*confirm) { screengo(ENDLINE,0); printf("delete %s %s cell %d? : ",cfp->case,cfp->slide,cfp->cellno); if (tryboth(1)) remove(alc->dir,fbuf); } else remove(alc->dir,fbuf); } } if ((typ == 0) || (typ == 2)) { cfp->type = KARYFILE; makefilename(fbuf,cfp); if (fileexists(alc->dir,fbuf)) { if (*confirm) { screengo(ENDLINE,0); printf("delete %s %s cell %d karyotype? : ",cfp->case, cfp->slide,cfp->cellno); if (tryboth(1)) remove(alc->dir,fbuf); } else remove(alc->dir,fbuf); } } } /* * G O _ S H E L L * */ go_shell() { scrollpart(0,ENDLINE); screengo(ENDLINE,0); fprintf(stdout,"\nType ^D to return to CYTOSCAN\n"); system("shell -e"); vclear(ENDLINE); scrollpart(OUTLINE,ENDLINE); setdisplay(BUST); } /* * S H O W F I L E -- Show current file being processed in relevant * menu line */ showfile(cur_case,muline) struct cyto_file *cur_case; int muline; { if (!muline) return(0); makefilestring(cur_case,workingfile); displin(0,muline); screengo(ENDLINE,0); workingfile[0]='\0'; tsleep(40); } /* * A D D U S E R -- Add a user - update password file, mak dirs etc * This routine assumes that it is called only * by user 0.0 * */ add_user() { FILE *passwd; char buffer[512], user[20], *password, *userno, *pri, *index(), *temp; char used_ids[256]; int free_name, i,nch, unum, ugrp; for (i=0; i<256; i++) used_ids[i]=0; if ((passwd = fopen(PASSWORD_FILE,"r")) == NULL) { fprintf(stderr,"Can't read password file error %d\n",errno); return; } else { putprompt(); fprintf(stdout,"Enter new user name :"); if (fgets(buffer,512,stdin)) { if (((nch = strlen(buffer)) <= 1) || (nch > 19)) return; strcpy(user,buffer); user[strlen(user)-1] = '\0'; /* Kill '\n' at end */ } else return; temp = user; while (*temp) { if (index(legal_username_chars,*temp) == NULL) { putprompt(); fprintf(stderr,"Illegal char (%c) in user name\n", *temp); return(0); } temp++; } fprintf(stderr,"Adding user %s\n",user); free_name = 1; while (!feof(passwd)) { fgets(buffer,512,passwd); password = index(buffer,','); if (password) { *password++ = '\0'; userno = index(password,','); if (userno) { *userno++ = '\0'; pri = index (userno,','); if (pri) { *pri++ = '\0'; if (strcmp(user,buffer)==0) free_name=0; if (alc->debug) { fprintf(stdout,"Username is %s grp %d num %d\n", buffer,usergrp(userno),usernum(userno)); } if (alc->onegroup) used_ids[usernum(userno)] = 1; else used_ids[usergrp(userno)] = 1; } } } } fclose(passwd); if (free_name == 0) { fprintf(stderr,"Name is already in use\n"); return(0); } printf("OK to add user %s",user); for (i=MIN_USER_NO;i<255;i++) if (used_ids[i] == NULL) break; if (i>=255) { fprintf(stderr," No usernumber free\n"); return(0); } if (alc->onegroup) { unum = i; ugrp = alc->usergroupnum; } else { unum = alc->usergroupnum; ugrp = i; } sprintf(buffer,"%s/%s",USER_ROOT,user); if (mknod(buffer,DIR_ATTR) == -1) { screengo(ENDLINE,0); fprintf(stderr,"Failed to make user directory %s, error %d\n",buffer,errno); return(0); } chown(buffer,(ugrp<<16)+unum); if (alc->debug) fprintf(debug_channel,"NEW user: %s,,%d.%d,128,.,%s/%s,shell setenv USER %s;ex kmr\n", user,ugrp,unum,USER_ROOT,user,user); if ((passwd = fopen(PASSWORD_FILE,"a")) == NULL) { fprintf(stderr,"Can't update password file error %d\n",errno); return; } else { fprintf(passwd,"%s,,%d.%d,128,.,%s/%s,shell setenv USER %s;ex kmr\n", user,ugrp,unum,USER_ROOT,user,user); fclose(passwd); } } } /* * D E L _ U S E R * */ del_user() { } /* */ usergrp(str) char *str; { return(atoi(str)); } /* */ usernum(str) char *str; { char *fred; if ((fred = index(str,'.')) && ((fred - str) < 4)) { return(atoi(fred+1)); } else return(0); } /* * C A S E R E P O R T -- Spool Case summary report * */ casereport(casename,dirname) char *casename, *dirname; { SFILE *sfp; sfp = spoolopen(); report(casename,dirname,sfp->fp,2); spoolclose(sfp); } /* * GETSPECIES - display current species, change if necessary * */ #define MAXspec 10 #define SPEC_FILE "/dd/params/species" #define CUR_SPEC_FILE "/dd/params/cur_species" static char *current_species = NULL; static char *current_classifier = NULL; static char *normal_classifier = "normal"; getspecies() { FILE *specfile, *curspecfile; static char specnms[154],*speclist[MAXspec],*specnm; char com[100], *curspec, *getspec(), fname[30]; int cc, getclassifier(), num; int i,specnum = 0, Exit_cmd, inlist =1; specnm = specnms; speclist[0] = specnm; specfile = fopen(SPEC_FILE,"r"); if ( !specfile ) { fprintf(stderr,"Cannot find species file\n"); return; } if ((curspec = getspec()) == '\0') return(0); while(1) { switch ( cc = getc(specfile)) { default: *specnm++ = cc; break; case EOF: goto endfil; case '.': if (speclist[specnum] < specnm) { *specnm++ =0; for (i=0; i MAXspec) { fprintf(stderr,"Too many spec. names\n"); return; } } endfil: fclose(specfile); newmenu("set species"); for ( i = 0; i < specnum ; ++i) cmmd(speclist[i]); cmmd ("change classifier type;%f", getclassifier); Exit_cmd = cmmd("exit"); mouse(LONGLB); while (1) { thismu(); if (nncmd == Exit_cmd) { return(0); } if ((nncmd > 0) && (nncmd < specnum+1)) if (strcmp(speclist[nncmd-1],getspec()) != 0) { num = nncmd-1; sprintf(fname, "%s.%d",CUR_SPEC_FILE,alc->seat); curspecfile = fopen (fname,"w"); fprintf(curspecfile,"%s.normal",speclist[num]); current_species = speclist[num]; current_classifier = normal_classifier; fclose(curspecfile); karyinitpos(); initclass(alc->kcn); for (i=0; ikcn->maxnumber; i++) if ((ACTIVE & alc->kcn->acl[i]) != 0) if (alc->kcn->mol && alc->kcn->mol[i] && alc->kcn->mol[i]->plist) { alc->kcn->mol[i]->plist->disppos = 0; alc->kcn->mol[i]->plist->pgroup = 0; alc->kcn->mol[i]->plist->Cpgroup = 0; } } } } /* end getspecies */ /* * GETCLASSIFIERS - display current classifiers, change if necessary * */ #define MAXclass 10 getclassifier() { FILE *specfile, *curspecfile; static char classnms[154],*classlist[MAXclass],*classnm; char com[100], *curclass, *curspec, fname[30]; char *getspec(), *getcurclass(); int cc; int i,classnum = 0; classnm = classnms; classlist[0] = classnm; specfile = fopen(SPEC_FILE,"r"); if ( !specfile ) { fprintf(stderr,"Cannot find species file\n"); return; } if ((curclass = getcurclass()) == '\0') return(0); if ((curspec = getspec()) == '\0') return(0); while(1) { switch ( cc = getc(specfile)) { default: *classnm++ = cc; break; case EOF: goto endfil; case '.': if (classlist[classnum] < classnm ) { *classnm++ = 0; if (strcmp(curspec, classlist[classnum]) != 0) while ((cc=getc(specfile)) != '\n') ; classnm = classlist[classnum]; } break; case '\n': if ( classlist[classnum] < classnm ) { *classnm++ =0; classlist[++classnum] = classnm; break; } } if ( classnum > MAXclass) { fprintf(stderr,"Too many classifier names\n"); return; } } endfil: fclose(specfile); newmenu("Set classifiers"); for ( i = 0; i < classnum ; ++i ) cmmd(classlist[i]); while (thismu() < 0) ; if ((nncmd > 0) && (classlist[nncmd-1] != curclass)) { classnum = nncmd-1; sprintf(fname, "%s.%d", CUR_SPEC_FILE, alc->seat); curspecfile = fopen(fname,"w"); fprintf(curspecfile,"%s.%s",curspec,classlist[classnum]); current_classifier = classlist[classnum]; fclose(curspecfile); initclass(alc->kcn); } } /* end getclassifier */ #define Maxchar 10 static char spec[Maxchar]; char *getspec() { FILE *curfile; int cc, i; char fname[30]; if (current_species != NULL) return(current_species); for (i=0; iseat); curfile = fopen(fname,"r"); if ( !curfile ) { fprintf(stderr,"Cannot find CURRENT species file\n"); return('\0'); } i=0; while ((cc=getc(curfile)) != '.') { spec[i] = cc; i++; } current_species = spec; fclose(curfile); return(spec); } /* end getspec */ static char class[Maxchar]; char *getcurclass() { FILE *curfile; int cc, i; char fname[30]; if (current_classifier != NULL) return(current_classifier); for (i=0; iseat); curfile = fopen(fname,"r"); if ( !curfile ) { fprintf(stderr,"Cannot find CURRENT species file\n"); return('\0'); } while ((cc= getc(curfile)) != '.') ; fscanf(curfile,"%s",class); current_classifier = class; fclose(curfile); return(class); } /* end getcurclass */