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