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 v

⟦8f1733ad3⟧ TextFile

    Length: 9171 (0x23d3)
    Types: TextFile
    Names: »vmh.c«

Derivation

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

TextFile

#ifndef lint
static char rcsid[] =
	"$Header: vmh.c,v 2.13 88/01/13 21:56:15 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

/* vmh.  I don't know what it is, but it sure isn't hm.       ardeb  */

/*
 * the main file and miscellaneous utility routines which fit nowhere else.
 *
 * $Source: /c/support/deboor/usr/src/old/vmh/RCS/vmh.c,v $
 * $Revision: 2.13 $
 * $Author: deboor $
 *
 * FUNCTIONS:
 *	CurrentMsgNum	returns the number of the current message in the current
 *			folder
 *	main		guess what?
 *	checkfcc	checks folders for extra messages introduced by Fcc:'s
 *	dofolder	switch to another folder
 *	goodbye		exit routine
 *	hdrseen		mark a message as seen
 *	punt		major boo boo routine
 *	readheader	read a file unfolding per RFC822
 *	snprintf	same relation to sprintf as strcpy to strncpy
 *	updatetop	refresh topWin and put plus by current msg.
 */

#include "vmh.h"                 /* Mine */

char	*progname;		/* basename of invocation */

main(argc, argv)
	int	argc;
	char	*argv[];
{
	extern	char	*cFold;
	char		junk[132];	/* to form version string */
	Reg1	char	*cp;

#ifndef LINEFLUSH
	extern char _sobuf[];

	setbuf( stdout, _sobuf );
#endif

	if (progname = rindex (argv[0], '/'))
		progname++;
	else
		progname = argv[0];

	(void) snprintf (junk, sizeof(junk), " %s %s ", progname, VERSION);
	for (cp = junk + 1; ! isspace (*cp); cp++) {
		if (isalpha (*cp) && islower (*cp))
			*cp = toupper (*cp);
	}
	version = newstr (junk);

	read_config(argv[0]);	/* read config file */
	scanopts(argc, argv);
	initpath();		/* initialize root path name */
	if (cFold)
		initstuff(cFold);      /* Go initialize most else */
	else
		initstuff(get_cur_fold());      /* Go initialize most else */
	initcmds();             /* Initialize command table(s) */

	if (strcmp("up", &progname[strlen(progname)-2])==0) goodbye();
	docmds();               /* Never returns */

}

/*
 * Dofolder:
 *
 *      Input:  Full folder pathname
 *              path has already been expanded and (void) write access verified
 *
 *      Got set global F pointer and display the folder
 */

dofolder(folder)
	char *folder;
{
	F = getF(folder);           /* Set global F to fldr structure */
	if (F->f_cur != (INFO *)NULL) {
		/*
		 * Because the top window size can change on us, we
		 * reposition the current message to the center of the
		 * window each time the folder is switched to
		 */
		F->f_top = i_pre(F->f_cur, topSize / 2);
		F->f_line = i_diff(F->f_top, F->f_cur);
	}

	putupmcount();
	showinfo();                     /* Update top half of screen */
	wrefresh(topWin);
}


/*
 * CurrentMsgNum()
 *	returns the number of the current message in the folder F or
 *	-1 if the folder is empty.
 */
CurrentMsgNum()
{
	if (!FEmpty(F)) {
		return (F->f_cur->i_mnum);
	} else {
		return (-1);
	}

}


/*
 *  Silly routine needed since comp and repl can put
 *  msgs directly into folders.
 *
 * This should go somewhere else. Where, I do not know.
 */

checkfcc()
{
    char	  temp[100];
    struct stat   sbuf;       /* Stat buffer for possible new msg */
    register FLDR *f;         /* temp folder ptr for checking all folders */
    int		  msgno;              /* Next msg number in this folder */
    FILE	  *msgfd;
    int		  rc;
    extern FLDR	  *FHead;
    
    
    for (f = FHead; f != NULL; f = f->f_link)        /* All folders */
    {
	/*** infomsg(f->foldername, 1);      /*dbug*/
	msgno = f->f_msgs.m_hghmsg + 1;       /* build new msg name */
	(void) sprintf(temp, "%s/%d", f->f_name, msgno);
	rc = stat(temp, &sbuf);
	if (rc < 0)
	    continue;           /* Loop if not there */
	
	/*** Have a new msg! ***/
	
	ClrSeen(sbuf.st_mode);          /* Reset seen bit if there */
	ClrReply(sbuf.st_mode);
	(void) chmod(temp, (int) sbuf.st_mode);      /* set into inode */
	
	msgfd = fopen(temp, "r");       /* Open the msg for info */
	if (msgfd == NULL)
	    punt("Open error in checkfcc routine");
	
	linkinfo (infosub(msgfd, msgno), f);    /* link in new record */
	(void) fclose(msgfd);
	
	if (f->f_head == f->f_tail) {	/* no longer empty */
	    f->f_top = f->f_cur = f->f_head;
	}
	add_new_msgs (f);	/* add new message(s?) here */
	
	if (f == F) {             /* If current folder */
	    bvShowScan = 1;
	    wrefresh(topWin);
	}
	
    }
}

/*
 * readheader (hdr, hlen, mf, keep_nl) register char *hdr; register hlen,
 *   keep_nl; register FILE *mf;
 *	reads and unfolds a header from file mf according to the RFC822
 *	internet standard (doesn't that sound official?). If  keep_nl  is true,
 *	any newlines in the header will be included in the string, otherwise
 *	they are ignored.
 *	If the header ended with a newline, the length of the string is returned
 *	If not all the header was read, minus the number of characters read is
 *	returned.
 *	
 */
readheader (hdr, hlen, mf, keep_nl)
    Reg1	char	*hdr;
    Reg3	int	hlen;
    Reg4	FILE	*mf;
    Reg5	int	keep_nl;
{
    Reg2	int	cnt;
    int		c;
    
    hlen--;	/* to protect against getting an extended header with */
    /* the \n at the end of hdr */
    for (cnt = 0; cnt < hlen && (c = getc(mf)) != EOF; hdr[cnt++] = c)
	if (c == '\n') {
	    /*
	     * If this is a newline, check the next character for a tab
	     * or space -- if that's what it is, the header is continued onto
	     * the next line...
	     *
	     * Note that if the line began with a newline, we assume it's the
	     * end of the header section and thus a header in its own right.
	     * Note that this is wrong if a header line is one character
	     * too big for the passed buffer (the first read of the header
	     * got everything except the newline but there's actually a
	     * valid continuation line. Buffers should be sized appropriately
	     * to avoid this...).
	     */
	    if (cnt != 0) {
		if (keep_nl == RH_NL)
		    hdr[cnt++] = '\n';	/* put newline in */
		if (((c = getc(mf)) == '\t' || c == ' ')) {
		    /* it's white space, so keep going */
		    continue;
		} else {
		    /* must be end of header */
		    (void) ungetc (c, mf);	/* save for next time */
		    c = '\n';
		    break;
		}
	    } else {
		if (keep_nl == RH_NL)
		    hdr[cnt++] = '\n';	/* put newline in */
		break;
	    }
	}
    hdr[cnt] = '\0';
    if (c == EOF || c == '\n') {
	return (cnt);
    } else
	return (-cnt);
}


/*
 ** hdrseen (filename) char *filename;
 **	extracts a message number from the filename and marks its info
 **	record as seen, then chmod's the file to be marked as seen.
 */
hdrseen(filename)
    char	*filename;
{
    struct stat	sb;
    char	*cp;
    register	msgno;
    INFO	*ss;
    int		u_seq[2];
    
    cp = rindex (filename, '/');
    if (cp)
	cp++;
    else
	cp = filename; /* yurg! */
    msgno = atoi (cp);
    /*
     *   Mark this message as 'seen', if it hasn't been
     *      'seen' before.
     */
    ss = findinfoR (msgno, F->f_cur);
    if( ! ss->i_seen ) {
	if( stat( filename, &sb ) != 0 )
	    punt( "can't stat msg" );
	SetSeen(sb.st_mode);    /* Mark inode as seen */
	(void) chmod( filename, (int) sb.st_mode );
	ss->i_seen = 1;
	F->f_modified = 1;
	
	u_seq[0] = ss->i_mnum;
	u_seq[1] = 0;
	del_from_sequence ("unseen", u_seq, F);
	
	bvShowScan = 1;
    }
}

/* Update the top window (also called by CurrentMsgNum) */

updatetop()
{
	static		lasty = 0;
	register	newy;

	if (no_tty) {	/* don't refresh if no tty */
#ifdef DEBUG
		DeBuG ("updatetop: no_tty set\n");
#endif
		return;
	}
	if (bvShowScan)
		showinfo();

	if (FEmpty(F)) {
		wmove(topWin, 0, 0);
		wrefresh(topWin);
		bvShowScan = 0;
		return;
	}
	if (!bvShowScan) {
		/*
		 * Since showinfo places the + next to the current message,
		 * there's no need to do it twice...
		 */
		newy = F->f_line;
		if (newy >= 0) {
			wmove (topWin, lasty, 0);
			waddch(topWin, ' ');
			wmove(topWin, (lasty = newy), 0);
			waddch(topWin, '+');
			wmove(topWin, newy, 0);
			wrefresh(topWin);       /* then update screen */
		} else {
			wmove (topWin, lasty, 0);
			waddch (topWin, ' ');
			wmove (topWin, (lasty = 0), 0);
			wrefresh(topWin);
		}
	}
	bvShowScan = 0;
}

char * /*VARARGS*/
snprintf (str, sz, fmt, args)
	char	*str,
		*fmt;
	int	sz,
		args;
{
	FILE	fi;

	fi._ptr = fi._base = str;
	fi._bufsiz = fi._cnt = sz-1;
	fi._flag = _IOWRT | _IOSTRG;
	fi._file = -1;

	_doprnt (fmt, &args, &fi);
	(void) putc ('\0', &fi);

	return str;
}


extern	char	byestring[];	/* init.c */

goodbye()
{
	infomsg(byestring, 1);
	printf("\r\n");         /* Weird 'cause of exit string clr to eol */
	oldtty();               /* Reset tty modes and signals */
	nl();			/* set back to mapping newlines */
	(void) fflush(stdout);         /* Final cr/lf */
	syncfolders();          /* Cleanup any changes to folder infos */
	mvcur (0, COLS-1, LINES-1, 0);
	exit(0);
}

punt(s)
	char	*s;
{
	extern	int	errno;
	extern	char	*sys_errlist[];

	oldtty();       /* Reset tty parms and signals */

	if (errno) {
		fprintf(stderr, "\nOops.  %s (%s)\n", s, sys_errlist[errno]);
	} else {
		fprintf (stderr, "\nOops. %s\n", s);
	}

#ifdef DEBUG
	(void) kill(0, SIGIOT);        /* Cause a core-dump */
#endif
	exit(0);
}