sources-request@mirror.UUCP (02/18/87)
Submitted by: rtech!rtech!bobm (Bob Mcqueer) Mod.sources: Volume 8, Issue 65 Archive-name: vn/Part02 [ I forgot to point out that I repacked the archives because of a patch Bob sent me. --r$ ] #! /bin/sh # This is a shell archive. Remove anything before this line, # then unpack it by saving it in a file and typing "sh file". # If all goes well, you will see the message "End of archive 2 (of 3)." # Contents: reader.c strtok.c term_set.c tty.h tty_set.c tune.h # userlist.c vn.h vnglob.c # Wrapped by rs@mirror on Tue Feb 17 12:10:31 1987 PATH=/bin:/usr/bin:/usr/ucb; export PATH echo shar: extracting "'reader.c'" '(18610 characters)' if test -f 'reader.c' ; then echo shar: will not over-write existing file "'reader.c'" else sed 's/^X//' >reader.c <<'@//E*O*F reader.c//' X/* X** vn news reader. X** X** reader.c - article reading interface - "more" like. X** X** see copyright disclaimer / history in vn.c source file X*/ X X#include <stdio.h> X#include <sys/types.h> X#include "tty.h" X#include "config.h" X#include "vn.h" X#include "head.h" X#include "reader.h" X X#define PERTAB 8 /* tab expansion factor */ X#define BACKTRACK 24 X Xextern char *Printer,*Editor,*Mailer,*Poster,*Orgdir,*Savefile,*Savedir,*Ccfile; Xextern int L_allow; Xextern int C_allow; Xextern int Rot; Xextern int Headflag; Xextern int Digest; Xextern char *No_msg; Xextern char *Roton_msg; Xextern char *Rotoff_msg; Xextern char *Hdon_msg; Xextern char *Hdoff_msg; X Xextern char *T_head, *FT_head, *N_head, *L_head, *RT_head, *DIS_head; Xextern char *TO_head, *F_head, *P_head, *M_head, *R_head; X Xextern char Cxrtoi[], Cxitor[]; X Xstatic FILE *Fpread; Xstatic char *Fname; Xstatic char *Lookahead; Xstatic int Rlines; Xstatic int Hlines; X X#ifdef ADDRMUNGE Xstatic int Newaddr; X#endif X X/* X readstr routine is the "funnel" to the reading state, X and controls signal setting. Some "session" context is passed X along to allow jumping back to a different display X X WARNING: X X NOTHING below readstr should call strtok() X*/ X Xreadstr (s,crec,highrec,count) Xchar *s; Xint *crec, *highrec; Xint count; X{ X char *fnext, *strtok(); X int pc; X Fname = strtok(s,LIST_SEP); X if (Fname != NULL) X { X term_set (ERASE); X sig_set (BRK_READ,&Fpread); X fnext = strtok(NULL,LIST_SEP); X while (Fname != NULL && readfile(fnext,&pc) >= 0) X { X if (Digest) X unlink (Fname); X Fname = fnext; X fnext = strtok (NULL,LIST_SEP); X } X if (Digest && Fname != NULL) X unlink (Fname); X if (pc != 0) X forward (pc, crec, highrec); X else X { X *crec += count; X if (*crec >= *highrec) X *crec = *highrec - 1; X } X sig_set (BRK_RFIN); X show (); X term_set (MOVE, 0, *crec); X } X else X { X preinfo ("%s",No_msg); X term_set (MOVE, 0, *crec); X } X} X X/* X readfile presents article: X sn - name of next article, NULL if last. X pages - pages to advance on return, if applicable X returns 0 for "continue", <0 for "quit" X*/ Xstatic readfile (sn,pages) Xchar *sn; Xint *pages; X{ X FILE *fopen(); X int lines,percent,artlin; X long rew_pos, ftell(); X char c, buf[RECLEN], mid[RECLEN], ngrp[RECLEN], dist[RECLEN]; X char from[RECLEN], title[RECLEN], flto[RECLEN], reply[RECLEN]; X char pstr[24], dgname[48], getpgch(), *index(), *digest_extract(); X char *tgetstr(); X X *pages = 0; X X term_set(ERASE); X X if (Digest) X { X lines = atoi(Fname); X if ((Fname = digest_extract(dgname,lines)) == NULL) X { X printf ("couldn't extract article %d",lines); X return (0); X } X } X X if ((Fpread = fopen(Fname,"r")) == NULL) X { X printf ("couldn't open article %s",Fname); X return (0); X } X X Hlines = gethead (mid, from, title, ngrp, flto, reply, dist, &artlin); X printf (ANFORM,Fname,Cxrtoi[PG_HELP]); X lines = 1; X rew_pos = ftell(Fpread); X if (Headflag) X { X rewind(Fpread); X Rlines = 0; X } X else X { X /* use do_out to guard against control sequences */ X Rlines = Hlines; X sprintf (buf,"%s%s\n",T_head,title); X lines += do_out(buf,1); X sprintf (buf,"%s%s\n",F_head,from); X lines += do_out(buf,1); X if (index(ngrp,',') != NULL) X { X sprintf (buf,"%s%s\n",N_head,ngrp); X lines += do_out(buf,1); X } X if (*flto != '\0') X { X sprintf (buf,"%s%s\n",FT_head,flto); X lines += do_out(buf,1); X } X printf ("%s%d\n",L_head,artlin); /* no controls */ X ++lines; X } X X /* will return out of outer while loop */ X Lookahead = NULL; X while (1) X { X /* X ** lines counts folded lines from do_out. X ** globals Hlines and Rlines refer to records. X ** If Lookahead is null after this loop, we've X ** hit EOF. X */ X lines += do_out(Lookahead,L_allow-lines); X while (1) X { X if (Lookahead == NULL) X { X if (fgets(buf,RECLEN-1,Fpread) == NULL) X break; X Lookahead = buf; X if (Rot != 0 && Rlines >= Hlines) X rot_line(buf); X ++Rlines; X } X if (lines >= L_allow) X break; X lines += do_out(buf,L_allow-lines); X } X X if (Lookahead != NULL) X { X /* X ** calculation is truncated rather than rounded, X ** so we shouldn't get "100%". Subtract 2 for X ** 1 line lookahead and empty line at beginning X ** of article. X */ X if (Headflag) X percent = ((Rlines-2)*100)/(artlin+Hlines); X else X percent = ((Rlines-Hlines-2)*100)/artlin; X sprintf (pstr,PAGE_MID,percent); X } X else X { X if (sn == NULL) X strcpy (pstr,PAGE_END); X else X strcpy (pstr,PAGE_NEXT); X } X c = getpgch(pstr,mid,from,reply,title,ngrp,flto,dist); X X /* X handle user input: X CAUTION!! return cases must close Fpread. X */ X switch (c) X { X case PG_NEXT: X fclose (Fpread); X return (0); X case PG_FLIP: X *pages = 1; /* fall through */ X case PG_QUIT: X fclose (Fpread); X return (-1); X case PG_REWIND: X if (Headflag) X { X Rlines = 0; X rewind (Fpread); X } X else X { X fseek (Fpread,rew_pos,0); X Rlines = Hlines; X } X Lookahead = NULL; X lines = 2 - RECBIAS; X break; X case PG_SEARCH: X searcher(buf); X lines = 2 - RECBIAS; X lines += do_out(buf,L_allow-lines); X break; X case PG_WIND: X fseek (Fpread,0L,2); X lines = 2 - RECBIAS; X Lookahead = NULL; X break; X case PG_STEP: X if (Lookahead == NULL) X { X fclose (Fpread); X return (0); X } X lines = L_allow - 1; X break; X default: X if (Lookahead == NULL) X { X fclose (Fpread); X return (0); X } X lines = 2 - RECBIAS; X break; X } X } X} X X/* X gethead obtains subject, reply, message id, from, lines, newsgroup and X followup-to lines of article for later use in mailing replies and X posting followups, does not rewind, but leaves file at end of header X lines. Returns number of header lines. X*/ Xstatic gethead (mid, from, title, ngrp, flto, reply, dist, lin) Xchar *mid, *from, *title, *ngrp, *flto, *reply, *dist; Xint *lin; X{ X int count; X char buf [RECLEN], *index(); X long pos,ftell(); X X#ifdef ADDRMUNGE X Newaddr = 1; X#endif X X *lin = 0; X *dist = *mid = *from = *title = *ngrp = *flto = *reply = '\0'; X X /* for conditional is abnormal - expected exit is break */ X for (count = 0; count < HDR_LINES && fgets(buf,RECLEN-1,Fpread) != NULL; ++count) X { X X /* reset position and bail out at first non-header line */ X if (index(buf,':') == NULL) X { X pos = ftell(Fpread); X pos -= strlen(buf); X fseek (Fpread,pos,0); X break; X } X X#ifdef MAILSMART X if (strncmp(buf,RT_head,RTHDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X strcpy (reply,buf+RTHDLEN); X continue; X } X#else X if (strncmp(buf,P_head,PHDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X strcpy (reply,buf+PHDLEN); X continue; X } X#endif X if (strncmp(buf,DIS_head,DISHDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X strcpy (dist,buf+DISHDLEN); X continue; X } X if (strncmp(buf,M_head,MHDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X strcpy (mid,buf+MHDLEN); X continue; X } X if (strncmp(buf,F_head,FHDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X strcpy (from,buf+FHDLEN); X continue; X } X if (strncmp(buf,T_head,THDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X strcpy (title,buf+THDLEN); X continue; X } X if (strncmp(buf,N_head,NHDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X strcpy (ngrp,buf+NHDLEN); X continue; X } X if (strncmp(buf,FT_head,FTHDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X strcpy (flto,buf+FTHDLEN); X continue; X } X if (strncmp(buf,L_head,LHDLEN) == 0) X { X buf [strlen(buf)-1] = '\0'; X *lin = atoi(buf+LHDLEN); X continue; X } X } X#ifdef MAILSMART X if (*reply == '\0') X strcpy(reply,from); X#endif X return (count); X} X X/* X getpgch prints prompt and gets command from user X handles "mail", "save" and "followup" internally X as well as flag resets. X*/ Xstatic char getpgch(prompt,mid,from,reply,title,ngrp,flto,dist) Xchar *prompt, *mid, *from, *reply, *title, *ngrp, *flto, *dist; X{ X char c; X int ic; X term_set (ONREVERSE); X printf("%s\015",prompt); X term_set (OFFREVERSE); X while ((ic=getnoctl()) != EOF) X { X switch (c = Cxitor[ic]) X { X case SETROT: X term_set (ZAP,0,PPR_MAX); X if (Rot == 0) X { X Rot = 13; X printf ("%s\n",Roton_msg); X } X else X { X Rot = 0; X printf ("%s\n",Rotoff_msg); X } X if (Lookahead != NULL && Rlines > Hlines) X rot_line(Lookahead); X break; X case HEADTOG: X term_set (ZAP,0,PPR_MAX); X if (Headflag) X { X Headflag = FALSE; X printf ("%s\n",Hdoff_msg); X } X else X { X Headflag = TRUE; X printf ("%s\n",Hdon_msg); X } X break; X case PG_HELP: X term_set (ZAP,0,PPR_MAX); X help_pg (); X break; X case PG_REPLY: X mail (reply,title,from); X break; X case PG_FOLLOW: X followup (mid,title,ngrp,flto,from,dist); X break; X case SAVE: X saver (); X break; X case PRINT: X printr (); X break; X default: X term_set (ZAP,0,PPR_MAX); X return (c); X } X X term_set (ONREVERSE); X printf("%s\015",prompt); X term_set (OFFREVERSE); X } X term_set (ZAP,0,PPR_MAX); X return (c); X} X X/* X save article X Like the savestr routine, it "loses" some storage every time X the user specifies a new file, but this should not be significant X*/ Xstatic saver () X{ X char *fn,cmd[RECLEN],*str_store(),*rprompt(); X X tty_set (SAVEMODE); X sprintf (cmd,SAVFORM,Savefile); X fn = rprompt(cmd,cmd); X if (fn != NULL) X Savefile = str_store(fn); X if (*Savefile != '/' && *Savefile != '$') X sprintf (cmd,"cat %s >>%s/%s",Fname,Savedir,Savefile); X else X sprintf (cmd,"cat %s >>%s",Fname,Savefile); X system (cmd); X tty_set (RESTORE); X} X X/* X invoke editor on new temp file, mail using reply line, X possibly first allowing user to overide the reply (not INLETTER) X*/ Xstatic mail (p, t, f) Xchar *p, *t, *f; X{ X char *new, fn[L_tmpnam], cmd [RECLEN+60], *rprompt (); X FILE *fp, *fopen(); X X tmpnam (fn); X if ((fp = fopen(fn,"w")) == NULL) X printex ("can't open %s\n",fn); X X if ((new = index(p, '(')) != NULL) X *new = '\0'; /* a poor way of deleting comments */ X X#ifdef ADDRMUNGE X if (Newaddr) X { X Newaddr = 0; X ADDRMUNGE(p); X } X#endif X X if (strncmp(t, FPFIX, FPFLEN) == 0) X t += FPFLEN; /* don't add multiple Re:s */ X#ifdef INLETTER X fprintf (fp,"%s%s\n%s%s%s\n\n%s:\n", TO_head, p, T_head, FPFIX, t, f); X#else X fprintf (fp,"%s%s%s\n\n%s:\n", T_head, FPFIX, t, f); X#endif X X edcopy (fp); X fclose (fp); X tty_set (SAVEMODE); X X#ifndef INLETTER X sprintf (cmd,"ADDRESS: %s\nreturn to accept, or input new address: ",p); X if ((new = rprompt(cmd,cmd)) != NULL) X strcpy (p,new); X#endif X X sprintf (cmd,"%s %s", Editor, fn); X chdir (Orgdir); X system (cmd); X cd_group (); X new = rprompt ("still want to mail it ? ",cmd); X if (new != NULL && (*new == 'y' || *new == 'Y')) X { X#ifndef INLETTER X sprintf (cmd,"%s '%s' <%s", Mailer, p, fn); X#else X sprintf (cmd,"%s <%s", Mailer, fn); X#endif X system (cmd); X printf ("given to mailer\n"); X } X else X printf ("not mailed\n"); X unlink (fn); X tty_set (RESTORE); X term_set (RESTART); X} X X/* X post a followup article, invoking editor for user after creating X new temp file. remove after posting. Hack in ".followup" if posting X newsgroup ends in ".general" - similar hack for preventing mod & X announce groups - should really be more thorough and parse the X whole string. User can change, anyway. X*/ Xstatic followup (m,t,n,ft,oa,dist) Xchar *m, *t, *n, *ft, *oa, *dist; X{ X char fn[L_tmpnam], *new, cmd [RECLEN], *rprompt(); X FILE *f, *fopen(); X char *rindex(); X X if (*ft != '\0') X strcpy (cmd,ft); X else X strcpy (cmd,n); X new = rindex(cmd,'.'); X if (new != NULL && strcmp(new,".general") == 0) X strcpy (new,".followup"); X if ( strncmp(cmd, "mod.", 4) == 0 || strcmp(new, ".announce") == 0) X { X term_set (ONREVERSE); X printf("Cannot post a follow-up to \"%s\", reply with mail to moderator\007\n", X cmd); X term_set (OFFREVERSE); X return; X } X X tmpnam (fn); X if ((f = fopen(fn,"w")) == NULL) X printex ("can't open %s\n",fn); X X if (strncmp(t, FPFIX, FPFLEN) == 0) X t += FPFLEN; /* don't add multiple Re:s */ X fprintf (f,"%s%s%s\n%s%s\n%s%s\n",T_head,FPFIX,t,N_head,cmd,R_head,m); X if (*dist != '\0') X fprintf(f,"%s%s\n",DIS_head,dist); X fprintf (f,"\nin article %s, %s says:\n",m,oa); X edcopy (f); X fclose (f); X tty_set (SAVEMODE); X sprintf (cmd,"%s %s", Editor, fn); X chdir (Orgdir); X system (cmd); X cd_group (); X new = rprompt("still want to post it ? ",cmd); X if (new != NULL && (*new == 'y' || *new == 'Y')) X { X sprintf (cmd,"%s <%s", Poster, fn); X system (cmd); X printf ("given to posting program\n"); X save_article (fn); X } X else X printf ("not posted\n"); X unlink (fn); X tty_set (RESTORE); X term_set (RESTART); X} X X/* X get user buffer, return whitespace delimited token X without using strtok(). buffer is allowed to overwrite X prompt string. X*/ Xstatic char * Xrprompt(s,buf) Xchar *s,*buf; X{ X printf("%s",s); X fgets (buf,RECLEN-1,stdin); X while (*buf == ' ' || *buf == '\t') X ++buf; X if (*buf == '\n' || *buf == '\0') X return (NULL); X for (s = buf; *s != ' ' && *s != '\t' && *s != '\n' && *s != '\0'; ++s) X ; X *s = '\0'; X return (buf); X} X X/* X edcopy copies article to file which user is editting for X a reply or followup, so it may be referenced. It places X ED_MARK in the left hand margin. X*/ Xedcopy(fp) XFILE *fp; X{ X long current; X char buf[RECLEN]; X int i; X X /* save position, rewind and skip over header lines */ X current = ftell(Fpread); X rewind (Fpread); X for (i=0; i < HDR_LINES; ++i) X { X if (fgets(buf,RECLEN-1,Fpread) == NULL) X break; X if (strncmp(buf,L_head,LHDLEN) == 0) X break; X } X X /* if line already begins with ED_MARK, forget about the space */ X while (fgets(buf,RECLEN-1,Fpread) != NULL) X { X if (buf[0] == ED_MARK) X fprintf(fp,"%c%s",ED_MARK,buf); X else X fprintf(fp,"%c %s",ED_MARK,buf); X } X X /* restore position */ X fseek(Fpread,current,0); X} X X/* X help menus X*/ Xstatic help_pg() X{ X h_print (Cxrtoi[PG_NEXT],HPG_NEXT); X h_print (Cxrtoi[PG_QUIT],HPG_QUIT); X h_print (Cxrtoi[PG_FLIP],HPG_FLIP); X h_print (Cxrtoi[PG_REWIND],HPG_REWIND); X h_print (Cxrtoi[PG_WIND],HPG_WIND); X h_print (Cxrtoi[PG_SEARCH],HPG_SEARCH); X h_print (Cxrtoi[PG_STEP],HPG_STEP); X h_print (Cxrtoi[PG_REPLY],HPG_REPLY); X h_print (Cxrtoi[PG_FOLLOW],HPG_FOLLOW); X h_print (Cxrtoi[SAVE],HPG_SAVE); X h_print (Cxrtoi[PRINT],HPG_PRINT); X h_print (Cxrtoi[SETROT],HPG_ROT); X h_print (Cxrtoi[HEADTOG],HPG_HEAD); X h_print (Cxrtoi[PG_HELP],HPG_HELP); X printf ("%s\n",HPG_DEF); X} X Xrot_line (s) Xunsigned char *s; X{ X for ( ; *s != '\0'; ++s) X { X if (*s >= 'A' && *s <= 'Z') X { X *s += Rot; X if (*s > 'Z') X *s -= 26; X continue; X } X if (*s >= 'a' && *s <= 'z') X { X *s += Rot; X if (*s > 'z') X *s -= 26; X } X } X} X X/* X** output record. folds record to terminal width on word boundaries, X** returning number of lines output. If limit is reached, remainder X** of buffer waiting to be output is returned. Processes several X** special characters: X** form-feed - return "lim" lines so we stop on that line X** tabs - counts "expanded" width X** backspace - assumes they work, -1 width unless in first col. X** bell - pass through with zero width X** newline - end of record. X** del - turns into '_' X** other control - 'A' - 1 added ('01' = ctl-A). Makes escape = "[". X** (prevents "letter bombs" containing inappropriate control X** sequences for the terminal). X** X** Sets Lookahead pointer to remainder of line or NULL. X*/ Xstatic do_out(s,lim) Xchar *s; Xint lim; X{ X int len,i; X char cs,*word,*start; X X Lookahead = NULL; X if (s == NULL) X return(0); X len = 0; X start = word = s; X X /* X ** NOTE: "normal" return is buried inside switch, at newline X ** ending record X */ X for (i=0; i < lim; ++i) X { X for ( ; len < C_allow; ++s) X { X switch (*s) X { X case '\n': X *s = '\0'; /* fall through */ X case '\0': X printf("%s\n",start); X return(i+1); X case '\t': X len = ((len/PERTAB)+1)*PERTAB; X word = s; X break; X case '\b': X if (len > 0) X --len; X break; X case '\014': X *s = ' '; X i = lim-1; /* fall through */ X case ' ': X word = s+1; X ++len; X break; X case '\177': X *s = '_'; X ++len; X break; X default: X if (*s < ' ') X *s += 'A' - 1; X ++len; /* fall through */ X case '\07': X break; X } X } X cs = *s; X *s = '\0'; X if ((len = strlen(word)) < BACKTRACK) X { X *s = cs; X s = word; X cs = *s; X *s = '\0'; X } X else X len = 0; X printf("%s\n",start); X start = s; X *s = cs; X } X Lookahead = start; X return(lim); X} X Xsave_article(tempfname) Xchar *tempfname; X{ X FILE *in, *out; X int c; X time_t timenow, time(); X char *today, *ctime(); X X X if ((in = fopen(tempfname, "r")) == NULL) X return; X if ((out = fopen(Ccfile, "a")) == NULL) X { X fclose(in); X return; X } X timenow = time((time_t)0); X today = ctime(&timenow); X fprintf(out,"From vn %s",today); X while ((c=getc(in)) != EOF) X putc(c, out); X putc('\n', out); X fclose(in); X fclose(out); X printf ("a copy has been saved in %s\n", Ccfile); X} X X/* X send article to printer X*/ Xstatic printr () X{ X char cmd[RECLEN]; X X tty_set (SAVEMODE); X printf("Sent to printer\n"); X sprintf (cmd,"%s %s 2>/dev/null",Printer,Fname); X system (cmd); X tty_set (RESTORE); X} X X/* X search article for specified search pattern, returning the line on which X it is found in buf, a null buffer otherwise. The input file will X be positioned either after the line on which the pattern is X found, or unaaltered if match fails. X*/ Xsearcher (buf) Xchar *buf; X{ X static char searchstr[RECLEN] = ""; X char lasave[RECLEN]; X char *s, *reg, *rprompt(), *regcmp(), *regex(); X long current; X int orlines; X X /* save position, then request search pattern */ X current = ftell(Fpread); X orlines = Rlines; X X tty_set (SAVEMODE); X sprintf (lasave,SEARCHFORM,searchstr); X s = rprompt(lasave,lasave); X tty_set (RESTORE); X if (s != NULL) X strcpy(searchstr, lasave); X X /* Now compile the search string */ X if(( reg = regcmp(searchstr, (char *)0)) == NULL) { X printf("Invalid search string \"%s\"\n", searchstr); X *buf = '\0'; X return; X } X X /* try lookahead buffer first */ X if (Lookahead != NULL && regex(reg,Lookahead) != NULL) X { X strcpy(buf,Lookahead); X regfree(reg); X return; X } X X /* Lookahead can point into buf */ X if (Lookahead != NULL) X strcpy(lasave,Lookahead); X X /* now start reading lines, rotating if necessary and do search */ X while (fgets(buf,RECLEN-1,Fpread) != NULL) X { X if (Rot != 0 && Rlines >= Hlines) X rot_line(buf); X ++Rlines; X if( regex(reg, buf) != NULL ){ /* Got it */ X term_set (ONREVERSE); X printf("\n\tSkipping ....\n\n"); X term_set (OFFREVERSE); X regfree(reg); X return; X } X } X X /* no dice, so restore position */ X regfree(reg); X term_set (ONREVERSE); X printf("Cannot find string \"%s\" in remainder of article\007\n", X searchstr); X term_set (OFFREVERSE); X fseek(Fpread,current,0); X Rlines = orlines; X if (Lookahead != NULL) X strcpy(buf,lasave); X else X *buf = '\0'; X return(0.0); X} @//E*O*F reader.c// if test 18610 -ne "`wc -c <'reader.c'`"; then echo shar: error transmitting "'reader.c'" '(should have been 18610 characters)' fi fi # end of overwriting check echo shar: extracting "'strtok.c'" '(1082 characters)' if test -f 'strtok.c' ; then echo shar: will not over-write existing file "'strtok.c'" else sed 's/^X//' >strtok.c <<'@//E*O*F strtok.c//' X/* X** vn news reader. X** X** strtok.c - strtok() and strpbrk() string routines using UCB index(). X** X** see copyright disclaimer / history in vn.c source file X*/ X X#include <stdio.h> X Xchar *strpbrk (s,del) Xchar *s, *del; X{ X char *ptr,*index(); X if (s == NULL) X return (NULL); X for (; *del != '\0'; ++del) X if ((ptr = index(s,*del)) != NULL) X return (ptr); X return (NULL); X} X Xchar *strtok(str,delim) Xchar *str, *delim; X{ X char *tokstart, *tokend, *first_ch (), *last_ch(); X static char *save=NULL; X X if (str != NULL) X save = str; X X if (save == NULL) X return (NULL); X X tokstart = first_ch (save, delim); X tokend = last_ch (tokstart, delim); X save = first_ch (tokend, delim); X *tokend = '\0'; X X if (*tokstart == '\0') X return (NULL); X X return (tokstart); X} X Xstatic char *first_ch (str,delim) Xchar *str,*delim; X{ X char *index (); X char *f; X X for (f = str; *f != '\0' && index(delim,*f) != NULL; ++f) X ; X X return (f); X} X Xstatic char *last_ch (str,delim) Xchar *str,*delim; X{ X char *index (); X char *f; X X for (f = str; *f != '\0' && index(delim,*f) == NULL; ++f) X ; X X return (f); X} @//E*O*F strtok.c// if test 1082 -ne "`wc -c <'strtok.c'`"; then echo shar: error transmitting "'strtok.c'" '(should have been 1082 characters)' fi fi # end of overwriting check echo shar: extracting "'term_set.c'" '(4914 characters)' if test -f 'term_set.c' ; then echo shar: will not over-write existing file "'term_set.c'" else sed 's/^X//' >term_set.c <<'@//E*O*F term_set.c//' X/* X** vn news reader. X** X** term_set.c - terminal control, hides termcap interface X** X** see copyright disclaimer / history in vn.c source file X*/ X X#include <stdio.h> X#include "tty.h" X#include "vn.h" X Xextern int L_allow, C_allow; Xextern char *Ku, *Kd, *Kl, *Kr; X Xstatic outc (c) Xchar c; X{ X putchar (c); X} X X/* X term_set controls terminal through termcap X START sets global parameters related to terminal also, X as well as allocating display buffer which depends on X terminal lines, and allocating escape strings. RESTART X simply re-issues the initialization - used following system X calls that could have goofed up the terminal state. X*/ X X/* X** Escape strings. X*/ X Xstatic char *Cm,*Cl,*So,*Se,*Te,*Bc,*Ce,*Ti,*Ks,*Ke; X#ifdef USEVS Xstatic char *Vs,*Ve; X#endif X Xstatic int Backspace; /* backspace works */ Xstatic int Overstrike; /* terminal overstrikes */ X Xstatic t_setup() X{ X int i; X char *tgetstr(), *getenv(), *str_store(); X char *c, tc_buf[2048],optstr[2048]; X X c = optstr; X if (tgetent(tc_buf,getenv("TERM")) != 1) X printex ("%s - unknown terminal",getenv("TERM")); X X /* get needed capabilities */ X Cm = str_store(tgetstr("cm",&c)); X Cl = str_store(tgetstr("cl",&c)); X So = str_store(tgetstr("so",&c)); X Se = str_store(tgetstr("se",&c)); X Te = str_store(tgetstr("te",&c)); X Ti = str_store(tgetstr("ti",&c)); X Bc = str_store(tgetstr("bc",&c)); X Ce = str_store(tgetstr("ce",&c)); X Kd = str_store(tgetstr("kd",&c)); X Ke = str_store(tgetstr("ke",&c)); X Kl = str_store(tgetstr("kl",&c)); X Kr = str_store(tgetstr("kr",&c)); X Ks = str_store(tgetstr("ks",&c)); X Ku = str_store(tgetstr("ku",&c)); X#ifdef USEVS X Vs = str_store(tgetstr("vs",&c)); X Ve = str_store(tgetstr("ve",&c)); X#endif X Backspace = tgetflag("bs"); X Overstrike = tgetflag("os"); X X if ( *Cm == '\0' || *Cl == '\0') X { X printex ("cursor control and erase capability needed"); X } X X /* X ** Checks for arrow keys which don't issue something beginning X ** with <ESC>. This is more paranoid than we need to be, strictly X ** speaking - we could get away with any string which didn't X ** conflict with controls used for commands. However, that would X ** be a maintenance headache - we will simply reserve <ESC> as the X ** only char not to be used for commands, and punt on terminals X ** which don't send reasonable arrow keys. It would be confusing X ** to have keys work partially, also. I know of no terminal with X ** one arrow key beginning with an escape, and another beginning X ** with something else, but let's be safe. This also insists on X ** definitions for all 4 arrows, which seems reasonable. X */ X X if ((*Ku != '\0' && *Ku != '\033') || *Kl != *Ku || *Kr != *Ku || *Kd != *Ku) X { X fgprintf("WARNING: arrow keys will not work for this terminal"); X Ku = Kd = Kl = Kr = Kd = Ke = ""; X } X X if (Overstrike) X fgprintf ("WARNING: terminal overstrikes - can't update display without erase\n"); X X i = RECBIAS+1 < HHLINES+2 ? HHLINES+2 : RECBIAS+1; X if ((L_allow = tgetnum("li")) < i) X { X if (L_allow < 0) X printex ("can't determine number of lines on terminal"); X printex ("too few lines for display - %d needed", i); X } X X /* X ** C_allow set so as to not use extreme right column. X ** Avoids "bad wraparound" problems - we're deciding it's best X ** to ALWAYS assume no automargin, and take care of it ourselves X */ X if((C_allow = tgetnum("co")) > MAX_C) X C_allow = MAX_C; X else X --C_allow; X if (C_allow < MIN_C) X { X if (C_allow < 0) X printex("can't determine number of columns on terminal."); X printex ("too few columns for display - %d needed",MIN_C); X } X X L_allow -= RECBIAS; X page_alloc(); X tputs(Ti,1,outc); X tputs(Ks,1,outc); X#ifdef USEVS X tputs(Vs,1,outc); X#endif X} X X/* VARARGS */ Xterm_set(cmd,x,y) Xint cmd,x,y; X{ X char *tgoto(); X int i; X switch (cmd) X { X case MOVE: X tputs (tgoto(Cm,x,y),1,outc); X break; X case ERASE: X tputs(Cl,1,outc); X break; X case ONREVERSE: X tputs(So,1,outc); X break; X case OFFREVERSE: X tputs(Se,1,outc); X break; X case START: X t_setup(); X break; X case RESTART: X tputs(Ti,1,outc); X tputs(Ks,1,outc); X#ifdef USEVS X tputs(Vs,1,outc); X#endif X break; X case STOP: X term_set (MOVE,0,L_allow+RECBIAS-1); X printf ("\n"); X tputs(Ke,1,outc); X tputs(Te,1,outc); X#ifdef USEVS X tputs(Ve,1,outc); X#endif X break; X case RUBSEQ: X if (Overstrike) X { X /* space overprint is futile */ X if (Backspace) X putchar('\010'); X else X tputs(Bc,1,outc); X break; X } X if (Backspace) X printf("%c %c",'\010','\010'); X else X { X tputs(Bc,1,outc); X putchar(' '); X tputs(Bc,1,outc); X } X break; X case ZAP: X if (Ce != NULL && *Ce != '\0') X tputs(Ce,1,outc); X else X { X if (Overstrike) X break; /* punt */ X for (i=x; i < y; ++i) X putchar(' '); X if (Backspace) X { X for (i=x; i < y; ++i) X putchar('\010'); X } X else X { X for (i=x; i < y; ++i) X tputs(Bc,1,outc); X } X } X break; X default: X printex ("term_set unknown code (%d)",cmd); X break; X } X return (0); X} @//E*O*F term_set.c// if test 4914 -ne "`wc -c <'term_set.c'`"; then echo shar: error transmitting "'term_set.c'" '(should have been 4914 characters)' fi fi # end of overwriting check echo shar: extracting "'tty.h'" '(404 characters)' if test -f 'tty.h' ; then echo shar: will not over-write existing file "'tty.h'" else sed 's/^X//' >tty.h <<'@//E*O*F tty.h//' X/* X** vn news reader. X** X** tty.h - codes for tty_set and term_set X** X** see copyright disclaimer / history in vn.c source file X*/ X X#define MOVE 100 X#define ERASE 101 X#define START 102 X#define STOP 103 X#define RUBSEQ 104 X#define ZAP 105 X#define ONREVERSE 106 X#define OFFREVERSE 107 X#define RESTART 108 X X#define RAWMODE 200 X#define COOKED 201 X#define SAVEMODE 202 X#define RESTORE 203 X#define BACKSTOP 204 @//E*O*F tty.h// if test 404 -ne "`wc -c <'tty.h'`"; then echo shar: error transmitting "'tty.h'" '(should have been 404 characters)' fi fi # end of overwriting check echo shar: extracting "'tty_set.c'" '(2552 characters)' if test -f 'tty_set.c' ; then echo shar: will not over-write existing file "'tty_set.c'" else sed 's/^X//' >tty_set.c <<'@//E*O*F tty_set.c//' X/* X** vn news reader. X** X** tty_set.c - interface to ioctl (system tty interface) X** X** see copyright disclaimer / history in vn.c source file X*/ X X#ifdef SYSV X#include <termio.h> X#else X#include <sgtty.h> X#endif X X#include "tty.h" X Xextern char Erasekey,Killkey; X X#ifdef SYSV Xstatic struct termio C_tp, O_tp; X#else Xstatic struct sgttyb C_tp; Xstatic unsigned short O_lflag; X#endif X Xstatic unsigned S_flag=0; Xstatic int R_ignore=0; /* up/down counter of reset calls to ignore */ X X#define IO_GOT 1 /* have polled for original terminal mode */ X#define IO_RAW 2 /* in RAW (CBREAK actually) mode */ X X/* X tty_set handles ioctl calls. SAVEMODE, RESTORE are used around X system calls and interrupts to assure cooked mode, and restore X raw if raw on SAVEMODE. The pair results in no calls to ioctl X if we are cooked already when SAVEMODE is called, and may be nested, X provided we desire no "restore" of cooked mode after restoring raw. X X When we get the original terminal mode, we also save erase and kill. X X sig_set makes an ioctl call to get process group leader. Otherwise X ioctl calls should come through here. X*/ Xtty_set(cmd) Xint cmd; X{ X int rc; X unsigned mask; X X switch (cmd) X { X case BACKSTOP: X#ifdef JOBCONTROL X if ((rc = ioctl(1,TIOCLGET,&mask)) != 0) X break; X mask |= LTOSTOP; X rc = ioctl(1,TIOCLSET,&mask); X#else X rc = 0; X#endif X break; X case RAWMODE: X if ((S_flag & IO_RAW) != 0) X { X rc = 0; X break; X } X if ((S_flag & IO_GOT) == 0) X { X /* Save original modes, get erase / kill */ X#ifdef SYSV X rc = ioctl(0,TCGETA,&C_tp); X O_tp = C_tp; X Erasekey = C_tp.c_cc[VERASE]; X Killkey = C_tp.c_cc[VKILL]; X#else X rc = ioctl(0,TIOCGETP,&C_tp); X O_lflag = C_tp.sg_flags; X Erasekey = C_tp.sg_erase; X Killkey = C_tp.sg_kill; X#endif X } X#ifdef SYSV X C_tp.c_lflag &= ~(ECHO | ICANON); X C_tp.c_cc[VMIN] = 1; X rc = ioctl(0,TCSETAW,&C_tp); X#else X C_tp.sg_flags |= CBREAK; X C_tp.sg_flags &= ~ECHO; X rc = ioctl(0,TIOCSETP,&C_tp); X#endif X S_flag = IO_GOT|IO_RAW; X break; X case COOKED: X if ((S_flag & IO_RAW) != 0) X { X#ifdef SYSV X C_tp = O_tp; X rc = ioctl(0,TCSETAW,&C_tp); X#else X C_tp.sg_flags = O_lflag; X rc = ioctl(0,TIOCSETP,&C_tp); X#endif X S_flag &= ~IO_RAW; X } X else X rc = 0; X break; X case SAVEMODE: X if ((S_flag & IO_RAW) != 0) X { X tty_set(COOKED); X R_ignore = 0; X } X else X ++R_ignore; X rc = 0; X break; X case RESTORE: X if (R_ignore <= 0) X { X tty_set(RAWMODE); X } X else X --R_ignore; X rc = 0; X break; X default: X rc = -1; X } X if (rc < 0) X printex ("ioctl failure, tty_set: %d",cmd); X} @//E*O*F tty_set.c// if test 2552 -ne "`wc -c <'tty_set.c'`"; then echo shar: error transmitting "'tty_set.c'" '(should have been 2552 characters)' fi fi # end of overwriting check echo shar: extracting "'tune.h'" '(2613 characters)' if test -f 'tune.h' ; then echo shar: will not over-write existing file "'tune.h'" else sed 's/^X//' >tune.h <<'@//E*O*F tune.h//' X/* X** vn news reader. X** X** tune.h - system tuning parameters X** X** see copyright disclaimer / history in vn.c source file X*/ X X/* X** buffer size needed for tmpnam() X*/ X#ifndef L_tmpnam X#define L_tmpnam 48 X#endif X X/* X** hash table size. linked list type of table which can expand to X** arbitrary density, including densities > 100%. Number of entries X** will be number of newsgroups in active list. This should be a prime X** number ("long division" of string modulo table size hash function). X*/ X#define HASHSIZE 809 X X/* X** maximum number of columns on terminal. If made smaller, there X** will be a savings in the size of the temporary file used X** for holding displays, at the penalty of not being able to use X** the entire screen width on terminals actually possessing more X** columns than this. A block roughly on the order of this value X** times the number of lines the terminal has is maintained per page in X** the temp file, and read / written as displays are interacted X** with. MIN_C put here because MAX_C > MIN_C. MIN_C is the minumum X** number of columns for which a "reasonable" display can be produced. X** before making it smaller, look at all uses of C_allow and variable X** to see that a setting that small won't screw up array bounds. X*/ X#define MAX_C 132 X#define MIN_C 36 X X/* X** large size for general purpose local buffers. only used in automatic X** variable declarations. Used with fgets for buffer size when reading X** file records, to hold pathnames, commands, etc. Reduce if you blow X** out stack storage. If reduced too far, will eventually show up X** as syntax errors on reading .newsrc's and the active list, and X** scrozzled article information arising from truncated header lines. X** The reply path line will probably be the first thing to cause trouble. X** Look through the reader to find the worst case chain of declarations X** (on the order of 12 or so is probably the max). X*/ X#define RECLEN 1200 X X/* X** to protect against reading entire articles to find non-existent header X** lines if an article should be hosed, only a limited number of records X** are searched. Should be big enough to get down to the last header X** entry on legitimate articles. X*/ X#define HDR_LINES 24 /* records of article to search for header line */ X X/* these determine some static array sizes */ X#define OPTLINES 60 /* maximum number of option lines in .newsrc */ X#define NUMFILTER 24 /* max number of filters on articles */ X X/* block sizes for allocation routines */ X#define STRBLKSIZE 1800 /* string storage allocation block */ X#define NDBLKSIZE 50 /* NODE structures to allocate at a time */ @//E*O*F tune.h// if test 2613 -ne "`wc -c <'tune.h'`"; then echo shar: error transmitting "'tune.h'" '(should have been 2613 characters)' fi fi # end of overwriting check echo shar: extracting "'userlist.c'" '(1923 characters)' if test -f 'userlist.c' ; then echo shar: will not over-write existing file "'userlist.c'" else sed 's/^X//' >userlist.c <<'@//E*O*F userlist.c//' X/* X** vn news reader. X** X** userlist.c - generate user's list of articles X** X** see copyright disclaimer / history in vn.c source file X*/ X X#include <stdio.h> X#include "vn.h" X Xextern PAGE Page; X X/* X generate user list of articles - either article numbers X are input directly (numeric list), or input is a search X string - invoke regular expression library and examine titles X search string "*" reserved for marked articles. Strings may X be prefixed with '!' for negation. X*/ Xuserlist (list) Xchar *list; X{ X int i,j,anum[RECLEN/2],acount; X char neg, *s, sbuf[MAX_C+1], *reg, *regex(), *regcmp(), *index(), *strtok(); X X user_str (sbuf,"Articles or title search string : ",1); X if (sbuf[0] == '!') X { X neg = '!'; X s = sbuf+1; X } X else X { X neg = '\0'; X s = sbuf; X } X for (i=0; s[i] != '\0'; ++i) X { X if (index(LIST_SEP,s[i]) == NULL) X { X if (s[i] < '0' || s[i] > '9') X break; X } X } X acount = 0; X X if (s[i] == '\0') X { X for (s = strtok(s,LIST_SEP); s != NULL; s = strtok(NULL,LIST_SEP)) X { X anum[acount] = atoi(s); X ++acount; X } X } X else X { X if (s[0] == ART_MARK) X { X for (i=0; i < Page.h.artnum; ++i) X { X if (Page.b[i].art_mark == ART_MARK) X { X anum[acount] = Page.b[i].art_id; X ++acount; X } X } X } X else X { X reg = regcmp(s,(char *) 0); X if (reg != NULL) X { X for (i=0; i < Page.h.artnum; ++i) X { X if (regex(reg,Page.b[i].art_t) != NULL) X { X anum[acount] = Page.b[i].art_id; X ++acount; X } X } X regfree (reg); X } X else X preinfo ("bad regular expression syntax"); X } X } X X /* algorithm is inefficient, but we're only handling a few numbers */ X *list = '\0'; X for (i=0; i < Page.h.artnum; ++i) X { X for (j=0; j < acount && anum[j] != Page.b[i].art_id; ++j) X ; X if (neg == '!') X { X if (j < acount) X continue; X } X else X { X if (j >= acount) X continue; X } X sprintf (list,"%d ",Page.b[i].art_id); X list += strlen(list); X } X} @//E*O*F userlist.c// if test 1923 -ne "`wc -c <'userlist.c'`"; then echo shar: error transmitting "'userlist.c'" '(should have been 1923 characters)' fi fi # end of overwriting check echo shar: extracting "'vn.h'" '(4278 characters)' if test -f 'vn.h' ; then echo shar: will not over-write existing file "'vn.h'" else sed 's/^X//' >vn.h <<'@//E*O*F vn.h//' X/* X** vn news reader. X** X** vn.h - general parameters X** X** see copyright disclaimer / history in vn.c source file X*/ X X#include "tune.h" X X#define TRUE 1 X#define FALSE 0 X X#ifdef OLDRC X#define NARGOPT "lprxfuMs" X#else X#define NARGOPT "lprxfuMsi" X#endif X X#define FIL_AUTHOR 'w' X#define FIL_TITLE 't' X X/* X newsrc states X*/ X#define NEWS_ON ':' X#define NEWS_OFF '!' X X/* bit flags for state of newsgroup */ X#define FLG_SCAN 1 X#define FLG_SUB 2 X#define FLG_PAGE 4 X#define FLG_WRIT 8 X#define FLG_SPEC 16 X X#define LIST_SEP " ," X#define ED_MARK '>' X#define ART_MARK '*' X#define ART_WRITTEN '_' X#define ART_UNWRITTEN ' ' X X#define FPFIX "Re: " X#define FPFLEN 4 X X#define ANFORM ":%s - %c for help:\n" X#define ANFLINES 1 X#define NOFORM "can't open article %s\n" X#define NEWGFORM "groups not mentioned in %s:\n" X#define SAVFORM "save file (%s) ? " X#define UDKFORM "undefined key - %c for help" X#define HELPFORM "%c for help" X X/* X page display format and dependent parameters X*/ X#define HFORMAT "\n%s (page %d of %d):" X#define DHFORMAT "\n%s (DIGEST EXTRACTION):" X#define TFORMAT "%s ~ %s %s" X#define AFORMAT "\n%c%c%d) " /* begin with newline - see show routine */ X#define CFORMAT "page %d of %d (%d shown), newsgroup %d of %d" X#define RECBIAS 2 /* lines before articles - depends on HFORMAT */ X#define AFLEN 5 /* min. char. in article id - depends on AFORMAT */ X#define WRCOL 1 /* column of written mark. depends on AFORMAT */ X#define INFOLINE 0 /* HFORMAT TFORMAT leaves for use */ X X/* X command characters - don't use numerics or <ESC> X ALTSAVE is a hack to avoid having to use ctl-s - XON/XOFF. X Wanted to preserve "s" pneumonic and lower / control /cap X convention. X*/ X#define DIGEST 'd' X#define UP 'k' X#define DOWN 'j' X#define FORWARD '\012' X#define BACK '\010' X#define READ 'r' X#define ALTREAD ' ' X#define READALL 'R' X#define READSTRING '\022' X#define SAVE 's' X#define SAVEALL 'S' X#define SAVESTRING '\023' X#define ALTSAVE '\024' X#define PRINT 'p' X#define PRINTALL 'P' X#define PRINTSTRING '\020' X#define MARK 'x' X#define UNMARK 'X' X#define REDRAW '\014' X#define QUIT 'q' X#define SSTAT '#' X#define GRPLIST '%' X#define ORGGRP 'o' X#define ORGSTAT 'O' X#define UPDATE 'w' X#define UNSUBSCRIBE 'u' X#define UPALL 'W' X#define UPSEEN '\027' X#define UNESC '!' X#define NEWGROUP 'n' X#define HEADTOG 'h' X#define SETROT 'z' X#define HELP '?' X#define HELP_HEAD "[...] = effect of optional number preceding command\n\ Xpipes are specified by filenames beginning with |\n\ Xarticles specified as a list of numbers, title search string, or\n\ X * to specify marked articles. ! may be used to negate any\n" X X#define HHLINES 5 /* lines (CRs + 1) contained in HELP_HEAD */ X X/* X state flags for handling breaks / values for sig_set calls. X BRK_IN, BRK_SESS, BRK_READ and BRK_OUT are the states. All X but BRK_INIT are used as calls to sig_set. BRK_RFIN indicates X a return from BRK_READ to BRK_SESS (no jump location passed), X*/ X#define BRK_INIT 0 /* initial value, indicating uncaught signals */ X#define BRK_IN 1 /* in NEWSRC / article scanning phase */ X#define BRK_SESS 2 /* in page interactive session */ X#define BRK_READ 3 /* reading articles */ X#define BRK_RFIN 4 /* finished reading, return to old mode */ X#define BRK_OUT 5 /* NEWSRC updating phase */ X X#define BRK_PR "really quit ? " X#define BRK_MSG "\nQUIT (signal %d)" X X/* X newsgroup structure (node of hash table) X next - hashtable link X nd_name - name of newsgroup (key to reach node by) X pnum - page number, initially used to establish Newsorder X pages - number of pages for news display X rdnum - articles read X orgrd - original articles read number X pgshwn - pages shown mask X pgrd - article number on highest conecutively shown page X art - articles in group X state - status X*/ Xtypedef struct _node X{ X struct _node *next; X char *nd_name; X int pnum,pages,art,rdnum,orgrd,pgrd; X unsigned long pgshwn; X unsigned state; X} NODE; X X/* X newsgroup information for page display X name - of group X group - pointer to table entry X artnum - number of articles X*/ Xtypedef struct X{ X char *name; X NODE *group; X int artnum; X} HEAD; X X/* X article information - id (spool) number, title string, mark, written. X*/ Xtypedef struct X{ X int art_id; X char art_mark; X char art_written; X char art_t[MAX_C-AFLEN]; X} BODY; X Xtypedef struct X{ X HEAD h; X BODY *b; X} PAGE; @//E*O*F vn.h// if test 4278 -ne "`wc -c <'vn.h'`"; then echo shar: error transmitting "'vn.h'" '(should have been 4278 characters)' fi fi # end of overwriting check echo shar: extracting "'vnglob.c'" '(1613 characters)' if test -f 'vnglob.c' ; then echo shar: will not over-write existing file "'vnglob.c'" else sed 's/^X//' >vnglob.c <<'@//E*O*F vnglob.c//' X/* X** vn news reader. X** X** vnglob.c - global variables - see string.c also X** X** see copyright disclaimer / history in vn.c source file X*/ X X#include <stdio.h> X#include "config.h" X#include "vn.h" X#include "head.h" X X/* X global data structure X*/ XNODE **Newsorder; /* .newsrc file order */ X Xchar *Editor,*Ps1,*Mailer,*Printer,*Poster; X Xchar Erasekey, Killkey; /* user keys from stty */ Xchar *Newsrc, *Orgdir; /* .newsrc file, and original pwd */ Xchar *Onews; /* temp. file for backing up .newsrc */ Xchar *Savefile = DEF_SAVE; /* file in which to save articles */ Xchar *Savedir; /* default directory for saved articles */ Xchar *Ccfile; /* author_copy file, stored /bin/mail fmt */ X Xint Rot; /* rotation */ Xint Headflag; /* header printing flag */ Xint Digest; /* if non-zero, digest article */ X Xchar *Ku, *Kd, *Kl, *Kr; /* Cursor movement capabilities */ X X/* character translation arrays for commands */ Xchar Cxitop[128], Cxitor[128], Cxrtoi[128], Cxptoi[128]; X X/* X cur_page - current page displayed; X lrec - last record X l_allow - lines allowed for article display X c_allow - columns allowed X ncount = newsorder index X nfltr - number of filters X*/ Xint Cur_page, Lrec, L_allow, C_allow, Ncount, Nfltr; X X/* X article filtration options. X*/ Xchar *Wopt[NUMFILTER]; /* regular expressions for -w options */ Xchar *Topt[NUMFILTER]; /* regular expressions for -t options */ Xchar *Negwopt[NUMFILTER]; /* regular expressions for negated -w options */ Xchar *Negtopt[NUMFILTER]; /* regular expressions for negated -t options */ X Xint Nwopt, Ntopt, Nnwopt, Nntopt; X Xint Nounsub, Listfirst; X/* X current page X*/ XPAGE Page; @//E*O*F vnglob.c// if test 1613 -ne "`wc -c <'vnglob.c'`"; then echo shar: error transmitting "'vnglob.c'" '(should have been 1613 characters)' fi fi # end of overwriting check echo shar: "End of archive 2 (of 3)." cp /dev/null ark2isdone DONE=true for I in 1 2 3; do if test -! f ark${I}isdone; then echo "You still need to run archive ${I}." DONE=false fi done case $DONE in true) echo "You have run all 3 archives." echo 'Now read the README' ;; esac ## End of shell archive. exit 0