DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T c

⟦8cf7708ed⟧ TextFile

    Length: 13455 (0x348f)
    Types: TextFile
    Names: »cmds.misc.c«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦e7f64e0c0⟧ »EurOpenD3/mail/vmh.tar.Z« 
        └─⟦dcb95597f⟧ 
            └─⟦this⟧ »cmds.misc.c« 

TextFile

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