home *** CD-ROM | disk | FTP | other *** search
- From: decvax!hplabs!hpcnou!dat (Dave Taylor)
- Subject: Msg Shar.part.3
- Newsgroups: mod.sources
- Approved: jpn@panda.UUCP
-
- Mod.sources: Volume 4, Issue 7
- Submitted by: decvax!hplabs!hpcnou!dat (Dave Taylor)
-
- # Msg Shar part 3 of 7
-
- # Shell Archive created by hpcnou!dat at Wed Feb 26 15:56:06 1986
-
- # 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
-
- # This archive contains;
- # src/addr_utils.c src/alias.c src/aliasdb.c src/aliaslib.c
- # src/args.c src/curses.c src/date.c src/delete.c
- # src/encode.c src/file.c
-
-
- if [ ! -d src ]
- then
- echo creating directory src
- mkdir src
- fi
-
- # ---------- file src/addr_utils.c ----------
-
-
- if [ -f src/addr_utils.c ]
- then
- echo File 'src/addr_utils.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/addr_utils.c...
- cat << 'END-OF-FILE' > src/addr_utils.c
- /** addr_utils.c **/
-
- /** This file contains addressing utilities
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <ctype.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- char *shift_lower(), *get_alias_address(), *get_token();
-
- int
- talk_to(sitename)
- char *sitename;
- {
- /** If we talk to the specified site, return true, else
- we're going to have to expand this baby out, so
- return false! **/
-
- struct lsys_rec *sysname;
-
- dprint1("talk-to(sitename='%s')\n", sitename);
-
- sysname = talk_to_sys;
-
- if (sysname == NULL) {
- dprint0("\tWarning: talk_to_sys is currently set to NULL!\n");
- return(0);
- }
-
- while (sysname != NULL) {
- if (strcmp(sysname->name, sitename) == 0)
- return(1);
- else
- sysname = sysname->next;
- }
-
- return(0);
- }
-
- remove_domains(host)
- char *host;
- {
- /** Remove all entries following the first '.' to ensure that
- entries like "MIT.ARPA" will match "MIT" in the database
- **/
-
- register int loc = 0;
-
- dprint1("remove_domains(host='%s')\n", host);
-
- while (host[loc] != '.' && host[loc] != '\0')
- loc++;
-
- if (host[loc] == '.') host[loc] = '\0';
- }
-
- add_site(buffer, site, lastsite)
- char *buffer, *site, *lastsite;
- {
- /** add site to buffer, unless site is 'uucp', current machine, or
- site is the same as lastsite. If not, set lastsite to
- site.
- **/
-
- char local_buffer[LONG_SLEN];
-
- dprint3("add_site(buffer='%s', site='%s', lastsite='%s')\n",
- buffer, site, lastsite);
-
- if (strcmp(site, "uucp") != 0)
- if (strcmp(site, lastsite) != 0)
- if (strcmp(site, hostname) != 0) {
- if (buffer[0] == '\0')
- strcpy(buffer, strip_parens(site)); /* first in list! */
- else {
- sprintf(local_buffer,"%s!%s", buffer, strip_parens(site));
- strcpy(buffer, local_buffer);
- }
- strcpy(lastsite, strip_parens(site)); /* don't want THIS twice! */
- }
- }
-
- #ifdef USE_EMBEDDED_ADDRESSES
-
- get_address_from(prefix, line, buffer)
- char *prefix, *line, *buffer;
- {
- /** This routine extracts the address from either a 'From:' line
- or a 'Reply-To:' line...the algorithm is quite simple, too:
- increment 'line' past header, then check last character of
- line. If it's a '>' then the address is contained within '<>'
- and if it's a ')' then the address is in the 'clear'... **/
-
- register int i, j = 0;
-
- no_ret(line);
-
- dprint2("get_address_from(prefix='%s', line='%s', <buffer>)\n",
- prefix, line);
-
- line = (char *) (line + strlen(prefix) + 1);
-
- if (line[strlen(line)-1] == '>') {
- for (i=strlen(line)-2; i > -1 && line[i] != '<'; i--)
- buffer[j++] = line[i];
- buffer[j] = 0;
- reverse(buffer);
- }
- else { /* either ')' or address in the clear... */
- for (i=0; i < strlen(line) && line[i] != '('; i++)
- buffer[j++] = line[i];
- if (buffer[j-1] == '(') j--;
- buffer[j] = 0;
- }
- }
-
- #endif
-
- translate_return(addr, ret_addr)
- char *addr, *ret_addr;
- {
- /** Return ret_addr to be the same as addr, but with the login
- of the person sending the message replaced by '%s' for
- future processing...
- Fixed to make "%xx" "%%xx" (dumb 'C' system!)
- **/
-
- register int loc, loc2, index = 0;
-
- dprint1("translate_return(addr='%s', <return buffer>)\n", addr);
-
- loc2 = chloc(addr,'@');
- if ((loc = chloc(addr, '%')) < loc2)
- loc2 = loc;
-
- if (loc2 != -1) { /* ARPA address. */
- /* algorithm is to get to '@' sign and move backwards until
- we've hit the beginning of the word or another metachar.
- */
- for (loc = loc2 - 1; loc > -1 && addr[loc] != '!'; loc--)
- ;
- }
- else { /* usenet address */
- /* simple algorithm - find last '!' */
-
- loc2 = strlen(addr); /* need it anyway! */
-
- for (loc = loc2; loc > -1 && addr[loc] != '!'; loc--)
- ;
- }
-
- /** now copy up to 'loc' into destination... **/
-
- while (index <= loc) {
- ret_addr[index] = addr[index];
- index++;
- }
-
- /** now append the '%s'... **/
-
- ret_addr[index++] = '%';
- ret_addr[index++] = 's';
-
- /** and, finally, if anything left, add that **/
-
- while (loc2 < strlen(addr)) {
- ret_addr[index++] = addr[loc2++];
- if (addr[loc2-1] == '%') /* tweak for "printf" */
- ret_addr[index++] = '%';
- }
-
- ret_addr[index] = '\0';
-
- dprint1("\treturning address: '%s'\n", ret_addr);
- }
-
- build_address(to, full_to)
- char *to, *full_to;
- {
- /** loop on all words in 'to' line...append to full_to as
- we go along, until done or length > len **/
-
- register int i, changed = 0;
- char word[SLEN], *ptr, buffer[SLEN];
- char new_to_list[LONG_SLEN];
-
- dprint1("build_address(to='%s', <buffer>)\n", to);
-
- new_to_list[0] = '\0';
-
- i = get_word(to, 0, word);
-
- full_to[0] = '\0';
-
- while (i > 0) {
-
- if (strpbrk(word,"!@:") != NULL)
- sprintf(full_to, "%s%s%s", full_to,
- full_to[0] != '\0'? ", " : "", expand_system(word, 1));
- else if ((ptr = get_alias_address(word, 1, 0)) != NULL)
- sprintf(full_to, "%s%s%s", full_to,
- full_to[0] != '\0'? ", " : "", ptr);
- else if (strlen(word) > 0) {
- if (valid_name(word))
- sprintf(full_to, "%s%s%s", full_to,
- full_to[0] != '\0'? ", " : "", word);
- else if (check_only) {
- printf("(alias \"%s\" is unknown)\n\r",
- word);
- changed++;
- }
- else if (! isatty(fileno(stdin)) ) { /* batch mode error! */
- fprintf(stderr,"Cannot expand alias '%s'!\n\r", word);
- fprintf(stderr,"Use \"checkalias\" to find valid addresses!\n\r");
- leave(1);
- }
- else {
- dprint1("-- Unknown address '%s'\n", buffer);
- sprintf(buffer, "'%s' is an unknown address. Replace with: ",
- word);
- word[0] = '\0';
- if (mail_only)
- printf("%s", buffer);
- else
- PutLine(LINES, 0, buffer);
-
- (void) optionally_enter(word, LINES, strlen(buffer), FALSE);
- if (strlen(word) > 0)
- sprintf(new_to_list, "%s%s%s", new_to_list,
- strlen(new_to_list) > 0? " ":"", word);
- if (mail_only) printf("\n\r");
- changed++;
- clear_error();
- continue;
- }
- }
-
- i = get_word(to, i, word);
- }
-
- if (changed)
- strcpy(to, new_to_list);
- }
-
- int
- real_from(buffer, entry)
- char *buffer;
- struct header_rec *entry;
- {
- /***** Returns true iff 's' has the seven 'from' fields, (or
- 8 - some machines include the TIME ZONE!!!)
- Initializing the date and from entries in the record
- and also the message received date/time. *****/
-
- char junk[SLEN], timebuff[SLEN];
- int eight_fields = 0;
-
- dprint1("real_from(buffer='%s', <header_rec>)\n", buffer);
-
- entry->year[0] = '\0';
- junk[0] = '\0';
-
- /* From <user> <day> <month> <day> <hr:min:sec> <year> */
-
- sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %s", timebuff, junk);
-
- if (timebuff[1] != ':' && timebuff[2] != ':')
- return(FALSE);
- if (junk[0] != '\0') { /* try for 8 field entry */
- junk[0] = '\0';
- sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %*s %s", timebuff, junk);
- if (junk[0] != '\0')
- return(FALSE);
- eight_fields++;
- }
-
- /** now get the info out of the record! **/
-
- if (eight_fields)
- sscanf(buffer, "%s %s %s %s %s %s %*s %s",
- junk, entry->from, entry->dayname, entry->month,
- entry->day, entry->time, entry->year);
- else
- sscanf(buffer, "%s %s %s %s %s %s %s",
- junk, entry->from, entry->dayname, entry->month,
- entry->day, entry->time, entry->year);
-
- resolve_received(entry);
- return(entry->year[0] != '\0');
- }
-
- forwarded(buffer, entry)
- char *buffer;
- struct header_rec *entry;
- {
- /** change 'from' and date fields to reflect the ORIGINATOR of
- the message by iteratively parsing the >From fields...
- Modified to deal with headers that include the time zone
- of the originating machine... **/
-
- char machine[SLEN], buff[SLEN];
-
- dprint1("forwarded(buffer='%s', <header_rec>)\n", buffer);
-
- machine[0] = '\0';
-
- sscanf(buffer, "%*s %s %s %s %s %s %s %*s %*s %s",
- entry->from, entry->dayname, entry->month,
- entry->day, entry->time, entry->year, machine);
-
- if (isdigit(entry->month[0])) { /* try for veeger address */
- sscanf(buffer, "%*s %s %s%*c %s %s %s %s %*s %*s %s",
- entry->from, entry->dayname, entry->day, entry->month,
- entry->year, entry->time, machine);
- }
- if (isalpha(entry->year[0])) { /* try for address including tz */
- sscanf(buffer, "%*s %s %s %s %s %s %*s %s %*s %*s %s",
- entry->from, entry->dayname, entry->month,
- entry->day, entry->time, entry->year, machine);
- }
-
-
- if (machine[0] == '\0')
- sprintf(buff,"anonymous");
- else
- sprintf(buff,"%s!%s", machine, entry->from);
-
- strncpy(entry->from, buff, SLEN);
- }
-
- parse_arpa_from(buffer, newfrom)
- char *buffer, *newfrom;
- {
- /** try to parse the 'From:' line given... It can be in one of
- two formats:
- From: Dave Taylor <hpcnou!dat>
- or From: hpcnou!dat (Dave Taylor)
- Change 'newfrom' ONLY if sucessfully parsed this entry and
- the resulting name is non-null!
- Added: removes quotes if name is quoted (12/12)
- **/
-
- char temp_buffer[SLEN], *temp;
- register int i, j = 0;
-
- dprint1("parse_arpa_from(buffer='%s', <old from>)\n", buffer);
-
- temp = (char *) temp_buffer;
- temp[0] = '\0';
-
- no_ret(buffer); /* blow away '\n' char! */
-
- if (lastch(buffer) == '>') {
- for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
- buffer[i] != '('; i++)
- temp[j++] = buffer[i];
- temp[j] = '\0';
- }
- else if (lastch(buffer) == ')') {
- for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
- buffer[i] != '<'; i--)
- temp[j++] = buffer[i];
- temp[j] = '\0';
- reverse(temp);
- }
-
- if (strlen(temp) > 0) { /* mess with buffer... */
-
- /* remove leading spaces and quotes... */
-
- while (whitespace(temp[0]) || quote(temp[0]))
- temp = (char *) (temp + 1); /* increment address! */
-
- /* remove trailing spaces and quotes... */
-
- i = strlen(temp) - 1;
-
- while (whitespace(temp[i]) || quote(temp[i]))
- temp[i--] = '\0';
-
- /* if anything is left, let's change 'from' value! */
-
- if (strlen(temp) > 0)
- strcpy(newfrom, temp);
- }
- }
-
- parse_arpa_date(string, entry)
- char *string;
- struct header_rec *entry;
- {
- /** Parse and figure out the given date format... return
- the entry fields changed iff it turns out we have a
- valid parse of the date! **/
-
- char word[15][NLEN], buffer[SLEN], *bufptr;
- char *aword, *strtok();
- int words = 0;
-
- dprint1("parse_arpa_date(string='%s', <header_rec>)\n", string);
-
- strcpy(buffer, string);
- bufptr = (char *) buffer;
-
- /** break the line down into words... **/
-
- while ((aword = strtok(bufptr," \t '\"-/(),.")) != NULL) {
- strcpy(word[words++], aword);
- bufptr = NULL;
- }
-
- if (words < 6) /* strange format. We're outta here! */
- return;
-
- /* There are now five possible combinations that we could have:
-
- Date: day_number month_name year_number time timezone
- Date: day_name day_number month_name year_number ...
- Date: day_name month_name day_number time year_number
- Date: day_name month_name day_number year_number time
- Date: day_number month_name year_number time timezone day_name
-
- Note that they are distinguishable by checking the first
- character of the second, third and fourth words...
- */
-
- if (isdigit(word[1][0])) { /*** type one! ***/
- if (! valid_date(word[1], word[2], word[3]))
- return; /* strange date! */
- strncpy(entry->day, word[1], 3);
- strncpy(entry->month, word[2], 3);
- strncpy(entry->year, word[3], 4);
- strncpy(entry->time, word[4], 10);
- }
- else if (isdigit(word[2][0])) { /*** type two! ***/
- if (! valid_date(word[2], word[3], word[4]))
- return; /* strange date! */
- strncpy(entry->day, word[2], 3);
- strncpy(entry->month, word[3], 3);
- strncpy(entry->year, word[4], 4);
- strncpy(entry->time, word[5], 10);
- }
- else if (isdigit(word[3][0])) {
- if (word[4][1] == ':' ||
- word[4][2] == ':') { /*** type three! ***/
- if (! valid_date(word[3], word[2], word[5]))
- return;
- strncpy(entry->year, word[5], 4);
- strncpy(entry->time, word[4], 10);
- }
- else { /*** type four! ***/
- if (! valid_date(word[3], word[2], word[4]))
- return;
- strncpy(entry->year, word[4], 4);
- strncpy(entry->time, word[5], 10);
- }
- strncpy(entry->day, word[3], 3);
- strncpy(entry->month, word[2], 3);
- }
- }
-
- fix_arpa_address(address)
- char *address;
- {
- /** Given a pure ARPA address, try to make it reasonable.
-
- This means that if you have something of the form a@b@b make
- it a@b. If you have something like a%b%c%b@x make it a%b@x...
- **/
-
- register int host_count = 0, i;
- char hosts[MAX_HOPS][2*NLEN]; /* array of machine names */
- char *host, *addrptr;
-
- dprint1("fix_arpa_address(%s)\n", address);
-
- /* break down into a list of machine names, checking as we go along */
-
- addrptr = (char *) address;
-
- while ((host = get_token(addrptr, "%@", 2)) != NULL) {
- for (i = 0; i < host_count && ! equal(hosts[i], host); i++)
- ;
-
- if (i == host_count) {
- strcpy(hosts[host_count++], host);
- if (host_count == MAX_HOPS) {
- error("Can't build return address - hit MAX_HOPS limit!");
- return(1);
- }
- }
- else
- host_count = i + 1;
- addrptr = NULL;
- }
-
- /** rebuild the address.. **/
-
- address[0] = '\0';
-
- for (i = 0; i < host_count; i++)
- sprintf(address, "%s%s%s", address,
- address[0] == '\0'? "" :
- (i == host_count - 1 ? "@" : "%"),
- hosts[i]);
-
- dprint1("\tmodified to address '%s'\n", address);
-
- return(0);
- }
- END-OF-FILE
-
- size=`wc -c < src/addr_utils.c`
-
- if [ $size != 13730 ]
- then
- echo Warning: src/addr_utils.c changed - should be 13730 bytes, not $size bytes
- fi
-
- chmod 644 src/addr_utils.c
-
- # ---------- file src/alias.c ----------
-
-
- if [ -f src/alias.c ]
- then
- echo File 'src/alias.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/alias.c...
- cat << 'END-OF-FILE' > src/alias.c
- /** alias.c **/
-
- /** This file contains alias stuff
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- char *expand_group(), *get_alias_address(), *expand_system(), *get_token();
-
- read_alias_files()
- {
- /** read the system and user alias files, if present.
- Set the flags 'systemfiles' and 'userfiles' accordingly.
- **/
-
- char fname[SLEN];
- int hash;
-
- dprint0("read_alias_files()\n");
-
- if ((hash = open(system_hash_file, O_RDONLY)) == -1)
- 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)
- goto user;
-
- system_files++; /* got the system files! */
-
- user: sprintf(fname, "%s/.alias_hash", home);
-
- if ((hash = open(fname, O_RDONLY)) == -1)
- 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)
- 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];
-
- dprint0("add_alias()\n");
-
- PutLine(LINES-2,0,"Enter alias name: ");
- CleartoEOLN();
- Raw(OFF);
- gets(name, 20);
- Raw(ON);
- if ((address = (char *) get_alias_address(name, 0, 0)) != NULL) {
- 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);
- }
- PutLine(LINES-2,0,"Full name for %s: ", name);
- CleartoEOLN();
- Raw(OFF);
- gets(comment,SLEN);
- Raw(ON);
- PutLine(LINES-2,0,"Enter address for %s: ",name);
- CleartoEOLN();
- Raw(OFF);
- gets(address1,LONG_SLEN);
- Raw(ON);
- 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];
-
- dprint0("add_current_alias()\n");
-
- if (current == 0) {
- error("No message to alias to!");
- return(0);
- }
-
- PutLine(LINES-2,0,"Current message address aliased to: ");
- CleartoEOLN();
- Raw(OFF);
- gets(name, 20);
- Raw(ON);
- if ((address = (char *) get_alias_address(name, 0, 0)) != NULL) {
- 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);
- }
- PutLine(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);
- PutLine(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... **/
-
- FILE *file;
- char fname[SLEN];
-
- dprint3("add_to_alias_text(name='%s', comment='%s', address='%s')\n",
- name, comment, address);
-
- sprintf(fname,"%s/.alias_text", home);
-
- if ((file = fopen(fname, "a")) == NULL)
- return(error1("couldn't open %s to add new alias!", fname));
-
- fprintf(file,"%s : %s : %s\n", name, comment, address);
- fclose(file);
-
- chown(fname, userid, getgid());
-
- return(0);
- }
-
- show_alias_menu()
- {
- MoveCursor(LINES-7,0); CleartoEOLN();
- MoveCursor(LINES-6,0); CleartoEOLN();
- MoveCursor(LINES-5,0); CleartoEOLN();
-
- PutLine(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;
-
- dprint0("alias()\n");
-
- if (mini_menu)
- show_alias_menu();
-
- define_softkeys(ALIAS);
-
- while (1) {
- PutLine(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!");
- PutLine(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] = ' ';
- PutLine(LINES-1,0,"Group alias:%-65.65s", address);
- CleartoEOLN();
- }
- else
- PutLine(LINES-1,0,"Aliased addresss: %-65.65s",
- address);
- }
- else
- error("not found");
- break;
-
- case 's': PutLine(LINES-2,0,"Check for system: ");
- CleartoEOS();
- Raw(OFF);
- gets(name,NLEN);
- Raw(ON);
- sprintf(buffer, "(user)@%s", name);
- address = (char *) expand_system(buffer, 0, FALSE);
- if (strlen(address) > strlen(name) + 7)
- PutLine(LINES-1,0,"Address is: %.65s", address);
- else
- error1("couldn't expand system '%s'", name);
- break;
-
- case '@': PutLine(LINES-2,0,"Fully expand alias: ");
- CleartoEOS();
- Raw(OFF);
- gets(name,NLEN);
- Raw(ON);
- if ((address = get_alias_address(name, 1, 0)) != NULL) {
- ClearScreen();
- PutLine(3,0,"Aliased address:\n\r%s", address);
- PutLine(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!
- **/
-
- dprint0("install_aliases()\n");
-
- error("Adding new aliases...");
- if (system_call(newalias, SH) == 0) {
- error("Re-reading the database in...");
- read_alias_files();
- set_error("New aliases installed successfully");
- }
- else
- set_error("'newalias' failed. Please check alias_text");
- }
- END-OF-FILE
-
- size=`wc -c < src/alias.c`
-
- if [ $size != 6455 ]
- then
- echo Warning: src/alias.c changed - should be 6455 bytes, not $size bytes
- fi
-
- chmod 644 src/alias.c
-
- # ---------- file src/aliasdb.c ----------
-
-
- if [ -f src/aliasdb.c ]
- then
- echo File 'src/aliasdb.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/aliasdb.c...
- cat << 'END-OF-FILE' > src/aliasdb.c
- /** aliasdb.c **/
-
- /** Alias database files...
-
- (C) Copyright 1986 Dave Taylor
- **/
-
-
- #include "headers.h"
-
- #include <sys/types.h>
- #include <sys/stat.h>
-
- char *shift_lower();
-
- 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 address[SLEN];
-
- dprint2("findnode(name='%s', display_error=%s)\n",
- name, display_error? "ON" : "OFF");
-
- if (strlen(name) == 0)
- return;
-
- if (expand_site(name, address) == -1) {
- if (display_error && name[0] != '!') {
- error1("Warning: couldn't expand %s...", name);
- sleep(1);
- }
- }
- 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 **/
-
- char name[VERY_LONG_STRING], sitename[VERY_LONG_STRING],
- address[VERY_LONG_STRING], temp[VERY_LONG_STRING];
- register int i = 0, j = 0, domain_name;
-
- dprint1("expand_site(cryptic='%s', <expanded>)\n", cryptic);
-
- /** break down **/
-
- while (cryptic[i] != '@' && cryptic[i] != '!' && 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] == '@');
-
- i++;
-
- while (cryptic[i] != '\0')
- name[j++] = cryptic[i++];
-
- name[j] = '\0';
-
- if (domain_name) {
- strcpy(temp, name);
- strcpy(name, sitename);
- strcpy(sitename, temp);
- }
-
- if (talk_to(sitename)) {
- sprintf(expanded,"%s!%s", sitename, name);
- return(0);
- }
-
- if (size_of_pathfd > 0) {
- if (binary_search(sitename, address) == -1)
- return(-1);
- }
- else {
- sprintf(expanded,"%s!%s", sitename, name);
- return(0);
- }
-
- /* otherwise... */
-
- sprintf(expanded, address, name);
- return(0);
- }
-
- int
- binary_search(name, address)
- char *name, *address;
- {
- /* binary search file for name. Return 0 if found, -1 if not */
-
- char machine[20];
- register long first = 0, last, middle;
- register int compare;
-
- dprint1("binary_search(name='%s', <address>)\n", name);
-
- 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, 0L);
-
- /* 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;
-
- dprint0("init_findnode()\n");
-
- if (stat(pathfile, &buffer) == -1) {
- dprint1("\tWarning: No pathalias file '%s' found!\n", pathfile);
- size_of_pathfd = 0;
- return;
- }
-
- size_of_pathfd = buffer.st_size;
-
- if ((pathfd = fopen(pathfile,"r")) == NULL) {
- dprint1("\tFound pathalias file '%s' but couldn't open to read\n",
- pathfile);
- size_of_pathfd = 0;
- }
- else
- dprint1("\tOpened file '%s' as path alias database\n", pathfile);
- }
- END-OF-FILE
-
- size=`wc -c < src/aliasdb.c`
-
- if [ $size != 3888 ]
- then
- echo Warning: src/aliasdb.c changed - should be 3888 bytes, not $size bytes
- fi
-
- chmod 644 src/aliasdb.c
-
- # ---------- file src/aliaslib.c ----------
-
-
- if [ -f src/aliaslib.c ]
- then
- echo File 'src/aliaslib.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/aliaslib.c...
- cat << 'END-OF-FILE' > src/aliaslib.c
- /** aliaslib.c **/
-
- /** Library of functions dealing with the alias system...
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- char *expand_group(), *get_alias_address(), *expand_system();
- char *get_token();
-
- char *get_alias_address(name, mailing, depth)
- char *name;
- int mailing, depth;
- {
- /** return the line from either datafile that corresponds
- to the specified name. If 'mailing' specified, then
- fully expand group names. Depth specifies the nesting
- depth - the routine should always initially be called
- with this equal 0. Returns NULL if not found **/
-
- static char buffer[VERY_LONG_STRING];
- int loc;
-
- dprint3("get_alias_address(name='%s', mailing=%s, depth=%d)\n",
- name, mailing? "ON" : "OFF", depth);
-
- if (strlen(name) == 0)
- return( (char *) NULL);
-
- if (user_files)
- if ((loc = find(name, user_hash_table, MAX_UALIASES)) >= 0) {
- lseek(user_data, user_hash_table[loc].byte, 0L);
- get_line(user_data, buffer);
- if (buffer[0] == '!' && mailing)
- return( (char *) expand_group(buffer, depth));
- else
- return( (char *) expand_system(buffer, depth, TRUE));
- }
-
- if (system_files)
- if ((loc = find(name, system_hash_table, MAX_SALIASES)) >= 0) {
- lseek(system_data, system_hash_table[loc].byte, 0L);
- get_line(system_data, buffer);
- if (buffer[0] == '!' && mailing)
- return( (char *) expand_group(buffer, depth));
- else
- return( (char *) expand_system(buffer, depth, TRUE));
- }
-
- return( (char *) NULL);
- }
-
- char *expand_system(buffer, depth, show_errors)
- char *buffer;
- int depth, show_errors;
- {
- /** This routine will check the first machine name in the
- given path (if any) and expand it out if it is an
- alias...if not, it will return what it was given.
- If show_errors is false, it won't display errors
- encountered...
- **/
-
- dprint2("expand_system(buffer='%s', show_errors=%s)\n",
- buffer, show_errors? "ON" : "OFF");
-
- findnode(buffer, show_errors);
-
- return( (char *) buffer);
- }
-
- char *expand_group(members, depth)
- char *members;
- int depth;
- {
- /** Given a group of names separated by commas, this routine
- will return a string that is the full addresses of each
- member separated by spaces. Depth is an internal counter
- that keeps track of the depth of nesting that the routine
- is in...it's for the get_token routine! **/
-
- static char buffer[VERY_LONG_STRING];
- char buf[LONG_STRING], *word, *address, *bufptr;
-
- dprint2("expand_group(members='%s', depth=%d)\n", members, depth);
-
- strcpy(buf, members); /* parameter safety! */
- buffer[0] = '\0'; /* nothing in yet! */
- bufptr = (char *) buf; /* grab the address */
- depth++; /* one deeper! */
-
- while ((word = get_token(bufptr, "!, ", depth)) != NULL) {
- if ((address = get_alias_address(word, 1, depth)) == NULL) {
- if (! valid_name(word)) {
- error1("%s is an illegal address!", word);
- return( (char *) NULL);
- }
- else if (strcmp(buffer, word) != 0)
- sprintf(buffer, "%s%s%s", buffer,
- (strlen(buffer) > 0)? ", ":"", word);
- }
- else if (strcmp(buffer, address) != 0)
- sprintf(buffer,"%s%s%s", buffer,
- (strlen(buffer) > 0)? ", ":"", address);
-
- bufptr = NULL;
- }
-
- return( (char *) buffer);
- }
-
- int
- find(word, table, size)
- char *word;
- struct alias_rec table[];
- int size;
- {
- /** find word and return loc, or -1 **/
- register int loc;
-
- if (strlen(word) > 20)
- exit(printf("Bad alias name: %s. Too long.\n", word));
-
- loc = hash_it(word, size);
-
- while (strcmp(word, table[loc].name) != 0) {
- if (table[loc].name[0] == '\0')
- return(-1);
- loc = (loc + 1) % size;
- }
-
- return(loc);
- }
-
- int
- hash_it(string, table_size)
- char *string;
- int table_size;
- {
- /** compute the hash function of the string, returning
- it (mod table_size) **/
-
- register int i, sum = 0;
-
- for (i=0; string[i] != '\0'; i++)
- sum += (int) string[i];
-
- return(sum % table_size);
- }
-
- get_line(fd, buffer)
- int fd;
- char *buffer;
- {
- /* read from file fd. End read upon reading either
- EOF or '\n' character (this is where it differs
- from a straight 'read' command!) */
-
- register int i= 0;
- char ch;
-
- while (read(fd, &ch, 1) > 0)
- if (ch == '\n' || ch == '\r') {
- buffer[i] = 0;
- return;
- }
- else
- buffer[i++] = ch;
- }
- END-OF-FILE
-
- size=`wc -c < src/aliaslib.c`
-
- if [ $size != 4347 ]
- then
- echo Warning: src/aliaslib.c changed - should be 4347 bytes, not $size bytes
- fi
-
- chmod 644 src/aliaslib.c
-
- # ---------- file src/args.c ----------
-
-
- if [ -f src/args.c ]
- then
- echo File 'src/args.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/args.c...
- cat << 'END-OF-FILE' > src/args.c
-
- /** args.c **/
-
- /** starting argument parsing routines for MSG system...
-
- (C) Copyright 1986 Dave Taylor
- **/
-
- #include "headers.h"
-
- #define DONE 0
- #define ERROR -1
-
- char *optional_arg; /* optional argument as we go */
- int opt_index; /* argnum + 1 when we leave */
-
- parse_arguments(argc, argv, to_whom)
- int argc;
- char *argv[], *to_whom;
- {
- /** set flags according to what was given to program. If we are
- fed a name or series of names, put them into the 'to_whom' buffer
- and set "mail_only" to TRUE **/
-
- register char c = 0;
-
- infile[0] = '\0';
- to_whom[0] = '\0';
- batch_subject[0] = '\0';
-
- while ((c = get_options(argc, argv, "?cdf:hkmsS:z")) > 0) {
- switch (c) {
- case 'c' : check_only++; break;
- case 'd' : debug++; break;
- case 'f' : strcpy(infile, optional_arg);
- mbox_specified = 2; break;
- case '?' :
- case 'h' : args_help();
- case 'k' : hp_terminal++; break;
- case 'm' : mini_menu = 0; break;
- case 's' : hp_softkeys++; break;
- case 'S' : strcpy(batch_subject, optional_arg); break;
- case 'z' : check_mailfile_size(); break;
- }
- }
-
- if (c == ERROR) {
- printf("Usage: msg [cdhkmsz] [-f file] [-S subject] <names>\n\n");
- args_help();
- }
-
- if (opt_index < argc)
- while (opt_index < argc) {
- sprintf(to_whom, "%s%s%s", to_whom,
- to_whom[0] != '\0'? " " : "", argv[opt_index]);
- mail_only++;
- opt_index++;
- }
-
- if (strlen(batch_subject) > 0 && ! mail_only)
- exit(printf(
- "\n\rDon't understand specifying a subject and no-one to send to!\n\r"));
-
- if (! isatty(fileno(stdin)) && strlen(batch_subject) == 0)
- strcpy(batch_subject, DEFAULT_BATCH_SUBJECT);
-
- }
-
- args_help()
- {
- /** print out possible starting arguments... **/
-
- printf("\nPossible Starting Arguments for MSG program:\n\n");
- printf("\targ\t\t\tMeaning\n");
- printf("\t -c \t\tCheckalias - check the given aliases only\n");
- printf("\t -d \t\tDebug - turn on debug mode (output to file)\n");
- printf("\t -f \t\tFile - read file (specified) rather than mailbox\n");
- printf("\t -h \t\tHelp - give this list of options\n");
- printf("\t -k \t\tKeypad - force knowledge of HP terminal keyboard\n");
- printf("\t -m \t\tMenu - Turn off menu, using more of the screen\n");
- printf("\t -s \t\tSoftkeys - enable use of softkeys\n");
- printf("\t -z \t\tZero - don't enter MSG if no mail is pending\n");
- printf("\n");
- printf("\t -S \t\tSubject - for batchmailing, combined with address\n");
- printf("\n");
- exit(1);
- }
-
- int _indx = 1, _argnum = 1;
-
- int
- get_options(argc, argv, options)
- int argc;
- char *argv[], *options;
- {
- /** Returns the character argument next, and optionally instantiates
- "argument" to the argument associated with the particular option
- **/
-
- char *word, *strchr();
-
- if (_indx >= strlen(argv[_argnum])) {
- _argnum++;
- _indx = 1; /* zeroeth char is '-' */
- }
-
- if (_argnum >= argc) {
- opt_index = argc;
- return(DONE);
- }
-
- if (argv[_argnum][0] != '-') {
- opt_index = _argnum;
- return(DONE);
- }
-
- word = strchr(options, argv[_argnum][_indx++]);
-
- if (strlen(word) == 0)
- return(ERROR);
-
- if (word[1] == ':') {
-
- /** Two possibilities - either tailing end of this argument or the
- next argument in the list **/
-
- if (_indx < strlen(argv[_argnum])) { /* first possibility */
- optional_arg = (char *) (argv[_argnum] + _indx);
- _argnum++;
- _indx = 1;
- }
- else { /* second choice */
- if (++_argnum >= argc)
- return(ERROR); /* no argument!! */
-
- optional_arg = (char *) argv[_argnum++];
- _indx = 1;
- }
- }
-
- return((int) word[0]);
- }
- END-OF-FILE
-
- size=`wc -c < src/args.c`
-
- if [ $size != 3662 ]
- then
- echo Warning: src/args.c changed - should be 3662 bytes, not $size bytes
- fi
-
- chmod 644 src/args.c
-
- # ---------- file src/curses.c ----------
-
-
- if [ -f src/curses.c ]
- then
- echo File 'src/curses.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/curses.c...
- cat << 'END-OF-FILE' > src/curses.c
- /** 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 hpcnoe!dat@HPLABS (fixed, if possible!)
-
- (C) Copyright 1985 Dave Taylor, HP Colorado Networks
- **/
-
- #include <stdio.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 BSD
- # include "/usr/include/curses.h" /* don't ask! */
- #endif
-
- #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? */
-
- #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;
- static
- int
- _lines, _columns;
-
- static char _terminal[1024]; /* Storage for terminal entry */
- static char _capabilities[256]; /* String for cursor motion */
-
- static char *ptr = _capabilities; /* for buffering */
-
- int outchar(); /* char output for tputs */
-
- 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 *tgetstr(), /* Get termcap capability */
- termname[40];
-
- if (strcpy(termname, getenv("TERM")) == NULL)
- return(-1);
-
- if ((error = tgetent(_terminal, termname)) != 1)
- return(error-2);
-
- /* 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);
-
-
- 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 **/
-
- char *tgetstr(); /* Get termcap capability */
-
- return( (char *) tgetstr(termcap_label, &ptr));
- }
-
- transmit_functions(newstate)
- int newstate;
- {
- /** turn function key transmission to ON | OFF **/
-
- 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. **/
-
- *lines = _lines - 1; /* assume index from zero */
- *columns = _columns;
- }
-
- ClearScreen()
- {
- /* clear the screen: returns -1 if not capable */
-
- 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 *tgoto();
- char *stuff;
-
- if (!_moveto)
- return(-1);
-
- stuff = (char *) tgoto(_moveto, col, row);
- tputs(stuff, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- CursorUp()
- {
- /** move the cursor up one line **/
-
- if (!_up)
- return(-1);
-
- tputs(_up, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- CursorDown()
- {
- /** move the cursor down one line **/
-
- if (!_down)
- return(-1);
-
- tputs(_down, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- CursorLeft()
- {
- /** move the cursor one character to the left **/
-
- if (!_left)
- return(-1);
-
- tputs(_left, 1, outchar);
- fflush(stdout);
- return(0);
- }
-
-
- CursorRight()
- {
- /** move the cursor one character to the right (nondestructive) **/
-
- if (!_right)
- return(-1);
-
- 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);
- }
-
- PutLine(x, y, line, args)
- int x,y;
- char *line;
- int args;
- {
- /** write line at location x,y **/
-
- MoveCursor(x,y);
- _doprnt(line, &args, stdout);
- fflush(stdout); /* ensure it actually gets out! */
- }
-
- CleartoEOLN()
- {
- /** clear to end of line **/
-
- if (!_cleartoeoln)
- return(-1);
-
- tputs(_cleartoeoln, 1, outchar);
- fflush(stdout); /* clear the output buffer */
- return(0);
- }
-
- CleartoEOS()
- {
- /** clear to end of screen **/
-
- 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 **/
-
- 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;
-
- 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
-
- size=`wc -c < src/curses.c`
-
- if [ $size != 8965 ]
- then
- echo Warning: src/curses.c changed - should be 8965 bytes, not $size bytes
- fi
-
- chmod 644 src/curses.c
-
- # ---------- file src/date.c ----------
-
-
- if [ -f src/date.c ]
- then
- echo File 'src/date.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/date.c...
- cat << 'END-OF-FILE' > src/date.c
- /** 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 *tzname();
- #else
- extern char *tzname[];
- #endif
-
- char *get_date()
- {
- /** return the date in the format exemplified by;
- Thursday, April 18th 1985 at 8:35 pm
- **/
-
- 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.... */
-
- dprint0("get_date()\n");
-
- junk = 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.... */
-
- dprint0("get_arpa_date()\n");
-
- junk = time(0); /* this must be here for it to work! */
- 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
- tzname());
- #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]);
-
- 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.... */
-
- dprint1("days_ahead(days=%d)\n", days);
-
- junk = 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;
-
- dprint3("valid_date(day='%s', month='%s', year='%s')\n", day, mon, year);
-
- daynum = atoi(day);
- yearnum = atoi(year);
-
- if (daynum < 1 || daynum > 31)
- return(0);
-
- if (yearnum < 1 || (yearnum > 100 && yearnum < 1900) ||
- yearnum > 2000)
- 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 **/
-
- dprint3("fix_date(month='%s', day='%s', year='%s')\n",
- entry->month, entry->day, entry->year);
-
- 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;
-
- dprint1("fix_time(string='%s')\n", timestring);
-
- 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);
- }
-
- #ifdef BSD
-
- char *tzname()
- {
- /** Return the name of the timezone (three letters) by plowing about
- in the various time structures on the Berkeley systems. This is
- a pretty grungy routine, actually! **/
-
- struct timeval *current_time;
- struct timezone *time_zone;
- char *timezone();
-
- gettimeofday(current_time, time_zone);
-
- return (timezone(time_zone->tz_minuteswest, time_zone->tz_dsttime));
- }
-
- #endif
- END-OF-FILE
-
- size=`wc -c < src/date.c`
-
- if [ $size != 7441 ]
- then
- echo Warning: src/date.c changed - should be 7441 bytes, not $size bytes
- fi
-
- chmod 644 src/date.c
-
- # ---------- file src/delete.c ----------
-
-
- if [ -f src/delete.c ]
- then
- echo File 'src/delete.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/delete.c...
- cat << 'END-OF-FILE' > src/delete.c
- /** delete.c **/
-
- /** Delete or undelete files: just set flag in header record!
-
- (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... **/
-
- dprint1("delete(real_del=%s)\n", real_del? "ON" : "OFF");
-
- if (real_del)
- header_table[current-1].delete = 1;
- else
- header_table[current-1].delete = ! header_table[current-1].delete;
-
- show_msg_status(current-1);
- }
-
- undelete()
- {
- /** clear the deleted message flag **/
-
- dprint0("undelete()\n");
-
- header_table[current-1].delete = 0;
-
- show_msg_status(current-1);
- }
-
- show_delete_flags()
- {
- /** display page of headers (10) if present. First check to
- ensure that header_page is in bounds, fixing silently if not **/
-
- register int first = 0, last = 0, line = 4;
-
- dprint0("show_delete_flags()\n");
-
- (void) fix_header_page();
-
- /** compute last header to display **/
-
- first = header_page*headers_per_page;
- last = first + (headers_per_page - 1);
-
- if (last > message_count)
- last = message_count;
-
- /** okay, now let's show the stuff **/
-
- while (first <= last) {
- MoveCursor(line++,7);
- if (header_table[first].delete) putchar('*');
- else putchar(' ');
- first++;
- }
- }
-
- show_msg_status(msg)
- int msg;
- {
- /** show the status of the current message only. **/
-
- register int line;
-
- dprint1("show_msg_status(msg=%d)\n", msg);
-
- line = (msg % headers_per_page) + 4;
-
- MoveCursor(line,7);
- putchar( header_table[msg].delete? '*' : ' ');
- }
- END-OF-FILE
-
- size=`wc -c < src/delete.c`
-
- if [ $size != 1591 ]
- then
- echo Warning: src/delete.c changed - should be 1591 bytes, not $size bytes
- fi
-
- chmod 644 src/delete.c
-
- # ---------- file src/encode.c ----------
-
-
- if [ -f src/encode.c ]
- then
- echo File 'src/encode.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/encode.c...
- cat << 'END-OF-FILE' > src/encode.c
- /** encode.c **/
-
- /** This is a heavily mangled version of the 'cypher' program written by
- person or persons unknown.
-
- (C) Copyright 1986, Dave Taylor
- **/
-
- #include <stdio.h>
- #include "curses.h"
- #include "headers.h"
-
- #define RS 94
- #define RN 4
- #define RMASK 0x7fff /* use only 15 bits */
-
- static char r[RS][RN]; /* rotors */
- static char ir[RS][RN]; /* inverse rotors */
- static char h[RS]; /* half rotor */
- static char s[RS]; /* shuffle vector */
- static int p[RN]; /* rotor indices */
-
- static char the_key[SLEN]; /* unencrypted key */
- static char *encrypted_key; /* encrypted key */
-
- getkey(send)
- int send;
- {
- /** this routine prompts for and returns an encode/decode
- key for use in the rest of the program. If send == 1
- then need to mess with rawmode. **/
-
- char buffer[NLEN];
- int gotkey = 0;
-
- dprint1("getkey(send=%s)\n", send? "ON" : "OFF");
-
- ClearLine(21);
-
- if (send) Raw(OFF);
-
- while ( !gotkey ) {
- MoveCursor(LINES-1,0);
- ClearLine(LINES-1);
- if (send)
- strcpy( buffer, getpass( "Enter encryption key: "));
- else
- strcpy( buffer, getpass( "Enter decryption key: "));
- MoveCursor(LINES-1,0);
- if ( strcmp( buffer, getpass( "Please enter it again: "))) {
- error("Your keys were not the same!");
- sleep(1);
- clear_error();
- continue;
- }
- strcpy(the_key, buffer); /* save unencrypted key */
- makekey( buffer );
- gotkey = 1;
- }
-
- if (send) Raw(ON);
-
- setup(); /** initialize the rotors etc. **/
-
- ClearLine(LINES-1);
- clear_error();
- }
-
- get_key_no_prompt()
- {
- /** This performs the same action as get_key, but assumes that
- the current value of 'the_key' is acceptable. This is used
- when a message is encrypted twice... **/
-
- char buffer[SLEN];
-
- dprint0("get_key_no_prompt()\n");
-
- strcpy(buffer, the_key);
-
- makekey( buffer );
-
- setup();
- }
-
- encode(line)
- char *line;
- {
- /** encrypt or decrypt the specified line. Uses the previously
- entered key... **/
-
- register int i, index, j, ph = 0;
-
- dprint1("encode(line='%s')\n", line);
-
- for (index=0; index < strlen(line); index++) {
- i = (int) line[index];
-
- if ( (i >= ' ') && (i < '~') ) {
- i -= ' ';
-
- for ( j = 0; j < RN; j++ ) /* rotor forwards */
- i = r[(i+p[j])%RS][j];
-
- i = ((h[(i+ph)%RS])-ph+RS)%RS; /* half rotor */
-
- for ( j-- ; j >= 0; j-- ) /* rotor backwards */
- i = (ir[i][j]+RS-p[j])%RS;
-
- j = 0; /* rotate rotors */
- p[0]++;
- while ( p[j] == RS ) {
- p[j] = 0;
- j++;
- if ( j == RN ) break;
- p[j]++;
- }
-
- if ( ++ph == RS )
- ph = 0;
-
- i += ' ';
- }
-
- line[index] = (char) i; /* replace with altered one */
- }
- }
-
-
- makekey( rkey)
- char *rkey;
- {
- /** encrypt the key using the system routine 'crypt' **/
-
- char key[8], salt[2], *crypt();
-
- dprint1("makekey(rkey='%s')\n", rkey);
-
- strncpy( key, rkey, 8);
- salt[0] = key[0];
- salt[1] = key[1];
- encrypted_key = crypt( key, salt);
- }
-
- /*
- * shuffle rotors.
- * shuffle each of the rotors indiscriminately. shuffle the half-rotor
- * using a special obvious and not very tricky algorithm which is not as
- * sophisticated as the one in crypt(1) and Oh God, I'm so depressed.
- * After all this is done build the inverses of the rotors.
- */
-
- setup()
- {
- register long i, j, k, temp;
- long seed;
-
- dprint0("setup()\n");
-
- for ( j = 0; j < RN; j++ ) {
- p[j] = 0;
- for ( i = 0; i < RS; i++ )
- r[i][j] = i;
- }
-
- seed = 123;
- for ( i = 0; i < 13; i++) /* now personalize the seed */
- seed = (seed*encrypted_key[i] + i) & RMASK;
-
- for ( i = 0; i < RS; i++ ) /* initialize shuffle vector */
- h[i] = s[i] = i;
-
- for ( i = 0; i < RS; i++) { /* shuffle the vector */
- seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
- k = ((seed % 65521) & RMASK) % RS;
- temp = s[k];
- s[k] = s[i];
- s[i] = temp;
- }
-
- for ( i = 0; i < RS; i += 2 ) { /* scramble the half-rotor */
- temp = h[s[i]]; /* swap rotor elements ONCE */
- h[s[i]] = h[s[i+1]];
- h[s[i+1]] = temp;
- }
-
- for ( j = 0; j < RN; j++) { /* select a rotor */
-
- for ( i = 0; i < RS; i++) { /* shuffle the vector */
- seed = (5 * seed + encrypted_key[i%13]) & RMASK;;
- k = ((seed % 65521) & RMASK) % RS;
- temp = r[i][j];
- r[i][j] = r[k][j];
- r[k][j] = temp;
- }
-
- for ( i = 0; i < RS; i++) /* create inverse rotors */
- ir[r[i][j]][j] = i;
- }
- }
- END-OF-FILE
-
- size=`wc -c < src/encode.c`
-
- if [ $size != 4349 ]
- then
- echo Warning: src/encode.c changed - should be 4349 bytes, not $size bytes
- fi
-
- chmod 644 src/encode.c
-
- # ---------- file src/file.c ----------
-
-
- if [ -f src/file.c ]
- then
- echo File 'src/file.c' already exists\!
- exit 1
- fi
-
- echo extracting file src/file.c...
- cat << 'END-OF-FILE' > src/file.c
- /** file.c **/
-
- /** File I/O routines, including deletion from the mailbox!
-
- (C) Copyright 1986, Dave Taylor
- **/
-
- #include "headers.h"
- #include <ctype.h>
-
- #ifdef BSD
- #undef tolower
- #endif
-
- int
- save()
- {
- /** save current message in file. Append if possible!
- Returns zero iff no file specified (cancelled command) **/
-
- char filename[SLEN], address[LONG_SLEN], buffer[SLEN];
- FILE *save_file;
-
- dprint0("save()\n");
-
- MoveCursor(LINES-2,0);
- printf("File current message in: ");
-
- if (save_by_name) {
- /** build default filename to save to **/
- get_return(address);
- get_return_name(address, buffer);
- sprintf(filename, "=/%s", buffer);
- }
- else
- filename[0] = '\0';
-
- optionally_enter(filename, LINES-2, 25, FALSE);
- MoveCursor(LINES-1,0);
-
- if (strlen(filename) == 0) /** <return> means 'cancel', right? **/
- return(0);
-
- if (! expand_filename(filename))
- return(0); /* failed expanding name! */
-
- if ((save_file = fopen(filename,"a")) == NULL) {
- error1("Couldn't append to file %s!", filename);
- return(0);
- }
-
- copy_message("", save_file, FALSE);
-
- fclose(save_file);
-
- chown(filename, getuid(), getgid()); /* owned by user */
- error1("Message saved in file %s", filename);
- return(1);
- }
-
- int
- expand_filename(filename)
- char *filename;
- {
- /* expands '~' and '=' to specified file names, also will
- try to expand shell variables if encountered.. */
-
- char buffer[SLEN], varname[SLEN], env_value[SLEN];
- register int i = 1, index = 0;
-
- dprint1("expand_filename(filename='%s')\n", filename);
-
- /** 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] == '=') {
- if (strlen(folders) == 0) {
- error("MAILDIR not defined. Can't expand '='");
- 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';
-
- strcpy(env_value, getenv(varname));
-
- if (strlen(env_value) == 0) {
- 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
-
- size=`wc -c < src/file.c`
-
- if [ $size != 2644 ]
- then
- echo Warning: src/file.c changed - should be 2644 bytes, not $size bytes
- fi
-
- chmod 644 src/file.c
-
- echo done
-
- exit 0
-
-
-
-
-