|
|
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 v
Length: 9171 (0x23d3)
Types: TextFile
Names: »vmh.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦e7f64e0c0⟧ »EurOpenD3/mail/vmh.tar.Z«
└─⟦dcb95597f⟧
└─⟦this⟧ »vmh.c«
#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);
}