|
|
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;
}