home *** CD-ROM | disk | FTP | other *** search
- Subject: v18i005: Fido/Usenet gateway, Part04/05
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Heikki Suonsivu <hsu@santra.hut.fi>
- Posting-number: Volume 18, Issue 5
- Archive-name: fnet/part04
-
- #!/bin/sh
- # this is part 4 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- # file fio.c continued
- #
- CurArch=4
- if test ! -r s2_seq_.tmp
- then echo "Please unpack part 1 first!"
- exit 1; fi
- ( read Scheck
- if test "$Scheck" != $CurArch
- then echo "Please unpack part $Scheck next!"
- exit 1;
- else exit 0; fi
- ) < s2_seq_.tmp || exit 1
- echo "x - Continuing file fio.c"
- sed 's/^X//' << 'SHAR_EOF' >> fio.c
- X{
- X nchars = 0;
- X}
- SHAR_EOF
- echo "File fio.c is complete"
- chmod 0644 fio.c || echo "restore of fio.c fails"
- echo "x - extracting xtsend.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > xtsend.c &&
- X#ifndef lint
- Xstatic char *sccsid = "@(#)%M% %I% Teemu Torma %H%";
- X#endif
- X
- X/* Send file(s) unsing Xmodem/TeLink/MODEM7 Batch protocols.
- X
- X @(#)Copyright (c) 1987 by Teemu Torma
- X
- X Permission is given to distribute this program and alter this code as
- X needed to adapt it to forign systems provided that this header is
- X included and that the original author's name is preserved. */
- X
- X/* LINTLIBRARY */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <string.h>
- X#include <time.h>
- X#include "fnet.h"
- X#include "fio.h"
- X#include "crc.h"
- X
- Xextern time_t time();
- Xextern int readline();
- Xextern void sendline();
- X
- X/* General macros to check timeouts. */
- X
- X#define SetStart() (stime = time((long *) NULL))
- X#define Timeout(t) (time((long *) NULL) - stime > (t))
- X#define BytesSend (block * BlockSize)
- X
- X/* General states for finite state machines. These are used to break
- X loops mostly. */
- X
- X#define Error (-1) /* error state */
- X#define Done (-2) /* state to break loops */
- X
- X/* XMODEM/TeLink send states. */
- X
- X#define WaitTeLnk (0)
- X#define WaitStart (1)
- X#define SendBlock (2)
- X#define WaitACK (3)
- X#define WaitEnd (4)
- X
- X/* BATCH File sender states. */
- X
- X#define MoreFiles (0)
- X#define CheckFNm (1)
- X#define CheckFile (2)
- X#define EndSend (3)
- X
- X/* States for MODEM7 filename sender. */
- X
- X#define WaitNak (0)
- X#define WaitChAck (1)
- X#define WaitCksm (2)
- X
- X/* Return filename for MS-DOS. Because MS-DOS has many restrictions in
- X filenames (that silly dot in between), we must use something equivalent
- X while sending TeLink. */
- X
- Xchar *
- Xconver_to_msdos_name(filename)
- X char *filename;
- X{
- X static char msdos_name[16];
- X register int pos;
- X register char *cp;
- X
- X /* strip off pathname */
- X cp = basename(filename);
- X
- X /* ignore leading dot */
- X if (*cp == '.')
- X cp++;
- X
- X /* create first 8 characters of ms-dos name */
- X for (pos = 0; *cp && *cp != '.' && pos < 8; pos++, cp++)
- X msdos_name[pos] = *cp;
- X
- X /* add dot for ms-dos */
- X msdos_name[pos] = '.';
- X
- X /* add 3 character type */
- X for (pos = 9; *cp && *cp != '.' && pos < 12; pos++, cp++)
- X msdos_name[pos] = *cp;
- X
- X /* null terminate ms-dos name */
- X msdos_name[pos] = 0;
- X
- X debug(2, "File %s changed to %s in MS-DOS", filename, msdos_name);
- X return msdos_name;
- X}
- X
- X/* Create special TeLink block. This block will be send as block 0 before
- X all other data will be sent. Return false if it couldn't be created,
- X otherwise true. */
- X
- Xbool
- Xmaketelnk(filename, buffer)
- X char *filename, *buffer;
- X{
- X struct stat stbuf;
- X register int cnt;
- X register char *cp;
- X
- X /* get status of file */
- X if (stat(filename, &stbuf) == -1)
- X {
- X log("$Cannot stat %s", filename);
- X return False;
- X }
- X
- X /* save file length */
- X for (cnt = 0; cnt < 4; cnt++)
- X buffer[cnt] = (stbuf.st_size >> (cnt * 8)) & 0377;
- X
- X /* creation time and date will be all zeroes */
- X for (cnt = 4; cnt < 8; cnt++)
- X buffer[cnt] = 0;
- X
- X /* save file name */
- X for (cnt = 8, cp = /*msdosname(*/ filename /*)*/ ; *cp; cp++, cnt++)
- X buffer[cnt] = *cp;
- X
- X /* if name was shorter that 16 chars, fill rest of it with blanks */
- X while (cnt < 24)
- X buffer[cnt++] = ' ';
- X
- X /* don't know why here's zero */
- X buffer[cnt] = 0;
- X
- X /* name of sending program... let's ignore */
- X for (cnt = 25; cnt < 41; cnt++)
- X buffer[cnt] = 0;
- X strcpy(&buffer[25], PROGRAMNAME);
- X
- X /* crc mode */
- X
- X buffer[41] = 1;
- X
- X /* rest of buffer will be full of zeroes */
- X for (cnt = 42; cnt < 128; cnt++)
- X buffer[cnt] = 0;
- X return True;
- X}
- X
- X/* Send block to line. Note that intial SOH or SYN is not sent by
- X this routine. */
- X
- Xvoid
- Xxtsendblk(sxbuf, blocknum, crcmode)
- X char *sxbuf;
- X int blocknum;
- X bool crcmode;
- X{
- X register unsigned short crc;
- X register int checksum, cnt;
- X
- X debug(1, "Send block %d", blocknum);
- X
- X /* send block number */
- X sendline(blocknum & 0377);
- X sendline(~(blocknum & 0377));
- X
- X /* send the block itself */
- X debug(1, "Send %d bytes", BlockSize);
- X (void) write(line, sxbuf, BlockSize);
- X
- X /* count crc and checksum */
- X for (crc = 0, checksum = 0, cnt = 0; cnt < BlockSize; cnt++)
- X {
- X crc = updcrc(sxbuf[cnt], crc);
- X checksum += sxbuf[cnt];
- X }
- X
- X if (crcmode)
- X {
- X /* send crc */
- X /* crc = updcrc(0, updcrc(0, crc)); /* What is this for? */
- X debug(1, "Send crc %d", crc);
- X sendline((int) (crc >> 8));
- X sendline((int) crc);
- X }
- X else
- X {
- X /* send checksum */
- X debug(1, "send checksum %d", checksum & 0377);
- X sendline(checksum & 0377);
- X }
- X}
- X
- X/* Send file using XMODEM/TeLink protocol. Return True is everything went
- X fine, otherwise false. */
- X
- Xbool
- Xxtsend(filename, telink)
- X char *filename;
- X bool telink;
- X{
- X int state = telink ? WaitTeLnk : WaitStart;
- X struct stat st;
- X time_t stime;
- X int tries, c;
- X char sxbuf[BlockSize];
- X FILE *fp;
- X bool resend = False, lastblock = False;
- X int block = 1, cnt;
- X bool crcmode = True;
- X
- X if ((fp = fopen(filename, "r")) == NULL)
- X log("$Can not open %s, sending empty file", filename);
- X else
- X log("Sending %s", filename);
- X
- X (void) stat(filename, &st);
- X
- X while (state >= WaitTeLnk && state <= WaitEnd)
- X switch (state)
- X {
- X case WaitTeLnk:
- X if (!maketelnk(filename, sxbuf))
- X {
- X log("Unable to send file %s", filename);
- X state = Error;
- X }
- X else
- X {
- X SetStart();
- X for (tries = 0; state == WaitTeLnk; tries++)
- X {
- X if ((c = readline(40)) == NAK || c == 'C')
- X {
- X crcmode = c == 'C';
- X debug(2, "Got %02x, sending TeLink block", c);
- X sendline(SYN);
- X /* telink block always has checksum */
- X xtsendblk(sxbuf, 0, False);
- X }
- X else if (c == ACK)
- X {
- X state = WaitStart;
- X debug(2, "Got ACK, TeLink block sent ok");
- X }
- X else if (c == NAK)
- X {
- X if (tries > 2)
- X {
- X log("Too many tries on telink block");
- X state = WaitStart;
- X }
- X /* If other stuff, not ack/nak received, just ignore */
- X }
- X else if (Timeout(40))
- X {
- X log("Timeout on telink block");
- X state = WaitStart;
- X }
- X }
- X }
- X break;
- X case WaitStart:
- X SetStart();
- X for (tries = 0; state == WaitStart; tries++)
- X if ((c = readline(60)) == NAK || c == 'C')
- X {
- X debug(1, "Got NAK, sendblock start");
- X crcmode = True; /* c == 'C'; */
- X state = SendBlock;
- X }
- X else if (Timeout(60))
- X {
- X log("Timeout on xmodem start");
- X state = Error;
- X }
- X else if (tries > 20)
- X {
- X debug(1, "Too many retries on xmodem start");
- X state = Error;
- X }
- X break;
- X case SendBlock:
- X if (!resend)
- X if (lastblock || !fp)
- X {
- X sendline(EOT);
- X state = WaitEnd;
- X }
- X else {
- X for (cnt = 0; cnt < BlockSize; cnt++)
- X {
- X if ((c = getc(fp)) == EOF) {
- X c = CTRLZ;
- X lastblock = True;
- X }
- X sxbuf[cnt] = c;
- X }
- X sendline(SOH);
- X xtsendblk(sxbuf, block, crcmode);
- X state = WaitACK;
- X }
- X else {
- X sendline(SOH);
- X xtsendblk(sxbuf, block, crcmode);
- X state = WaitACK;
- X resend = False;
- X }
- X break;
- X case WaitACK:
- X SetStart();
- X for (tries = 0; state == WaitACK; tries++)
- X if ((c = readline(60)) == NAK)
- X {
- X resend = True;
- X state = SendBlock;
- X debug(1, "Got NAK, resend current block");
- X if (tries >= 10)
- X {
- X log("Too many tries on xmodem send");
- X state = Error;
- X }
- X }
- X else if (c == ACK)
- X {
- X debug(1, "Got ACK, send next block");
- X block++;
- X debug(2, "%ld bytes send (%d %%)", BytesSend,
- X (BytesSend / st.st_size) * 100);
- X state = SendBlock;
- X }
- X else if (Timeout(60))
- X {
- X log("Xodem send timeout");
- X state = Error;
- X }
- X break;
- X case WaitEnd:
- X for (tries = 0; state == WaitEnd; tries++)
- X if ((c = readline(60)) == NAK)
- X {
- X sendline(EOT);
- X debug(2, "Send EOT");
- X }
- X else if (c == ACK)
- X {
- X log("Xmodem/TeLink send successful");
- X state = Done;
- X }
- X else if (Timeout(60))
- X {
- X log("Timeout on xmodem/telink end");
- X state = Error;
- X }
- X else if (tries >= 10)
- X {
- X log("Too many retries on xmodem end");
- X state = Error;
- X }
- X break;
- X }
- X
- X return state == Error ? False : True;
- X}
- X
- X/* Send MODEM7 filename. */
- X
- Xbool
- Xsendmdmfn(filename)
- X char *filename;
- X{
- X int state = WaitNak;
- X time_t stime;
- X int tries = 0;
- X int c, checksum, cnt;
- X
- X SetStart();
- X while (state >= WaitNak && state <= WaitCksm)
- X switch (state)
- X {
- X case WaitNak:
- X for (tries = 0; state == WaitNak; )
- X if ((c = readline(60)) == NAK)
- X {
- X debug(2, "Got NAK for filename %s", filename);
- X sendline(ACK);
- X sendline(*filename);
- X cnt = 1;
- X state = WaitChAck;
- X }
- X else if (Timeout(60))
- X {
- X debug(1, "Timeout on filename");
- X state = Error;
- X }
- X else if (tries >= 20)
- X {
- X debug(1, "Too many retries on filename");
- X state = Error;
- X }
- X break;
- X case WaitChAck:
- X if (readline(2) == ACK)
- X {
- X if (filename[cnt])
- X sendline(filename[cnt++]);
- X else
- X {
- X sendline(SUB);
- X state = WaitCksm;
- X }
- X }
- X else
- X {
- X sendline('u');
- X tries++;
- X state = WaitNak;
- X }
- X break;
- X case WaitCksm:
- X if ((c = readline(2)) == TIMEOUT)
- X {
- X sendline('u');
- X tries++;
- X state = WaitNak;
- X }
- X else
- X {
- X for (cnt = 0, checksum = SUB; filename[cnt]; cnt++)
- X checksum += filename[cnt];
- X if (c != (checksum & 0377))
- X {
- X debug(1, "Checksum error in filename");
- X sendline('u');
- X state = WaitNak;
- X tries++;
- X }
- X else
- X {
- X sendline(ACK);
- X debug(2, "Filename sent ok");
- X state = Done;
- X }
- X }
- X break;
- X }
- X
- X return state != Error;
- X}
- X
- X/* Batch file sender. If filename is NULL, no more files to send. */
- X
- Xbool
- Xbatchsend(filename)
- X char *filename;
- X{
- X int state = MoreFiles;
- X int c;
- X time_t stime;
- X bool ok;
- X
- X while (state >= MoreFiles && state <= EndSend)
- X switch (state)
- X {
- X case MoreFiles:
- X if (filename)
- X {
- X debug(2, "Sending filename for %s", filename);
- X ok = sendmdmfn(filename);
- X state = CheckFNm;
- X }
- X else
- X state = EndSend;
- X break;
- X case CheckFNm:
- X if (ok)
- X {
- X debug(1, "Sending file %s", filename);
- X ok = xtsend(filename, True);
- X state = CheckFile;
- X }
- X else
- X state = Error;
- X break;
- X case CheckFile:
- X if (ok)
- X {
- X debug(1, "File send ok");
- X state = Done;
- X }
- X else
- X {
- X log("TeLink file send failed");
- X state = Error;
- X }
- X break;
- X case EndSend:
- X SetStart();
- X while (!Timeout(10))
- X if ((c = readline(10)) == NAK || c == 'C')
- X {
- X sendline(EOT);
- X log("Batch file send ok");
- X state = Done;
- X break;
- X }
- X if (state != Done)
- X {
- X log("Batch file send failed, no NAK");
- X sendline(EOT);
- X state = Error;
- X }
- X break;
- X }
- X
- X return state != Error;
- X}
- SHAR_EOF
- chmod 0644 xtsend.c || echo "restore of xtsend.c fails"
- echo "x - extracting xtrec.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > xtrec.c &&
- X#ifndef lint
- Xstatic char *sccsid = "@(#)%M% %I% Teemu Torma %H%";
- X#endif
- X
- X/* Receive file(s) using Xmodem/TeLink/MODEM7 Batch protocols.
- X
- X @(#)Copyright (c) 1987 by Teemu Torma
- X
- X Permission is given to distribute this program and alter this code as
- X needed to adapt it to forign systems provided that this header is
- X included and that the original author's name is preserved. */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <string.h>
- X#include "hsu.h"
- X#include "fnet.h"
- X#include "fio.h"
- X#include "crc.h"
- X
- Xextern time_t time();
- X
- X/* Macros to check timeouts */
- X
- X#define Timeout(t) (time((long *) NULL) - stime > t)
- X#define SetStart() (stime = time((long *) NULL))
- X
- X/* General error states to break the loops. */
- X
- X#define Error (-1)
- X#define Done (-2)
- X
- X/* States for XMODEM/TeLink receiver. */
- X
- X#define RecStart (0)
- X#define WaitFirst (1)
- X#define WaitBlock (2)
- X
- X/* States for BATCH file receiver. */
- X
- X#define RecvName (0)
- X#define CheckFNm (1)
- X#define CheckFile (2)
- X
- X/* States for MODEM7 filename receiver. */
- X
- X#define SendNak (0)
- X#define WaitAck (1)
- X#define WaitChar (2)
- X#define WaitOkCk (3)
- X
- Xstatic received_block_number = 0;
- Xint receiving_data = FALSE;
- X
- Xbool
- Xxtrecblk(rxbuf, blocknum, crcmode)
- X char *rxbuf;
- X int blocknum;
- X bool crcmode;
- X{
- X register int c, cnt, checksum;
- X register unsigned short crc;
- X
- X if (blocknum == -1)
- X debug(1, "Receiving block ignoring block number");
- X else
- X debug(1, "Receiving block %d", blocknum);
- X
- X received_block_number = blocknum;
- X
- X if ((c = readline(10)) == TIMEOUT || c != (blocknum & 0377))
- X {
- X if (c == TIMEOUT)
- X debug(1, "Timeout on block number receive");
- X else
- X {
- X if (blocknum == -1)
- X if (c == 0 || c == 1) /* Both telink and xmodem allowed */
- X {
- X blocknum = c;
- X received_block_number = blocknum;
- X debug(1, "Setting blocknum to %d", blocknum);
- X goto blockok;
- X }
- X
- X debug(1, "Bad block number %d, expected %d", c, blocknum & 0377);
- X }
- X goto blidge;
- X }
- X
- X blockok:
- X if ((c = readline(10)) == TIMEOUT || c != (~blocknum & 0377))
- X {
- X if (c == TIMEOUT)
- X debug(1, "Timeout on complement block number receive");
- X else
- X debug(1, "Bad ~block number %d, expected %d", c, (~blocknum & 0377));
- X goto blidge;
- X }
- X
- X receiving_data = TRUE;
- X for (crc = 0, checksum = 0, cnt = 0; cnt < BlockSize; cnt++)
- X if ((c = readline(5)) == TIMEOUT)
- X {
- X debug(1, "Timeout while receiving block");
- X receiving_data = FALSE;
- X goto blidge;
- X }
- X else
- X {
- X checksum += c;
- X crc = updcrc(c, crc);
- X rxbuf[cnt] = c;
- X }
- X receiving_data = FALSE;
- X debug(5, "Received %d bytes", BlockSize);
- X
- X if (crcmode)
- X {
- X if (readline(10) != (int) ((crc >> 8) & 0377)
- X || readline(10) != (int) (crc & 0377))
- X {
- X debug(1, "Crc error");
- X goto blidge;
- X }
- X }
- X else
- X {
- X if (readline(10) != (checksum & 0377))
- X {
- X debug(1, "Checksum error");
- X goto blidge;
- X }
- X }
- X return True;
- X
- X blidge:
- X debug(1, "Fail, Skipping rest of the block");
- X while (readline(1) != TIMEOUT)
- X /* skip rest of the block */;
- X return False;
- X}
- X
- Xbool
- Xxtrec(filename, xmodem)
- X char *filename;
- X int xmodem;
- X{
- X int state = RecStart;
- X time_t stime;
- X int tries = 0;
- X bool crcmode = True;
- X FILE *fp;
- X char rxbuf[BlockSize];
- X int cnt, block = 1, c;
- X
- X if ((fp = fopen(filename, "w")) == NULL)
- X {
- X log("$Unable to open %s for writing", filename);
- X return False;
- X }
- X log("Receive file %s", filename);
- X SetStart();
- X while (state >= RecStart && state <= WaitBlock)
- X switch (state)
- X {
- X case RecStart:
- X debug(1,"Send %s", crcmode ? "C" : "NAK");
- X sendline(crcmode ? 'C' : NAK);
- X sendline(0);
- X sendline(~0);
- X state = WaitFirst;
- X break;
- X case WaitFirst:
- X if (tries > 10 || Timeout(60))
- X {
- X if (tries > 10)
- X log("Too many tries on xmodem receive");
- X else
- X log("Timeout on xmodem receive start");
- X state = Error;
- X }
- X else if ((c = readline(10)) == EOT)
- X {
- X sendline(ACK);
- X log("No file to receive");
- X state = Done;
- X }
- X else if (c == SYN || c == SOH) /* Probably telink block? */
- X {
- X debug(1, "Startup in %s mode", crcmode ? "crc" : "checksum");
- X if (!xtrecblk(rxbuf, -1 /* c == SYN ? 0 : 1 */ , crcmode))
- X {
- X debug(1, "Retry, bad block");
- X tries++; /* No valid block received */
- X state = RecStart;
- X#ifdef NEEDED
- X block = 1; /* Bad block, ignore? */
- X state = WaitBlock;
- X#endif
- X }
- X else
- X {
- X if (c == SOH && received_block_number == 1)
- X {
- X for (cnt = 0; cnt < BlockSize; cnt++)
- X (void) putc(c, fp);
- X block = 2;
- X debug(2, "Block written onto disk");
- X }
- X else if (c == SYN || received_block_number == 0)
- X {
- X sendline(ACK); /* Tell sender we got it */
- X sendline(0);
- X sendline(~0);
- X block = 1;
- X debug(1, "TeLink block ignored");
- X }
- X else
- X {
- X debug(1, "Retry, bad block");
- X tries++;
- X state = RecStart;
- X }
- X state = WaitBlock;
- X }
- X }
- X else if (c == TIMEOUT || c == TSYNCH) /* Tsynch ? Maybe it... */
- X {
- X debug(1, "Timout on Xmodem rcv start");
- X tries++;
- X state = RecStart;
- X }
- X else if (tries > 3 || Timeout(30))
- X {
- X log("Try checksum mode");
- X crcmode = False;
- X state = RecStart;
- X sleep(1);
- X }
- X break;
- X case WaitBlock:
- X SetStart();
- X for (tries = 0; state == WaitBlock; tries++)
- X if (tries > 10 || Timeout(60))
- X {
- X if (tries > 10)
- X log("Too many retries (%d) on %s", tries, filename);
- X else
- X log("Timeout on receive %s, tries %d", filename, tries);
- X state = Error;
- X }
- X else if ((c = readline(10)) == EOT)
- X {
- X log("File %s received ok", filename);
- X state = Done;
- X }
- X else if (c == SOH)
- X {
- X if (xtrecblk(rxbuf, block, crcmode))
- X {
- X for (cnt = 0; cnt < BlockSize; cnt++)
- X (void) putc(rxbuf[cnt], fp);
- X debug(2, "Block written onto disk, tries %d", tries);
- X sendline(ACK);
- X sendline(block);
- X sendline(~block);
- X block++;
- X tries = 0;
- X SetStart();
- X }
- X else
- X {
- X debug(1, "Block not received correctly, tries %d", tries);
- X sendline(NAK);
- X sendline(block);
- X sendline(~block);
- X tries++;
- X }
- X }
- X else if (c == TIMEOUT)
- X {
- X debug(1, "Timeout on block %d, tries %d", block, tries);
- X sendline(NAK);
- X sendline(block);
- X sendline(~block);
- X tries++;
- X }
- X else
- X tries = 0; /* Trash from send-ahead... skip it */
- X
- X }
- X
- X (void) fclose(fp);
- X
- X return state != Error;
- X}
- X
- Xint
- Xrecmdmfn(filename)
- X char *filename;
- X{
- X int state = SendNak;
- X time_t stime;
- X int tries = 0, c, pos;
- X
- X SetStart();
- X while (state >= SendNak && state <= WaitOkCk)
- X switch (state)
- X {
- X case SendNak:
- X if (tries > 20)
- X {
- X log("Too many tries to get filename");
- X state = Error;
- X }
- X else if (Timeout(60))
- X {
- X log("Timeout while getting filename");
- X state = Error;
- X }
- X else
- X {
- X sendline(NAK);
- X state = WaitAck;
- X tries++;
- X }
- X break;
- X case WaitAck:
- X switch (readline(5))
- X {
- X case ACK:
- X pos = 0;
- X state = WaitChar;
- X break;
- X case EOT:
- X pos = 0;
- X state = Done;
- X break;
- X case TIMEOUT:
- X debug(2, "Timout while waiting ACK/EOT on MDM7");
- X state = SendNak;
- X break;
- X default:
- X state = SendNak;
- X debug(2, "Garbage on line while getting filename");
- X (void) sleep((unsigned) 1);
- X flush();
- X break;
- X }
- X break;
- X case WaitChar:
- X switch (c = readline(1))
- X {
- X case EOT:
- X pos = 0;
- X debug(2, "Got EOT in middle of filename, no files left");
- X state = Done;
- X break;
- X case SUB:
- X filename[pos] = 0;
- X debug(2, "Got fn %s, sending checksum", filename);
- X for (pos = 0, c = SUB; filename[pos]; pos++)
- X c += filename[pos];
- X sendline(c & 0377);
- X state = WaitOkCk;
- X break;
- X case 'u':
- X debug(2, "Got 'u', send NAK again");
- X state = SendNak;
- X break;
- X case TIMEOUT:
- X debug(2, "Timeout while waiting char of filename");
- X state = SendNak;
- X break;
- X default:
- X filename[pos++] = c;
- X debug(3, "Got char '%c' of filename", c);
- X break;
- X }
- X break;
- X case WaitOkCk:
- X if (readline(1) == ACK)
- X {
- X debug(1, "Got filename %s ok", filename);
- X state = Done;
- X }
- X else
- X {
- X debug(1, "Checksum faiure in filename %s", filename);
- X state = SendNak;
- X }
- X break;
- X }
- X
- X return state == Error ? -1 : pos ? 1 : 0;
- X}
- X
- Xbool
- Xbatchrec(filename)
- X char *filename;
- X{
- X int state = RecvName;
- X char filen[100];
- X int ok;
- X if (!filename) filename = filen;
- X
- X while (state >= RecvName && state <= CheckFile)
- X switch (state)
- X {
- X case RecvName:
- X ok = recmdmfn(filename);
- X state = CheckFNm;
- X break;
- X case CheckFNm:
- X switch (ok)
- X {
- X case -1:
- X debug(1, "Abort batch receive");
- X state = Error;
- X break;
- X case 0:
- X log("All files received successfully");
- X state = Done;
- X break;
- X case 1:
- X ok = xtrec(filename, FALSE);
- X state = CheckFile;
- X }
- X break;
- X case CheckFile:
- X if (ok)
- X {
- X debug(1, "%s received successfully", filename);
- X state = RecvName;
- X }
- X else
- X {
- X log("Batch receive aborted, %s not received", filename);
- X state = Error;
- X }
- X break;
- X }
- X
- X return state != Error;
- X}
- SHAR_EOF
- chmod 0644 xtrec.c || echo "restore of xtrec.c fails"
- echo "x - extracting nodelist.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > nodelist.c &&
- X#ifndef lint
- Xstatic char *sccsid = "@(#)%M% %I% Teemu Torma %H%";
- X#endif
- X
- X/* Routines to get and translate information in nodelist.
- X
- X @(#)Copyright (c) 1987 by Teemu Torma
- X
- X Permission is given to distribute this program and alter this code as
- X needed to adapt it to forign systems provided that this header is
- X included and that the original author's name is preserved. */
- X
- X/*
- X Sat Oct 8 17:36:11 1988
- X Rewrote nodelist index handling and reading. Now index is kept
- X in memory, and has zones also.
- X */
- X
- X/* LINTLIBRARY */
- X
- X#include <stdio.h>
- X#include <string.h>
- X#include <unistd.h>
- X#include <errno.h>
- X#include <ctype.h>
- X#include <malloc.h>
- X#include <values.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include "hsu.h"
- X#include "config.h"
- X#include "fnet.h"
- X#include "nodelist.h"
- X
- Xextern long atol();
- XNode originnode;
- XNODEINDEX *nodeindex = NULL;
- XNAMEINDEX *nameindex = NULL;
- Xint nodes, names, compile_zone, compile_region, compile_net;
- X
- Xfine_convert(name)
- X char *name;
- X{
- X int wasspace = TRUE;
- X
- X for (; *name; name++)
- X {
- X if (*name == '_') *name = ' ';
- X if (isspace(*name))
- X wasspace = TRUE;
- X else if (wasspace)
- X {
- X *name = toupper(*name);
- X wasspace = FALSE;
- X }
- X else
- X *name = tolower(*name);
- X }
- X}
- X
- X/* Strip bad chars from names, ie chars not which may be dangerous in
- X different networks. Currectly removes all non-alphanumeric chars,
- X but leaves whitespace alone. Strips 8bit chars also. */
- X
- Xstripbad(name)
- X char *name;
- X{
- X char *d;
- X
- X d = alloca(strlen(name) + 1);
- X strcpy(d, name);
- X for (; *d; d++) if (isalpha(*d) || isspace(*d) || strchr("-._", *d))
- X *name++ = *d;
- X
- X *name = *d; /* Terminating null, result can be shorter */
- X}
- X
- X/* Compare two strings, considering '_' and ' ', and converting
- X {|}[\] to aoaAOA instead, and ignoring case.
- X
- X ascii_convert(string) does conversion.
- X */
- X
- Xchar *ascii_convert(s)
- X char *s;
- X{
- X char *p;
- X
- X p = s;
- X while (*s) {
- X switch (*s) {
- X case '_':
- X *s = ' ';
- X break;
- X case '{':
- X case '}':
- X case '[':
- X case ']':
- X *s = 'a';
- X break;
- X case '|':
- X case '\\':
- X *s = 'o';
- X break;
- X default:
- X *s = tolower(*s);
- X }
- X s++;
- X }
- X return p;
- X}
- X
- Xstricmp(d, s)
- X char *d, *s;
- X{
- X char ds[BUFSIZ], ss[BUFSIZ];
- X
- X return strcmp(ascii_convert(strcpy(ds, d)),
- X ascii_convert(strcpy(ss, s)));
- X}
- X
- Xstrnicmp(d, s, n)
- X char *d, *s;
- X int n;
- X{
- X return strncmp(ascii_convert(strcpy(alloca(strlen(d) + 2), d)),
- X ascii_convert(strcpy(alloca(strlen(s) + 2), s)), n);
- X}
- X
- X/* Compare nodelist index entry (for qsort) */
- Xcmpnodeindex(node1, node2)
- X NODEINDEX *node1, *node2;
- X{
- X if (node1->zone < node2->zone) return -1;
- X if (node1->zone > node2->zone) return 1;
- X if (node1->net < node2->net) return -1;
- X if (node1->net > node2->net) return 1;
- X if (node1->node < node2->node) return -1;
- X if (node1->node > node2->node) return 1;
- X return 0; /* Same node */
- X}
- X
- Xcmpnameindex(name1, name2)
- X NAMEINDEX *name1, *name2;
- X{
- X int n;
- X n = stricmp(name1->name, name2->name);
- X /* debug(9, "name1 %s name2 %s = %d", name1->name, name2->name, n); */
- X return n;
- X}
- X
- X/* Read file in to a buffer allocating buffer for it */
- X
- Xlong read_file(buffer, name)
- X char **buffer, *name;
- X{
- X FILE *fp;
- X long size = 0;
- X
- X if (fp = fopen(name, "r")) {
- X fseek(fp, 0L, SEEK_END);
- X size = ftell(fp);
- X
- X /* Apparently we are on 16-bit? */
- X if (size > MAXINT)
- X {
- X log("Brain damaged CPU architecture reading file?");
- X size = 0;
- X goto out;
- X }
- X
- X fseek(fp, 0L, SEEK_SET);
- X
- X if (*buffer)
- X *buffer = realloc( *buffer, (unsigned) size);
- X else
- X *buffer = malloc( (unsigned) size);
- X
- X debug(2, "Reading %d bytes from %s", size, name);
- X if (fread( *buffer, 1, (int) size, fp) != size) size = 0;
- X fclose(fp);
- X }
- X
- X out:
- X return size;
- X}
- X
- Xwrite_file(buffer, name, size)
- X char *buffer, *name;
- X int size;
- X{
- X FILE *fp;
- X int rvalue = 0;
- X
- X if (fp = fopen(name, "w+"))
- X {
- X debug(2, "Writing %d bytes to %s", size, name);
- X if (fwrite(buffer, 1, size, fp) != size) rvalue = -1;
- X fclose(fp);
- X }
- X
- X return rvalue;
- X}
- X
- Xread_nodeindex()
- X{
- X nodes = read_file( (char **) &nodeindex,
- X sprintfs("%s/%s", LIBDIR, INODELIST)) / sizeof(NODEINDEX);
- X return nodes == 0L;
- X}
- X
- Xread_nameindex()
- X{
- X names = read_file( (char **) &nameindex,
- X sprintfs("%s/%s", LIBDIR, NAMELIST)) / sizeof(NAMEINDEX);
- X return names == 0L;
- X}
- X
- Xwrite_nodeindex()
- X{
- X return write_file( (char *) nodeindex,
- X sprintfs("%s/%s", LIBDIR, INODELIST),
- X (int) (nodes * sizeof(NODEINDEX)));
- X}
- X
- Xwrite_nameindex()
- X{
- X return write_file( (char *) nameindex,
- X sprintfs("%s/%s", LIBDIR, NAMELIST),
- X (int) (names * sizeof(NAMEINDEX)));
- X}
- X
- X/* Make nodelist's index-file. That index-file will be used to search
- X desired net/region from nodelist.
- X Return NULL if everything was fine, otherwise error-message string. */
- X
- Xchar *
- Xupdate_index()
- X{
- X struct stat nlstat, inlstat;
- X FILE *nl = NULL, *nlidx = NULL, *namefp = NULL;
- X char nodelist[BUFLEN], inodelist[BUFLEN], namelist[BUFLEN];
- X char buffer[BUFSIZ];
- X long offset;
- X char *error;
- X Node node;
- X NODEINDEX nodei;
- X NAMEINDEX namei;
- X extern void qsort();
- X
- X /* generate nodelist and index-file names */
- X (void) sprintf(nodelist, "%s/%s", LIBDIR, NODELIST);
- X (void) sprintf(inodelist, "%s/%s", LIBDIR, INODELIST);
- X (void) sprintf(namelist, "%s/%s", LIBDIR, NAMELIST);
- X
- X /* get statuses of nodelist and index */
- X if (stat(nodelist, &nlstat) == -1)
- X return "$Error in getting nodelist status";
- X
- X errno = 0;
- X if (stat(inodelist, &inlstat) == -1 && errno != ENOENT)
- X return "$Error in getting status of existing nodelist-index";
- X
- X /* If index-file does exists then check modification times and
- X first lines. If nodelist is older and first lines are the same,
- X no update is needed. If index-file should be rebuild, assume
- X also rebuilding namelist. */
- X
- X if (errno == 0 && nlstat.st_mtime <= inlstat.st_mtime)
- X {
- X error = NULL;
- X goto done;
- X }
- X else
- X log("Update nodelist-index: nodelist is newer than index");
- X
- X /* open index-file for writing */
- X if (nlidx != NULL)
- X (void) fclose(nlidx);
- X if ((nlidx = fopen(inodelist, "w")) == NULL)
- X {
- X error = "$Unable to open nodelist-index for writing";
- X goto done;
- X }
- X if (namefp)
- X (void) fclose(namefp);
- X if ((namefp = fopen(namelist, "w")) == NULL)
- X {
- X error = "$Unable to open namelist-index for writing";
- X goto done;
- X }
- X
- X if (!nl)
- X if ((nl = fopen(nodelist, "r")) == NULL)
- X return "$Unable to open nodelist";
- X
- X (void) rewind(nl);
- X
- X compile_zone = MY_ZONE;
- X compile_region = MY_REGION;
- X compile_net = MY_NET;
- X nodes = 0;
- X names = 0;
- X
- X /* save host/region offsets */
- X for (offset = ftell(nl); fgets(buffer, BUFSIZ, nl); offset = ftell(nl))
- X {
- X if (*buffer == '\n' || *buffer == ';') continue;
- X
- X parse_entry(&node, buffer);
- X
- X nodei.zone = node.zone;
- X nodei.net = node.net;
- X nodei.node = node.node;
- X nodei.offset = offset;
- X
- X#ifdef NEEDED
- X debug(8, "%s", buffer);
- X debug(8, "writing %d:%d/%d", node.zone, node.net, node.node);
- X#endif
- X FWRITE( (char *) &nodei, sizeof(NODEINDEX), 1, nlidx);
- X if (ferror(nlidx))
- X {
- X error = "$Cannot write index, no space?";
- X goto done;
- X }
- X
- X if (node.type != REGION && node.type != HOST &&
- X node.type != ZONE && node.type != KENL && node.type != HUB)
- X {
- X strcpy(namei.name, node.sysop);
- X namei.offset = offset;
- X namei.zone = compile_zone;
- X namei.net = compile_net;
- X names++;
- X FWRITE( (char *) &namei, sizeof(NAMEINDEX), 1, namefp);
- X if (ferror(namefp))
- X {
- X error = "$Cannot write name index, no space?";
- X goto done;
- X }
- X }
- X
- X nodes++;
- X }
- X error = NULL;
- X
- X /* Ok, now get both indices back and qsort them */
- X
- X (void) fclose(nl);
- X nl = NULL;
- X (void) fclose(nlidx);
- X nlidx = NULL;
- X (void) fclose(namefp);
- X namefp = NULL;
- X
- X if (read_nodeindex())
- X {
- X error = "$Cannot read nodelist index";
- X goto done;
- X }
- X if (read_nameindex())
- X {
- X error = "$Cannot read name index";
- X goto done;
- X }
- X
- X log("Sorting nodelist index");
- X (void) qsort( (char *) nodeindex, (unsigned) nodes,
- X sizeof(NODEINDEX), cmpnodeindex);
- X log("Sorting name index");
- X (void) qsort( (char *) nameindex, (unsigned) names,
- X sizeof(NAMEINDEX), cmpnameindex);
- X log("Sorted indices");
- X
- X if (write_nodeindex())
- X {
- X error = "$Cannot write nodelist index";
- X goto done;
- X }
- X if (write_nameindex())
- X {
- X error = "$Cannot write name index";
- X goto done;
- X }
- X
- X /* done, close files and return error message */
- X done:
- X if (nl)
- X (void) fclose(nl);
- X if (nlidx)
- X (void) fclose(nlidx);
- X if (namefp)
- X (void) fclose(namefp);
- X return error;
- X}
- X
- X/* Convert underscores in string to spaces. In nodelist there is always
- X underscore insted of space (flags is special case). */
- X
- Xvoid
- Xconvert_space(s)
- X register char *s;
- X{
- X while (*s)
- X {
- X if (*s == '_')
- X *s = ' ';
- X s++;
- X }
- X}
- X
- X/* Get one comma-terminated field from buffer, retrun pointer to right
- X after terminating comma. Convert underscores to spaces in string. */
- X
- Xchar *
- Xparse_field(buffer, entry, size)
- X char *buffer, *entry;
- X int size;
- X{
- X char *np = entry;
- X
- X /* copy string */
- X while (--size >= 0 && *buffer && *buffer != ',')
- X *entry++ = *buffer++;
- X *entry = 0;
- X
- X switch (*buffer)
- X {
- X case 0:
- X /* end of buffer */
- X log("No closing comma in field");
- X return (char *) 0;
- X case ',':
- X /* succesful copy */
- X convert_space(np);
- X return buffer + 1;
- X default:
- X /* buffer too long, find comma */
- X while (*buffer && *buffer != ',')
- X buffer++;
- X if (*buffer)
- X {
- X convert_space(np);
- X return buffer + 1;
- X }
- X else
- X {
- X log("Missing comma in field");
- X return (char *) 0;
- X }
- X }
- X /* NOTREACHED */
- X}
- X
- X/* Parse one line of nodelist to node structure. Return NULL is there
- X was error's in that line or missing fields. */
- X
- XNode *
- Xparse_entry(entry, buffer)
- X Node *entry;
- X char *buffer;
- X{
- X char *cp;
- X int n;
- X
- X /* strip newline if exists */
- X if (cp = strchr(buffer, '\n'))
- X *cp = 0;
- X
- X /* get type of entry */
- X if (!strncmp("Zone,", buffer, 5))
- X entry->type = ZONE;
- X else if (!strncmp("Region,", buffer, 7))
- X entry->type = REGION;
- X else if (!strncmp("Host,", buffer, 5))
- X entry->type = HOST;
- X else if (!strncmp("Hub,", buffer, 4))
- X entry->type = HUB;
- X else if (!strncmp("Pvt,", buffer, 4))
- X entry->type = PVT;
- X else if (!strncmp("Hold,", buffer, 5))
- X entry->type = HOLD;
- X else if (!strncmp("Down,", buffer, 5))
- X entry->type = DOWN;
- X else if (!strncmp("Kenl,", buffer, 5))
- X entry->type = KENL;
- X else if (*buffer == ',')
- X entry->type = NORMAL;
- X else
- X {
- X log("Unknown type in line '%s'", buffer);
- X return (Node *) 0;
- X }
- X
- X /* get net/region/node number */
- X if ((cp = strchr(buffer, ',')) == NULL)
- X {
- X log("Missing zone/net/node/region in line '%s'", buffer);
- X return (Node *) 0;
- X }
- X if ((n = atoi(++cp)) == 0)
- X {
- X log("Value of zone/net/node/region is 0 in line '%s'", buffer);
- X return (Node *) 0;
- X }
- X if (entry->type == ZONE)
- X {
- X entry->zone = n;
- X entry->net = 0;
- X entry->node = 0;
- X entry->point = 0;
- X compile_zone = n;
- X debug(8, "Zone %d", compile_zone);
- X }
- X else if (entry->type == REGION)
- X {
- X entry->zone = compile_zone;
- X entry->region = n;
- X entry->net = n; /* For compatibility with old version */
- X entry->node = 0;
- X entry->point = 0;
- X compile_region = n;
- X compile_net = n; /* For compatibility with old version */
- X debug(8, "Region %d", compile_region);
- X }
- X else if (entry->type == HOST)
- X {
- X entry->zone = compile_zone;
- X entry->region = compile_region;
- X entry->net = n;
- X entry->node = 0;
- X entry->point = 0;
- X compile_net = n;
- X debug(8, "Net %d", compile_net);
- X }
- X else
- X {
- X entry->zone = compile_zone;
- X entry->region = compile_region;
- X entry->net = compile_net;
- X entry->node = n;
- X entry->point = 0;
- X }
- X while (*cp && *cp++ != ',');
- X
- X /* get node/net/region name */
- X if ((cp = parse_field(cp, entry->name, sizeof(entry->name))) == NULL)
- X {
- X log("Invalid name in line '%s'", buffer);
- X return (Node *) 0;
- X }
- X
- X /* get city */
- X if ((cp = parse_field(cp, entry->city, sizeof(entry->city))) == NULL)
- X {
- X log("Invalid city in line '%s'", buffer);
- X return (Node *) 0;
- X }
- X
- X /* get sysop */
- X if ((cp = parse_field(cp, entry->sysop, sizeof(entry->sysop))) == NULL)
- X {
- X log("Invalid sysop in line '%s'", buffer);
- X return (Node *) 0;
- X }
- X
- X /* get phone number */
- X if ((cp = parse_field(cp, entry->phone, sizeof(entry->phone))) == NULL)
- X {
- X log("Invalid phone-number in line '%s'", buffer);
- X return (Node *) 0;
- X }
- X
- X /* get maximum baud rate */
- X if ((n = atoi(cp)) == 0)
- X {
- X log("Baud rate is 0 in line '%s'", buffer);
- X return (Node *) 0;
- X }
- X entry->speed = n;
- X while (*cp && *cp++ != ',');
- X
- X /* get flags */
- X (void) strncpy(entry->flags, cp, sizeof(entry->flags));
- X entry->flags[sizeof(entry->flags) - 1] = 0;
- X
- X /* all done */
- X return entry;
- X}
- X
- X/* Get entry for one node from nodelist. Return NULL, if there is no
- X entry for that node. */
- X
- XNode *
- Xnode_entry(node)
- X Node node;
- X{
- X static Node entry;
- X FILE *fp;
- X char buffer[BUFSIZ];
- X extern char *bsearch();
- X long offset;
- X NODEINDEX *nodeip, nodei;
- X
- X /* Read index file into memory */
- X
- X if (!nodeindex)
- X if (read_nodeindex())
- X {
- X log("$Unable to read nodelist");
- X return (Node *) 0;
- X }
- X
- X nodei.zone = node.zone;
- X nodei.net = node.net;
- X nodei.node = node.node;
- X
- X debug(2, "Searching %s from %d nodes", ascnodei(nodei), nodes);
- X nodeip = (NODEINDEX *) bsearch( (char *) &nodei, (char *) nodeindex,
- X (unsigned) nodes, sizeof(NODEINDEX),
- X cmpnodeindex);
- X
- X if (nodeip) {
- X offset = nodeip->offset;
- X
- X /* open nodelist */
- X (void) sprintf(buffer, "%s/%s", LIBDIR, NODELIST);
- X if ((fp = fopen(buffer, "r")) == NULL)
- X {
- X log("$Unable to open %s", buffer);
- X return (Node *) 0;
- X }
- X
- X if (fseek(fp, offset, 0))
- X {
- X log("$Seek error on nodelist");
- X (void) fclose(fp);
- X return (Node *) 0;
- X }
- X
- X fgets(buffer, BUFSIZ, fp);
- X fclose(fp);
- X
- X compile_zone = nodeip->zone;
- X compile_net = nodeip->net;
- X return parse_entry(&entry, buffer);
- X }
- X
- X log("Could not find node %s", ascnodei(nodei));
- X
- X /* we didn't find net/region */
- X (void) fclose(fp);
- X return (Node *) 0;
- X}
- X
- Xchar *dialtable[] = { DIALTABLE };
- X
- Xdial_translation(dest, source)
- X char *dest, *source;
- X{
- X register int count = 0;
- X
- X for (;;) {
- X if (!*dialtable[count] ||
- X !strncmp(dialtable[count], source, strlen(dialtable[count]))) {
- X
- X /* Matched, take prefix, */
- X strcpy(dest, dialtable[count + 1]);
- X
- X /* Then add phone number */
- X strcat(dest, source + strlen(dialtable[count]));
- X return;
- X }
- X count += 2;
- X }
- X}
- X
- Xstatic char **aliastable = NULL;
- Xstatic allocated = 0;
- Xstatic aliases = 0;
- X
- Xexpand_aliastable()
- X{
- X if (!aliastable)
- X {
- X aliastable = (char **) malloc(sizeof(char *) * 20);
- X if (aliastable) allocated = 20;
- X }
- X
- X if (aliases == allocated) /* Need more pointers */
- X {
- X allocated += 20;
- X aliastable = (char **) realloc( (char *) aliastable,
- X sizeof(char *) * allocated);
- X if (!aliastable)
- X {
- X log("Cannot realloc %d bytes", sizeof(char *) * allocated);
- X return -1;
- X }
- X }
- X return 0;
- X}
- X
- X#define FILENAME_SIZE 256
- X
- Xsearch_name(name)
- X char *name;
- X{
- X Node entry;
- X FILE *fp;
- X char buffer[BUFSIZ];
- X extern char *bsearch();
- X char *nlname;
- X long offset;
- X NAMEINDEX *nameip, namei;
- X
- X if (!nameindex)
- X if (read_nameindex())
- X {
- X log("$Unable to read namelist");
- X return -1;
- X }
- X
- X strncpy(namei.name, name, 36);
- X namei.name[35] = 0;
- X
- X nameip = (NAMEINDEX *) bsearch( (char *) &namei, (char *) nameindex,
- X (unsigned) names, sizeof(NAMEINDEX),
- X cmpnameindex);
- X
- X if (nameip)
- X {
- X offset = nameip->offset;
- X
- X /* Open nodelist */
- X if ((fp =
- X fopen(nlname = sprintfs("%s/%s", LIBDIR, NODELIST), "r")) == NULL)
- X {
- X log("$Unable to open nodelist %s", nlname);
- X return -1;
- X }
- X
- X if (fseek(fp, offset, 0))
- X {
- X log("$Seek error on nodelist");
- X (void) fclose(fp);
- X return -1;
- X }
- X
- X fgets(buffer, BUFSIZ, fp);
- X fclose(fp);
- X
- X compile_zone = nameip->zone;
- X compile_net = nameip->net;
- X if (parse_entry(&entry, buffer) == NULL) return -1;
- X
- X debug(1, "Search name %s returns %d:%d/%d.%d", name,
- X entry.zone, entry.net, entry.node, entry.point);
- X memcpy( (char *) &originnode, (char *) &entry, sizeof(Node));
- X return 0;
- X }
- X
- X debug(1, "Search name %s return no node", name);
- X return -1;
- X}
- X
- SHAR_EOF
- chmod 0644 nodelist.c || echo "restore of nodelist.c fails"
- echo "x - extracting gethostname.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > gethostname.c &&
- X#ifndef lint
- Xstatic char *sccsid = "@(#)%M% %I% Teemu Torma %H%";
- X#endif
- X
- X/* Get host name. This emulates routine with same name in BSD-Unix.
- X
- X @(#)Copyright (c) 1987 by Teemu Torma
- X
- X Permission is given to distribute this program and alter this code as
- X needed to adapt it to forign systems provided that this header is
- X included and that the original author's name is preserved. */
- X
- X#include <sys/utsname.h>
- X#include <string.h>
- X
- X/* Get name of this uucp-node. Name is stored in buffer. Len in maximum
- X length of buffer. Return -1 if can not do uname(2), otherwise 0. */
- X
- Xint
- Xgethostname(buffer, len)
- X char *buffer;
- X int len;
- X{
- X struct utsname name;
- X
- X if (uname(&name) == -1)
- X return -1;
- X (void) strncpy(buffer, name.nodename, len);
- X buffer[len - 1] = 0;
- X return 0;
- X}
- SHAR_EOF
- chmod 0644 gethostname.c || echo "restore of gethostname.c fails"
- echo "x - extracting dateconv.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > dateconv.c &&
- X#ifndef lint
- Xstatic char *sccsid = "@(#)%M% %I% Teemu Torma %H%";
- X#endif
- X
- X/* Convert date to type time_t (time in seconds since 1 Jan 1970).
- X
- X @(#)Copyright (c) 1987 by Teemu Torma
- X
- X Permission is given to distribute this program and alter this code as
- X needed to adapt it to forign systems provided that this header is
- X included and that the original author's name is preserved. */
- X
- X/* LINTLIBRARY */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <time.h>
- X#include "fnet.h"
- X
- X#define epoch 1970
- X#define daysec (24l * 60l * 60l)
- X#define AM 1
- X#define PM 2
- X
- X/* days in each month */
- Xstatic int mdays[12] = {
- X 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,
- X};
- X
- X/* Convert hours, minutes and seconds to seconds */
- X
- Xtime_t
- Xtimeconv(hh, mm, ss, mer)
- X int hh, mm, ss;
- X int mer;
- X{
- X /* check correctness of time */
- X if (mm < 0 || mm > 59 || ss < 0 || ss > 59)
- X return (time_t) -1;
- X
- X /* count time */
- X switch (mer)
- X {
- X case AM:
- X if (hh < 1 || hh > 12)
- X return(time_t) 1;
- X return (60L * ((hh % 12) * 60L + mm) + ss);
- X case PM:
- X if (hh < 1 || hh > 12)
- X return(time_t) 1;
- X return (60L * ((hh % 12 +12) * 60L + mm) + ss);
- X case 24:
- X if (hh < 0 || hh > 23)
- X return (time_t) 1;
- X return (60L * (hh * 60L + mm) + ss);
- X default:
- X return (time_t) 1;
- X }
- X /* NOTREACHED */
- X}
- X
- X/* Convert date to seconds from beginning of year 1970 (normal Unix
- X time). Return -1 if something wen't wrong. */
- X
- X/* ARGSUSED */
- Xtime_t
- Xdateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
- X int mm, dd, yy, h, m, s;
- X int mer, zone;
- X{
- X time_t tod, jdate;
- X register int n;
- X
- X /* if negative year make it positive */
- X if (yy < 0)
- X yy = -yy;
- X
- X /* if year is 00..99 make it right */
- X if (yy < 100)
- X yy += 1900;
- X
- X /* count days for february */
- X mdays[1] = 28 + (yy % 4 == 0 && (yy % 100 != 0 || yy % 400 == 0));
- X
- X /* check correctess of date (year 1970..1999) */
- X if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 || dd < 1 ||
- X dd > mdays[--mm])
- X return (time_t) -1;
- X
- X /* counts days from beginning of year */
- X jdate = (time_t ) (dd - 1);
- X for (n = 0; n < mm; n++)
- X jdate += (time_t) mdays[n];
- X
- X /* add years to days */
- X for (n = epoch; n < yy; n++)
- X jdate += (time_t) (365 + (n % 4 == 0));
- X
- X /* convert days to seconds */
- X jdate *= daysec;
- X
- X /* add time of day */
- X if ((tod = timeconv(h, m, s, mer)) < 0)
- X return (time_t) -1;
- X jdate += tod;
- X
- X /* add time zone to date */
- X jdate += (time_t) zone * 60L;
- X
- X return jdate;
- X}
- SHAR_EOF
- chmod 0644 dateconv.c || echo "restore of dateconv.c fails"
- echo "x - extracting address.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > address.c &&
- X#ifndef lint
- Xstatic char *sccsid = "@(#)%M% %I% Teemu Torma %H%";
- X#endif
- X
- X/* Routines to handle fidonet addresses. Currently addres format in outside
- X fidonet is <name>@<node>.<net>.fidonet. This will propablty change when
- X zones are coming. Those standards are ready, but I haven't seen them
- X yet.
- X
- X Mon Oct 3 02:43:49 1988
- X zones-format will be <name>@<point>.<node>.<net>.<zone>.fidonet.
- X Fidonet-like format maybe would be easier to get used to but
- X parsing it with sendmails etc would be more difficult. Notice that there
- X certainly will be problems if different number of numbers than 4
- X is specified. I will use following solution:
- X
- X case 4: assume point.node.net.zone
- X case 3: assume node.net.zone (point 0)
- X case 2: assume node.net (in current zone, point 0)
- X case 1: assume node (in current net, zone, point 0)
- X
- X Other way would be to force users to use zones and/or try to check
- X other possibilities by checking if its on the nodelist. I don't
- X really like points, they make life difficult, they could just be local
- X nodes off the nodelist, and no special support would be needed!
- X
- X @(#)Copyright (c) 1987 by Teemu Torma
- X
- X Permission is given to distribute this program and alter this code as
- X needed to adapt it to forign systems provided that this header is
- X included and that the original author's name is preserved. */
- X
- X/* LINTLIBRARY */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <string.h>
- X#include <sys/types.h>
- X#include "hsu.h"
- X#include "config.h"
- X#include "fnet.h"
- X#include "nodelist.h"
- X#include "shuffle.h"
- X
- X
- X/* Parse fidonet address to name, net and node. Address contains address,
- X and name, net and node will be returned. Return NULL is it was valid
- X fidonet address, otherwise string to error message. */
- X
- Xchar *
- Xparse_address(address, name, node)
- X char *address, *name;
- X Node *node;
- X{
- X static char error[64];
- X register char *cp;
- X register int cnt;
- X
- X /* make address to lowercase */
- X for (cp = address; *cp; cp++)
- X if (isupper(*cp))
- X *cp = tolower(*cp);
- X
- X /* Get name. We assume that name has space at least 36 charcers (maximum
- X length of name in fido). First check wheather format is name@domain
- X of domain!name format. */
- X if ((cp = strchr(address, '!')) != NULL)
- X {
- X debug(2, "Fidonet address domain!name");
- X for (cp++, cnt = 0; *cp && cnt < 35; cnt++, cp++)
- X name[cnt] = *cp;
- X name[cnt] = 0;
- X cp = address;
- X debug(3, "Name %s", name);
- X }
- X else
- X {
- X debug(2, "Fidonet address name@domain");
- X for (cp = address, cnt = 0; *cp && cnt < 35 && *cp != '@'; cp++, cnt++)
- X name[cnt] = *cp;
- X name[cnt] = 0;
- X debug(3, "Name %s", name);
- X
- X if (*cp != '@')
- X {
- X /* name is too long or address is invalid */
- X while (*cp && *cp != '@')
- X cp++;
- X if (*cp == 0)
- X {
- X debug(1, "Invalid address: %s: missing @", address);
- X (void) sprintf(error, "No @ in address %s", address);
- X return error;
- X }
- X }
- X cp++;
- X }
- X
- X debug(2, "Address %s, up to '!' or end", cp);
- X
- X if (parseinternode(cp, node))
- X {
- X sprintf(error, "Bad address %s", cp);
- X return error;
- X }
- X
- X#ifdef NEEDED
- X /* now parse address, cp points to beginning of it. */
- X for (*node = 0; isdigit(*cp); cp++)
- X *node = 10 * *node + *cp - '0';
- X if (*cp != '.')
- X {
- X debug(1, "Invalid address: %s: no . after node", address);
- X debug(2, "Rest of address %s, node %d", cp, *node);
- X (void) sprintf(error, "No net number in address %s", address);
- X return error;
- X }
- X
- X /* get net */
- X for (cp++, *net = 0; isdigit(*cp); cp++)
- X *net = 10 * *net + *cp - '0';
- X if (*cp != '.')
- X {
- X debug(1, "Invalid address: %s: no . after net", address);
- X debug(2, "Rest of address %s, net/node %d/%d", *net, *node);
- X (void) sprintf(error, "No domain in address %s", address);
- X return error;
- X }
- X
- X cp++;
- X debug(3, "Domain %s", cp);
- X
- X /* check that .fidonet is present */
- X if (strncmp(cp, "fidonet", 7) || (cp[7] != 0 && cp[7] != '!'))
- X {
- X debug(1, "Invalid address: %s: not .fidonet domain", address);
- X (void) sprintf(error, "Domain is not .fidonet in address %s", address);
- X return error;
- X }
- X
- X#endif
- X /* we're done */
- X return NULL;
- X}
- X
- Xreturnbad(errtype, s, node)
- X char *errtype, *s;
- X Node *node;
- X{
- X log("Bad address %s : %s, returning my node", s, errtype);
- X node->zone = MY_ZONE;
- X node->net = MY_NET;
- X node->node = MY_NODE;
- X node->point = MY_POINT;
- X return -1;
- X}
- X
- X/* Parse internet format fidonet address */
- X
- Xparseinternode(address, node)
- X char *address;
- X Node *node;
- X{
- X char *p, *s;
- X int numbers[4], count = 0;
- X
- X s = alloca(strlen(address) + 1);
- X strcpy(s, address);
- X numbers[0] = numbers[1] = numbers[2] = numbers[3] = -1;
- X
- X if (strlen(s) > strlen(".fidonet"))
- X if (!strcmp(s + strlen(s) - strlen(".fidonet"), ".fidonet"))
- X s[strlen(s) - strlen(".fidonet")] = 0;
- X
- X for (p = strtok(s, "."); p; p = strtok(NULL, "."))
- X numbers[count++] = atoi(p);
- X
- X if (!count) return returnbad("empty fidonet address", address, node);
- X if (count == 4)
- X {
- X node->zone = numbers[3];
- X node->net = numbers[2];
- X node->node = numbers[1];
- X node->point = numbers[0];
- X return 0;
- X }
- X
- X if (numbers[0] == -1) return returnbad("no node", address, node);
- X if (numbers[1] == -1) numbers[1] = MY_NET;
- X if (numbers[2] == -1) numbers[2] = MY_ZONE;
- X node->zone = numbers[2];
- X node->net = numbers[1];
- X node->node = numbers[0];
- X node->point = 0;
- X return 0;
- X}
- X
- X/* It would have been more sensible if
- X fidonet addresses were down to up, it would be easier to parse.
- X
- X Fri Oct 7 12:09:21 1988
- X Removes non-numeric chars at start, Opus puts 'Opus ' there
- X */
- X
- Xparsefnetaddress(s, node)
- X char *s;
- X Node *node;
- X{
- X char *p, *lastnumber;
- X char nodenbuf[100];
- X
- X strncpy(nodenbuf, s, 99);
- X nodenbuf[99] = 0;
- X s = nodenbuf;
- X
- X node->zone = 0;
- X node->net = 0;
- X node->node = 0;
- X node->point = 0;
- X p = s;
- X
- X while (!isdigit(*p) && *p) p++;
- X
- X while (*p) {
- X switch (*p) {
- X case '0':
- X case '1':
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X case '7':
- X case '8':
- X case '9':
- X {
- X lastnumber = p;
- X while (isdigit(*++p));
- X continue;
- X }
- X case ':':
- X /* Previous number is zone */
- X if (node->zone) return returnbad("two zones", s, node);
- X node->zone = atoi(lastnumber);
- X lastnumber = p + 1;
- X break;
- X case '/':
- X /* Previous number is net */
- X if (node->net) return returnbad("two nets", s, node);
- X node->net = atoi(lastnumber);
- X lastnumber = p + 1;
- X break;
- X case '.':
- X /* Previous number is node */
- X if (node->node) return returnbad("two nodes", s, node);
- X node->node = atoi(lastnumber);
- X lastnumber = p + 1;
- X break;
- X case 0:
- X /* End: lastnumber should have point (or its at end, which gives us 0) */
- X node->node = atoi(lastnumber);
- X if (node->zone == 0) node->zone = MY_ZONE;
- X if (node->net == 0) node->net = MY_NET;
- X return 0;
- X default:
- X log("Bad char %d in %s", *p, s);
- X return returnbad("bad char", s, node);
- X }
- X p++;
- X }
- X if (node->zone == 0) node->zone = MY_ZONE;
- X if (node->net == 0) return returnbad("no net", s, node);
- X if (node->node == 0)
- X node->node = atoi(lastnumber);
- X
- X return 0;
- X}
- X
- X/* Return address in string format */
- X
- Xchar *ascnode(node)
- X Node node;
- X{
- X SHUFFLEBUFFERS;
- X
- X sprintf(tcharp, "%d:%d/%d.%d", node.zone, node.net, node.node, node.point);
- X return tcharp;
- X}
- X
- X/* Internet format */
- Xchar *internode(node)
- X Node node;
- X{
- X SHUFFLEBUFFERS;
- X
- X if (node.point)
- X sprintf(tcharp, "%d.%d.%d.%d.fidonet", node.point, node.node, node.net,
- X node.zone);
- X else
- X sprintf(tcharp, "%d.%d.%d.fidonet", node.node, node.net, node.zone);
- X
- X return tcharp;
- X}
- X
- X/* same for index node structure */
- X
- Xchar *ascnodei(node)
- X NODEINDEX node;
- X{
- X SHUFFLEBUFFERS;
- X
- X sprintf(tcharp, "%d:%d/%d", node.zone, node.net, node.node);
- X return tcharp;
- X}
- SHAR_EOF
- chmod 0644 address.c || echo "restore of address.c fails"
- echo "x - extracting crc.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > crc.c &&
- X#ifndef lint
- Xstatic char *sccsid = "@(#)%M% %I% Teemu Torma %H%";
- X#endif
- X
- X/*
- X * @(#)Copyright (C) Teemu Torma 1987
- X */
- X
- X#include <stdio.h>
- X
- X#ifdef NEEDED
- X/* ARGSUSED */
- Xint main(argc, argv, envp)
- Xint argc;
- Xchar **argv;
- Xchar **envp;
- X{
- X exit(0);
- X /* NOTREACHED */
- X}
- X#endif
- X
- X/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
- Xunsigned short crctab[256] = {
- X 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
- X 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
- X 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
- X 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
- X 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
- X 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
- X 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
- X 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
- X 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
- X 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
- X 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
- X 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
- X 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
- X 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
- X 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
- X 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
- X 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
- X 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
- X 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
- X 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
- X 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
- X 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- X 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
- X 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
- X 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
- X 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
- X 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
- X 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
- X 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
- X 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
- X 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
- X 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
- X};
- X
- X#ifdef NEEDED
- Xstatic long cr3tab[] = { /* CRC polynomial 0xedb88320 */
- X0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
- 0xe963a535, 0x9e6495a3,
- X0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd,
- 0xe7b82d07, 0x90bf1d91,
- X0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb,
- 0xf4d4b551, 0x83d385c7,
- X0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
- 0xfa0f3d63, 0x8d080df5,
- X0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447,
- 0xd20d85fd, 0xa50ab56b,
- X0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75,
- 0xdcd60dcf, 0xabd13d59,
- X0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
- 0xcfba9599, 0xb8bda50f,
- X0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11,
- 0xc1611dab, 0xb6662d3d,
- X0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
- 0x9fbfe4a5, 0xe8b8d433,
- X0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
- 0x91646c97, 0xe6635c01,
- X0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b,
- 0x8208f4c1, 0xf50fc457,
- X0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49,
- 0x8cd37cf3, 0xfbd44c65,
- X0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
- 0xa4d1c46d, 0xd3d6f4fb,
- X0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
- 0xaa0a4c5f, 0xdd0d7cc9,
- X0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3,
- 0xb966d409, 0xce61e49f,
- X0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
- 0xb7bd5c3b, 0xc0ba6cad,
- X0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af,
- 0x04db2615, 0x73dc1683,
- X0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d,
- 0x0a00ae27, 0x7d079eb1,
- X0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
- 0x196c3671, 0x6e6b06e7,
- X0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9,
- 0x17b7be43, 0x60b08ed5,
- X0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767,
- 0x3fb506dd, 0x48b2364b,
- SHAR_EOF
- echo "End of part 4"
- echo "File crc.c is continued in part 5"
- echo "5" > s2_seq_.tmp
- exit 0
-
-