|
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 c
Length: 13455 (0x348f) Types: TextFile Names: »cmds.misc.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit └─⟦e7f64e0c0⟧ »EurOpenD3/mail/vmh.tar.Z« └─⟦dcb95597f⟧ └─⟦this⟧ »cmds.misc.c«
#ifndef lint static char rcsid[] = "$Header: cmds.misc.c,v 2.11 88/01/13 18:55:54 deboor Exp $"; static char notice[] = "This program is in the public domain and is available for unlimited \ distribution as long as this notice is enclosed."; #endif /* * This file contains commands which couldn't really fit anywhere else * except, perhaps, in their own files. * * $Source: /c/support/deboor/usr/src/old/vmh/RCS/cmds.misc.c,v $ * $Revision: 2.11 $ * $Author: deboor $ * * FUNCTIONS: * cmdClear clear entire screen (privacy?) * cmdClrbot clear bottom window * cmdCshcmd execute half-screen shell escape * cmdDebug toggle debug info (DEBUG....of course) * cmdExpunge clean out +deleted folder * cmdGripe send complaint/suggestion/etc. to author * cmdHELP do full-screen help * cmdHelp do help in bottom window * cmdLs list all top-level folders in MH directory * cmdPack pack current folder * cmdRedraw redisplay entire screen * cmdSet set command-line switches * cmdShowM display MSGS structure (DEBUG) * cmdUnseen mark message(s) as unseen * cmdVersion print vmh version number * cmdcshcmd execute full-screen shell escape * cmdBuild rebuild the current folder. */ #include "vmh.h" #ifndef DIRBLKSIZ # include <sys/dir.h> /* for cmdLs() */ #endif /* * cmdLs() * list all the top-level folders in the user's MH directory * * TODO: look for a folders: profile entry and a -recurse switch??? * or recurse always??? */ # define SPREAD 8 /* minimum distance between folder names */ cmdLs() { Reg2 DIR *mh_dir = opendir (rootpath); Reg1 struct direct *mh_entry; struct stat mh_stat; char emsg[80]; char mh_file[1024]; extern char *sys_errlist[]; extern int errno; if (mh_dir == NULL) { errormsg (sprintf (emsg, "%s: %s", rootpath, sys_errlist[errno]), 1); return; } wclear (botWin); wrefresh (botWin); dotitle (botHdr, " Folders: "); wmove (botWin,1,0); init_pager ((FILE *) 0, botWin); while ((mh_entry = readdir (mh_dir)) != NULL) { if (stat (sprintf (mh_file, "%s/%s", rootpath, mh_entry->d_name), &mh_stat) < 0) continue; if ((mh_stat.st_mode & S_IFDIR) && (mh_entry->d_name[0] != '.' || (mh_entry->d_name[1] != '.' && mh_entry->d_name[1]))) { int wx, wy; getyx (botWin, wy, wx); wmove (botWin, wy, (wx = (wx + SPREAD) & ~(SPREAD - 1))); if ((wx + mh_entry->d_namlen) > (botWin->_maxx - SPREAD)) if (newline() == ERR && nextpage()) goto done; waddstr (botWin, mh_entry->d_name); } } done: (void) closedir (mh_dir); end_pager(); wrefresh (botWin); } /* * Mark message as unseen. */ cmdUnseen(count) int count; { int *msgno; char filestr[PATHLENGTH]; struct stat sb; Reg2 int i; INFO *ss; Reg1 char *cp; msgno = GetMessages(&count); if (msgno == NULL) return; (void) strcpy (filestr, F->f_name); cp = &filestr[strlen(filestr)]; for (i = 0; msgno[i]; i++ ) { /* * If this message is already unseen, don't do anything with it */ ss = findinfoR (msgno[i], F->f_cur); /* find it starting from cur */ if( ! ss->i_seen ) { continue; } (void) sprintf( cp, "/%d", msgno[i] ); if( stat( filestr, &sb ) != 0 ) punt( "cmdUnseen: can't stat msg" ); ClrSeen(sb.st_mode); /* Reset seen bit */ (void) chmod( filestr, (int) sb.st_mode ); /* * Mark this message as 'unseen'. */ ss->i_seen = FALSE; F->f_modified = TRUE; } bvShowScan = 1; /*UNSEEN*/ add_to_sequence ("unseen", msgno, F); /* add them to 'unseen' seq */ } /* * execute command calling my version of popen(); cmd executes in * the bottom window - unsuitable for editors! */ cmdCshcmd() { char usercmd[80]; register int rc; usercmd[0] = '\0'; /* * Prompt user for command */ wclear(cmdWin); wmove(cmdWin, 0, 0); if (!terse) wprintw(cmdWin, "Enter command: "); /* Put up the prompt */ else waddstr (cmdWin, "% "); wrefresh(cmdWin); rc = mywgetstr(cmdWin, usercmd, 1); /* Get a string */ if( rc == 0 || usercmd[0] == '\0' ) { /* Abort now, if getstr */ wclear( cmdWin ); /* aborted */ wrefresh( cmdWin ); return; } /* * Run the command. */ Pcmd( usercmd ); wclear(cmdWin); wrefresh(cmdWin); recheckfldrs(); /* the goon might have used mh */ } /* * Clear the bottom screen */ cmdClrbot() { dotitle( botHdr, HELPMSG ); wclear( botWin ); wrefresh( botWin ); } /* * execute csh command using entire screen (suitable for an editor). */ cmdcshcmd() { char usercmd[80]; register int rc; usercmd[0] = '\0'; /* * Prompt user for command */ wclear(cmdWin); wmove(cmdWin, 0, 0); if (!terse) wprintw(cmdWin, "Enter command: "); /* Put up the prompt */ else waddstr (cmdWin, "% "); wrefresh(cmdWin); rc = mywgetstr(cmdWin, usercmd, 1); /* Get a string */ if (rc == 0 || usercmd[0] == '\0'){ /* Abort now, if getstr aborted */ wclear( cmdWin ); wrefresh( cmdWin ); return; } /* * Run the command. */ rc = my_system( usercmd, 0 ); bvShowScan = 1; wclear( cmdWin ); if( rc != 0 ) { wmove( cmdWin, 0, 0 ); wprintw( cmdWin, "** Return code not 0 for command: %s", usercmd ); } wrefresh( cmdWin ); recheckfldrs(); /* the twit could have used mh */ } cmdVersion() { extern char *progname; infomsg (progname, 1); infomsg (version, 0); } cmdDebug() { extern int debug; /* in cmds.c */ debug = (++debug)%2; } cmdRedraw() { wrefresh(curscr); } cmdShowM() { register struct msgs *m = &F->f_msgs; int i; wclear(botWin); wprintw(botWin, "\n -- Msgs structure --\n"); wprintw(botWin, "m->hghmsg = %d\n", F->f_msgs.m_hghmsg); wprintw(botWin, "m->nummsg = %d\n", F->f_msgs.m_nummsg); wprintw(botWin, "m->lowmsg = %d\n", F->f_msgs.m_lowmsg); for (i = 1; i <= F->f_msgs.m_hghmsg; i++) { if (i >= F->f_msgs.m_lowmsg) { if (Exists(i,&F->f_msgs)) waddch(botWin, (i % 10) + '0'); else waddch(botWin, '.'); } else { waddch(botWin, ','); } } wrefresh(botWin); } #include <sys/wait.h> #include <sys/resource.h> /* * cmdGripe() * calls Mail to send a letter to the author with the * version number passed as the subject. */ cmdGripe() { char *argv[5]; int pid; extern char *progname; (void) sprintf (version, "%s %s", progname, VERSION); argv[0] = "/usr/ucb/Mail"; argv[1] = "-s"; argv[2] = version; argv[3] = AUTHOR; argv[4] = (char *) 0; call_prepare(); printf ("\r\n"); printf ("Please type your gripe.\r\n"); printf ("A line with just a period will end the letter.\r\n"); printf ("You will be using `Mail', so <return>~q<return> will get\r\n"); printf ("you back into %s without sending the letter...\r\n", progname); (void) fflush (stdout); /* * we should use my_vfork(), but it calls call_prepare() which prints * 'Wait...' and Mail won't tell the user it's ready for input, so * he'd get very confused. Sigh. Silly wabbits... */ pid = vfork(); if (pid == 0) { execvp(argv[0], argv); printf(" *** Unable to exec %s\n", argv[0]); (void) fflush(stdout); _exit(1); /*NOTREACHED*/ } else { /* Parent */ int cpid; union wait CStat; int (*istat)(); int (*qstat)(); /* Copied from system(3) */ istat = signal(SIGINT, SIG_IGN); qstat = signal(SIGQUIT, SIG_IGN); do { while ((cpid = wait3 (&CStat, WUNTRACED, (struct rusage *)0)) == 0) ; if ((cpid == pid) && WIFSTOPPED (CStat)) { (void) kill (pid, SIGCONT); cpid = 0; } } while (cpid != -1 && cpid != pid); (void) signal(SIGINT, istat); (void) signal(SIGQUIT, qstat); /* If non-zero rc (i.e. error) */ if (WIFSIGNALED (CStat) || WIFEXITED (CStat)) sleep(2); /* then sleep 2 to show err msg */ call_recover(0, 0); /* Recover from call & do pause logic */ } } /* * cmdSet() * set operating parameters using command-line switches. Almost every * switch may be given (exceptions: scanwindow, help...). */ /*ARGSUSED*/ cmdSet (count, undo, argc, argv) int count, undo, argc; char **argv; { char iline[132]; if (!argc) { wclear(cmdWin); if (terse) { waddstr (cmdWin, "> "); } else { waddstr (cmdWin, "Switches? "); } wrefresh(cmdWin); *iline = '\0'; if (mywgetstr (cmdWin, iline, 1) == 0) return; argv = brkstring (iline, " \t", "\n"); for (argc = 0; argv[argc]; argc++) ; argc++; } while (--argc > 0) { if (pcsswitch (&argv, &argc, 0)) return; argv++; } } /* * cmdHelp() * print helpfile in bottom window */ cmdHelp() { dotitle(botHdr, helpfile); typeit(helpfile, botWin); } /* * cmdHELP() * print helpfile using entire screen */ cmdHELP() { char *argv[3]; argv[0] = pagerstr; /* /usr/ucb/page normally */ argv[1] = helpfile; /* from config file */ argv[2] = 0; (void) my_vfork(argv, 1); /* Go do the page command (alias of more) */ } /* * Clear the screen temporarily, user should issue a ^L to * repaint the screen afterwards. */ cmdClear() { tputs (clstring, 1, _putchar); /* Clear the screen */ } /* * Pack a folder (global F) */ cmdPack() { Reg1 int s; /* Source msg number */ Reg2 int d; /* Destination msg number */ Reg3 struct msgs *m = &F->f_msgs; prt_action (" Pack folder %s ", &F->f_name[rootlen+1]); if (m->m_nummsg == m->m_hghmsg) { /* If already packed */ infomsg("Folder is already packed tight.", 1); return; } infomsg("Packing folder ... ", 1); /* * In the below loop, there is the additional * check for the range on s due to a bug where * the m_nummsg can be greater than it should be * from pathnames like "20config" in the folder * Not sure how to protect myself totally. * like man, for sure. gag me with a spoon. */ s = m->m_lowmsg; /* First source msg # known */ for ( d = 1; /* Dests #'s are [1..m_nummsg] */ (d <= m->m_nummsg && s <= m->m_hghmsg) ; d++) { if (s != d) /* If differ then */ renamemsg(s, d); /* do the rename & updates */ for (s++; /* Find next src msg */ s <= m->m_hghmsg && ! (Exists(s, m)); s++) ; } m->m_lowmsg = 1; m->m_hghmsg = m->m_nummsg; infomsg("Done.", 0); bvShowScan = 1; /* Redisplay screen w/new numbers! */ } /* * Really delete msgs in the +deleted folder */ cmdExpunge() { FLDR *f; register MSGS *m; register char *cp; char folder[150], temp[150], c; register int i; int rc; rc = getpath("deleted", folder, sizeof(folder)); /* Get pathname */ if (rc != 0) { errormsg("Can't find deleted folder?", 1); return; } f = getF(folder); /* Get fldr structure for deleted folder */ m = &f->f_msgs; prt_action (" Expunging %d messages ", m->m_nummsg); if (FEmpty(f)) { errormsg("Deleted folder is empty!", 1); return; } (void) sprintf(temp, "Expunge %d msgs from deleted folder? [CR to Confirm]", m->m_nummsg); infomsg(temp, 1); if ((c = (mygetch(cmdWin)&0177)) != '\n' && c != '\r') { infomsg(" Aborted.", 0); return; } infomsg(". . .", 0); (void) sprintf (temp, "%s/", f->f_name); cp = &temp[strlen (temp)]; for (i=m->m_lowmsg; i <= m->m_hghmsg ; i++) { if (Exists(i,m)) { (void) sprintf(cp, "%d", i); (void) unlink(temp); } } freeF(f); /* Discard fldr w/out update */ infomsg("Done.", 0); if (F==f) /* If displaying deleted folder */ dofolder(folder); /* redisplay it (will reset F) */ } /* * cmdInit() * rebuild the current folder */ cmdInit() { char temp[80]; char c; char *cp; cp = rindex (F->f_name, '/'); if (cp++ == (char *) NULL) { cp = F->f_name; } (void) sprintf (temp, "Reinitialize folder `%s'? [CR to confirm] ", cp); infomsg (temp, 1); if ((c = mygetch (cmdWin)&0177) != '\n' && c != '\r') { infomsg (" Aborted", 0); } else { char infofile[PATHLENGTH]; infomsg (" . . . ", 0); /* * The easiest way to do this is to unlink the old .info file so it * is out of date, free the previous idea of the folder and then * call the right function to rebuild the entire structure again, * since that is exactly what is needed and takes care of reading the * sequences, etc. etc. etc. Unfortunate side effect is all the * previous marks are lost as well as any internal sequences, but * c'est la vie. */ (void) sprintf (infofile, "%s/.info", F->f_name); (void) unlink (infofile); freeF (F); *rindex (infofile, '/') = '\0'; F = getF (infofile); infomsg (" done.", 0); } /* * redisplay any newly-discovered messages or, at the very least, * clean up whatever caused the poor dear to invoke this function */ bvShowScan = 1; }