home *** CD-ROM | disk | FTP | other *** search
- Subject: v06i030: Elm mail system (elm), Part05/14
- Newsgroups: mod.sources
- Approved: rs@mirror.UUCP
-
- Submitted by: Dave Taylor <pyramid!hplabs!hpldat!taylor>
- Mod.sources: Volume 6, Issue 30
- Archive-name: elm/Part05
-
- # Continuation of Shell Archive, created by hpldat!taylor
-
- # This is part 5
-
- # To unpack the enclosed files, please use this file as input to the
- # Bourne (sh) shell. This can be most easily done by the command;
- # sh < thisfilename
-
-
- if [ ! -d src ]
- then
- echo creating directory src
- mkdir src
- fi
-
- # ---------- file src/Makefile ----------
-
- filename="src/Makefile"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/Makefile...
- fi
-
- cat << 'END-OF-FILE' > $filename
- #
- # Makefile for the ELM mail program.
- #
- # (C) Copyright 1986, Dave Taylor
- #
- # Last modification: March 7th, 1986
-
- SHELL=/bin/sh
-
- ##############################
- #
- # if on a BSD system;
- # DEFINE=-DBSD
- # LIB2 = -lcurses
- # else if on a UTS system;
- # DEFINE=-DUTS
- # LIB2 = -la -lq
- # else if on a SUN system;
- # DEFINE=-DBSD -DSUN
- # LIB2 = -lcurses
- # else if on a Pyramid system;
- # DEFINE=-DBSD -DNO_VAR_ARGS
- # LIB2 = -lcurses
- # else
-
- DEFINE=
- LIB2 =
-
- # IF you're on an ACSnet system (Australia) then
- # you'll want to uncomment the following;
-
- # DEFINE= ${DEFINE} -DACSNET
-
- ##############################
-
- CFILES= addr_utils.c alias.c aliasdb.c aliaslib.c args.c bounceback.c \
- calendar.c connect_to.c curses.c date.c delete.c domains.c edit.c \
- encode.c errno.c file.c file_utils.c fileio.c hdrconfg.c help.c \
- initialize.c input_utils.c leavembox.c mailmsg1.c mailmsg2.c \
- mailtime.c mkhdrs.c elm.c newmbox.c notesfile.c options.c opt_utils.c \
- output_utils.c pattern.c quit.c read_rc.c remail.c reply.c \
- return_addr.c savecopy.c screen.c showmsg.c signals.c softkeys.c \
- sort.c strings.c syscall.c utils.c validname.c getopt.c string2.c
-
- HEADERS=../hdrs/curses.h ../hdrs/defs.h ../hdrs/headers.h ../hdrs/sysdefs.h
-
- OBJS= addr_utils.o alias.o aliasdb.o aliaslib.o args.o bounceback.o \
- calendar.o connect_to.o curses.o date.o delete.o domains.o edit.o \
- encode.o errno.o file.o file_utils.o fileio.o hdrconfg.o help.o \
- initialize.o input_utils.o leavembox.o mailmsg1.o mailmsg2.o \
- mailtime.o mkhdrs.o elm.o newmbox.o notesfile.o options.o opt_utils.o \
- output_utils.o pattern.o quit.o read_rc.o remail.o reply.o \
- return_addr.o savecopy.o screen.o showmsg.o signals.o softkeys.o \
- sort.o strings.o syscall.o utils.o validname.o getopt.o string2.o
-
- BIN= ../bin
- LIBS= -ltermcap
- CFLAGS= -O -I../hdrs
- CC= /bin/cc
- RM= /bin/rm -f
-
- ../bin/elm: ${OBJS} ${EXTRA} ${HEADERS} ../hdrs/elm.h
- ${CC} -o ${BIN}/elm -n ${OBJS} ${LIBS} ${LIB2}
-
- .c.o: ${HEADERS}
- ${CC} -c ${CFLAGS} ${DEFINE} $*.c
-
- curses.o: curses.c ../hdrs/curses.h
- ${CC} -c ${CFLAGS} -DRAWMODE ${DEFINE} curses.c
-
- # curses.c : curses.q
- # @../bin/quickscreen curses.q
- #
- # curses.q :
- # @cp curses.c curses.q
-
- clean:
- ${RM} ${OBJS} LINT.OUT
-
- lint: LINT.OUT
-
- LINT.OUT: ${CFILES}
- lint -p -I../hdrs ${CFILES} > LINT.OUT
-
- listing: LISTING
-
- LISTING: Makefile INDEX ${HEADERS} ${CFILES}
- @echo adding file 'Makefile'...
- @/bin/echo \\f > LISTING
- @cat Makefile >> LISTING
- @echo adding file 'INDEX'...
- @/bin/echo \\f >> LISTING
- @cat INDEX >> LISTING
- @../bin/makelisting ${HEADERS} ${CFILES}
- @echo LISTING generated.
-
- index: INDEX
-
- INDEX: ${CFILES} ${HEADERS}
- @echo Creating function definition index
- @index *.c | sort > INDEX
- @echo File INDEX generated
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 2822 ]
- then
- echo $filename changed - should be 2822 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/alias.c ----------
-
- filename="src/alias.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/alias.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** alias.c **/
-
- /** This file contains alias stuff
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
- #include <errno.h>
-
- char *expand_group(), *get_alias_address(), *expand_system(), *get_token();
- char *error_name(), *error_description();
-
- extern int errno;
-
- read_alias_files()
- {
- /** read the system and user alias files, if present.
- Set the flags 'systemfiles' and 'userfiles' accordingly.
- **/
-
- char fname[SLEN];
- int hash;
-
- if ((hash = open(system_hash_file, O_RDONLY)) == -1) {
- dprint1(1,
- "Warning: Can't read system hash file %s (read_alias_files)\n",
- system_hash_file);
- goto user;
- }
-
- read(hash, system_hash_table, sizeof system_hash_table);
- close(hash);
-
- /* and data file opened.. */
-
- if ((system_data = open(system_data_file, O_RDONLY)) == -1) {
- dprint1(1,
- "Warning: Can't read system data file %s (read_alias_files)\n",
- system_data_file);
- goto user;
- }
-
- system_files++; /* got the system files! */
-
- user: sprintf(fname, "%s/.alias_hash", home);
-
- if ((hash = open(fname, O_RDONLY)) == -1) {
- dprint1(1,"Warning: Can't read user hash file %s (read_alias_files)\n",
- fname);
- return;
- }
-
- read(hash, user_hash_table, sizeof user_hash_table);
- close(hash);
-
- sprintf(fname, "%s/.alias_data", home);
-
- if ((user_data = open(fname, O_RDONLY)) == -1) {
- dprint1(1,
- "Warning: can't read user data file %s (read_alias_files)\n",
- fname);
- return;
- }
-
- user_files++; /* got user files too! */
- }
-
- int
- add_alias()
- {
- /** add an alias to the user alias text file. Return zero
- if alias not added in actuality **/
-
- char name[SLEN], *address, address1[LONG_STRING];
- char comment[SLEN];
-
- PutLine0(LINES-2,0,"Enter alias name: ");
- CleartoEOLN();
- Raw(OFF);
- gets(name, 20);
- Raw(ON);
- if (strlen(name) == 0)
- return(0);
- if ((address = get_alias_address(name, 0, 0)) != NULL) {
- dprint1(2, "Attempt to add a duplicate alias [%s] (add_alias)\n",
- address);
- if (address[0] == '!') {
- address[0] = ' ';
- error1("already a group with that name:%s", address);
- }
- else
- error1("already an alias for that: %s", address);
- return(0);
- }
- PutLine1(LINES-2,0,"Full name for %s: ", name);
- CleartoEOLN();
- Raw(OFF);
- gets(comment,SLEN);
- Raw(ON);
- if (strlen(comment) == 0) strcpy(comment, name);
- PutLine1(LINES-2,0,"Enter address for %s: ",name);
- CleartoEOLN();
- Raw(OFF);
- gets(address1,LONG_SLEN);
- Raw(ON);
- if (strlen(address1) == 0) {
- error("No address specified!");
- return(0);
- }
- add_to_alias_text(name, comment, address1);
- return(1);
- }
-
- int
- add_current_alias()
- {
- /** alias the current message to the specified name and
- add it to the alias text file, for processing as
- the user leaves the program. Returns non-zero iff
- alias actually added to file **/
-
- char name[SLEN], address1[LONG_STRING], *address;
- char comment[SLEN];
-
- if (current == 0) {
- dprint0(3,"Add current alias called without any current message!\n");
- error("No message to alias to!");
- return(0);
- }
-
- PutLine0(LINES-2,0,"Current message address aliased to: ");
- CleartoEOLN();
- Raw(OFF);
- gets(name, 20);
- Raw(ON);
- if (strlen(name) == 0) /* cancelled... */
- return(0);
- if ((address = get_alias_address(name, 0, 0)) != NULL) {
- dprint1(3,
- "Attempt to add a duplicate alias [%s] (add_current_alias)\n",
- address);
- if (address[1] == '!') {
- address[0] = ' ';
- error1("already a group with that name:%s", address);
- }
- else
- error1("already an alias for that: %s", address);
- return(0);
- }
- PutLine1(LINES-2,0,"Full name of %s: ", name);
- CleartoEOLN();
- Raw(OFF);
- gets(comment, 40);
- Raw(ON);
- get_return(address1); /* grab the return address of this message */
- optimize_return(address1);
- PutLine3(LINES-2,0,"%s (%s) = %s", comment, name, address1);
- CleartoEOLN();
- add_to_alias_text(name, comment, address1);
- return(1);
- }
-
- add_to_alias_text(name, comment, address)
- char *name, *comment, *address;
- {
- /** Add the data to the user alias text file. Return zero if we
- succeeded, 1 if not **/
-
- FILE *file;
- char fname[SLEN];
-
- sprintf(fname,"%s/.alias_text", home);
-
- if ((file = fopen(fname, "a")) == NULL) {
- dprint2(2, "FILE Failure attempting to add alias to file %s (%s)",
- fname, "add_to_alias_text");
- dprint2(2, "** %s - %s **\n", error_name(errno),
- error_description(errno));
- error1("couldn't open %s to add new alias!", fname);
- return(1);
- }
-
- fprintf(file,"%s : %s : %s\n", name, comment, address);
- fclose(file);
-
- chown(fname, userid, groupid);
-
- return(0);
- }
-
- show_alias_menu()
- {
- MoveCursor(LINES-7,0); CleartoEOLN();
- MoveCursor(LINES-6,0); CleartoEOLN();
- MoveCursor(LINES-5,0); CleartoEOLN();
-
- PutLine0(LINES-7,COLUMNS-45, "Alias commands");
- Centerline(LINES-5,
- "A)lias current msg, Check a P)erson or S)ystem, M)ake new alias, or R)eturn"
- );
- }
-
- alias()
- {
- /** work with alias commands... **/
- char name[NLEN], *address, ch, buffer[SLEN];
- int newaliases = 0;
-
- if (mini_menu)
- show_alias_menu();
-
- define_softkeys(ALIAS);
-
- while (1) {
- PutLine0(LINES-3,0,"Alias: ");
- CleartoEOLN();
- ch = ReadCh();
- MoveCursor(LINES-1,0); CleartoEOLN();
-
- switch (tolower(ch)) {
- case 'a': newaliases += add_current_alias(); break;
- case 'm': newaliases += add_alias(); break;
-
- case RETURN:
- case 'q':
- case 'x':
- case 'r': if (newaliases) install_aliases();
- return;
- case 'p': if (newaliases)
- error("Warning: new aliases not installed yet!");
- PutLine0(LINES-2,0,"Check for person: ");
- CleartoEOLN();
- Raw(OFF);
- gets(name,NLEN);
- Raw(ON);
- if ((address = get_alias_address(name, 0, 0))!=NULL) {
- if (address[0] == '!') {
- address[0] = ' ';
- PutLine1(LINES-1,0,"Group alias:%-65.65s", address);
- CleartoEOLN();
- }
- else
- PutLine1(LINES-1,0,"Aliased addresss: %-65.65s",
- address);
- }
- else
- error("not found");
- break;
-
- case 's': PutLine0(LINES-2,0,"Check for system: ");
- CleartoEOS();
- Raw(OFF);
- gets(name,NLEN);
- Raw(ON);
- if (talk_to(name))
- #ifdef INTERNET_ADDRESS_FORMAT
- PutLine1(LINES-1,0,
- "You have a direct connection - the address is (user)@%s",
- name);
- #else
- PutLine1(LINES-1,0,
- "You have a direct connection - the address is %s!(user)",
- name);
- #endif
- else {
- sprintf(buffer, "(user)@%s", name);
- address = expand_system(buffer, FALSE);
- if (strlen(address) > strlen(name) + 7)
- PutLine1(LINES-1,0,"Address is: %.65s", address);
- else
- error1("couldn't expand system '%s'", name);
- }
- break;
-
- case '@': PutLine0(LINES-2,0,"Fully expand alias: ");
- CleartoEOS();
- Raw(OFF);
- gets(name,NLEN);
- Raw(ON);
- if ((address = get_alias_address(name, 1, 0)) != NULL) {
- ClearScreen();
- PutLine1(3,0,"Aliased address:\n\r%s", address);
- PutLine0(LINES-1,0,"Press <return> to continue: ");
- (void) getchar();
- }
- else
- error("not found");
- break;
- default : error("Invalid input!");
- }
- }
- }
-
- install_aliases()
- {
- /** run the 'newalias' program and install the newly
- added aliases before going back to the main
- program!
- **/
-
- error("Adding new aliases...");
- sleep(2);
-
- if (system_call(newalias, SH) == 0) {
- error("Re-reading the database in...");
- sleep(2);
- read_alias_files();
- set_error("New aliases installed successfully");
- }
- else
- set_error("'newalias' failed. Please check alias_text");
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 7725 ]
- then
- echo $filename changed - should be 7725 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/curses.c ----------
-
- filename="src/curses.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/curses.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** curses.c **/
-
- /** This library gives programs the ability to easily access the
- termcap information and write screen oriented and raw input
- programs. The routines can be called as needed, except that
- to use the cursor / screen routines there must be a call to
- InitScreen() first. The 'Raw' input routine can be used
- independently, however.
-
- Modified 2/86 to work (hopefully) on Berkeley systems. If
- there are any problems with BSD Unix, please report them to
- the author at taylor@hplabs (fixed, if possible!)
-
- Modified 5/86 to add memory lock support, thanks to the
- suggested code by Steve Wolf.
-
- (C) Copyright 1985 Dave Taylor, HP Colorado Networks
- **/
-
- #ifdef BSD
- # include "/usr/include/curses.h" /* don't ask! */
- #endif
-
- #include "headers.h"
-
- #ifdef RAWMODE
- # ifdef BSD
- # include <sgtty.h>
- # else
- # include <termio.h>
- # endif
- #endif
-
- #include <ctype.h>
-
- #ifdef BSD
- #undef tolower
- #endif
- #include "curses.h"
-
- #ifdef RAWMODE
- # define TTYIN 0
- #endif
-
- extern int debug;
-
- #ifdef RAWMODE
- # ifndef BSD
- struct termio _raw_tty,
- _original_tty;
- # endif
-
- static int _inraw = 0; /* are we IN rawmode? */
- static int _memory_locked = 0; /* are we IN memlock?? */
- static int _line = -1, /* initialize to "trash" */
- _col = -1;
-
- #ifdef UTS
- static int _clear_screen = 0; /* Next i/o clear screen? */
- static char _null_string[SLEN]; /* a string of nulls... */
- #endif
-
- #endif
-
- static int _intransmit; /* are we transmitting keys? */
-
- static
- char *_clearscreen, *_moveto, *_up, *_down, *_right, *_left,
- *_setbold, *_clearbold, *_setunderline, *_clearunderline,
- *_sethalfbright, *_clearhalfbright, *_setinverse, *_clearinverse,
- *_cleartoeoln, *_cleartoeos, *_transmit_on, *_transmit_off,
- *_set_memlock, *_clear_memlock;
-
- static
- int _lines, _columns;
-
- static char _terminal[1024]; /* Storage for terminal entry */
- static char _capabilities[1024]; /* String for cursor motion */
-
- static char *ptr = _capabilities; /* for buffering */
-
- int outchar(); /* char output for tputs */
- char *tgetstr(), /* Get termcap capability */
- *tgoto(); /* and the goto stuff */
-
- InitScreen()
- {
- /* Set up all this fun stuff: returns zero if all okay, or;
- -1 indicating no terminal name associated with this shell,
- -2..-n No termcap for this terminal type known
- */
-
- int tgetent(), /* get termcap entry */
- error;
- char termname[40];
-
- dprint0(8,"InitScreen()\n");
-
- #ifdef SUN
- if (getenv("TERM") == NULL)
- return(-1);
- #endif
-
- #ifdef UTS
-
- /* use _line for lack of a better variable, what the heck! */
-
- for (_line = 0; _line < SLEN; _line++)
- _null_string[_line] = '\0';
- #endif
-
- if (strcpy(termname, getenv("TERM")) == NULL)
- return(-1);
-
- if ((error = tgetent(_terminal, termname)) != 1)
- return(error-2);
-
- _line = 0; /* where are we right now?? */
- _col = 0; /* assume zero, zero... */
-
- /* load in all those pesky values */
- _clearscreen = tgetstr("cl", &ptr);
- _moveto = tgetstr("cm", &ptr);
- _up = tgetstr("up", &ptr);
- _down = tgetstr("do", &ptr);
- _right = tgetstr("nd", &ptr);
- _left = tgetstr("bs", &ptr);
- _setbold = tgetstr("so", &ptr);
- _clearbold = tgetstr("se", &ptr);
- _setunderline = tgetstr("us", &ptr);
- _clearunderline = tgetstr("ue", &ptr);
- _setinverse = tgetstr("so", &ptr);
- _clearinverse = tgetstr("se", &ptr);
- _sethalfbright = tgetstr("hs", &ptr);
- _clearhalfbright = tgetstr("he", &ptr);
- _cleartoeoln = tgetstr("ce", &ptr);
- _cleartoeos = tgetstr("cd", &ptr);
- _lines = tgetnum("li");
- _columns = tgetnum("co");
- _transmit_on = tgetstr("ks", &ptr);
- _transmit_off = tgetstr("ke", &ptr);
- _set_memlock = tgetstr("ml", &ptr);
- _clear_memlock = tgetstr("mu", &ptr);
-
-
- if (!_left) {
- _left = ptr;
- *ptr++ = '\b';
- *ptr++ = '\0';
- }
-
- #ifdef BSD
- initscr(); /* initalize curses too! */
- #endif
-
- return(0);
- }
-
- char *return_value_of(termcap_label)
- char *termcap_label;
- {
- /** This will return the string kept by termcap for the
- specified capability. Modified to ensure that if
- tgetstr returns a pointer to a transient address
- that we won't bomb out with a later segmentation
- fault (thanks to Dave@Infopro for this one!) **/
-
- static char escape_sequence[20];
-
- char *tgetstr(); /* Get termcap capability */
-
- dprint1(9,"return_value_of(%s)\n", termcap_label);
-
- strcpy(escape_sequence, tgetstr(termcap_label, &ptr));
- return( (char *) escape_sequence);
- }
-
- transmit_functions(newstate)
- int newstate;
- {
- /** turn function key transmission to ON | OFF **/
-
- dprint1(9,"transmit_functions(%s)\n", onoff(newstate));
-
- if (newstate != _intransmit) {
- _intransmit = ! _intransmit;
- if (newstate == ON)
- tputs(_transmit_on, 1, outchar);
- else
- tputs(_transmit_off, 1, outchar);
-
- fflush(stdout); /* clear the output buffer */
- }
- }
-
- /****** now into the 'meat' of the routines...the cursor stuff ******/
-
- ScreenSize(lines, columns)
- int *lines, *columns;
- {
- /** returns the number of lines and columns on the display. **/
-
- dprint2(9,"ScreenSize(_,_) returning %d, %d\n", _lines-1, _columns);
-
- *lines = _lines - 1; /* assume index from zero */
- *columns = _columns;
- }
-
- ClearScreen()
- {
- /* clear the screen: returns -1 if not capable */
-
- dprint0(9,"ClearScreen()\n");
-
- _line = 0; /* clear leaves us at top... */
- _col = 0;
-
- #ifdef UTS
- if (isatube) {
- _clear_screen++; /* queue up for clearing... */
- return(0);
- }
- #endif
-
- if (!_clearscreen)
- return(-1);
-
- tputs(_clearscreen, 1, outchar);
- fflush(stdout); /* clear the output buffer */
- return(0);
- }
-
- MoveCursor(row, col)
- int row, col;
- {
- /** move cursor to the specified row column on the screen.
- 0,0 is the top left! **/
-
- char *stuff;
-
- /* we don't want to change "rows" or we'll mangle scrolling... */
-
- if (col > COLUMNS) col = COLUMNS;
- if (col < 0) col = 0;
-
- #ifdef UTS
- if (isatube) {
- at row+1, col+1;
- _line = row;
- _col = col;
- return(0);
- }
- #endif
- if (!_moveto)
- return(-1);
-
- if (row == _line) {
- if (col == _col)
- return(0);
- else if (abs(col - _col) < 5) {
- if (col > _col)
- CursorRight(col - _col);
- else
- CursorLeft(_col - col);
- }
- else {
- stuff = tgoto(_moveto, col, row);
- tputs(stuff, 1, outchar);
- fflush(stdout);
- }
- }
- else if (col == _col && abs(row - _line) < 5) {
- if (row < _line)
- CursorUp(_line - row);
- else
- CursorDown(row - _line);
- }
- else if (_line == row-1 && col == 0) {
- putchar('\n'); /* that's */
- putchar('\r'); /* easy! */
- fflush(stdout);
- }
- else {
- stuff = tgoto(_moveto, col, row);
- tputs(stuff, 1, outchar);
- fflush(stdout);
- }
-
- _line = row; /* to ensure we're really there... */
- _col = col;
-
- return(0);
- }
-
- CursorUp(n)
- int n;
- {
- /** move the cursor up 'n' lines **/
-
- dprint1(9,"CursorUp(%d)\n", n);
-
- _line = (_line-n > 0? _line - n: 0); /* up 'n' lines... */
-
- #ifdef UTS
- if (isatube) {
- at _line+1, _col+1;
- return(0);
- }
- #endif
- if (!_up)
- return(-1);
-
- while (n-- > 0)
- tputs(_up, 1, outchar);
-
- fflush(stdout);
- return(0);
- }
-
-
- CursorDown(n)
- int n;
- {
- /** move the cursor down 'n' lines **/
-
- dprint1(9,"CursorDown(%d)\n", n);
-
- _line = (_line+n < LINES? _line + n: LINES); /* down 'n' lines... */
-
- #ifdef UTS
- if (isatube) {
- at _line+1, _col+1 ;
- return(0);
- }
- #endif
-
- if (!_down)
- return(-1);
-
- while (n-- > 0)
- tputs(_down, 1, outchar);
-
- fflush(stdout);
- return(0);
- }
-
-
- CursorLeft(n)
- int n;
- {
- /** move the cursor 'n' characters to the left **/
-
- dprint1(9,"CursorLeft(%d)\n", n);
-
- _col = (_col - n> 0? _col - n: 0); /* left 'n' chars... */
-
- #ifdef UTS
- if (isatube) {
- at _line+1, _col+1;
- return(0);
- }
- #endif
-
- if (!_left)
- return(-1);
-
- while (n-- > 0)
- tputs(_left, 1, outchar);
-
- fflush(stdout);
- return(0);
- }
-
-
- CursorRight(n)
- int n;
- {
- /** move the cursor 'n' characters to the right (nondestructive) **/
-
- dprint1(9,"CursorRight(%d)\n", n);
-
- _col = (_col+n < COLUMNS? _col + n: COLUMNS); /* right 'n' chars... */
-
- #ifdef UTS
- if (isatube) {
- at _line+1, _col+1;
- return(0);
- }
- #endif
-
- if (!_right)
- return(-1);
-
- while (n-- > 0)
- tputs(_right, 1, outchar);
-
- fflush(stdout);
- return(0);
- }
-
-
- StartBold()
- {
- /** start boldface/standout mode **/
-
- if (!_setbold)
- return(-1);
-
- tputs(_setbold, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- EndBold()
- {
- /** compliment of startbold **/
-
- if (!_clearbold)
- return(-1);
-
- tputs(_clearbold, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- StartUnderline()
- {
- /** start underline mode **/
-
- if (!_setunderline)
- return(-1);
-
- tputs(_setunderline, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- EndUnderline()
- {
- /** the compliment of start underline mode **/
-
- if (!_clearunderline)
- return(-1);
-
- tputs(_clearunderline, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- StartHalfbright()
- {
- /** start half intensity mode **/
-
- if (!_sethalfbright)
- return(-1);
-
- tputs(_sethalfbright, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
- EndHalfbright()
- {
- /** compliment of starthalfbright **/
-
- if (!_clearhalfbright)
- return(-1);
-
- tputs(_clearhalfbright, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
- StartInverse()
- {
- /** set inverse video mode **/
-
- if (!_setinverse)
- return(-1);
-
- tputs(_setinverse, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- EndInverse()
- {
- /** compliment of startinverse **/
-
- if (!_clearinverse)
- return(-1);
-
- tputs(_clearinverse, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
- int
- HasMemlock()
- {
- /** returns TRUE iff memory locking is available (a terminal
- feature that allows a specified portion of the screen to
- be "locked" & not cleared/scrolled... **/
-
- return ( _set_memlock && _clear_memlock );
- }
-
- static int _old_LINES;
-
- int
- StartMemlock()
- {
- /** mark the current line as the "last" line of the portion to
- be memory locked (always relative to the top line of the
- screen) Note that this will alter LINES so that it knows
- the top is locked. This means that (plus) the program
- will scroll nicely but (minus) End memlock MUST be called
- whenever we leave the locked-memory part of the program! **/
-
- if (! _set_memlock)
- return(-1);
-
- if (! _memory_locked) {
-
- _old_LINES = LINES;
- LINES -= _line; /* we can't use this for scrolling */
-
- tputs(_set_memlock, 1, outchar);
- fflush(stdout);
- _memory_locked = TRUE;
- }
-
- return(0);
- }
-
- int
- EndMemlock()
- {
- /** Clear the locked memory condition... **/
-
- if (! _set_memlock)
- return(-1);
-
- if (_memory_locked) {
- LINES = _old_LINES; /* back to old setting */
-
- tputs(_clear_memlock, 1, outchar);
- fflush(stdout);
- _memory_locked = FALSE;
- }
- return(0);
- }
-
-
- Writechar(ch)
- char ch;
- {
- /** write a character to the current screen location. **/
-
- #ifdef UTS
- char buffer[2]; /* can't output characters! */
- #endif
-
- dprint1(9,ch >= ' ' ? "Writechar(%c)\n" : "Writechar(^%c)\n",
- ch >= ' ' ? ch : ch + 'A' - 1);
- #ifdef UTS
-
- if (isatube) {
- buffer[0] = ch;
- buffer[1] = '\0';
-
- at _line+1, _col+1;
- panel (noerase, noinit, noread) {
- #ON, buffer, 1#
- }
- }
- else
- #endif
- putchar(ch);
-
- if (ch == BACKSPACE) /* moved BACK one! */
- _col--;
- else if (ch >= ' ') /* moved FORWARD one! */
- _col++;
- }
-
- Write_to_screen(line, argcount, arg1, arg2, arg3)
- char *line;
- int argcount, arg1, arg2, arg3;
- {
- /** This routine writes to the screen at the current location.
- when done, it increments lines & columns accordingly by
- looking for "\n" sequences... **/
-
- dprint2(9,"Write_to_screen(%s) [%d args]\n", line, argcount);
-
- switch (argcount) {
- case 0 :
- PutLine0(_line, _col, line);
- break;
- case 1 :
- PutLine1(_line, _col, line, arg1);
- break;
- case 2 :
- PutLine2(_line, _col, line, arg1, arg2);
- break;
- case 3 :
- PutLine3(_line, _col, line, arg1, arg2, arg3);
- break;
- }
- }
-
- PutLine0(x, y, line)
- int x,y;
- char *line;
- {
- /** Write a zero argument line at location x,y **/
-
- register int i;
-
- dprint3(8,"PutLine0(%d, %d, %s.30...)\n", x, y, line);
-
- #ifdef UTS
- if (isatube) {
- at x+1, y+1;
- panel (init=_clear_screen, noread, erase=_clear_screen) {
- #ON, line, strlen(line)-1#
- }
- _clear_screen = 0;
- _col += printable_chars(line);
-
- /* line wrapped around?? */
- while (_col > COLUMNS) {
- _col -= COLUMNS;
- _line += 1;
- }
-
- /* now let's figure out if we're supposed to do a "<return>" */
-
- for (i=0; i < strlen(line); i++)
- if (line[i] == '\n') {
- _line++;
- _col = 0; /* on new line! */
- }
- return(0);
- }
- #endif
- MoveCursor(x,y);
- printf("%s", line); /* to avoid '%' problems */
- fflush(stdout);
- _col += printable_chars(line);
-
- while (_col > COLUMNS) { /* line wrapped around?? */
- _col -= COLUMNS;
- _line += 1;
- }
-
- /** now let's figure out if we're supposed to do a "<return>" **/
-
- for (i=0; i < strlen(line); i++)
- if (line[i] == '\n') {
- _line++;
- _col = 0; /* on new line! */
- }
- }
-
- PutLine1(x,y, line, arg1)
- int x,y;
- char *line;
- char *arg1;
- {
- /** write line at location x,y - one argument... **/
-
- char buffer[SLEN];
-
- dprint0(9, "PutLine1(...)\n");
-
- sprintf(buffer, line, arg1);
-
- PutLine0(x, y, buffer);
- }
-
- PutLine2(x,y, line, arg1, arg2)
- int x,y;
- char *line;
- char *arg1, *arg2;
- {
- /** write line at location x,y - one argument... **/
-
- char buffer[SLEN];
-
- dprint0(9, "PutLine2(...)\n");
-
- sprintf(buffer, line, arg1, arg2);
-
- PutLine0(x, y, buffer);
- }
-
- PutLine3(x,y, line, arg1, arg2, arg3)
- int x,y;
- char *line;
- char *arg1, *arg2, *arg3;
- {
- /** write line at location x,y - one argument... **/
-
- char buffer[SLEN];
-
- dprint0(9, "PutLine3(...)\n");
-
- sprintf(buffer, line, arg1, arg2, arg3);
-
- PutLine0(x, y, buffer);
- }
-
- CleartoEOLN()
- {
- /** clear to end of line **/
- #ifdef UTS
- char buffer[SLEN];
- register int cols, i = 0;
-
- if (isatube) {
-
- dprint0(9, "CleartoEOLN()\n");
-
- for (cols = _col; cols < COLUMNS; cols++)
- buffer[i++] = ' ';
-
- buffer[i] = '\0';
-
- at _line+1, _col+1;
- panel (noerase, noinit, noread) {
- #ON, buffer, strlen(buffer)-1#
- }
-
- return(0);
- }
- #endif
-
- dprint0(9, "CleartoEOLN()\n");
-
- if (!_cleartoeoln)
- return(-1);
-
- tputs(_cleartoeoln, 1, outchar);
- fflush(stdout); /* clear the output buffer */
- return(0);
- }
-
- CleartoEOS()
- {
- /** clear to end of screen **/
-
- #ifdef UTS
- register int line_at;
-
- if (isatube) {
- dprint0(9,"CleartoEOS()\n");
- for (line_at = _line; line_at < LINES-1; line_at++) {
- panel (noread, noinit, noread) {
- #@ line_at, 1# #ON, _null_string, COLUMNS#
- }
- }
-
- return(0);
- }
-
- #endif
- dprint0(9,"CleartoEOS()\n");
-
- if (!_cleartoeos)
- return(-1);
-
- tputs(_cleartoeos, 1, outchar);
- fflush(stdout); /* clear the output buffer */
- return(0);
- }
-
- #ifdef RAWMODE
-
- Raw(state)
- int state;
- {
- /** state is either ON or OFF, as indicated by call **/
-
- dprint1(8,"Raw(%s)\n", onoff(state));
-
- if (state == OFF && _inraw) {
- #ifdef BSD
- echo();
- nocrmode();
- #else
- (void) ioctl(TTYIN, TCSETAW, &_original_tty);
- #endif
- _inraw = 0;
- }
- else if (state == ON && ! _inraw) {
- #ifdef BSD
- noecho();
- crmode();
- #else
- (void) ioctl(TTYIN, TCGETA, &_original_tty); /** current setting **/
-
- (void) ioctl(TTYIN, TCGETA, &_raw_tty); /** again! **/
- _raw_tty.c_iflag &= ~(INLCR | ICRNL |BRKINT);
- _raw_tty.c_iflag |= IXON;
- _raw_tty.c_oflag |= OPOST;
- _raw_tty.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
- _raw_tty.c_lflag &= ~(ICANON | ECHO);
- _raw_tty.c_cc[VMIN] = '\01';
- _raw_tty.c_cc[VTIME] = '\0';
- (void) ioctl(TTYIN, TCSETAW, &_raw_tty);
- #endif
-
- _inraw = 1;
- }
- }
-
- int
- ReadCh()
- {
- /** read a character with Raw mode set! **/
-
- register int result;
- char ch;
-
- dprint0(9,"ReadCh()\n");
-
- result = read(0, &ch, 1);
-
- return(result == 0? EOF : ch);
- }
-
- #endif
-
- outchar(c)
- char c;
- {
- /** output the given character. From tputs... **/
- /** Note: this CANNOT be a macro! **/
-
- putc(c, stdout);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 15951 ]
- then
- echo $filename changed - should be 15951 bytes, not $size bytes
- fi
-
- chmod 666 $filename
- fi
-
- # ---------- file src/date.c ----------
-
- filename="src/date.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/date.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** date.c **/
-
- /** return the current date and time in a readable format! **/
- /** also returns an ARPA RFC-822 format date... **/
-
- /** (C) Copyright 1985, Dave Taylor **/
-
- #include "headers.h"
- #ifdef BSD
- # include <sys/time.h>
- #else
- # include <time.h>
- #endif
-
- #include <ctype.h>
-
- #ifdef BSD
- #undef toupper
- #endif
-
- #define MONTHS_IN_YEAR 11 /* 0-11 equals 12 months! */
- #define FEB 1 /* 0 = January */
- #define DAYS_IN_LEAP_FEB 29 /* leap year only */
-
- #define ampm(n) (n > 12? n - 12 : n)
- #define am_or_pm(n) (n > 11? (n > 23? "am" : "pm") : "am")
- #define leapyear(year) ((year % 4 == 0) && (year % 100 != 0))
-
- char *dayname[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
- "Friday", "Saturday", "" };
-
- char *monname[] = { "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November",
- "December", ""};
-
- char *arpa_dayname[] = { "Sun", "Mon", "Tue", "Wed", "Thu",
- "Fri", "Sat", "" };
-
- char *arpa_monname[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""};
-
- int days_in_month[] = { 31, 28, 31, 30, 31, 30,
- 31, 31, 30, 31, 30, 31, -1};
-
- #ifdef BSD
- char *timezone();
- #else
- extern char *tzname[];
- #endif
-
- char *get_date()
- {
- /** Return the date in the format exemplified by;
- Thursday, April 18th 1985 at 8:35 pm
-
- *************************************
- ** This routine is not used by ELM **
- *************************************
-
- **/
-
- static char buffer[SLEN]; /* static character buffer */
- struct tm *the_time, /* Time structure, see CTIME(3C) */
- *localtime();
- char *suffix(); /* digit suffix for date */
- long junk; /* time in seconds.... */
-
- junk = (long) time(0); /* this must be here for it to work! */
- the_time = localtime(&junk);
-
- sprintf(buffer, "%s, %s %d%s %d at %d:%02d %s",
- dayname[the_time->tm_wday], /* weekday */
- monname[the_time->tm_mon], /* month */
- the_time->tm_mday, /* day */
- suffix(the_time->tm_mday), /* suffix */
- the_time->tm_year + 1900, /* year */
- ampm(the_time->tm_hour), /* hour */
- the_time->tm_min, /* minute */
- ((the_time->tm_hour == 12 || the_time->tm_hour == 24)
- && the_time->tm_min == 0) ? (the_time->tm_hour == 12? "noon" :
- "midnight") : am_or_pm(the_time->tm_hour)); /* am | pm */
-
- return( (char *) buffer);
- }
-
- char *suffix(day)
- int day;
- {
- /** this routine returns the suffix appropriate for the
- specified number to make it an ordinal number. ie,
- if given '1' it would return 'st', and '2' => 'nd'
- **/
-
- static char buffer[10];
- register int digit;
-
- digit = day % 10;
-
- if (digit == 0 || digit > 3)
- strcpy(buffer,"th");
- else if (digit == 1)
- strcpy(buffer,"st");
- else if (digit == 2)
- strcpy(buffer, "nd");
- else
- strcpy(buffer, "rd");
-
- return( (char *) buffer);
- }
-
- char *get_arpa_date()
- {
- /** returns an ARPA standard date. The format for the date
- according to DARPA document RFC-822 is exemplified by;
-
- Mon, 12 Aug 85 6:29:08 MST
-
- **/
-
- static char buffer[SLEN]; /* static character buffer */
- struct tm *the_time, /* Time structure, see CTIME(3C) */
- *localtime();
- long junk; /* time in seconds.... */
- #ifdef BSD
- struct timeval time_val;
- struct timezone time_zone;
- #endif
-
- #ifdef BSD
- gettimeofday(&time_val, &time_zone);
- junk = time_val.tv_sec;
- #else
- junk = (long) time(0); /* this must be here for it to work! */
- #endif
- the_time = localtime(&junk);
-
- sprintf(buffer, "%s, %d %s %d %d:%02d:%02d %s",
- arpa_dayname[the_time->tm_wday],
- the_time->tm_mday % 32,
- arpa_monname[the_time->tm_mon],
- the_time->tm_year % 100,
- the_time->tm_hour % 24,
- the_time->tm_min % 61,
- the_time->tm_sec % 61,
- #ifdef BSD
- timezone(time_zone.tz_minuteswest, time_zone.tz_dsttime));
- #else
- tzname[the_time->tm_isdst]);
- #endif
-
- return( (char *) buffer);
- }
-
- char *full_month(month)
- char *month;
- {
- /** Given a three letter month abbreviation, return the
- full name of the month. If can't figure it out, just
- return the given argument. **/
-
- char name[4];
- register int i;
-
- /** ensure name in correct case... **/
-
- strncpy(name, shift_lower(month), 3);
- name[0] = toupper(name[0]);
-
- /** now simply step through arpa_monname table to find a match **/
-
- for (i=0; i < 12; i++)
- if (strncmp(name, arpa_monname[i], 3) == 0)
- return((char *) monname[i]);
-
- dprint1(2, "Warning: Couldn't expand monthname %s (full_month)\n",
- month);
-
- return( (char *) month);
- }
-
- days_ahead(days, buffer)
- int days;
- char *buffer;
- {
- /** return in buffer the date (Day, Mon Day, Year) of the date
- 'days' days after today. **/
-
- struct tm *the_time, /* Time structure, see CTIME(3C) */
- *localtime();
- long junk; /* time in seconds.... */
-
- junk = (long) time(0); /* this must be here for it to work! */
- the_time = localtime(&junk);
-
- /* increment the day of the week */
-
- the_time->tm_wday = (the_time->tm_wday + days) % 7;
-
- /* the day of the month... */
- the_time->tm_mday += days;
-
- if (the_time->tm_mday > days_in_month[the_time->tm_mon]) {
- if (the_time->tm_mon == FEB && leapyear(the_time->tm_year)) {
- if (the_time->tm_mday > DAYS_IN_LEAP_FEB) {
- the_time->tm_mday -= days_in_month[the_time->tm_mon];
- the_time->tm_mon += 1;
- }
- }
- else {
- the_time->tm_mday -= days_in_month[the_time->tm_mon];
- the_time->tm_mon += 1;
- }
- }
-
- /* check the month of the year */
- if (the_time->tm_mon > MONTHS_IN_YEAR) {
- the_time->tm_mon -= MONTHS_IN_YEAR;
- the_time->tm_year += 1;
- }
-
- /* now, finally, build the actual date string */
-
- sprintf(buffer, "%s, %d %s %d",
- arpa_dayname[the_time->tm_wday],
- the_time->tm_mday % 32,
- arpa_monname[the_time->tm_mon],
- the_time->tm_year % 100);
- }
-
- int
- valid_date(day, mon, year)
- char *day, *mon, *year;
- {
- /** validate the given date - returns TRUE iff the date
- handed is reasonable and valid. **/
-
- register int daynum, yearnum;
-
- daynum = atoi(day);
- yearnum = atoi(year);
-
- if (daynum < 1 || daynum > 31) {
- dprint1(3, "Error: day %d is obviously wrong! (valid_date)\n",
- daynum);
- return(0);
- }
-
- if (yearnum < 1 || (yearnum > 100 && yearnum < 1900) ||
- yearnum > 2000) {
- dprint1(3, "Error: year %d is obviously wrong! (valid_date)\n",
- yearnum);
- return(0);
- }
-
- return(1);
- }
-
- fix_date(entry)
- struct header_rec *entry;
- {
- /** This routine will 'fix' the date entry for the specified
- message. This consists of 1) adjusting the year to 0-99
- and 2) altering time from HH:MM:SS to HH:MM am|pm **/
-
- if (atoi(entry->year) > 99)
- sprintf(entry->year,"%d", atoi(entry->year) - 1900);
-
- fix_time(entry->time);
- }
-
- fix_time(timestring)
- char *timestring;
- {
- /** Timestring in format HH:MM:SS (24 hour time). This routine
- will fix it to display as: HH:MM [am|pm] **/
-
- int hour, minute;
-
- sscanf(timestring, "%d:%d", &hour, &minute);
-
- if (hour < 1 || hour == 24)
- sprintf(timestring, "12:%2d (midnight)", minute);
- else if (hour < 12)
- sprintf(timestring, "%d:%2.2d am", hour, minute);
- else if (hour == 12)
- sprintf(timestring, "%d:%2.2d (noon)", hour, minute);
- else if (hour < 24)
- sprintf(timestring, "%d:%2.2d pm", hour-12, minute);
- }
-
- int
- compare_dates(rec1, rec2)
- struct header_rec *rec1, *rec2;
- {
- /** This function works similarly to the "strcmp" function, but
- has lots of knowledge about the internal date format...
- Apologies to those who "know a better way"...
- **/
-
- int month1, day1, year1, hour1, minute1,
- month2, day2, year2, hour2, minute2;
-
- year1 = atoi(rec1->year);
- year2 = atoi(rec2->year);
-
- if (year1 != year2)
- return( year1 - year2 );
-
- /* And HERE's where the performance of this sort dies... */
-
- month1 = month_number(rec1->month); /* retch... gag.... */
- month2 = month_number(rec2->month); /* puke... */
-
- if (month1 == -1)
- dprint1(2,"month_number failed on month '%s'\n", rec1->month);
-
- if (month2 == -1)
- dprint1(2,"month_number failed on month '%s'\n", rec2->month);
-
- if (month1 != month2)
- return( month1 - month2 );
-
- /* back and cruisin' now, though... */
-
- day1 = atoi(rec1->day); /* unfortunately, 2 is greater than 19 */
- day2 = atoi(rec2->day); /* on a dump string-only compare... */
-
- if (day1 != day2)
- return( day1 - day2 );
-
- /* we're really slowing down now... */
-
- sscanf(rec1->time, "%d:%d", &hour1, &minute1);
- sscanf(rec2->time, "%d:%d", &hour2, &minute2);
-
- if (hour1 != hour2)
- return( hour1 - hour2 );
-
- return( day1 - day2 ); /* ignore seconds... */
- }
-
- int
- month_number(name)
- char *name;
- {
- /** return the month number given the month name... **/
-
- char ch;
-
- switch (tolower(name[0])) {
- case 'a' : if ((ch = tolower(name[1])) == 'p') return(APRIL);
- else if (ch == 'u') return(AUGUST);
- else return(-1); /* error! */
-
- case 'd' : return(DECEMBER);
- case 'f' : return(FEBRUARY);
- case 'j' : if ((ch = tolower(name[1])) == 'a') return(JANUARY);
- else if (ch == 'u') {
- if ((ch = tolower(name[2])) == 'n') return(JUNE);
- else if (ch == 'l') return(JULY);
- else return(-1); /* error! */
- }
- else return(-1); /* error */
- case 'm' : if ((ch = tolower(name[2])) == 'r') return(MARCH);
- else if (ch == 'y') return(MAY);
- else return(-1); /* error! */
- case 'n' : return(NOVEMBER);
- case 'o' : return(OCTOBER);
- case 's' : return(SEPTEMBER);
- default : return(-1);
- }
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 9538 ]
- then
- echo $filename changed - should be 9538 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/delete.c ----------
-
- filename="src/delete.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/delete.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** delete.c **/
-
- /** Delete or undelete files: just set flag in header record!
- Also tags specified message(s)...
-
- (C) Copyright 1985 Dave Taylor
- **/
-
- #include "headers.h"
-
- delete(real_del)
- int real_del;
- {
- /** Delete current message. If real-del is false, then we're
- actually requested to toggle the state of the current
- message... **/
-
- if (real_del)
- header_table[current-1].status |= DELETED;
- else if (ison(header_table[current-1].status, DELETED))
- clearit(header_table[current-1].status, DELETED);
- else
- setit(header_table[current-1].status, DELETED);
-
- show_msg_status(current-1);
- }
-
- undelete()
- {
- /** clear the deleted message flag **/
-
- clearit(header_table[current-1].status, DELETED);
-
- show_msg_status(current-1);
- }
-
- show_msg_status(msg)
- int msg;
- {
- /** show the status of the current message only. **/
-
- if (on_page(msg)) {
- MoveCursor((msg % headers_per_page) + 4, 3);
- Writechar( ison(header_table[msg].status, DELETED)? 'D' : ' ');
- }
- }
-
- tag_message()
- {
- /** Tag current message. If already tagged, untag it. **/
-
- if (ison(header_table[current-1].status, TAGGED))
- clearit(header_table[current-1].status, TAGGED);
- else
- setit(header_table[current-1].status, TAGGED);
-
- show_msg_tag(current-1);
- }
-
- show_msg_tag(msg)
- int msg;
- {
- /** show the tag status of the current message only. **/
-
- if (on_page(msg)) {
- MoveCursor((msg % headers_per_page) + 4, 4);
- Writechar( ison(header_table[msg].status, TAGGED)? '+' : ' ');
- }
- }
-
- show_new_status(msg)
- int msg;
- {
- /** If the specified message is on this screen, show
- the new status (could be marked for deletion now,
- and could have tag removed...)
- **/
-
- if (on_page(msg))
- PutLine2((msg % headers_per_page) + 4, 3, "%c%c",
- ison(header_table[msg].status, DELETED)? 'D' : ' ',
- ison(header_table[msg].status, TAGGED )? '+' : ' ');
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 1863 ]
- then
- echo $filename changed - should be 1863 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/aliasdb.c ----------
-
- filename="src/aliasdb.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/aliasdb.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** aliasdb.c **/
-
- /** Alias database files...
-
- (C) Copyright 1986 Dave Taylor
- **/
-
-
- #include "headers.h"
-
- #include <sys/types.h>
- #include <sys/stat.h>
-
- char *shift_lower(), *find_path_to();
-
- findnode(name, display_error)
- char *name;
- int display_error;
- {
- /** break 'name' into machine!user or user@machine and then
- see if you can find 'machine' in the path database..
- If so, return name as the expanded address. If not,
- return what was given to us! If display_error, then
- do so...
- **/
-
- char old_name[SLEN];
- char address[SLEN];
-
- if (strlen(name) == 0)
- return;
-
- strcpy(old_name, name); /* save what we were given */
-
- if (expand_site(name, address) == -1) {
- if (display_error && name[0] != '!') {
- dprint2(2,"Couldn't expand host %s in address. (%s)\n",
- name, "findnode");
- if (! check_only) { /* be silent if just checking */
- error1("Warning: couldn't expand %s...", name);
- sleep(1);
- }
- }
- strcpy(name, old_name); /* and restore... */
- }
- else
- strcpy(name, address);
-
- return;
- }
-
- int
- expand_site(cryptic, expanded)
- char *cryptic, *expanded;
- {
-
- /** Given an address of the form 'xyz@site' or 'site!xyz'
- return an address of the form <expanded address for site>
- with 'xyz' embedded according to the path database entry.
- Note that 'xyz' can be eiher a simple address (as in "joe")
- or a complex address (as in "joe%xerox.parc@Xerox.ARPA")!
- 0 = found, -1 return means unknown site code **/
-
- #ifdef ACSNET
-
- strcpy(expanded, cryptic); /* fast and simple */
- return(0);
-
- #else
-
- char name[VERY_LONG_STRING], sitename[VERY_LONG_STRING],
- temp[VERY_LONG_STRING], old_name[VERY_LONG_STRING];
- char *expand_domain(), *addr;
- register int i = 0, j = 0, domain_name;
-
- strcpy(old_name, cryptic); /* remember what we were given */
-
- /** break down **/
-
- while (cryptic[i] != AT_SIGN && cryptic[i] != BANG &&
- cryptic[i] != '\0')
- sitename[j++] = cryptic[i++];
-
- sitename[j++] = '\0';
-
- j = 0;
-
- if (cryptic[i] == '\0') return(-1); /* nothing to expand! */
-
- domain_name = (cryptic[i] == AT_SIGN);
-
- i++;
-
- while (cryptic[i] != '\0')
- name[j++] = cryptic[i++];
-
- name[j] = '\0';
-
- if (domain_name) {
- strcpy(temp, name);
- strcpy(name, sitename);
- strcpy(sitename, temp);
- }
-
- #ifndef LOOK_CLOSE_AFTER_SEARCH
-
- if (talk_to(sitename)) {
- strcpy(expanded, old_name); /* restore! */
- return(0);
- }
- #endif
-
- if ((addr = find_path_to(sitename, TRUE)) == NULL) {
-
- #ifdef LOOK_CLOSE_AFTER_SEARCH
-
- if (talk_to(sitename)) {
- strcpy(expanded, old_name); /* restore! */
- return(0);
- }
- else
- #endif
- if ((addr = expand_domain(cryptic)) != NULL) {
- strcpy(expanded, addr); /* into THIS buffer */
- return(0);
- }
- else if (size_of_pathfd == 0) { /* no path database! */
- strcpy(expanded, old_name); /* restore! */
- return(0);
- }
- else /* We just can't get there! */
- return(-1);
- }
- else { /* search succeeded */
- sprintf(expanded, addr, name);
- return(0);
- }
- #endif
- }
-
- int
- binary_search(name, address)
- char *name, *address;
- {
- /* binary search file for name. Return 0 if found, -1 if not */
-
- char machine[40];
- register long first = 0, last, middle;
- register int compare;
-
- address[0] = '\0';
-
- last = size_of_pathfd;
-
- do {
-
- middle = (long) ((first+last) / 2);
-
- get_entry(machine, address, pathfd, middle);
-
- compare = strcmp(name, machine);
-
- if (compare < 0)
- last = middle - 1;
- else if (compare == 0)
- return(0);
- else /* greater */
- first = middle + 1;
- } while (abs(last) - abs(first) > FIND_DELTA);
-
- return(-1);
- }
-
- get_entry(machine, address, fileid, offset)
- char *machine, *address;
- FILE *fileid;
- long offset;
- {
- /** get entry...return machine and address immediately
- following given offset in fileid. **/
-
- fseek(fileid, offset, 0);
-
- /* read until we hit an end-of-line */
-
- while (getc(fileid) != '\n')
- ;
-
- fscanf(fileid, "%s\t%s", machine, address);
- }
-
- init_findnode()
- {
- /** Initialize the FILE and 'size_of_file' values for the
- findnode procedure **/
-
- struct stat buffer;
-
- if (stat(pathfile, &buffer) == -1) {
- dprint2(1, "Warning: No pathalias file [filename %s] found! (%s)\n",
- pathfile, "init_findnode");
- size_of_pathfd = 0;
- return;
- }
-
- size_of_pathfd = (long) buffer.st_size;
-
- if ((pathfd = fopen(pathfile,"r")) == NULL) {
- dprint2(1, "Warning: Can't read pathalias file [filename %s] (%s)\n",
- pathfile, "init_findnode");
- size_of_pathfd = 0;
- }
- else
- dprint2(2, "\nOpened file '%s' as path alias database. (%s)\n\n",
- pathfile, "init_findnode");
- }
-
- char *find_path_to(machine, printf_format)
- char *machine;
- int printf_format;
- {
- /** Returns either the path to the specified machine or NULL if
- not found. If "printf_format" is TRUE, then it leaves the
- '%s' intact, otherwise it assumes that the address is a uucp
- address for the domain expansion program and removes the
- last three characters of the expanded name ("!%s") since
- they're redundant with the expansion!
- **/
-
- static char buffer[LONG_SLEN]; /* space for path */
-
- if (size_of_pathfd > 0)
- if (binary_search(machine, buffer) != -1) { /* found it! */
- if (! printf_format && strlen(buffer) > 3)
- buffer[strlen(buffer)-3] = '\0';
- return( (char *) buffer);
- }
-
- return(NULL); /* failed if it's here! */
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 5484 ]
- then
- echo $filename changed - should be 5484 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- # ---------- file src/file.c ----------
-
- filename="src/file.c"
-
- if [ -f $filename ]
- then
- echo File \"$filename\" already exists\! Skipping...
- filename=/dev/null # throw it away
- else
- echo extracting file src/file.c...
- fi
-
- cat << 'END-OF-FILE' > $filename
- /** file.c **/
-
- /** File I/O routines, mostly the save to file command...
-
- (C) Copyright 1986, Dave Taylor
- **/
-
- #include "headers.h"
- #include <ctype.h>
- #include <errno.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- extern int errno;
-
- char *error_name(), *error_description();
-
- int
- save()
- {
- /** Save all tagged messages + current in a file. If no messages
- are tagged, save the current message instead! This routine
- will return ZERO if the operation failed.
- **/
-
- register int tagged = 0, i, oldstat, appending = 0;
- char filename[SLEN], address[LONG_SLEN], buffer[SLEN];
- FILE *save_file;
-
- oldstat = header_table[current-1].status; /* remember */
-
- for (i=0; i < message_count; i++)
- if (ison(header_table[i].status, TAGGED))
- tagged++;
-
- if (tagged == 0) {
- tagged = 1;
- setit(header_table[current-1].status, TAGGED);
- }
-
- dprint2(4,"%d message%s tagged for saving (save)\n", tagged,
- plural(tagged));
-
- PutLine1(LINES-2, 0, "File message%s in: ", plural(tagged));
-
- if (save_by_name) {
- /** build default filename to save to **/
- get_return(address);
- get_return_name(address, buffer, FALSE);
- sprintf(filename, "=%s", buffer);
- }
- else
- filename[0] = '\0';
-
- if (tagged > 1)
- optionally_enter(filename, LINES-2, 19, FALSE);
- else
- optionally_enter(filename, LINES-2, 18, FALSE);
-
- MoveCursor(LINES-1,0);
-
- if (strlen(filename) == 0) { /** <return> means 'cancel', right? **/
- header_table[current-1].status = oldstat; /* BACK! */
- return(0);
- }
-
- if (! expand_filename(filename)) {
- dprint1(2,"Error: Failed on expansion of filename %s (save)\n",
- filename);
- header_table[current-1].status = oldstat; /* BACK! */
- return(0); /* failed expanding name! */
- }
-
- if (access(filename,ACCESS_EXISTS)) /* already there!! */
- appending = 1;
-
- if ((errno = can_open(filename, "a"))) {
- error1("Wrong permissions to save message to file %s!", filename);
- dprint2(2,"Error: access permission on file %s denied (%s)! (save)\n",
- filename, error_name(errno));
- header_table[current-1].status = oldstat; /* BACK! */
- return(0);
- }
-
- dprint1(4,"Saving mail to file '%s'...\n", filename);
-
- if ((save_file = fopen(filename,"a")) == NULL) {
- dprint1(2, "Error: couldn't append to specified file %s (save)\n",
- filename);
- error1("Couldn't append to file %s!", filename);
- header_table[current-1].status = oldstat; /* BACK! */
- return(0);
- }
-
- for (i=0; i < message_count; i++) /* save each tagged msg */
- if (header_table[i].status & TAGGED)
- save_message(i, filename, save_file, (tagged > 1), appending++);
-
- fclose(save_file);
-
- chown(filename, userid, groupid); /* owned by user */
- if (tagged > 1)
- error1("Message%s saved", plural(tagged));
- return(1);
- }
-
- int
- save_message(number, filename, fd, pause, appending)
- int number, pause, appending;
- char *filename;
- FILE *fd;
- {
- /** Save an actual message to a file. This is called by
- "save()" only! The parameters are the message number,
- and the name and file descriptor of the file to save to.
- If 'pause' is true, a sleep(2) will be done after the
- saved message appears on the screen...
- 'appending' is only true if the file already exists
- **/
-
- register int save_current;
-
- dprint1(4, "\tSaving message %d to file...\n", number);
-
- save_current = current;
- current = number+1;
- copy_message("", fd, FALSE, FALSE);
- current = save_current;
-
- if (resolve_mode)
- setit(header_table[number].status, DELETED); /* deleted, but ... */
- clearit(header_table[number].status, TAGGED); /* not tagged anymore */
- clearit(header_table[number].status, NEW); /* it's not new now! */
-
- if (! appending) /* don't ask */
- error2("Message %d appended to file %s", number+1, filename);
- else
- error2("Message %d saved to file %s", number+1, filename);
-
- show_new_status(number); /* update screen, if needed */
-
- if (pause) sleep(2);
- }
-
- int
- expand_filename(filename)
- char *filename;
- {
- /** Expands '~' and '=' to specified file names, also will try to
- expand shell variables if encountered.. '+' and '%' are synonymous
- with '=' (folder dir)... **/
-
- char buffer[SLEN], varname[SLEN], env_value[SLEN];
- register int i = 1, index = 0;
-
- /** new stuff - make sure no illegal char as last **/
-
- if (lastch(filename) == '\n' || lastch(filename) == '\r')
- lastch(filename) = '\0';
-
- if (filename[0] == '~') {
- sprintf(buffer, "%s%s%s", home,
- (filename[1] != '/' && lastch(folders) != '/')? "/" : "",
- (char *) filename + 1);
- strcpy(filename, buffer);
- }
- else if (filename[0] == '=' || filename[0] == '+' ||
- filename[0] == '%') {
- if (strlen(folders) == 0) {
- dprint2(3,"Error: maildir not defined - can't expand '%c' (%s)\n",
- filename[0], "expand_filename");
- error1("MAILDIR not defined. Can't expand '%c'", filename[0]);
- return(0);
- }
- sprintf(buffer, "%s%s%s", folders,
- (filename[1] != '/' && lastch(folders) != '/')? "/" : "",
- (char *) filename + 1);
- strcpy(filename, buffer);
- }
- else if (filename[0] == '$') { /* env variable! */
- while (isalnum(filename[i]))
- varname[index++] = filename[i++];
- varname[index] = '\0';
-
- #ifdef SUN
- env_value[0] = '\0'; /* null string for strlen! */
- if (getenv(varname) != NULL)
- #endif
- strcpy(env_value, getenv(varname));
-
- if (strlen(env_value) == 0) {
- dprint2(3,"Error: Can't expand environment variable $%s (%s)\n",
- varname, "expand_filename");
- error1("Don't know what the value of $%s is!", varname);
- return(0);
- }
-
- sprintf(buffer, "%s%s%s", env_value,
- (filename[i] != '/' && lastch(env_value) != '/')? "/" : "",
- (char *) filename + i);
- strcpy(filename, buffer);
- }
-
- return(1);
- }
- END-OF-FILE
-
- if [ "$filename" != "/dev/null" ]
- then
- size=`wc -c < $filename`
-
- if [ $size != 5704 ]
- then
- echo $filename changed - should be 5704 bytes, not $size bytes
- fi
-
- chmod 644 $filename
- fi
-
- echo end of this archive file....
- exit 0
-
-