|
|
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 i
Length: 12274 (0x2ff2)
Types: TextFile
Names: »infostuff.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦e7f64e0c0⟧ »EurOpenD3/mail/vmh.tar.Z«
└─⟦dcb95597f⟧
└─⟦this⟧ »infostuff.c«
#ifndef lint
static char rcsid[] =
"$Header: infostuff.c,v 2.12 88/01/13 19:03:28 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
#include "vmh.h"
#include <sys/file.h>
/*
* routines for dealing with info files themselves....oh dear. well if this
* were in info.c, info.c would be too big.
*
* $Source: /c/support/deboor/usr/src/old/vmh/RCS/infostuff.c,v $
* $Revision: 2.12 $
* $Author: deboor $
*
* FUNCTIONS:
* checkinfo check currentness of .info file
* makeinfo recreate a .info file
* showinfo display INFO of current folder in top window
* showline format a single INFO structure and print it
*/
/*
* CheckInfo:
*
* Attempts to check validity of .info file in the folder.
*
* Input: partially filled fldr structure, must have:
* f->f_name with full path name
* f->f_mtime with mod time of folder
*
* Returns 1 if new .info file needed. 0 if already ok.
*/
checkinfo(f)
FLDR *f;
{
struct stat sbuf; /* Stat buffer for the .info */
int rc;
char junk[PATHLENGTH];
(void) sprintf (junk, "%s/.info", f->f_name);
rc = stat(junk, &sbuf); /* stat the .info file */
#ifdef DEBUG
DeBuG("time .info = %ld time %s %ld\n",sbuf.st_mtime,
f->f_name, f->f_mtime);
#endif
if ( (rc < 0) /* If .info file not there */
||(sbuf.st_mtime < f->f_mtime)) /* or older than directory */
{
return 1;
}
return(0); /* Was ok already */
}
/*
* Makeinfo:
* Input: Folder structure
*
* The .info file is out of date. Make a new one by invoking
* a derivative of the mh scan program (redirecting its output to
* the .info file).
*
* Doesn't invoke infosub if msg structure tells me there are no
* messages in the folder.
*
* Now doesn't direct output anywhere, just links the resultant
* structure into the list of messages.
*/
makeinfo(f)
FLDR *f;
{
INFO *ss;
MSGS *m = &f->f_msgs;
char tmpstr[PATHLENGTH];
Reg1 char *msgp;
int i; /* Current msg number in folder */
FILE *msgfd;
struct stat sb;
(void) sprintf(tmpstr, " (rebuilding %s .info file) ",
&f->f_name[rootlen+1]);
dotitle(botHdr, tmpstr); /*** Dbug ***/
(void) sprintf (tmpstr, "%s/", f->f_name);
msgp = &tmpstr[strlen(tmpstr)];
f->f_lock = 1; /* lock it so updatefolder() won't die*/
if (m->m_nummsg > 0) { /* If anything in it then */
invalfldr (f);
for (i = m->m_lowmsg; i <= m->m_hghmsg; i++) {
if (Exists(i,m)) {
(void) sprintf(msgp, "%d", i);
msgfd = fopen(tmpstr, "r");
if (msgfd == NULL)
punt ("Open error in makeinfo");
if (fstat (fileno(msgfd),&sb)) {
punt ("Can't fstat message!");
}
ss = findinfo (i, f);
if (!ss || ss->i_mnum != i ||
ss->i_mtime != sb.st_mtime) {
ss = infosub (msgfd, i);
linkinfo (ss, f);
}
ss->i_invalid = 0;
(void) fclose (msgfd);
}
}
}
(void) sprintf (tmpstr, "%s/.info", f->f_name);
i = creat (tmpstr, 0600);
if (i < 0) {
punt ("Couldn't open .info file");
}
flushinfo (i, f); /* write it out now */
f->f_lock = 0; /* done playing with it. unlock */
dotitle(botHdr, HELPMSG); /* Not perfect, but ... */
}
/*
* Showinfo:
*
* Input: Global F->f_top
* Output: Global F->f_bot
* Global F->f_line
*
* Display the info file in the top window. First line in the
* window is "f_top"; sets f_bot to point to the last line displayed.
* f_line is set to the line number of the current message.
*
*/
showinfo()
{
register y; /* Line number in the top window */
register INFO *cs;
cs = F->f_top;
bvShowScan = 0; /* reset showinfo needed flag */
F->f_bot = (INFO *) 0;
for (y=0; cs != (INFO *)0 && y < topSize;) /* Loop over window */
{
if (cs == F->f_cur)
F->f_line = y;
if (!cs->i_invalid) {
showline (y, cs);
F->f_bot = cs; /* remember last ok line */
if (cs == F->f_tail) {
break; /* exits on eof */
} else {
y++;
}
}
cs = cs->i_next;
}
if (F->f_bot == (INFO *) 0) {
wclear(topWin);
wmove(topWin, 0, 10);
wprintw(topWin, "*** Empty Folder ***");
wrefresh(topWin);
}
F->f_lock = 0; /* clearly not messing with .info, unlock it */
}
/*
* Showline
*
* Input:
* Window line number and pointer to info structure
*
* Returns:
* 0 on end of file
* 1 if ok
*
* Read a line from the la file (.info file), and display
* on a given line in the topwindow.
* If cannot open message, it deletes it from the folder.
*/
static struct {
int len;
char *name;
} mnames[] = {
0, "???",
7, "January",
8, "February",
5, "March",
5, "April",
3, "May",
4, "June",
4, "July",
6, "August",
9, "September",
7, "October",
8, "November",
8, "December"
};
char *format_string; /* string for printing out line */
showline(winlin, ss)
int winlin; /* Window line number */
INFO *ss; /* info structure */
{
Reg1 int ct; /* Number of characters in line */
Reg2 char *fmtc; /* current char in format string */
Reg6 int needspace; /* true if need to insert a space
* before next non-space */
static char line[256]; /* temporary storage for output */
char msgpath[PATHLENGTH]; /* absolute path of message */
FILE *msgf; /* file open to message */
Reg5 int maxlen; /* maximum length of output */
int c; /* a general purpose character */
Reg3 char *cp; /* pointer into line */
Reg4 int i; /* general purpose index */
struct stat sb; /* stat buffer for checking datedness
* of info structure */
int field_width; /* width of next field to be stuck
* into the output line */
int do_string; /* output certain fields as strings
* instead of numbers */
int lead_zero;
maxlen = topWin->_maxx;
field_width = 0;
do_string = 0;
lead_zero = 0;
wmove(topWin, winlin, 0);
if (! ss || ss == F->f_tail) {
wclrtobot(topWin); /* clear to bottom of window */
}
if (! ss) {
DeBuG("showline: null pointer passed for line %d\n", winlin);
return (0);
}
(void) sprintf (msgpath, "%s/%d", F->f_name, ss->i_mnum);
if ((msgf = fopen (msgpath, "r")) == (FILE *) 0) {
(void) strcpy (line, " *** Can't open message ***");
/*
* if we can't open the message, we mark it as invalid.
*/
invalmsg (ss, F);
goto output;
}
if (fstat (fileno(msgf), &sb) < 0) {
(void) strcpy (line, " *** Can't fstat message ***");
invalmsg (ss, F);
goto output;
}
if (sb.st_size != ss->i_size) {
/*
* if file changed size, re-info now.
* since linkinfo will just copy to the current record,
* the ss record is automatically changed to reflect the
* new message info. pretty slick, wot?
*/
linkinfo (infosub (msgf, ss->i_mnum), F);
}
if (ss != F->f_cur)
line[0] = ' ';
else
line[0] = '+';
for (ct = 1, fmtc = format_string;
*fmtc && ct <= maxlen;
fmtc++,field_width = 0) {
if (*fmtc == '\\') {
line[ct++] = do_backslash(*++fmtc);
} else if (*fmtc != '%') {
line[ct++] = *fmtc;
} else {
decode:
switch (*++fmtc) {
case '%':
line[ct++] = '%';
break;
case 'U':
line[ct++] = ss->i_seen ? ' ': NOTSEEN;
break;
case 'R':
line[ct++] = ss->i_replied ? REPLYCHAR : ' ';
break;
case 'M':
if (!field_width)
field_width = DMAXFOLDER;
if (ct + field_width <= maxlen) {
sprintf (&line[ct], lead_zero ? "%0*d" : "%*d",
field_width,
ss->i_mnum);
ct += field_width;
} else {
line[ct++] = '\\';
}
break;
case 'd':
if (field_width && ct + field_width <= maxlen) {
sprintf (&line[ct], lead_zero ? "%0*d" : "%*d",
field_width,
ss->i_day);
ct += field_width;
} else if (ss->i_day > 9 && ct + 2 <= maxlen) {
sprintf (&line[ct], lead_zero ? "0%d" : "%d",
ss->i_day);
ct += 2;
} else
line[ct++] = ss->i_day + '0';
break;
case 'm':
if (do_string) {
if (!field_width &&
ct + mnames[ss->i_month].len <= maxlen) {
(void) strcpy (&line[ct],
mnames[ss->i_month].name);
ct += mnames[ss->i_month].len;
} else if (field_width &&
ct + field_width <= maxlen) {
sprintf (&line[ct], "%*s", field_width,
mnames[ss->i_month].name);
ct += field_width;
}
} else if (field_width && ct + field_width <= maxlen) {
sprintf (&line[ct], "%*d",field_width,
ss->i_month);
ct += field_width;
} else if (ss->i_month >9 && ct + 3 <= maxlen) {
sprintf (&line[ct], lead_zero ? "0%d" : "%d",
ss->i_month);
ct += 2;
} else {
line[ct++] = ss->i_month + '0';
}
break;
case 'y':
if (field_width && ct + field_width <= maxlen) {
sprintf (&line[ct], "%*d",field_width,
(field_width >= 4) ?
ss->i_year + 1900 :
(field_width < 2) ?
ss->i_year % 10 :
ss->i_year);
ct += field_width;
} else if (ss->i_year > 9 && ct + 2 <= maxlen) {
sprintf (&line[ct], "%d", ss->i_year);
ct += 2;
} else
line[ct++] = (ss->i_year % 10) + '0';
break;
case 's':
if (!field_width)
field_width = SIZELEN;
if (ct + field_width <= maxlen) {
sprintf (&line[ct], "%*d",field_width,
ss->i_size);
ct += field_width;
} else
line[ct++] = '\\';
break;
case 'F':
if (!field_width)
field_width = FROMLEN;
if (ss->i_path == -1) {
for (i = 0; ct <= maxlen && i < field_width;
i++)
line[ct++] = '*';
break;
}
if (Fseek (msgf, ss->i_path, L_SET) < 0) {
errormsg ("Can't seek to From: line?!", 1);
(void) fclose (msgf);
return 0;
}
if (ss->i_fromMe) {
line[ct++] = 'T'; line[ct++] = 'o'; line[ct++] = ':';
field_width -= 3;
}
for (i = 0; ct <= maxlen &&
i < field_width && !feof (msgf);
ct++,i++) {
if ((c = getc (msgf)) == '\n'|| c==EOF){
line[ct] = ' ';
ct++, i++;
break;
} else
line[ct] = c;
}
for (; ct <= maxlen && i < field_width; i++)
line[ct++] = ' ';
break;
case 'S':
if (ss->i_subject == -1)
break;
if (!field_width)
field_width = maxlen - ct;
if (Fseek (msgf, ss->i_subject, L_SET) < 0) {
errormsg ("Can't seek to subject?!", 1);
(void) fclose (msgf);
return 0;
}
for (i = 0; ct <= maxlen && i < field_width &&
(c = getc(msgf)) != '\n' && c != EOF; i++)
line[ct++] = c;
break;
case 'B':
if (ss->i_body == -1)
break;
if (Fseek (msgf, ss->i_body, L_SET) < 0) {
errormsg ("Can't seek to body?!", 1);
(void) fclose (msgf);
return 0;
}
if (!field_width)
field_width = maxlen - ct;
for (i = 0, needspace = 0; ct <= maxlen &&
i < field_width && (c = getc(msgf)) !=EOF;){
if (isspace(c))
needspace = 1;
else if (needspace) {
line[ct++] = ' ';
if (ct <= maxlen)
line[ct++] = c;
needspace = 0;
} else
line[ct++] = c;
}
break;
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0':
if (*fmtc == '0') {
lead_zero = 1;
} else {
lead_zero = 0;
}
for (i = *fmtc++ - '0'; isdigit(*fmtc);
i = i * 10 + *fmtc++ - '0')
;
fmtc--;
field_width = i;
goto decode;
case '-': /* string-like things for numbers */
do_string = 1;
goto decode;
default:
errormsg ("bad format string", 1);
return(0);
}
do_string = 0;
}
}
line[ct] = '\0';
output:
line[maxlen] = '\0'; /* just to make sure */
waddstr(topWin, line);
if (ct < topWin->_maxx) /* If needed, clear to end of line */
wclrtoeol(topWin);
if (msgf != (FILE *)0) {
(void) fclose (msgf);
}
waddch (topWin, '\n');
return(1);
}