home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky alt.sources:3114 eunet.sources:12
- Path: sparky!uunet!olivea!hal.com!decwrl!parc!biosci!uwm.edu!spool.mu.edu!howland.reston.ans.net!paladin.american.edu!news.univie.ac.at!hp4at!usenet
- From: paul@eunet.co.at (Paul Gillingwater)
- Newsgroups: alt.sources,eunet.sources
- Subject: EEP 1.61 -- bug-fix point release of .newsrc editor
- Summary: User friendly newsgroup subscription browser
- Message-ID: <1k6qmeINNblt@hp4at.eunet.co.at>
- Date: 27 Jan 93 20:18:22 GMT
- References: <1k4hm7INNo7l@nic.umass.edu>
- Followup-To: alt.sources.d
- Organization: EUnet EDV Dienstleistungs GmbH A-1010 Wien Austria
- Lines: 3366
- NNTP-Posting-Host: hp4at.eunet.co.at
-
- Submitted-by: paul@actrix.co.at
- Archive-name: EEP 1.61 .newsrc editor (for rn, trn, nn)
-
- What the heck -- everybody loves source, and the net has unlimited
- bandwidth (NOT!), so here it is again with a few tweaks to remove the
- nasty core dumps. Enjoy!
-
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # Wrapped by Paul Gillingwater <paul@hp4at> on Wed Jan 27 21:07:48 1993
- #
- # This archive contains:
- # README eep.1 eep.h eepmain.c
- # eepmenu.c eepmisc.c eepview.c makefile
- # makefile.dos makefile.unx
- #
-
- LANG=""; export LANG
- PATH=/bin:/usr/bin:$PATH; export PATH
-
- echo x - README
- sed 's/^@//' >README <<'@EOF'
- EEP (Easy Editor Program for .newsrc)
-
- (c) 1990-1993 Paul Gillingwater <paul@actrix.co.at>
-
-
- This is EEP version 1.61, an experimental .newsrc editor program.
-
- It is intended to work with news readers such as ``rn'' and ``trn'',
- that create a .newsrc file in the $HOME directory of each user, in
- order to track what messages have been read by them. A major design
- objective is that it should be easy to use, even by someone who is
- not familiar with other UNIX editors. There is however a distinct
- bias towards vi in some of the commands, although this is redeemed
- somewhat by use of curses, which means that up and down arrows may
- be used on many systems. Another redeeming feature is the on-line
- help, activated with the ``?'' key.
-
- Note that EEP is _NOT_ intended to be called from within ``rn'' or
- ``trn'' by shelling out, since it will modify the .newsrc which is
- presently on disk -- and which the newsreader may have open.
-
- Eep was written by Paul Gillingwater <paul@actrix.co.at>.
- It was initially written for Actrix Information Exchange, a
- Public Access UNIX BBS in Wellington, New Zealand.
-
- This entire work is Copyrighted (C) 1991 by Paul Gillingwater, as
- the sole original author (apart from where otherwise explicitly
- acknowledged). The source code provided is available for anyone to
- use in any way, EXCEPT that you may not sell it or pretend that you
- wrote it. I would be happy if people wish to incorporate part or
- all of this in some other product, as long as you acknowledge me as
- original author of these parts. If this code is to be incorporated
- into a commercial product, I request that you contact me with regard
- to licensing.
-
- You may contact me care of:
- Actrix Information Exchange
- PO Box 11-410
- Wellington
- NEW ZEALAND
-
- **** WARNING: This program will modify your .newsrc file. Please
- ensure you have a safe copy of this file to prevent an unfortunate
- accident.
-
- Revision History
- ================
- Version 1.0 ``Warts'n'All'' version released on limited (NZ only)
- distribution. Made available via anon. FTP or UUCP from Actrix.
- Sent to various people to test porting to other platforms, and
- implemented on Actrix BBS since it might be useful for new users.
- Released: July 20, 1991
-
- Version 1.1 This version records the order in which newsgroups are
- found in the .newsrc file, and will maintain that order for display
- and output purposes. In addition, any newsgroups which don't yet
- have any entry in the newsgroups file or newslocal will be sorted so
- they appear first -- this will help find new newsgroups quickly (but
- it's not a full solution).
-
- Version 1.2 A small but important change. It seems that ``rn'' will
- check your .newsrc for newsgroup names not present, then will try to
- present you with a large list of so-called "New" newsgroups. It
- seems the only way to stop this is to leave all the unsubscribed
- newsgroups in the .newsrc. This seems somehow inelegant, but
- necessary.
-
- Version 1.3 After a long hiatus, several important bug fixes
- contributed by various net.people. Credits follow:
-
- Dean Roth <sysop@mixcom.com>
- Paul Close <pdc@sgi.com>
- Arjan de Vet <devet@win.tue.nl>
-
- As well as bug fixes, some additional functionality:
- o Newsgroups may be indexed by number (':' command)
- o MS-DOS version developed using PDCurses
- o Compatible with the Waffle system (MS-DOS and UNIX)
-
- Version 1.4 The list of newsgroups now has a top and bottom,
- and commands to get there. Newsgroups may be deleted from
- the .newsrc with the 'd' command. The 'd' command (delete)
- is now a toggle.
-
- January 1993: Version 1.5: Major new command is 'v'
- for view, which will open the directory and look through
- headers in articles to allow browsing subjects, keywords,
- authors, dates, etc. Using dirent.h for directory access.
-
- Version 1.6: Major rewrite of initialization code to change order of
- reading files. Now the active file is read first, then the newsgroup
- and newslocal files, finally the .newsrc. Changed the 'a' command so
- that it's a toggle, swapping between alphabetic sorting and the original
- order from the .newsrc. Various minor pointer arithmetic bug fixes.
- A new feature is the ability to mark newsgroups with the "." key,
- then move them to above the cursor position. Note that if multiple
- groups are marked then moved, they may not stay in the same relative
- order because of the sorting used.
-
- Version 1.61: minor bug fixes to avoid feeding NULL pointers to
- strlen(), plus other improvements.
-
- ------------------------------------------------------------
- News Descriptions
- =================
- A major benefit of Eep is that it is intended to provide a mechanism
- for selecting news groups based on more than just their name. By
- using lists provided by Gene Spafford, a brief description of each
- newsgroup is presented on screen, allowing novices to make decisions
- on what to read more easily. Although both ``rn'' and ``trn'' offer
- the L command to list news groups, this is unwieldy if you want to
- search for specific key words in newsgroup names or descriptions.
- Furthermore, Eep eliminates the necessity to actually type in the
- name of a newsgroup when subscribing to it. Simply point and play!
-
- Eep tries to be user friendly in moving around the .newsrc file.
- Experienced UNIX users will wish to use Emacs or vi to edit their
- @.newsrc for themselves. Eep is intended for novice users, and is
- a good addition to UNIX based BBS systems.
-
- Other features of Eep include the ability to subscribe or unsubscribe
- to a newsgroup, delete newsgroups, and catch up on messages.
-
- Eep will read a list of newsgroups and descriptions from two files,
- "/usr/lib/news/newsgroups" or "/usr/lib/news/newslocal".
-
- The NEWSGROUPS file contains one line per news group. The first
- ``word'' (in the UNIX sense) on the line is the newsgroup name,
- separated from its description by a space or tab. The NEWSLOCAL
- file is similar in structure, and is intended to contain groups
- which are purely local to your system, as well as the top level
- names of all of your hierarchies, plus other names as you desire for
- descriptive purposes.
-
- e.g. few articles are posted in comp.unix, but it makes a great
- place to hold the description for all the directories under it.
-
- Installation
- ------------
-
- This release assumes that all news files are stored on one
- file system, and that the paths to the files may be safely hard
- coded. Please edit the eep.h file to change where those paths may
- be on your system.
-
- The /usr/lib/news/newsgroups should exist as a result of allowing the
- checkgroups script (part of 'C' news) to run. Alternatively, you can
- create the file manually by editing the messages which are posted in
- news.announce.newusers on a regular basis by the net.god, Gene Spafford.
- You may embed comments in the file by starting the line with a ``#''.
- The /usr/lib/news/newslocal file contains your own local newsgroups
- (ones not covered by Gene's postings), or ones specific to your country.
- It is also used to keep descriptions of top level hierarchies (which will
- be used in a future version of this software).
-
- The format of the newsgroups and newslocal files is very simple:
-
- news.group.name description all on one line
-
- The first space or tab is the separator.
-
- Edit the makefile to set your preferences for compiler, then
- run ``make''. I have tried to make the code relatively
- portable. Please send me context diffs for any changes you'd like
- to suggest (or bugs, of which there are still a few).
-
- For those with early Sun OS variants (prior to Solaris, which decided to
- do SYSV properly), mattair@ds62.synercom.hounix.org (Charles Mattair) writes:
-
- > Sun-os is mostly a BSD derivative with the
- > brain dead BSD curses as its default libraries and include files. However,
- > the SYSV variant is around under /usr/5bin/... and if you link with
- > /usr/5bin/cc, you automagically get SYSV curses and its associated include
- > files.
-
- Oh, and for those who are wondering: "Why call it EEP?". Well, may
- I refer you to Sol Libes' excellent book, ``Life With UNIX''. There
- is a reference in there to an aspect of UniForum conferences in New
- Zealand, and the types of jokes found there. Then consider that one
- can start a command by prefixing it with the name of the shell to
- execute, e.g.:
- sh eep
-
- <baaaah!>
- -----------
- The ``To Do'' list:
-
- Although I use NNTP to fetch my news, I have not incorporated any of
- the hooks for NNTP in this version. This is definitely planned, but
- not for some time. I would welcome efforts in this direction from
- others. Should EEP become a newsreader? No, there are too many already.
-
- The Help screen is really ugly.
-
- This version of eep will maintain the order of the .newsrc, except
- that newsgroups not in the .newsrc will be sorted AFTER other newsgroups.
-
- Information on a newsgroup will include the actual number of
- articles found in the directory -- only upon request. Note that
- this will impact portability, since it will have to open
- directories.
-
- A later version will allow the ``!'' key to shell out to UNIX.
- Because some sites will use eep from inside a BBS, this may not be
- appropriate. For that reason, the -! flag may be used to set the
- no_shell boolean.
-
- The next version should have all files read (optionally) from
- environment variables.
-
- The MS-DOS version will work with Waffle. It will read the STATIC file
- as its active file, and will look at the user's JOIN file to obtain the
- equivalent of .newsrc.
-
- Cut and paste, or at least mark and move.
-
- Write out file for use with dynafeed.
-
-
- Design issues.
- --------------
-
- (a) Should eep sort the news groups into alphabetical order for
- reading? The early version of eep will sort by group name when
- displaying descriptions on screen. It seems useful to track the
- order in which they are read from the .newsrc, so that this order
- can be restored (if desired) by the user. Further, it would follow
- from this that they should be displayed in this way, and that groups
- (or multiple groups) should be able to be moved around from one
- place to another. On screen, this could be accomplished by marking
- the groups with a ``['' on the left edge of the screen, and use
- numbering, as well as Lotus-123 like anchoring for moving (NOT
- copying) the newsgroup lines. Of course, ESC will cancel.
-
- (b) If we change the ordering mechanism to use the ability to move
- groups around, it may be more appropriate to change the indexing
- method into a linked list. This linked list would be based upon the
- order in which the news groups were first read from the user's
- @.newsrc.
-
- (c) How should we deal with newsgroups that are not in the user's
- @.newsrc? If they have trimmed down their .newsrc, then that is
- their choice. We shouldn't litter it with a whole heap of
- unsubscribed news groups. That implies that when we write out the
- @.newsrc, we don't output the unsubscribed ones. But what if the
- user wants to keep track of how far they had read? Philosophical
- issue, I guess, but I'm tempted to say that it's just too bad. If
- the want to subscribe later, they can always catch up.
-
- (d) I don't fully understand (because I haven't tried to find out)
- the mechanism by which rn and trn detect that new news groups are
- present. I suspect it is something to do with determining whether
- the last modification date of the active file is subsequent to the
- most recent modification date of one's .newsrc, but I don't know how
- it knows which groups specifically are new. Eep is likely to
- interfere with this mechanism, because it will recreate the .newsrc,
- thus making to possible to miss automatic notification of new
- newsgroups. The newsgroups will still appear in Eep's list of
- course.
-
- (e) Some hooks are present to allow the root user to modify the
- active file. This will be a later addition, along with possible
- editing of the newsgroups file to add descriptions.
-
- (f) Early user feedback indicates the sorting the .newsrc is rather
- antisocial behaviour. As a quick hack, it may be useful to record
- the order of appearance from the .newsrc file, and sort the array
- into this order immediately prior to displaying the opening screen.
- (This has been done as of version 1.1).
- There will of course be some newsgroups' descriptions NOT present
- in the .newsrc, including the distributions file, as well as new
- newsgroups. If we set the default value of the sorting field to 9999
- then these will appear at the end of the file. This is good
- if they are new newsgroups, but maybe not so good if they are top
- level distribution names.
-
- (g) One addition that has been planned since the germination of eep
- has been to present the newsgroups in a hierarchical structure.
- Currently there are close to 2,000 newsgroups (in New Zealand) and
- this is growing fast. Having one long list, however you scroll
- through it, is not good enough for newer users. Eventually, eep
- will show an opening menu of just the top-level groups (i.e. ones
- with not "." in their name). Users will then "drill-down" to the
- next level, and thus will see the hierarchy as an inverted tree. As
- a prelude to this, and taking (h) into account, it seems appropriate
- to add code to take the top-level names separately, and not show
- them in the main list.
-
- (h) Most of the top-level names may be found in the
- /usr/lib/news/distributions file, however not all. For example,
- there are some news groups which have a single name, e.g. control,
- junk. Should these be shown at all? I think so -- but it's not
- appropriate to treat them as top levels. Perhaps these specials
- could be kept in newslocal file.
- @EOF
-
- chmod 600 README
-
- echo x - eep.1
- sed 's/^@//' >eep.1 <<'@EOF'
- @.TH EEP 1 "Eep v1.6" "by Paul Gillingwater"
- @.SH NAME
- eep v1.6 -- Easy Editor Program for .newsrc
- @.SH SYNOPSIS
- @.B eep [-p]
- @.PP
- @.SH DESCRIPTION
- @.I Eep\^
- is a user-friendly full-screen editor designed to
- modify the .newsrc file associated with the
- @.B rn
- or
- @.B trn
- news readers. It is NOT intended to be used while the .newsrc
- is currently open, i.e. by shelling out.
- @.P
- The program will read the .newsrc file from the $HOME directory
- of the user, and will combine this with a list of descriptions
- taken from /usr/lib/news/newsgroups and /usr/lib/news/newslocal.
- Further information will be taken from the news active file, which
- is maintained by the ``B'' or ``C'' news systems.
- @.P
- Curses is used to draw a list of the newsgroups, which may be
- navigated using arrow keys as well as commands similar to the
- @.B vi
- editor. Newsgroups which are currently subscribed to will be
- prefixed with a ``+'' character, while those not subscribed to
- will have a SPACE. If the newsgroup is invalid in same way, e.g.
- it is bogus (not known in the active file) it will be marked with
- a ``?''. Pressing the ENTER key will show further information about
- the highlighted newsgroup, including its position in the file, low
- and high message numbers, and whether it is active, inactive or
- moderated. Other commands allow the user to subscribe or
- unsubscribe to newsgroups, delete them from their .newsrc
- or catch up (mark all messages as read).
- @.P
- @.SH
- COMMANDS
- @.P
- Here is a summary of commands available (upper and lower case
- letters are treated the same.) Note that some commands have more
- than one character to activate them, to offer variety of choice.
- @.P
- @.B
- Movement
- @.nf
-
- ^n ) Move pointer down one line
- SPACE )
- j )
- Down_Arrow )
-
- ^p ) Move pointer up one line
- BACKSPACE )
- k )
- Up_Arrow )
-
- ^d ) Move pointer down one page
- ^f )
-
- ^u ) Move pointer up one page
- ^b )
-
- t ) Move to top of file
- ^ )
-
- b ) Move to bottom of file
- $ )
-
- : ) Select newsgroup by number
- @.fi
- @.PP
- @.B
- Searching
- @.nf
-
- / ) Search for string of text
-
- n ) Search again
- @.fi
- @.PP
- @.B
- Subscription
- @.nf
-
- s ) Subscribe to current newsgroup
- + )
-
- u ) Unsubscribe to current newsgroup
- - )
-
- d ) Toggle delete flag on current newsgroup
- @.fi
- @.PP
- @.B
- Other
- @.nf
-
- ? ) Display help screen
- h )
-
- p ) Change type of pointer
-
- a ) Toggle: Alphabetise the list or back to .newsrc order
-
- c ) Catch up (mark all messages as read)
-
- . ) Toggle mark. This is used to select
- groups to be moved with the (m) Move
- command.
-
- m ) Move marked groups to current position.
-
- i ) Show more information on newsgroup
-
- r ) Redraw screen
- ^L )
-
- v ) View list of messages in newsgroup
- = )
- ENTER )
- @.fi
- @.PP
- @.B
- Exit
- @.nf
-
- q ) Quit without saving changes
- ESC )
- ^C )
- DEL )
-
- x ) Exit and save changes
- @.fi
- @.PP
- Options are:
- @.TP 1.0i
- @.B " -p"
- Change the pointer used from scroll bar to simple arrow. This is
- faster at low modem speeds when moving through the file.
-
- @.SH AUTHOR
- Paul Gillingwater, Actrix Information Exchange <paul@actrix.gen.nz>
- @.SH WARNINGS
- Your existing .newsrc will be renamed to .newsrc.old, deleting any
- existing file of that name. This will occur only when you exit with
- the
- @.B "``x''"
- command. Until then,
- @.B "eep's"
- working file is .newsrc.new.
- @.P
- New newsgroups will not automatically be notified. Newsgroups
- which are not present in your .newsrc file, but are found in the
- active file, will be sorted to the bottom of the list.
- @.P
- When moving a set of newsgroups with the mark and move commands,
- the set will not necessarily stay in the same relative order.
- @.P
- Bogus newsgroups (those not found in the active file, but present
- in your .newsrc) will be (optionally) deleted.
- @.SH FILES
- $HOME/.newsrc file to be modified
- @.br
- $HOME/.newsrc.old backup of previous .newsrc
- @.br
- $HOME/.newsrc.eep temporary working file
- @.br
- /usr/lib/news/newsgroups } names and descriptions
- @.br
- /usr/lib/news/newslocal } of newsgroups
- @.br
- /usr/lib/news/active active newsgroups file
- @.SH BUG REPORTS TO
- Paul Gillingwater <paul@actrix.gen.nz>
- @.SH COPYRIGHTS
- @.ps 18
- \fB\(co\fR\s12 Copyright 1991-1993 by Paul Gillingwater
- @EOF
-
- chmod 600 eep.1
-
- echo x - eep.h
- cat >eep.h <<'@EOF'
- /* eep.h
-
- This is the common header file for the eep program.
-
- */
-
- #ifdef UNIX
- #define NEWSBASE "/usr/spool/news/" /* where news lives */
- #define ACTIVEFILE "/usr/lib/news/active" /* active file */
- #define NEWSGROUPS "/usr/lib/news/newsgroups" /* descriptions of newsgroups */
- #define NEWSLOCAL "/usr/lib/news/newslocal" /* local newsgroups */
- #define NEWSRC ".newsrc" /* filename for .newsrc */
- #define CRLF "\n"
- #define SHELL "/bin/ksh" /* default shell */
- #endif /* UNIX */
-
- #ifdef DOS
- #define NEWSBASE "/news/" /* where news lives */
- #define ACTIVEFILE "active" /* active file */
- #define NEWSGROUPS "newsgroups" /* descriptions of newsgroups */
- #define NEWSLOCAL "newslocal" /* local newsgroups */
- #define NEWSRC "newsrc" /* filename for .newsrc */
- #define CRLF "\r\n"
- #endif /* DOS */
-
- #ifndef FALSE
- #define FALSE 0 /* this may be redefined elsewhere */
- #endif
- #ifndef TRUE
- #define TRUE 1 /* this may be redefined elsewhere */
- #endif
- #define EEPLINES 24 /* lines shown on screen */
- #define EEPCOLUMNS 80 /* columns shown on screen */
- #define EEPPAGE EEPLINES-2 /* page size for scrolling */
- #define BUFSIZE 4096 /* general line buffer length */
- #define MAXLEVELS 20 /* depth of news hierachies */
- #ifdef DOS /* limitations of memory models */
- #define MAXLINES 6000 /* max. number of news groups */
- #define MAXARTS 600
- #endif /* DOS */
- #ifdef UNIX
- #define MAXLINES 20000 /* thank Cthulu for virtual memory */
- #define MAXARTS 2000
- #endif /* UNIX */
- #define MAXDIST 40 /* number of top level distribution names */
- #define TIMEOUT 2 /* keyboard inactivity timer in minutes */
- #define SHELLDENY 3 /* uid for user to deny shell access to */
-
- /* This is the primary data storage structure. It combines both the
- active file and the .newsrc file. We'll malloc() space for each
- element of the structure, and use an array of pointers to access it
- */
-
- struct actif {
-
- char *name, /* news group */
- *desc, /* description of newsgroup */
- *hilo; /* high to low range from my .newsrc */
-
- long hi; /* hi message number from active file */
-
- int index, /* used as alternate index into array */
- mark; /* used to mark groups to be moved */
-
- char flag, /* [ynm] from active file */
- status; /* [:!] from .newsrc file */
-
- struct actif *depth; /* pointer to next entry in ``depth'' list */
- };
-
- @EOF
-
- chmod 600 eep.h
-
- echo x - eepmain.c
- cat >eepmain.c <<'@EOF'
- /*------------------------------------------------------------------------
- Name: eepmain.c
-
- This program makes it easier for users to change their .newsrc file.
- It uses curses to implement a simple editor, which allows users to
- join or unjoin newsgroups, from outside of rn or trn.
-
- Author: Paul Gillingwater, paul@actrix.gen.nz
-
- Usage:
- eep [-p] [-!]
-
- Options:
- -p: Use a terse pointer on screen instead of a bar
- -!: Set flag to disallow user shell out
-
- ------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <signal.h>
-
- #ifdef ANSI
- #include <stdlib.h>
- #else
- #define void int
- extern char *malloc();
- extern char *getenv();
- #endif /* ANSI */
-
- #include "eep.h"
-
- /* Some function definitions */
-
- extern void newsmain();
-
- char buffer[BUFSIZE], /* general purpose line buffer */
- tmp[BUFSIZE],
- s_hi[30], /* strings for numbers */
- s_lo[30], /* strings for numbers */
- s_flag[8];
- char t_status, /* from .newsrc file */
- t_flag; /* from active file */
- char *ptr; /* general purpose pointer */
- char *bog_msg = "Bogus newsgroup (not in active file)";
-
- int eepoint = 0, /* -p flag for screen pointer type */
- noshell = 0, /* -! flag to deny shell-out */
- uid = 0, /* real user id */
- result; /* flag for searching */
-
- FILE *fnewsrc,
- *factive;
-
- struct actif *act[MAXLINES]; /* here's the main array */
- struct actif *topact[MAXDIST]; /* array for top level distributions only */
- struct actif *aptr; /* temporary pointer */
-
- int i_active, /* index into actif arrays */
- c_active, /* number of elements in act array */
- t_active, /* number of elements in topact array */
- bog_count; /* count of bogus newsgroups */
- int high,low,mid; /* used for binary chop searching */
-
- /* The levels array contains the Head pointers which control the
- linked lists of newsgroups grouped by their "depth" in the
- hierarchy, and sorted alphabetically. E.g. alt, sci, soc are
- level 0, alt.pagan, sci.physics are level 1 and so on. */
-
- struct actif *levels[MAXLEVELS]; /* keep track of levels with this array */
-
- int i_levels; /* index into array */
-
- /* Comparison functions for qsort. These functions are used for
- sorting the array of pointers that point to our actif data structures. */
-
- int qcompare(item1,item2) /* sort by name */
- struct actif **item1, **item2;
- {
- struct actif *ptr1, *ptr2;
- ptr1 = (struct actif *) *item1;
- ptr2 = (struct actif *) *item2;
- return (strcmp(ptr1->name, ptr2->name));
- }
-
- int icompare(item1,item2) /* sort by index number */
- struct actif **item1, **item2;
- {
- struct actif *ptr1, *ptr2;
- ptr1 = (struct actif *) *item1;
- ptr2 = (struct actif *) *item2;
- return (ptr1->index - ptr2->index);
- }
-
- /* This routine will read the a file (descfile) containing names and
- descriptions of newsgroups, matching it with the active file. */
-
- void read_desc(descfile)
- FILE *descfile;
- {
- char *name, *desc; /* pointers to name and description */
-
- i_active = 0; /* start with first one of course */
- aptr = (struct actif *)NULL;
-
- while (fgets(buffer,BUFSIZE,descfile) != (char *)NULL) {
-
- /* ignore comment lines or blank lines */
- switch(buffer[0]) {
- case '#':
- case '\n':
- case '\r':
- case '\0':
- continue;
- }
-
- /* Get name and description. If either is absent, skip this line. */
- if ((name = strtok(buffer, " \t\r\n")) == (char *)NULL) continue;
- if ((desc = strtok((char *)NULL, "\r\n")) == (char *)NULL) continue;
-
- /* Advance over any whitespace preceding description */
- while ((*(desc) == ' ') || (*(desc) == '\t')) desc++;
-
- /* Although we cannot assume that the newsgroups are in alphabetical
- * order, we'll try looking at the next one anyway before doing a
- * search. */
-
- if (i_active <= c_active) /* range check */
- aptr = act[i_active];
-
- /* This next line should never happen. It would only occur if
- * we've run out of things to match! */
-
- if (aptr == (struct actif *)NULL) {
- printf("This should never happen!\n");
- continue;
- }
-
- /* Now compare the name read with current position in active file */
-
- if (strcmp(name,aptr->name) == 0) {
-
- /* Here we look for the best description possible, i.e. one that is not
- null, and preferably longest (i.e. not just a '?'). This will be because
- we may find duplicate lines in the newsgroups file. Also, it may be
- possible to find no description at all. */
-
- if (aptr->desc != (char *)NULL) {
- /* don't accept an inferior description */
- if (strlen(desc) <= strlen(aptr->desc)) continue;
-
- #ifdef UNIX /* free up the memory previously occupied */
- if ((aptr->desc != (char *)NULL) &&
- (aptr->desc != bog_msg)) free(aptr->desc);
- #endif /* UNIX */
- }
-
- /* allocate space for string + null byte, then copy it in */
- if ((aptr->desc = (char *)malloc(strlen(desc)+1)) == (char *)NULL) {
- printf("Fatal error while allocating memory!\n");
- exit(1);
- }
- strcpy(aptr->desc,desc);
- i_active++; /* advance index to next pointer */
- if (i_active == c_active) i_active = 0;
- continue;
- }
-
- /* Here we begin a binary chop search, comparing the newsgroup
- * name we have just read from the newsgroups file with the list
- * of newsgroups read from the active file. */
-
- low = 0;
- high = c_active - 1;
- loop1:
- if (low <= high) {
- mid = (low+high)/2;
- aptr = act[mid];
- result = strcmp(name,aptr->name);
- if (result == 0) {
-
- if (aptr->desc != (char *)NULL) {
- /* don't accept an inferior description */
- if (strlen(desc) <= strlen(aptr->desc)) continue;
-
- #ifdef UNIX /* free up the memory previously occupied */
- if ((aptr->desc != (char *)NULL) &&
- (aptr->desc != bog_msg)) free(aptr->desc);
- #endif /* UNIX */
- }
-
- /* allocate space for string + null byte, then copy it in */
- if ((aptr->desc = (char *)malloc(strlen(desc)+1))
- == (char *)NULL) {
- printf("Fatal error while allocating memory!\n");
- exit(1);
- }
- strcpy(aptr->desc,desc);
-
- i_active = mid + 1;
- if (i_active == c_active) i_active = 0;
- continue; /* with read loop */
- } else
- if (result > 0) { /* after */
- low = mid+1;
- goto loop1;
- } else
- if (result < 0) { /* before */
- high = mid-1;
- goto loop1;
- }
- }
- }
- fclose(descfile);
- }
-
- /* Initialise the various chunks of memory and read in files. */
-
- void initial()
- {
-
- int newsrc_order; /* track reading order from .newsrc */
- int warning = FALSE; /* if warning messages have been issued */
-
- char *name, /* pointers into line in active file */
- *hi,
- *lo,
- *flag;
-
- #ifdef UNIX
- uid = getuid();
- /* For systems with a fixed BBS login, we have this hack
- to deny shell access. */
- if (uid == SHELLDENY) noshell++;
- #endif /* UNIX */
-
- /* CHANGES for JAN 1993: ************************************
-
- Because NEWSGROUPS can often contain lots of duplicates, while
- the active file is "cleaner", let's read the active file FIRST,
- then scan the NEWSGROUPS and NEWSLOCAL file looking for
- descriptions. We should try to find the best description, i.e.
- one that is not null, not a '?', and not "alt group".
- A simple sequential read of these files is adequate. Note
- that the active file is authoritative when it comes to bogus
- groups, which means we could simply ignore entries from the
- NEWSGROUPS file that aren't in the active file.
-
- When we read the .newsrc, we still need to add entries for
- bogus groups, to give people the option of keeping strange
- stuff in their .newsrc. This means we should prompt before
- saving whether they want to lose the bogus groups or not.
-
- *************************************************************/
-
- c_active = 0; /* count the newsgroups as we go. */
-
- if ((factive = fopen(ACTIVEFILE, "r")) == (FILE *)NULL) {
- printf("Fatal: Unable to read %s\n",ACTIVEFILE);
- exit(1);
- }
-
- while (fgets(buffer,BUFSIZE,factive) != (char *)NULL) {
-
- /* ignore comment lines or blank lines */
- switch(buffer[0]) {
- case '#':
- case '\n':
- case '\r':
- case '\0':
- continue;
- }
-
- /* strip off newlines or returns */
- while ((ptr = strchr(buffer,'\n')) != (char *)NULL) *ptr = '\0';
- while ((ptr = strchr(buffer,'\r')) != (char *)NULL) *ptr = '\0';
-
- /* process line from active file -- low message number ignored. */
- if ((name = strtok(buffer, " \t\r\n")) == (char *)NULL) continue;
- if ((hi = strtok((char *)NULL, " \t\r\n")) == (char *)NULL) continue;
- if ((lo = strtok((char *)NULL, " \t\r\n")) == (char *)NULL) continue;
- if ((flag = strtok((char *)NULL, " \t\r\n")) == (char *)NULL) continue;
-
- /* check validity of data. Must have something in each position. */
-
- /* Now allocate a chunk of memory for actif */
- if ((aptr = (struct actif *) malloc(sizeof(struct actif)))
- == (struct actif *)NULL) {
- printf("Fatal error while allocating memory!\n");
- exit(1);
- }
- act[c_active] = aptr; /* record this pointer */
-
- /* allocate space for string + null byte, then copy it in */
- if ((aptr->name = (char *)malloc(strlen(name)+1)) == (char *)NULL) {
- printf("Fatal error while allocating memory!\n");
- exit(1);
- }
-
- /* now move data into the structure */
- strcpy(aptr->name,name);
- aptr->hi = atol(hi);
- aptr->hilo = (char *)NULL;
- aptr->desc = (char *)NULL;
- aptr->mark = 0; /* mark flag */
- aptr->flag = flag[0]; /* from active file */
- aptr->status = '!'; /* from .newsrc */
- aptr->index = 9999; /* sort unknowns at end */
- aptr->depth = (struct actif *) NULL;
- c_active++;
- }
- fclose(factive);
-
- if (c_active == 0) {
- printf("Fatal: Can't find any news groups in %s\n",ACTIVEFILE);
- exit(1);
- }
-
- /* Sort the list by newsgroup name. */
- qsort( act, (unsigned) c_active,(unsigned) sizeof(act[0]), qcompare);
-
- /* Now open NEWSGROUPS and NEWSLOCAL to look for descriptions. If
- these files don't exist, it's no great tragedy -- but the whole
- point of EEP will be missed. */
-
- if ((factive = fopen(NEWSGROUPS, "r")) != (FILE *)NULL)
- read_desc(factive);
-
- if ((factive = fopen(NEWSLOCAL, "r")) != (FILE *)NULL)
- read_desc(factive);
-
- /* Let's now build chains of pointers for each of the
- hierarchies of news groups, taking our initial pointer
- from the array levels[]. */
-
- i_levels = 0;
- while (i_levels < MAXLEVELS)
- levels[i_levels++] = (struct actif *) NULL; /* null array */
-
- /* Work backwards through the array, building the linked list.
- We also record the array index in each record. If we were
- only accessing it as an array, this would be redundant, but
- we're using multiple linked lists of pointers as well.
- We work backwards to ensure our chains are NULL terminated. */
-
- i_active = c_active - 1;
- while (i_active >= 0) {
- aptr = act[i_active];
- ptr = aptr->name;
- i_levels = 0;
- while ((ptr = strchr(ptr,'.')) != (char *)NULL) {
- i_levels++;
- ptr++;
- }
- if (i_levels < MAXLEVELS) {
- aptr->depth = levels[i_levels];
- levels[i_levels] = aptr;
- }
- i_active--;
- }
-
- /* This code will be re-used later when parsing newsgroups */
- /* let's check the pointers in levels[] */
- /*
- i_levels = 0;
- while (i_levels < MAXLEVELS) {
- aptr = levels[i_levels];
- while (aptr != (struct actif *)NULL) {
- sprintf(tmp,"%-25s %-.67s\n",
- aptr->name,
- aptr->desc);
- printf(tmp);
- aptr = (struct actif *) aptr->depth;
- }
- i_levels++;
- }
- */
-
-
- /* Now read in and match up our personal .newsrc
- Get HOME from the environment. */
-
- if ((ptr = getenv("HOME")) != (char *)NULL)
- sprintf(tmp, "%s/%s", ptr, NEWSRC);
- else
- sprintf(tmp, "%s", NEWSRC); /* default to current directory */
-
- if ((fnewsrc = fopen(tmp, "r")) == (FILE *)NULL) {
- printf("Fatal: Unable to read the file %s\n", tmp);
- printf("Please create it using the rn or trn news reader.\n");
- exit(1);
- }
-
- i_active = 0;
- newsrc_order = 1;
- bog_count = 0;
-
- while (fgets(buffer,BUFSIZE,fnewsrc) != (char *)NULL) {
-
- /* ignore comment lines */
- switch(buffer[0]) {
- case '#':
- case '\n':
- case '\r':
- case '\0':
- continue;
- }
-
- /* strip off CR and LF */
- while ((ptr = strchr(buffer,'\n')) != (char *)NULL) *ptr = '\0';
- while ((ptr = strchr(buffer,'\r')) != (char *)NULL) *ptr = '\0';
-
- /* don't try to match a null string */
- if (strlen(buffer) == 0) continue;
-
- /* Now examine the character that terminates the newsgroup name.
- If it's a colon ':', then this means the newsgroup is active
- for the user. If it's an exclamation mark, then it is
- inactive (unsubscribed). Anything else means the
- newsgroup may not be valid. */
-
- t_status = ' '; /* default to SPACE */
- if ((ptr = strchr(buffer,':')) != (char *)NULL) {
- t_status = ':';
- *ptr = '\0'; /* null terminate newsgroup */
- ptr++; /* point to rest of line (hilo) */
- } else if ((ptr = strchr(buffer,'!')) != (char *)NULL) {
- t_status = '!';
- *ptr = '\0'; /* null terminate newsgroup */
- ptr++; /* point to rest of line (hilo) */
- }
- /* advance past any whitespace */
- /* clean up this code to handle strange formats -- use strtok() */
- while ((*ptr == ' ') || (*ptr == '\t')) ptr++;
- strcpy(tmp,ptr); /* this is hilo */
-
- aptr = act[i_active]; /* range check */
- if ((aptr != (struct actif *)NULL)
- && (strcmp(buffer,aptr->name) == 0)) {
- if ((aptr->hilo = (char *)malloc(strlen(tmp)+1)) == (char *)NULL) {
- printf("Error allocating memory!\n");
- exit(1);
- }
- strcpy(aptr->hilo,tmp);
- aptr->status = t_status;
- aptr->index = newsrc_order++;
- i_active++;
- if (i_active == c_active) i_active = 0;
- continue;
- }
-
- low = 0;
- high = c_active - 1;
- loop2:
- if (low <= high) {
- mid = (low+high)/2;
- aptr = act[mid];
- result = strcmp(buffer,aptr->name);
- if (result == 0) {
- if ((aptr->hilo = (char *)malloc(strlen(ptr)+1))
- == (char *)NULL) {
- printf("Error allocating memory!\n");
- return;
- }
- strcpy(aptr->hilo,tmp);
- aptr->status = t_status;
- aptr->index = newsrc_order++;
- i_active = mid + 1;
- /* This next hack is necessary to prevent the
- corner case where mid has pointed at the very
- last entry in the act strucutre. */
- if (i_active == c_active) i_active = 0;
- continue; /* read loop */
- } else
- if (result > 0) { /* after */
- low = mid+1;
- goto loop2;
- } else
- if (result < 0) { /* before */
- high = mid-1;
- goto loop2;
- }
- } else {
- bog_count++; /* must be bogus! */
-
- if ((aptr = (struct actif *) malloc(sizeof(struct actif)))
- == (struct actif *)NULL) {
- printf("Fatal error while allocating memory!\n");
- exit(1);
- }
- act[c_active] = aptr;
-
- if ((aptr->name = (char *)malloc(strlen(buffer)+1))
- == (char *)NULL) {
- printf("Fatal error while allocating memory!\n");
- exit(1);
- }
- strcpy(aptr->name,buffer);
-
- if (strlen(tmp) > 0) {
- if ((aptr->hilo = (char *)malloc(strlen(tmp)+1))
- == (char *)NULL) {
- printf("Fatal error while allocating memory!\n");
- exit(1);
- }
- strcpy(aptr->hilo,tmp);
- }
- aptr->hi = 0;
- aptr->mark = 0;
- aptr->desc = "Bogus newsgroup (not in active file)";
- aptr->flag = '\0';
- aptr->status = t_status;
- aptr->index = newsrc_order++;
- aptr->depth = (struct actif *) NULL;
- c_active++;
- if (c_active < 2) continue;
- qsort( act, (unsigned) c_active,(unsigned) sizeof(act[0]),
- qcompare);
- continue; /* with read loop */
- }
- }
- fclose(fnewsrc);
-
- if (bog_count > 0) {
- if (bog_count == 1)
- printf("There was 1 bogus newsgroup in your .newsrc.\n");
- else
- printf("There were %d bogus newsgroups in your .newsrc.\n",
- bog_count);
- warning = TRUE;
- }
-
- /* Now let's sort this lot into the order that we originally
- read it from the .newsrc in. New newsgroups will be forced
- to the top, making it easier for them to be spotted. */
-
- qsort( act, (unsigned) c_active, (unsigned) sizeof(act[0]), icompare);
-
- #ifdef UNIX
- /* Now let's see if we can create a new .newsrc in $HOME */
- if ((ptr = getenv("HOME")) != (char *)NULL)
- sprintf(tmp, "%s/.newsrc.eep", ptr);
- else sprintf(tmp, ".newsrc.eep");
-
- if ((fnewsrc = fopen(tmp, "w")) == (FILE *)NULL) {
- printf("warning: cannot create .newsrc.eep -- check permissions\n");
- warning = TRUE;
- }
- #endif /* UNIX */
-
- if (warning) {
- printf("\nPress ENTER to continue.");
- gets(buffer);
- }
- }
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int ch;
- int timer;
-
- #ifdef UNIX
- while ((ch = getopt(argc,argv,"ap")) != EOF) switch(ch) {
- case 'p':
- eepoint++;
- break;
- case '!':
- noshell++;
- break;
- case '?':
- fprintf(stderr,"usage: eep [-p] [-!]\n\n");
- fprintf(stderr,"-p means use terse pointer\n");
- fprintf(stderr,"-! means deny shell out\n");
- fprintf(stderr,"\nUse man eep for more info.\n");
- exit (2);
- }
- #endif /* UNIX */
-
- fprintf(stderr,"eep version 1.61 .newsrc editor\n");
-
- #ifdef DOS
- /* msleep(0L);*/ /* invoke once to set precision */
- #endif /* DOS */
-
- initial(); /* read in newsgroups, active and .newsrc */
- newsmain();
-
- #ifdef UNIX /* just can't get free() working under MS-DOS. Sigh. */
- /* garbage collection */
- i_active = 0;
- while (i_active < c_active) {
- aptr = act[i_active];
- if (aptr != (struct actif *)NULL) {
- if (aptr->hilo != (char *)NULL) free(aptr->hilo);
- if ((aptr->desc != (char *)NULL) &&
- (aptr->desc != bog_msg)) free(aptr->desc);
- if (aptr->name != (char *)NULL) free(aptr->name);
- free((struct actif *)aptr);
- }
- i_active++;
- }
- #endif /* UNIX */
- exit(0);
- } /* end of eepmain.c */
- @EOF
-
- chmod 600 eepmain.c
-
- echo x - eepmenu.c
- cat >eepmenu.c <<'@EOF'
- /* This module contains the code for the user interface for eep. */
-
- #include <stdio.h>
- #include <string.h>
- #include <curses.h>
-
- #ifdef UNIX
- #include <ctype.h>
- #include <signal.h>
- #endif /* UNIX */
-
- #ifdef ANSI
- #include <stdlib.h>
- #else
- #define void int
- extern char *malloc();
- #endif /* ANSI */
-
- #include "eep.h" /* local changes */
-
- /* Function declarations for forward references */
-
- void showlist();
-
- extern int qcompare(); /* sort alphabetically */
- extern int icompare(); /* sort by index */
- extern char *shift_lower(); /* see eepmisc.c */
- extern char buffer[], /* general purpose line buffer */
- tmp[];
-
- extern struct actif *act[]; /* main data structure */
- extern struct actif *topact[]; /* top level names only */
-
- extern int i_active, /* index into arrays */
- c_active, /* number of lines in act array */
- t_active, /* number of lines in act array */
- eepoint, /* pointer switch */
- bog_count, /* bogus newsgroups */
- noshell; /* noshell switch */
-
-
- extern FILE *fnewsrc; /* .newsrc.eep */
-
- /* The levels array contains the Head pointers which control the
- linked lists of newsgroups grouped by their "depth" in the
- hierarchy, and sorted alphabetically. E.g. alt, sci, soc are
- level 0, alt.pagan, sci.physics are level 1 and so on. */
-
- extern struct actif *levels[]; /* keep track of levels with this array */
- extern struct actif *aptr; /* temporary pointer */
- extern int i_levels; /* index into array */
-
- /* Global variables */
-
- int scrnpos = 0, /* position of highlight on screen */
- current = 0, /* matching highlight in data structure */
- top = 0, /* data element on top of screen */
- eeplines = 0, /* number of lines on screen */
- eepcolumns = 0; /* columns on screen */
-
- WINDOW *over; /* used for on-screen help window etc. */
- void showhelp(); /* forward declaration */
-
- /* pad() -- this function will take a pointer to a string and a
- numeric argument, and will pad the string with spaces to reach
- the desired length. If the string is too long, it will be
- truncated to fit. The function will return a pointer to a
- static buffer that will contain the padded
- string (or original if it's long enough already).
- If str is a NULL pointer, we'll return spaces only. */
-
- char *pad(str,len)
- char *str;
- int len;
- {
- static char mybuf[BUFSIZE];
-
- int count;
- mybuf[0] = '\0';
- if (len >= BUFSIZE) return(mybuf); /* safety */
- /* In case we are passed a NULL pointer... */
- if (str == (char *) NULL) {
- mybuf[0] = '\0';
- /* while (strlen(mybuf) < len) strcat(mybuf," "); */
- count = 0;
- while (count++ < len) strcat(mybuf," ");
- return(mybuf);
- }
- if (strlen(str) >= len) {
- strncpy(mybuf,str,len);
- return(mybuf);
- }
- strcpy(mybuf,str);
- /* while (strlen(mybuf) < len) */
- count = len;
- while (count-- > 0)
- strcat(mybuf," ");
- return(mybuf);
- }
-
- /* newsmain() -- this provides the mainline user interface. */
-
- void newsmain()
- {
-
- char *ptr;
- char search[BUFSIZE]; /* search string buffer */
- int found = FALSE, /* flag to say we've found something */
- quit = FALSE, /* flag used when ready to quit */
- alphabetized = FALSE, /* flag showing if sorted */
- index, /* used when searching */
- counter, /* used when counting */
- ch; /* input character */
-
- /* Work out how many lines and columns we have.
- Use the environment variables first -- if they don't
- exist, we'll try terminfo. Yes, I know terminfo
- should do this, but don't bet on it for all versions.
- If that doesn't work, default to the ones in eep.h. */
-
-
- if ((ptr = getenv("LINES")) != (char *)NULL)
- eeplines = atoi(ptr);
- if ((ptr = getenv("COLUMNS")) != (char *)NULL)
- eepcolumns = atoi(ptr);
-
- /* Now let's try to use the ones defined by curses. */
- if (eeplines <= 0)
- eeplines = LINES;
- if (eepcolumns <= 0)
- eepcolumns = COLS;
- if (eeplines <= 0)
- eeplines = EEPLINES;
- if (eepcolumns <= 0)
- eepcolumns = EEPCOLUMNS;
- if ((eeplines < 19) || (eepcolumns < 80)) {
- printf("Sorry, EEP needs at least 19 lines by 80 columns.\n");
- exit(1);
- }
-
- initscr(); /* set up for curses */
- raw();
- noecho();
- nonl();
- keypad(stdscr,TRUE);
- erase(); /* clear screen */
-
- #ifdef UNIX
- idlok(stdscr,TRUE);
- #endif /* UNIX */
-
- showlist(0);
- while (quit == FALSE) {
- ch = getch();
- switch(ch) {
- case 'q': /* quit */
- case 'Q':
- case '\033': /* ESCAPE by itself */
- case '\003': /* for those who like ^C */
- case '\177': /* for those who like INTR */
- move(eeplines-1,0);
- deleteln();
- addstr("Do you want to quit without saving your changes? [n]: ");
- refresh();
- if (tolower(getch()) == (int) 'y') quit = TRUE;
- deleteln();
- move(scrnpos,0);
- refresh();
- break;
-
- case '?': /* on-line help */
- case 'h':
- case 'H':
- case KEY_F(1):
- over = newwin(19,60,0,5);
- if (!eepoint) wstandout(over);
- box(over,'\0','\0');
- if (!eepoint) wstandend(over);
- wmove(over,2,5);
- wstandout(over);
- waddstr(over," eep v1.6: .newsrc & JOIN file editor ");
- wstandend(over);
- wmove(over,3,5);
- waddstr(over,"by Paul Gillingwater, paul@actrix.co.at");
- wmove(over,5,5);
- waddstr(over,": Pick by number / Search");
- wmove(over,6,5);
- waddstr(over,"a (un)Alphabetise b Bottom of file");
- wmove(over,7,5);
- waddstr(over,"c Catch up d (un)Delete ");
- wmove(over,8,5);
- waddstr(over,"i Show info j Next line");
- wmove(over,9,5);
- waddstr(over,"k Previous line n Search next");
- wmove(over,10,5);
- waddstr(over,"p Pointer change r Redraw screen");
- wmove(over,11,5);
- waddstr(over,"s Subscribe t Top of file");
- wmove(over,12,5);
- waddstr(over,"u Unsubscribe v View subjects");
- wmove(over,13,5);
- waddstr(over,"x Save and exit q Quit without saving");
- wmove(over,14,5);
- waddstr(over,"^D Page down ^U Page up");
- wmove(over,15,5);
- waddstr(over,". (un)Mark group m Move marked groups");
- wmove(over,17,5);
- sprintf(buffer,"There are %d available newsgroups.",c_active);
- waddstr(over,buffer);
- wmove(over,18,5);
- wstandout(over);
- waddstr(over," Press SPACE BAR to exit from help ");
- wstandend(over);
- wrefresh(over);
- ch = wgetch(over);
- delwin(over);
- touchwin(stdscr);
- refresh();
- break;
-
- case ':': /* enter number */
- move(eeplines - 1,0);
- deleteln();
- addch(':');
- refresh();
- getbuf(search);
- index = atoi(search);
- if ((index <= 0) || (index > c_active)) {
- move(eeplines - 1,0);
- printw("Newsgroups available: %d ",c_active);
- refresh();
- sleep(2);
- deleteln();
- move(scrnpos,0);
- refresh();
- break;
- }
- current = index - 1;
- showlist(current);
- break;
-
- case '.': /* mark group -- used to move later */
- aptr = act[current];
- if (aptr->mark == 0)
- aptr->mark = 1;
- else
- aptr->mark = 0;
- goto scroll_down;
- break;
-
- case 'm': /* move marked groups */
- case 'M':
- i_active = 0;
- while (i_active < c_active) {
- if ((aptr = act[i_active]) == (struct actif *)NULL) {
- i_active++;
- continue;
- }
- if (aptr->mark == 0) {
- i_active++;
- continue;
- }
- aptr->index = current;
- aptr->mark = 0;
- i_active++;
- }
- qsort( act, (unsigned) c_active,
- (unsigned) sizeof(act[0]), icompare);
- alphabetized = FALSE;
-
- /* Renumber to match current order. */
- i_active = 0;
- while (i_active < c_active) {
- if ((aptr = act[i_active]) == (struct actif *)NULL) {
- i_active++;
- continue;
- }
- aptr->index = ++i_active;
- }
- showlist(current);
- break;
-
- case 'r': /* redraw */
- case 'R': /* redraw */
- case '\014': /* form feed ^L */
- touchwin(stdscr);
- clearok(stdscr,TRUE);
- refresh();
- break;
-
- case 'v': /* view newsgroup */
- case '=': /* view newsgroup */
- case '\r':
- case '\n': /* new line to select a group */
- if ((aptr = act[current]) == (struct actif *)NULL)
- break;
- eepview(aptr->name);
- showlist(current);
- break;
-
- case 'i':
- if ((aptr = act[current]) == (struct actif *)NULL)
- break;
- over = newwin(18,65,0,5);
- if (!eepoint) wstandout(over);
- box(over,'\0','\0');
- if (!eepoint) wstandend(over);
- wmove(over,2,5);
- wprintw(over,"Number: %d",current + 1);
- wmove(over,3,5);
- wprintw(over,"Name: %.50s",pad(aptr->name,50));
- wmove(over,4,5);
- wprintw(over,"Desc: %.50s",pad(aptr->desc,50));
- wmove(over,6,5);
- wprintw(over,"This news group is ");
- switch(aptr->flag) {
- case 'y':
- wprintw(over,"Active.");
- break;
- case 'n':
- wprintw(over,"Not Active.");
- break;
- case 'm':
- wprintw(over,"Moderated.");
- break;
- default:
- wprintw(over,"Invalid.");
- }
- wmove(over,7,5);
- wprintw(over,"Your .newsrc says this is ");
- switch(aptr->status) {
- case ':':
- wprintw(over,"Subscribed to.");
- break;
- case '!':
- wprintw(over,"Not Subscribed to.");
- break;
- default:
- wprintw(over,"Not valid.");
- break;
- }
- if (aptr->hi > 0) {
- wmove(over,9,5);
- wprintw(over,"Active high message is %ld",
- aptr->hi);
- wmove(over,11,5);
- wprintw(over,"Messages already read by you include:");
- wmove(over,12,5);
- wprintw(over,"%s",pad(aptr->hilo,50));
- }
- wmove(over,17,5);
- wstandout(over);
- waddstr(over," Press SPACE BAR to continue ");
- wstandend(over);
- wrefresh(over);
- ch = wgetch(over);
- delwin(over);
- touchwin(stdscr);
- refresh();
- break;
-
- case '/': /* search */
- move(eeplines - 1,0);
- deleteln();
- addch('/');
- refresh();
- getbuf(search);
- if (strlen(search) == 0) {
- move(eeplines - 1,0);
- deleteln();
- move(scrnpos,0);
- refresh();
- break;
- }
- found = FALSE;
- /* make it lower case for searching */
- strcpy(search,shift_lower(search));
- index = current + 1; /* track progress */
- if (index >= c_active) index = 0;
-
- while (index != current) {
- aptr = act[index];
- if (aptr != (struct actif *)NULL) {
- if (in_string(shift_lower(aptr->name),search) ||
- in_string(shift_lower(aptr->desc),search)) {
- /* found match */
- found = TRUE;
- current = index;
- showlist(current);
- break;
- }
- }
- index++;
- if (index >= c_active) index = 0;
- }
- if (!found) {
- beep();
- move(scrnpos,0);
- refresh();
- }
- break;
-
- case 't':
- case 'T':
- case '^': /* top of list */
- current = 0;
- scrnpos = 0;
- showlist(current);
- break;
-
- case 'b':
- case 'B':
- case '$': /* bottom of list */
- current = c_active - 1;
- scrnpos = eeplines - 2;
- showlist(current);
- break;
-
- case 'n': /* look for next occurence */
- case 'N':
- if (!found) {
- beep(); /* nothing to find */
- break;
- }
- index = current; /* track progress */
- while (++index != current) {
- if (index >= c_active) index = 0;
- aptr = act[index];
- if (in_string(shift_lower(aptr->name),search) ||
- in_string(shift_lower(aptr->desc),search)) {
- /* found match */
- found = TRUE;
- current = index;
- showlist(current);
- break;
- }
- }
- break;
-
- case 'a': /* change sorting order */
- case 'A':
- move(eeplines-1,0);
- deleteln();
- if (alphabetized) {
- addstr("Do you wish to sort in .newsrc order? [n]: ");
- refresh();
- if (tolower(getch()) != (int) 'y') {
- deleteln();
- move(scrnpos,0);
- refresh();
- break;
- }
- qsort( act, (unsigned) c_active,
- (unsigned) sizeof(act[0]), icompare);
- alphabetized = FALSE;
- } else {
- addstr("Do you wish to sort alphabetically? [n]: ");
- refresh();
- if (tolower(getch()) != (int) 'y') {
- deleteln();
- move(scrnpos,0);
- refresh();
- break;
- }
- qsort( act, (unsigned) c_active,
- (unsigned) sizeof(act[0]), qcompare);
- alphabetized = TRUE;
- }
- deleteln();
- move(scrnpos,0);
- showlist(current);
- break;
-
- case '+': /* subscribe to this newsgroup */
- case 's':
- case 'S':
- aptr = act[current];
- /* check if group is valid */
- if ((aptr->flag == 'y') ||
- (aptr->flag == 'm')) {
- aptr->status = ':';
- move(scrnpos,2);
- standout();
- addch('+');
- standend();
- move(scrnpos,0);
- } else {
- move(eeplines - 1,0);
- printw("Not a valid newsgroup -- cannot subscribe");
- refresh();
- sleep(2);
- deleteln();
- move(scrnpos,0);
- }
- refresh();
- goto scroll_down;
- break;
-
- case '-': /* unsubscribe to this newsgroup */
- case 'u': /* also means unjoin */
- case 'U':
- aptr = act[current];
- /* check if group is valid */
- aptr->status = '!';
- if ((aptr->flag == 'y') ||
- (aptr->flag == 'm')) {
- move(scrnpos,2);
- standout();
- addch(' ');
- standend();
- move(scrnpos,0);
- } else {
- move(eeplines - 1,0);
- printw("Not a valid newsgroup -- unsubscribing anyway");
- refresh();
- sleep(2);
- deleteln();
- move(scrnpos,0);
- }
- refresh();
- goto scroll_down;
- break;
-
- case ' ':
- case 'j':
- case 'J': /* join */
- case '\016': /* for emacs users */
- case KEY_DOWN:
- scroll_down:
- /* Don't move if we're at the end. */
- if (current == c_active - 1) {
- beep();
- break;
- }
- /* remove highlights by redrawing line */
- aptr = act[current];
- move(scrnpos,0);
- if (!eepoint) standend();
- if (aptr->mark == 0)
- printw(" ");
- else
- printw("* ");
- switch(aptr->status) {
- case ':': printw("+"); /* subscribed */
- break;
- case '!': printw(" "); /* unsubscribed */
- break;
- default: printw("?"); /* mystery! */
- }
- if (!eepoint) {
- printw("%.28s ", pad(aptr->name,28));
- printw("%.46s ", pad(aptr->desc,46));
- }
- refresh();
- current++;
- if (++scrnpos == eeplines - 1) { /* scroll up */
- move(0,0);
- deleteln();
- move(eeplines - 2,0);
- insertln();
- refresh();
- scrnpos = eeplines - 2;
- top++;
- };
- /* Now paint our new position */
- move(scrnpos,0);
- aptr = act[current];
- if (!eepoint) standout();
- if (aptr->mark == 0)
- printw("-");
- else
- printw("*");
- switch(aptr->status) {
- case ':': printw(">+"); /* subscribed */
- break;
- case '!': printw("> "); /* unsubscribed */
- break;
- default: printw(">?"); /* mystery! */
- }
- printw("%.28s ", pad(aptr->name,28));
- printw("%.46s ", pad(aptr->desc,46));
- if (!eepoint) standend();
- move(scrnpos,0);
- refresh();
- break;
-
- case 'k':
- case 'K':
- case '\010': /* backspace */
- case '\020': /* for emacs users */
- case KEY_UP:
- /* Don't move if we're at the top. */
- if (current == 0) {
- beep();
- break;
- }
- move(scrnpos,0);
- aptr = act[current];
- if (!eepoint) standend();
- if (aptr->mark == 0)
- printw(" ");
- else
- printw("* ");
- switch(aptr->status) {
- case ':': printw("+"); /* subscribed */
- break;
- case '!': printw(" "); /* unsubscribed */
- break;
- default: printw("?"); /* mystery! */
- }
- if (!eepoint) {
- printw("%.28s ", pad(aptr->name,28));
- printw("%.46s ", pad(aptr->desc,46));
- }
- move(scrnpos,0);
- refresh();
- current--;
- if (--scrnpos == -1) {
- move(eeplines - 2,0);
- deleteln();
- move(0,0);
- insertln();
- refresh();
- move(0,0);
- scrnpos = 0;
- if (top > 0) top--;
- }; /* cause scroll */
- move(scrnpos,0);
- aptr = act[current];
- if (!eepoint) standout();
- if (aptr->mark == 0)
- printw("-");
- else
- printw("*");
- switch(aptr->status) {
- case ':': printw(">+"); /* subscribed */
- break;
- case '!': printw("> "); /* unsubscribed */
- break;
- default: printw(">?"); /* mystery! */
- }
- printw("%.28s ", pad(aptr->name,28));
- printw("%.46s ", pad(aptr->desc,46));
- if (!eepoint) standend();
- move(scrnpos,0);
- refresh();
- break;
-
-
- case KEY_NPAGE: /* next page */
- case '\004': /* ^D */
- case '\006': /* ^F */
-
- /* If a pagedown will go past the end
- of the list, simply position at the end. */
-
- if (current == c_active - 1) {
- beep();
- break;
- }
- if ((current += EEPPAGE) >= c_active) {
- current = c_active - 1;
- if ((c_active - current) < (eeplines - 2))
- scrnpos = eeplines - 2;
- } else if (scrnpos + EEPPAGE < eeplines - 2)
- scrnpos += EEPPAGE;
- showlist(current);
- break;
-
- case KEY_PPAGE: /* previous page */
- case '\025': /* ^U */
- case '\002': /* ^B */
- if (current == 0) {
- beep();
- break;
- }
- if ((current -= EEPPAGE) < 0) {
- current = 0;
- scrnpos = 0;
- } else if ((scrnpos - EEPPAGE) >= 0)
- scrnpos -= EEPPAGE;
- showlist(current);
- break;
-
- case 'p': /* change type of pointer */
- case 'P':
- if (eepoint) eepoint = FALSE;
- else eepoint = TRUE;
- showlist(current);
- break;
-
- case 'c': /* catch up */
- case 'C':
- aptr = act[current];
- /* only if it's a real news group */
- if (aptr->hi <= 0) goto scroll_down;
- if ((aptr->flag == 'y') ||
- (aptr->flag == 'm') ||
- (aptr->flag == 'n')) {
- move(eeplines-1,0);
- deleteln();
- addstr("Catch up this news group? [n]: ");
- refresh();
- if (tolower(getch()) == 'y') {
- sprintf(buffer,"1-%ld", aptr->hi);
- if (aptr->hilo != (char *)NULL) {
- if (aptr->hilo[0] == '0')
- sprintf(buffer,"0-%ld", aptr->hi);
- }
- aptr->hilo = (char *)malloc(strlen(buffer)+1);
- if (aptr->hilo == (char *)NULL) {
- fprintf(stderr, "Fatal memory allocation error.\n");
- exit(2);
- }
- strcpy(aptr->hilo,buffer);
- deleteln();
- move(eeplines-1,0);
- printw("High message now %ld", aptr->hi);
- } else deleteln();
- move(scrnpos,0);
- refresh();
- }
- goto scroll_down;
- break;
-
- case 'd': /* delete from .newsrc */
- case 'D':
- move(eeplines-1,0);
- deleteln();
- aptr = act[current];
- if (aptr->status == 0) {
- printw("Group %s already marked for deletion. Undelete? ",
- aptr->name);
- refresh();
- if (tolower(getch()) == (int) 'y') {
- move(eeplines-1,0);
- deleteln();
- aptr->status = '!';
- printw("Group %s undeleted.",
- aptr->name);
- } else {
- move(eeplines-1,0);
- deleteln();
- printw("Group %s marked for deletion.",
- aptr->name);
- }
- move(scrnpos,0);
- refresh();
- goto scroll_down;
- break;
- }
- printw("Delete newsgroup %s? ",aptr->name);
- refresh();
- if (tolower(getch()) == (int) 'y') {
- aptr = act[current];
- aptr->status = 0;
- deleteln();
- move(eeplines-1,0);
- printw("Group %s marked for deletion.",
- aptr->name);
- } else {
- deleteln();
- move(eeplines-1,0);
- printw("Group %s NOT marked for deletion.",
- aptr->name);
- }
- move(scrnpos,0);
- refresh();
- goto scroll_down;
- break;
-
- case 'x': /* write the local .newsrc and exit */
- case 'X':
- move(eeplines-1,0);
- deleteln();
- if (fnewsrc == (FILE *) NULL) {
- addstr("Couldn't open .newsrc.eep -- write failed.");
- refresh();
- break;
- }
- addstr("Do you want to save and exit? [n]: ");
- refresh();
- if (tolower(getch()) != (int) 'y') {
- deleteln();
- move(scrnpos,0);
- refresh();
- break;
- }
- if (bog_count > 0) {
- move(eeplines-1,0);
- deleteln();
- addstr("Delete bogus groups from your .newsrc? [n]: ");
- refresh();
- if (tolower(getch()) != (int) 'y') bog_count = 0;
- }
- deleteln();
- index = 0;
- counter = 0;
- while (index < c_active) {
- aptr = act[index];
- if ((aptr->flag == '\0') ||
- (aptr->status == '\0') ||
- (aptr->name == (char *)NULL)) {
- /* must be bogus -- shall we forget it? */
- if (bog_count != 0) {
- index++;
- continue;
- }
- }
-
- fprintf(fnewsrc,"%s",
- aptr->name);
- if (aptr->status == ':') {
- fprintf(fnewsrc,": ");
- } else {
- fprintf(fnewsrc,"! ");
- }
- if (aptr->hilo != (char *)NULL) {
- fprintf(fnewsrc,"%s", aptr->hilo);
- }
- fprintf(fnewsrc,"\n");
- counter++;
- index++;
- if (counter % 100 == 0) {
- move(eeplines-1,0);
- printw("%d",counter);
- refresh();
- }
- }
- fclose(fnewsrc);
-
- printf("\rTotal of %d lines written.\r\n",counter);
- if (bog_count > 0) {
- if (bog_count == 1)
- printf("There was 1 bogus newsgroup deleted.\r\n");
- else
- printf("There were %d bogus newsgroups deleted.\r\n",
- bog_count);
- }
-
- fnewsrc = (FILE *) NULL;
- if ((ptr = getenv("HOME")) != (char *)NULL) {
- sprintf(tmp, "%s/%s", ptr, NEWSRC);
- sprintf(buffer, "%s/%s.old", ptr, NEWSRC);
- } else {
- sprintf(tmp, NEWSRC);
- sprintf(buffer, "%s.old", NEWSRC);
- }
- #ifdef UNIX
-
- /* Narrative: we rename the current .newsrc to .newsrc.old -- but
- * first we unlink any existing .newsrc.old. We have just written
- * the modified .newsrc to .newsrc.new, and now we rename it to
- * replace the .newsrc -- which should be safely backed-up.
- */
-
- unlink(buffer); /* don't care about errors */
-
- if (link(tmp,buffer) < 0) {
- fprintf(stderr,"[1] .newsrc not replaced.");
- break;
- }
- if (unlink(tmp) < 0) {
- fprintf(stderr,"[2] .newsrc not replaced.");
- break;
- }
- if ((ptr = getenv("HOME")) != (char *)NULL)
- sprintf(buffer, "%s/.newsrc.eep", ptr);
- else
- sprintf(buffer, ".newsrc.eep");
-
- if (link(buffer,tmp) < 0) {
- fprintf(stderr,"[3] .newsrc not replaced.");
- break;
- }
- if (unlink(buffer) < 0) {
- fprintf(stderr,"[4] .newsrc not replaced.");
- break;
- }
- #endif /* UNIX */
- noraw();
- endwin(); /* terminate */
- return;
- break;
- }
- }
- move(eeplines - 1,0);
- clrtoeol();
- refresh();
- noraw();
- endwin(); /* terminate */
- }
-
-
- /* This routine will show the window that opens into the current list
- of newsgroup lines. Current is the one that will be highlighted.
- The global variable scrnpos is used to indicate where this line
- is on the screen, with 0 being at the top line.
-
- The intention of this routine is that it should be used whenever
- there is a major change to the cursor position within the list. This
- may be the result of a search, or jumping to the top or bottom of
- the file, or using page up or page down keys. The desired behaviour
- is that the highlighted line should stay roughly in the same position
- on the screen when this move occurs. We can calculate the relative
- position of the current line by subtracting the scrnpos from current
- to begin the index. */
-
- void showlist(current)
- int current;
- {
- int index, counter;
-
- counter = 0;
- index = current - scrnpos;
- while (counter < (eeplines - 1)) {
- move(counter,0);
- if ((index >= 0) && (index < c_active)) {
- if (counter == scrnpos) {
- if (!eepoint) standout();
- if (aptr->mark == 0)
- printw("->");
- else
- printw("*>");
- } else if (aptr->mark == 0)
- printw(" ");
- else
- printw("* ");
- aptr = act[index];
- /* Show whether subscribed or not */
- switch(aptr->status) {
- case ':': printw("+"); /* subscribed */
- break;
- case '!': printw(" "); /* unsubscribed */
- break;
- default: printw("?"); /* mystery! */
- }
-
- printw("%.28s ", pad(aptr->name,28));
- printw("%.46s ", pad(aptr->desc,46));
- move(counter,0);
- if ((counter == scrnpos) && !eepoint)
- standend();
- } else printw("%.79s", pad((char *)NULL,79));
- index++;
- counter++;
- }
- move(eeplines - 1,0);
- deleteln();
- printw("There are %d available newsgroups",c_active);
- move(eeplines - 1,60);
- printw("Press ? for Help");
- move(scrnpos,0);
- refresh();
- }
- @EOF
-
- chmod 600 eepmenu.c
-
- echo x - eepmisc.c
- cat >eepmisc.c <<'@EOF'
- /*
- eepmisc.c -- Miscellaneous functions
- */
-
- #ifdef DOS
- #include <dos.h>
- #endif /* DOS */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <curses.h>
-
- #ifdef ANSI
- #include <stdlib.h>
- #else
- #define void int
- extern char *malloc();
- #endif /* ANSI */
-
- #include "eep.h"
-
-
- extern int qcompare(); /* sort alphabetically */
- extern char *shift_lower(); /* see eepmisc.c */
- extern char buffer[], /* general purpose line buffer */
- tmp[];
-
- extern struct actif *act[]; /* main data structure */
- extern struct actif *topact[]; /* top level names only */
-
- extern int i_active, /* index into arrays */
- c_active, /* number of lines in act array */
- t_active, /* number of lines in act array */
- eepoint, /* pointer switch */
- noshell; /* noshell switch */
-
- /* The levels array contains the Head pointers which control the
- linked lists of newsgroups grouped by their "depth" in the
- hierarchy, and sorted alphabetically. E.g. alt, sci, soc are
- level 0, alt.pagan, sci.physics are level 1 and so on. */
-
- extern struct actif *levels[]; /* keep track of levels with this array */
- extern struct actif *aptr; /* temporary pointer */
- extern int i_levels; /* index into array */
-
-
- WINDOW *over; /* used for on-screen help window etc. */
-
- #ifdef UNIX
- int time_out = TIMEOUT; /* keyboard inactivity timer */
-
- /* Process the alarm signal here. This will cause a keyboard timeout
- to occur, and exit from the system. */
-
- int catchalarm(signo)
- int signo;
- {
- printf("Keyboard inactivity timer caused exit.\r\n");
- fflush(stdout);
- exit(0);
- }
- #endif /* UNIX */
-
- /* getbuf() -- read input into the buffer */
-
- void getbuf(buf)
- char *buf;
- {
- int count = 0,
- c; /* character */
-
- while (count < BUFSIZE - 1) { /* -1 to allow for nul */
- c = getch();
- switch(c) {
- case KEY_BREAK:
- case '\033':
- case '\003':
- #ifdef DOS
- case KEY_EXIT:
- #endif /* DOS */
- deleteln();
- refresh();
- buf[0] = '\0';
- return;
- break; /* just in case */
- case KEY_BACKSPACE:
- case '\010':
- case '\177':
- case KEY_LEFT:
- if (count == 0) continue;
- addstr("\010 \010");
- refresh();
- count--;
- continue;
- case KEY_ENTER:
- case '\n':
- case '\r':
- buf[count] = '\0';
- return;
- break;
- }
- /* yes, this is very ASCII and doesn't take into
- account non-English alphabets. This is because
- I'm not planning to fix curses in free software. */
- if ((c < '\020') || /* some other control code */
- (c > '\177'))
- continue; /* ignore it */
- buf[count] = c;
- addch(buf[count]);
- refresh();
- count++;
- }
- buf[count] = '\0'; /* nul terminate the string */
- }
-
- /* wrap -- this function will take a string, and word wrap it to
- within the defined width by inserting CRLF at appropriate places.
- The result will be output directly. An offset may be defined,
- which will not be used on the first line only. */
-
- void wrap(string,width,offset)
- char *string;
- int width,
- offset;
- {
- char temp[80]; /* temporary buffer */
- char *p,*q; /* traverse the string with this */
- int count; /* keep track of characters */
- int offcount;
- int first_line;
-
- if (width == 0) {
- printf("Can't wrap to zero width, sorry!");
- printf(CRLF);
- return;
- }
- if (strlen(string) == 0) return;
- p = string;
- q = temp;
- count = 0;
- first_line = 0; /* no offset for first line */
- while (*p != '\000') {
- *q = *p;
- if (count == width) { /* check for wrapping */
- while (*p != ' ') {
- q--;
- p--;
- if (--count == 0) { /* can't wrap! */
- /* so we truncate */
- q = temp + width;
- p = p + width; /* carry on... */
- break;
- }
- }
- *q = '\0'; /* terminate output here */
- if (first_line != 0) {
- offcount = offset;
- while (offcount-- > 0) printf(" ");
- }
- first_line = 1;
- printf(temp);
- printf(CRLF);
- count = -1; /* new line */
- q = temp - 1;
- }
- count++;
- p++;
- q++;
- }
- *q = '\0';
- if (first_line != 0) {
- offcount = offset;
- while (offcount-- > 0) printf(" ");
- }
- printf(temp);
- printf(CRLF);
- }
-
-
- /* These next two routines simply lifted from the Elm mail package,
- by Dave Taylor. If you need a nice mail system, you won't have to
- look much further than Elm! -- P.G. */
-
- char *shift_lower(string)
- char *string;
- {
- /** return 'string' shifted to lower case. Do NOT touch the
- actual string handed to us! **/
-
- static char buf[BUFSIZE];
- register char *bufptr = buf;
-
- if (string == (char *)NULL) {
- *bufptr = '\0';
- return((char *)buf);
- }
-
- for (; *string; string++, bufptr++)
- if (isupper(*string))
- *bufptr = tolower(*string);
- else
- *bufptr = *string;
-
- *bufptr = 0;
-
- return( (char *) buf);
- }
-
-
- int in_string(buf, pat)
- char *buf, *pat;
- {
- /** Returns TRUE iff pat occurs IN ITS ENTIRETY in buf. **/
-
- register int i = 0, j = 0;
-
- while (buf[i] != '\0') {
- while (buf[i++] == pat[j++])
- if (pat[j] == '\0')
- return(TRUE);
- i = i - j + 1;
- j = 0;
- }
- return(FALSE);
- }
-
- #ifdef DOS
- /*
- * Here are some timing routines. Call msleep() with parameter
- * of 0L to establish precision the first time.
- */
-
-
- typedef struct
- { /* time holder */
- int hour;
- int minute;
- int sec;
- int hsec;
- } TIME, *TIME_PTR;
-
- #define GET_TIME 0x2c /* time request */
- #define DOS_INT 0x21 /* int to call DOS */
- #define INIT 60 /* initial clock set */
-
- /*
- * get_time(n)
- * TIME_PTR n;
- *
- * fills timetype structure n with current time using DOS interrupt 21
- *
- */
-
- get_time(n)
- TIME_PTR n;
- {
- union REGS inregs;
- union REGS outregs;
-
- inregs.h.ah = GET_TIME;
-
- int86(DOS_INT, &inregs, &outregs);
-
- n->hour = outregs.h.ch;
- n->minute = outregs.h.cl;
- n->sec = outregs.h.dh;
- n->hsec = outregs.h.dl;
-
- return(0);
- }
-
- /* This will sleep for x seconds. */
-
- void sleep(x)
- int x;
- {
- int i;
- unsigned s;
- TIME n; /* current time record */
-
- i = 0;
- get_time(&n);
- s = n.sec;
-
- while (i < x){
- while (s == n.sec)
- get_time(&n);
- s = n.sec;
- ++i;
- }
- }
-
- void msleep(ms)
- long ms;
- { /* sleep for ms miliseconds */
- static long estimate = 2000L; /* loops per milisecond */
- #define OFFSET 2000L
- long loops;
- TIME n1, n2;
- unsigned int mydelay;
-
- /* If the value is 0, then we try to calculate the number of miliseconds
- * that make up a clock tick, then estimate a timing loop that will
- * delay for 1 milisecond. */
-
- if (ms == 0L) {
-
- /* Loop until we see a change in time. */
-
- try_again:
- get_time(&n1);
- for (loops = estimate*10; loops == 0; loops--)
- loops = (loops << 1) / 2;
- get_time(&n2);
- printf("Estimating... %ld\n", estimate);
-
- if ((n1.hsec == n2.hsec) && (n1.sec == n2.sec)) {
- estimate += OFFSET;
- goto try_again;
- }
-
- /* Calculate the difference in hundredths of seconds. Note
- * that is is possible that n2.sec is less than n1.sec if
- * the minute has just changed, in which case we cheat.
- */
- if (n2.minute != n1.minute) n2.sec = n1.sec + 1;
- mydelay = (100*n2.sec + n2.hsec) - (100*n1.sec + n1.hsec);
-
- /* this is the first guess */
- estimate = estimate / ((long)mydelay * 10);
-
- get_time(&n1);
- for (loops = INIT*estimate*10; loops > 0; loops--)
- loops = (loops << 1) / 2;
- get_time(&n2);
- if (n2.minute != n1.minute) n2.sec = n1.sec + 1;
- mydelay = (100*n2.sec + n2.hsec) - (100*n1.sec + n1.hsec);
- if (mydelay == 0) mydelay = INIT;
- estimate = (INIT*estimate) / ((long)mydelay);
- printf("Estimate %ld loops per millisecond\n",estimate);
- for (loops = 10; loops > 0; loops--) {
- printf("Tick... ");
- msleep(1000L);
- }
- printf(" BOOM!\n");
- }
- for (loops = (long)ms*estimate; loops > 0; loops--)
- loops = (loops << 1) / 2; /* do nothing really */
- }
- #endif /* DOS */
- @EOF
-
- chmod 600 eepmisc.c
-
- echo x - eepview.c
- cat >eepview.c <<'@EOF'
- /*------------------------------------------------------------------------
- Name: eepview.c
-
- This module provides code to open a newsgroup directory, construct a
- list of all the messages, and display the list, along with subjects
- and names of the posters, plus size of messages. This will replace the
- full screen, and allow scrolling down with a pointer in a similar way
- to the main screen.
-
- ------------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <string.h>
- #include <curses.h>
-
- #ifdef UNIX
- #include <ctype.h>
- #include <errno.h>
- #include <signal.h>
- #endif /* UNIX */
-
- #ifdef ANSI
- #include <stdlib.h>
- #else
- #define void int
- extern char *malloc();
- #endif /* ANSI */
-
- #ifdef DIRENT /* defined in makefile */
- #include <dirent.h> /* or <sys/dirent.h> */
- #define direct dirent
- #else
- #include "ndir.h"
- #endif /* DIRENT */
-
- #ifdef DOS
- #include <dos.h>
- #endif /* DOS */
-
- #include "eep.h"
-
- /* function definitions */
- void showarts();
-
- FILE *farticle;
-
- struct newsview {
-
- long artnum; /* article number */
- long size; /* size in bytes */
- char *from; /* poster */
- char *date; /* date */
- char *msgid; /* Msg-id: */
- char *subject; /* Subject: */
- char *keywords; /* Keywords: */
- char *references; /* References: */
- };
-
- int news_index; /* index into newsview */
- int art_count; /* count of articles */
- int art_current; /* current article index */
- long artnum_tmp; /* temporary article number */
- char *dir; /* pointer to directory name */
- int viewpos = 0; /* view position */
-
- char nirvana[] = "(null)";
-
- extern int eeplines;
- extern int eepoint;
- extern int current;
- extern WINDOW *over;
- extern char buffer[];
- extern char *shift_lower();
-
- struct newsview *art_ptr; /* pointer to news structure */
-
- struct newsview *article[MAXARTS]; /* array of pointers to articles struct */
-
- int artnum_compare(item1,item2) /* sort by article number */
- struct newsview **item1, **item2;
- {
- struct newsview *ptr1, *ptr2;
- long int diff;
-
- ptr1 = *item1;
- ptr2 = *item2;
- diff = ptr1->artnum - ptr2->artnum;
- if (diff == 0L) return(0);
- if (diff > 0L) return(1);
- if (diff < 0L) return(-1);
- }
-
- #ifdef DOS
-
- static void free_dircontents (struct _dircontents *);
-
- #define ATTRIBUTES (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_SUBDIR)
-
- DIR *
- opendir (char *name)
- {
- struct find_t find_buf;
- DIR *dirp;
- struct _dircontents *dp;
- char name_buf[_MAX_PATH + 1];
- char *slash = "";
-
- if (!name)
- name = "";
- else if (*name)
- {
- char *s;
- int l = strlen (name);
-
- s = name + l - 1;
- if ( !(l == 2 && *s == ':') && *s != '\\' && *s != '/')
- slash = "/"; /* save to insert slash between path and "*.*" */
- }
-
- strcat (strcat (strcpy (name_buf, name), slash), "*.*");
-
- dirp = (DIR *) malloc (sizeof (DIR));
- if (dirp == (DIR *)0)
- return (DIR *)0;
-
- dirp->dd_loc = 0;
- dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) 0;
-
- if (_dos_findfirst (name_buf, ATTRIBUTES, &find_buf))
- {
- free (dirp);
- return (DIR *)0;
- }
-
- do
- {
- dp = (struct _dircontents *) malloc (sizeof (struct _dircontents));
- if (dp == (struct _dircontents *)0)
- {
- free_dircontents (dirp->dd_contents);
- return (DIR *)0;
- }
-
- dp->_d_entry = (char *)malloc (strlen (find_buf.name) + 1);
- if (dp->_d_entry == (char *)0)
- {
- /* free(dp); */
- free_dircontents (dirp->dd_contents);
- return (DIR *)0;
- }
-
- if (dirp->dd_contents)
- dirp->dd_cp = dirp->dd_cp->_d_next = dp;
- else
- dirp->dd_contents = dirp->dd_cp = dp;
-
- strcpy (dp->_d_entry, find_buf.name);
-
- dp->_d_next = (struct _dircontents *)0;
-
- } while (! _dos_findnext (&find_buf));
-
- dirp->dd_cp = dirp->dd_contents;
-
- return dirp;
- }
-
-
- void
- closedir (DIR *dirp)
- {
- free_dircontents (dirp->dd_contents);
- free (dirp);
- }
-
-
- struct direct *
- readdir (DIR *dirp)
- {
- static struct direct dp;
-
- if (dirp->dd_cp == (struct _dircontents *)0)
- return (struct direct *)0;
- dp.d_namlen = dp.d_reclen =
- strlen ((char *)strcpy (dp.d_name, dirp->dd_cp->_d_entry));
- strlwr (dp.d_name); /* JF */
- dp.d_ino = 0;
- dirp->dd_cp = dirp->dd_cp->_d_next;
- dirp->dd_loc++;
-
- return &dp;
- }
-
-
- void
- seekdir (DIR *dirp, long off)
- {
- long i = off;
- struct _dircontents *dp;
-
- if (off < 0)
- return;
- for (dp = dirp->dd_contents; --i >= 0 && dp; dp = dp->_d_next)
- ;
- dirp->dd_loc = off - (i + 1);
- dirp->dd_cp = dp;
- }
-
-
- long
- telldir (DIR *dirp)
- {
- return dirp->dd_loc;
- }
-
-
- /* Garbage collection */
-
- static void
- free_dircontents (struct _dircontents *dp)
- {
- struct _dircontents *odp;
-
- while (dp)
- {
- if (dp->_d_entry)
- free ((struct _dirdesc *)dp->_d_entry);
- dp = (odp = dp)->_d_next;
- free ((struct _dirdesc *)odp);
- }
- }
- #endif /* DOS */
-
- /* Main EEP routines start here */
-
-
- void eepview(groupname)
- char *groupname; /* place to find articles */
- {
- static DIR *directory;
- struct direct *entry = (struct direct *)0;
- char *name = "";
-
- char *ptr; /* general pointer */
- char search[BUFSIZE]; /* search string buffer */
- int found = FALSE, /* flag to say we've found something */
- quit = FALSE, /* flag used when ready to quit */
- index, /* used when searching */
- top,
- counter, /* used when counting */
- ch; /* input character */
-
-
- DIR *dirp;
- struct direct *direntp;
-
- if (strlen(groupname) == 0) return;
- /* Allow two extra bytes, one for terminating null and
- * the other for the separating '/' if needed.
- */
- dir = (char *)malloc(strlen(NEWSBASE)+strlen(groupname)+2);
- strcpy(dir,NEWSBASE);
- if (dir[strlen(dir)-1] != '/') strcat(dir,"/");
- strcat(dir,groupname);
- /* convert newsgroup name to directory name */
- while ((ptr = strchr(dir,'.')) != (char *) NULL)
- *ptr = '/';
- if ((dirp = opendir(dir)) == NULL)
- {
- move(eeplines - 1,0);
- deleteln();
- printw("Cannot open %s",dir);
- move(current,0);
- refresh();
- sleep(2);
- return;
- }
- move(eeplines - 1,0);
- deleteln();
- printw("Opening %s",dir);
- refresh();
- news_index = 0;
- errno = 0;
- while ((direntp = readdir(dirp)) != NULL) {
- artnum_tmp = atol(direntp->d_name);
- if (artnum_tmp <= 0) continue;
-
- /* atol() will be fooled by filenames that start with
- * digits, so let's confirm that it has only digits. */
-
- ptr = direntp->d_name;
- while (isdigit((int)(*ptr))) ptr++;
- if (*ptr != '\0') break; /* should point to terminating null */
-
- if ((art_ptr = (struct newsview *)malloc(sizeof(struct newsview))) ==
- (struct newsview *) NULL) {
- fprintf(stderr,"Memory allocation error!\n");
- exit(1);
- }
- article[news_index] = art_ptr;
- art_ptr->artnum = artnum_tmp;
- art_ptr->size = 0L;
- art_ptr->from = nirvana;
- art_ptr->date = nirvana;
- art_ptr->msgid = nirvana;
- art_ptr->subject = nirvana;
- art_ptr->keywords = nirvana;
- art_ptr->references = nirvana;
- news_index++;
- }
- closedir(dirp);
- if (errno != 0)
- fprintf(stderr,"Error reading directory %s\n",dir);
-
- art_count = news_index;
- if (art_count == 0) {
- move(eeplines - 1,0);
- deleteln();
- printw("No articles found in %s",dir);
- refresh();
- sleep(2);
- return;
- }
-
- /* We have now read in the directory, keeping only those file names
- * which are numeric. (We're ignoring aberrant files with leading
- * zeros -- this assumes standard news files.)
- * Now we shall sort this into numerical order. */
-
- qsort( article, (unsigned) art_count,
- (int) sizeof(article[0]), artnum_compare);
-
- /* Now let's read each file to get some basic info on it. */
-
- news_index = 0;
- while (news_index < art_count) {
- /* Start by initializing the data element */
- art_ptr = article[news_index];
- if (art_ptr == (struct newsview *)NULL) {
- news_index++;
- continue;
- }
- sprintf(buffer, "%s/%ld", dir, art_ptr->artnum);
- if ((farticle = fopen(buffer,"r")) == (FILE *)NULL) {
- news_index++;
- continue;
- }
- while (fgets(buffer,BUFSIZE,farticle) != (char *)NULL) {
-
- /* Since we're reading headers, break at the first
- * line that isn't part of a header, especially
- * the blank line that separates the header from
- * the body of the message
- */
- if ((buffer[0] == '#') ||
- (buffer[0] == '\n') ||
- (buffer[0] == '\r') ||
- (buffer[0] == '\0'))
- break;
-
- /* Now allocate memory for article headers */
-
- ptr = shift_lower(strtok(buffer," \t\r\n"));
-
- if (strcmp(ptr,"from:") == 0) {
- ptr = strtok((char *)NULL,"\r\n");
- if ((art_ptr->from = (char *) malloc(strlen(ptr)+1))
- == (char *)NULL) {
- printf("Error while allocating memory!\n");
- sleep(2);
- return;
- }
- strcpy(art_ptr->from,ptr);
- continue;
- }
-
- if (strcmp(ptr,"date:") == 0) {
- ptr = strtok((char *)NULL,"\r\n");
- if ((art_ptr->date = (char *) malloc(strlen(ptr)+1))
- == (char *)NULL) {
- printf("Error while allocating memory!\n");
- sleep(2);
- return;
- }
- strcpy(art_ptr->date,ptr);
- continue;
- }
-
- if (strcmp(ptr,"message-id:") == 0) {
- ptr = strtok((char *)NULL,"\r\n");
- if ((art_ptr->msgid = (char *) malloc(strlen(ptr)+1))
- == (char *)NULL) {
- printf("Error while allocating memory!\n");
- sleep(2);
- return;
- }
- strcpy(art_ptr->msgid,ptr);
- continue;
- }
-
- if (strcmp(ptr,"subject:") == 0) {
- ptr = strtok((char *)NULL,"\r\n");
- if ((art_ptr->subject = (char *) malloc(strlen(ptr)+1))
- == (char *)NULL) {
- printf("Error while allocating memory!\n");
- sleep(2);
- return;
- }
- strcpy(art_ptr->subject,ptr);
- continue;
- }
-
- if (strcmp(ptr,"references:") == 0) {
- ptr = strtok((char *)NULL,"\r\n");
- if ((art_ptr->references = (char *) malloc(strlen(ptr)+1))
- == (char *)NULL) {
- printf("Error while allocating memory!\n");
- sleep(2);
- return;
- }
- strcpy(art_ptr->references,ptr);
- continue;
- }
-
- if (strcmp(ptr,"keywords:") == 0) {
- ptr = strtok((char *)NULL,"\r\n");
- if ((art_ptr->keywords = (char *) malloc(strlen(ptr)+1))
- == (char *)NULL) {
- printf("Error while allocating memory!\n");
- sleep(2);
- return;
- }
- strcpy(art_ptr->keywords,ptr);
- continue;
- }
- }
- fclose(farticle);
- news_index++;
- }
-
-
- #ifdef UNIX
- idlok(stdscr,TRUE);
- #endif /* UNIX */
-
- showarts(0);
- art_current = 0;
-
- while (quit == FALSE) {
- ch = getch();
- switch(ch) {
- case 'q': /* quit */
- case 'Q':
- case '\033': /* ESCAPE by itself */
- case '\003': /* for those who like ^C */
- case '\177': /* for those who like INTR */
- quit = TRUE;
- break;
-
- case '?': /* on-line help */
- case 'h':
- case 'H':
- case KEY_F(1):
- over = newwin(18,60,0,5);
- if (!eepoint) wstandout(over);
- box(over,'\0','\0');
- if (!eepoint) wstandend(over);
- wmove(over,2,5);
- wstandout(over);
- waddstr(over," eep v1.6: .newsrc & JOIN file editor ");
- wstandend(over);
- wmove(over,3,5);
- waddstr(over," Newsgroup browser submenu");
- wmove(over,5,5);
- waddstr(over,"t Top of file b Bottom of file");
- wmove(over,6,5);
- waddstr(over,"i Show info j Next line");
- wmove(over,7,5);
- waddstr(over,"k Previous line p Pointer change");
- wmove(over,8,5);
- waddstr(over,"q Quit to main r Redraw screen");
- wmove(over,9,5);
- waddstr(over,"^D Page down ^U Page up");
- wmove(over,10,5);
- waddstr(over,"? This help");
- wmove(over,17,5);
- wstandout(over);
- waddstr(over," Press SPACE BAR to exit from help ");
- wstandend(over);
- wrefresh(over);
- ch = wgetch(over);
- delwin(over);
- touchwin(stdscr);
- refresh();
- break;
-
- case 'r': /* redraw */
- case 'R': /* redraw */
- case '\014': /* form feed ^L */
- touchwin(stdscr);
- clearok(stdscr,TRUE);
- refresh();
- break;
-
- case 'i':
- if ((art_ptr = article[art_current]) == (struct newsview *)NULL)
- break;
- over = newwin(18,67,0,2);
- if (!eepoint) wstandout(over);
- box(over,'\0','\0');
- if (!eepoint) wstandend(over);
- wmove(over,2,2);
- wprintw(over,"No. : %ld",art_ptr->artnum);
- wmove(over,3,2);
- wprintw(over,"From: %.57s",art_ptr->from);
- wmove(over,4,2);
- wprintw(over,"Subj: %.57s",art_ptr->subject);
- wmove(over,5,2);
- wprintw(over,"MsID: %.57s",art_ptr->msgid);
- wmove(over,6,2);
- wprintw(over,"Refs: %.57s",art_ptr->references);
- wmove(over,7,2);
- wprintw(over,"Date: %.57s",art_ptr->date);
- wmove(over,8,2);
- wprintw(over,"Keys: %.57s",art_ptr->keywords);
- wmove(over,17,9);
- wstandout(over);
- waddstr(over," Press SPACE BAR to continue ");
- wstandend(over);
- wrefresh(over);
- ch = wgetch(over);
- delwin(over);
- touchwin(stdscr);
- refresh();
- break;
-
-
- case 't':
- case 'T':
- case '^': /* top of list */
- art_current = 0;
- viewpos = 0;
- showarts(art_current);
- break;
-
- case 'b':
- case 'B':
- case '$': /* bottom of list */
- art_current = art_count - 1;
- if (art_current < eeplines - 1)
- viewpos = art_current;
- else
- viewpos = eeplines - 2;
- showarts(art_current);
- break;
-
-
- case ' ':
- case 'j':
- case 'J': /* join */
- case '\016': /* for emacs users */
- case KEY_DOWN:
- scroll_down:
- /* Don't move if we're at the end. */
- if (art_current == art_count - 1) {
- beep();
- break;
- }
- /* remove highlights by redrawing line */
- art_ptr = article[art_current];
- move(viewpos,0);
- clrtoeol();
- if (!eepoint) standend();
- if ((art_current >= 0) && (art_current < art_count)) {
- printw(" ");
- art_ptr = article[art_current];
- printw("%8ld", art_ptr->artnum);
- move(viewpos,11);
- printw("%.38s", art_ptr->subject);
- move(viewpos,50);
- printw("%.28s", art_ptr->from);
- move(viewpos,0);
- } else clrtoeol();
- art_current++;
- if (++viewpos == eeplines - 1) { /* scroll up */
- move(0,0);
- deleteln();
- move(eeplines - 2,0);
- insertln();
- viewpos = eeplines - 2;
- top++;
- };
- /* Now paint our new position */
- move(viewpos,0);
- clrtoeol();
- art_ptr = article[art_current];
- if (!eepoint) standout();
- if ((art_current >= 0) && (art_current < art_count)) {
- printw("->");
- art_ptr = article[art_current];
- printw("%8ld", art_ptr->artnum);
- move(viewpos,11);
- printw("%.38s", art_ptr->subject);
- move(viewpos,50);
- printw("%.28s", art_ptr->from);
- move(viewpos,0);
- } else clrtoeol();
- if (!eepoint) standend();
- move(viewpos,0);
- refresh();
- break;
-
- case 'k':
- case 'K':
- case '\010': /* backspace */
- case '\020': /* for emacs users */
- case KEY_UP:
- /* Don't move if we're at the top. */
- if (art_current == 0) {
- beep();
- break;
- }
- move(viewpos,0);
- clrtoeol();
- if (!eepoint) standend();
- if ((art_current >= 0) && (art_current < art_count)) {
- printw(" ");
- art_ptr = article[art_current];
- printw("%8ld", art_ptr->artnum);
- move(viewpos,11);
- printw("%.38s", art_ptr->subject);
- move(viewpos,50);
- printw("%.28s", art_ptr->from);
- move(viewpos,0);
- } else clrtoeol();
- refresh();
- art_current--;
- if (--viewpos == -1) {
- move(eeplines - 2,0);
- deleteln();
- move(0,0);
- insertln();
- refresh();
- move(0,0);
- viewpos = 0;
- if (top > 0) top--;
- }; /* cause scroll */
- move(viewpos,0);
- clrtoeol();
- art_ptr = article[art_current];
- if (!eepoint) standout();
- if ((art_current >= 0) && (art_current < art_count)) {
- printw("->");
- art_ptr = article[art_current];
- printw("%8ld", art_ptr->artnum);
- move(viewpos,11);
- printw("%.38s", art_ptr->subject);
- move(viewpos,50);
- printw("%.28s", art_ptr->from);
- move(viewpos,0);
- } else clrtoeol();
- if (!eepoint) standend();
- move(viewpos,0);
- refresh();
- break;
-
-
- case KEY_NPAGE: /* next page */
- case '\004': /* ^D */
- case '\006': /* ^F */
-
- /* If a pagedown will go past the end
- of the list, simply position at the end. */
-
- if (art_current == art_count - 1) {
- beep();
- break;
- }
- if ((art_current += EEPPAGE) >= art_count) {
- art_current = art_count - 1;
- if ((art_count - art_current) < (eeplines - 2))
- viewpos = eeplines - 2;
- } else if (viewpos + EEPPAGE < eeplines - 2)
- viewpos += EEPPAGE;
- showarts(art_current);
- break;
-
- case KEY_PPAGE: /* previous page */
- case '\025': /* ^U */
- case '\002': /* ^B */
- if (art_current == 0) {
- beep();
- break;
- }
- if ((art_current -= EEPPAGE) < 0) {
- art_current = 0;
- viewpos = 0;
- } else if ((viewpos - EEPPAGE) >= 0)
- viewpos -= EEPPAGE;
- showarts(art_current);
- break;
-
- case 'p': /* change type of pointer */
- case 'P':
- if (eepoint) eepoint = FALSE;
- else eepoint = TRUE;
- showarts(art_current);
- break;
-
- }
- }
- /* Now some garbage collection to free some memory */
- #ifdef UNIX /* can't make it work with MS-DOS!!!! */
- news_index = 0;
- while (news_index < art_count) {
- art_ptr = article[news_index];
- if (art_ptr != (struct newsview *)NULL) {
- if (art_ptr->from != nirvana) free(art_ptr->from);
- if (art_ptr->date != nirvana) free(art_ptr->date);
- if (art_ptr->msgid != nirvana) free(art_ptr->msgid);
- if (art_ptr->subject != nirvana) free(art_ptr->subject);
- if (art_ptr->keywords != nirvana) free(art_ptr->keywords);
- if (art_ptr->references != nirvana) free(art_ptr->references);
- free(art_ptr);
- /* printf("%d: Freeing %ld\n",news_index,(long)art_ptr); */
- }
- news_index++;
- }
- #endif /* UNIX */
- }
-
- /* showarts() -- show list of articles by number */
-
- void showarts(art_current)
- int art_current;
- {
- int index, counter;
-
- erase(); /* clear screen */
- counter = 0;
- index = art_current - viewpos;
- while (counter < (eeplines - 1)) {
- move(counter,0);
- if (counter == viewpos) {
- if (!eepoint) standout();
- printw("->");
- } else printw(" ");
- if ((index >= 0) && (index < art_count)) {
- art_ptr = article[index];
- printw("%8ld", art_ptr->artnum);
- move(counter,11);
- printw("%.38s", art_ptr->subject);
- move(counter,50);
- printw("%.28s", art_ptr->from);
- move(counter,0);
- if ((counter == viewpos) && !eepoint)
- standend();
- } else clrtoeol();
- index++;
- counter++;
- }
- move(eeplines - 1,0);
- clrtoeol();
- printw("There are %d articles in %s",art_count,dir);
- move(eeplines - 1,60);
- printw("Press ? for Help");
- move(viewpos,0);
- refresh();
- }
- @EOF
-
- chmod 600 eepview.c
-
- echo x - makefile
- cat >makefile <<'@EOF'
- #
- # Makefile for eep .newsrc editor
- #
- # The following flags are important:
- # UNIX - compiles UNIX version of code
- # DIRENT - does your system have dirent.h?
- # See eep.h -- you might need to change path to sys/dirent.h
- # ANSI - Try to follow ANSI conventions
- #
-
- CC=cc
- CCFLAGS=-O -DUNIX -DDIRENT -DANSI
- LIBS=-lcurses
-
- HDR=eep.h
-
- eep: eepmain.o eepmisc.o eepmenu.o eepview.o
- $(CC) -o eep eepmain.o eepmisc.o eepmenu.o eepview.o $(LIBS)
- strip eep
-
- eepmain.o: eepmain.c $(HDR)
- $(CC) $(CCFLAGS) -c eepmain.c
-
- eepmisc.o: eepmisc.c $(HDR)
- $(CC) $(CCFLAGS) -c eepmisc.c
-
- eepmenu.o: eepmenu.c $(HDR)
- $(CC) $(CCFLAGS) -c eepmenu.c
-
- eepview.o: eepview.c $(HDR)
- $(CC) $(CCFLAGS) -c eepview.c
- @EOF
-
- chmod 600 makefile
-
- echo x - makefile.dos
- cat >makefile.dos <<'@EOF'
- #
- # Makefile for eep .newsrc editor
- #
- # DOS version was compiled with Zortech C++ v2.1.
- # The curses libraries were prepared using the PDCurses package for MS-DOS
-
- CC=ztc
- CCFLAGS= =30000 -b -DDOS -mli -DANSI
- LIB=lcurses.lib
-
- eep.exe: eepmain.obj eepmisc.obj eepmenu.obj eepview.obj
- blink eepmain+eepmisc+eepmenu+eepview,eep,eep,$(LIB)
-
- eepmain.obj: eepmain.c eep.h
- $(CC) $(CCFLAGS) -c eepmain.c
-
- eepmisc.obj: eepmisc.c eep.h
- $(CC) $(CCFLAGS) -c eepmisc.c
-
- eepmenu.obj: eepmenu.c eep.h
- $(CC) $(CCFLAGS) -c eepmenu.c
-
- eepview.obj: eepview.c eep.h
- $(CC) $(CCFLAGS) -c eepview.c
-
- getopt.obj: getopt.c getopt.h debug.h
- $(CC) $(CCFLAGS) -c getopt.c
-
- @EOF
-
- chmod 600 makefile.dos
-
- echo x - makefile.unx \[linked to makefile\]
- ln makefile makefile.unx
-
- chmod 600 makefile.unx
-
- exit 0
- --
- Paul Gillingwater
- Home system: paul@actrix.co.at (Waffle)
-