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 i

⟦7ff023728⟧ TextFile

    Length: 12274 (0x2ff2)
    Types: TextFile
    Names: »infostuff.c«

Derivation

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

TextFile

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