home *** CD-ROM | disk | FTP | other *** search
- From: mj@dfv.rwth-aachen.de (Martin Junius)
- Newsgroups: alt.sources
- Subject: FIDOGATE 04/06
- Message-ID: <mj.675078457@suntex>
- Date: 24 May 91 09:47:37 GMT
-
- ---- Cut Here and feed the following to sh ----
- #!/bin/sh
- # This is part 04 of a multipart archive
- # ============= funcs.c ==============
- if test -f 'funcs.c' -a X"$1" != X"-c"; then
- echo 'x - skipping funcs.c (File already exists)'
- else
- echo 'x - extracting funcs.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'funcs.c' &&
- /*:ts=4*/
- /*****************************************************************************
- X * FIDOGATE --- Gateway software UNIX <-> FIDO
- X *
- X * $Id: funcs.c,v 1.8 91/05/21 08:48:10 mj Exp $
- X *
- X * Miscancelleus functions, logging, sequence numberic etc.
- X *
- X * $Log: funcs.c,v $
- X * Revision 1.8 91/05/21 08:48:10 mj
- X * Less verbose log().
- X *
- X * Revision 1.7 90/12/02 21:21:57 mj
- X * Changed program header to mention both authors of the original
- X * software posted to alt.sources.
- X *
- X * Revision 1.6 90/11/05 20:49:53 mj
- X * Changed my signature in all program headers.
- X *
- X * Revision 1.5 90/11/01 14:33:39 mj
- X * Added function xtol()
- X *
- X * Revision 1.4 90/10/29 21:19:14 mj
- X * Added functions strnicmp() and stricmp().
- X *
- X * Revision 1.3 90/09/08 18:45:54 mj
- X * Some changes.
- X *
- X * Revision 1.2 90/08/12 14:14:09 mj
- X * Removed unused code.
- X *
- X * Revision 1.1 90/06/28 22:04:15 mj
- X * Much rework of the sources, no more hsu.h and other clean up.
- X * rmail improved, now handles special XENIX quirks.
- X *
- X * Revision 1.0 90/06/21 19:01:04 mj
- X * Initial revision
- X *
- X *
- X *****************************************************************************
- X * This version hacked and maintained by:
- X * _____ _____
- X * | |___ | Martin Junius FIDO: 2:242/6.1 2:242/6.0
- X * | | | | | | Republikplatz 3 DOMAIN: mju@dfv.rwth-aachen.de
- X * |_|_|_|_____| D-5100 Aachen Tel. (Voice) 0241-86931
- X *
- X * Original version of these programs and files:
- X *
- X * Teemu Torma
- X * Heikki Suonsivu FIDO: 2:504/1 UUCP: ...!mcsun!santra!hsu
- X *
- X *****************************************************************************/
- X
- #include "fidogate.h"
- X
- #include <varargs.h>
- #include <unistd.h>
- X
- #include "shuffle.h"
- X
- X
- /*
- X * We supply our own version of the toupper()/tolower()
- X * macros, because the exact behaviour of those in
- X * <ctype.h> varies among systems.
- X */
- X
- #undef _toupper
- #undef _tolower
- #undef toupper
- #undef tolower
- X
- #define _toupper(c) ((c)-'a'+'A')
- #define _tolower(c) ((c)-'A'+'a')
- #define toupper(c) (islower(c) ? _toupper(c) : (c))
- #define tolower(c) (isupper(c) ? _tolower(c) : (c))
- X
- X
- X
- #define labs(n) (((n) < 0l) ? (-(n)) : (n))
- X
- extern void exit(), perror();
- extern long atol();
- extern time_t time();
- X
- X
- /***** strnicmp() --- compare n chars of strings ignoring case ***************/
- X
- int strnicmp(sa, sb, len)
- register char *sa, *sb;
- int len;
- {
- X while(len--)
- X if(tolower(*sa) == tolower(*sb)) {
- X sa++;
- X sb++;
- X }
- X else if(tolower(*sa) < tolower(*sb))
- X return(-1);
- X else
- X return(1);
- X return(0);
- }
- X
- X
- X
- /***** stricmp() --- compare strings ignoring case ***************************/
- X
- int stricmp(sa, sb)
- register char *sa, *sb;
- {
- X while(tolower(*sa) == tolower(*sb)) {
- X if(!*sa)
- X return(0);
- X sa++;
- X sb++;
- X }
- X return(tolower(*sa) - tolower(*sb));
- }
- X
- X
- X
- /***** xtol() --- convert hex string to long *********************************/
- X
- long xtol(s)
- char *s;
- {
- long val = 0;
- int n;
- X
- X while(*s) {
- X n = toupper(*s) - (isalpha(*s) ? 'A'-10 : '0');
- X val = val*16 + n;
- X s++;
- X }
- X return(val);
- }
- X
- X
- X
- FILE *logfp = NULL;
- X
- /* Lock file descriptor up to the end. If yur system doesn't have lockf()
- X (also known as locking()), or other region or file locking function
- X or system call, this should be done with lock-files. */
- X
- int
- lock(fd)
- X int fd;
- {
- #ifdef LOCK_LOCKF
- X return lockf(fd, F_LOCK, 0l);
- #else
- X return locking(fd, F_LOCK, 0l);
- #endif
- }
- X
- /* Unlock file descriptor up to the end. Routine which calls this should
- X first seek to original position. */
- X
- int
- unlock(fd)
- X int fd;
- {
- #ifdef LOCK_LOCKF
- X return lockf(fd, F_ULOCK, 0l);
- #else
- X return locking(fd, F_ULOCK, 0l);
- #endif
- }
- X
- /* Return ascii-date in specified format. If format string is null, return
- X date as date(1) returns it. Format is same than date(1) has, in addition
- X %z, which means timezone name. Clock is the time to convert, if NULL,
- X we'll use current time. */
- X
- char *
- date(fmt, clock)
- X char *fmt;
- X time_t *clock;
- {
- X /* names for weekdays */
- X static char *weekdays[] = {
- X "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
- X };
- X
- X /* names for months */
- X static char *months[] = {
- X "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- X };
- X
- X static char buffer[80];
- X char *bp = buffer;
- X time_t _clock;
- X struct tm *tm;
- X
- X if (!clock)
- X _clock = time((long *) 0);
- X tm = localtime(clock ? clock : &_clock);
- X
- X /* if no format string, this is default */
- X if (!fmt)
- X fmt = "%a %h %d %T %z 19%y";
- X
- X for (*bp = 0; *fmt; fmt++)
- X switch (*fmt)
- X {
- X case '%':
- X switch (*++fmt)
- X {
- X /* newline */
- X case 'n':
- X *bp++ = '\n';
- X break;
- X /* tabulator */
- X case 't':
- X *bp++ = '\t';
- X break;
- X /* month number 1-12 */
- X case 'm':
- X (void) sprintf(bp, "%02d", tm->tm_mon + 1);
- X while (*bp)
- X bp++;
- X break;
- X /* day of month 1-31 */
- X case 'd':
- X (void) sprintf(bp, "%2d", tm->tm_mday);
- X while (*bp)
- X bp++;
- X break;
- X case 'q':
- X (void) sprintf(bp, "%02d", tm->tm_mday);
- X while (*bp)
- X bp++;
- X break;
- X /* year 00-99 */
- X case 'y':
- X (void) sprintf(bp, "%02d", tm->tm_year);
- X while (*bp)
- X bp++;
- X break;
- X /* date in format YY/MM/DD */
- X case 'D':
- X (void) sprintf(bp, "%02d/%02d/%02d", tm->tm_year,
- X tm->tm_mon + 1, tm->tm_mday);
- X while (*bp)
- X bp++;
- X break;
- X /* hour 0-23 */
- X case 'H':
- X (void) sprintf(bp, "%02d", tm->tm_hour);
- X while (*bp)
- X bp++;
- X break;
- X /* minutes 0-59 */
- X case 'M':
- X (void) sprintf(bp, "%02d", tm->tm_min);
- X while (*bp)
- X bp++;
- X break;
- X /* seconds 0-59 */
- X case 'S':
- X (void) sprintf(bp, "%02d", tm->tm_sec);
- X while (*bp)
- X bp++;
- X break;
- X /* time in format HH:MM:SS */
- X case 'T':
- X (void) sprintf(bp, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min,
- X tm->tm_sec);
- X while (*bp)
- X bp++;
- X break;
- X /* day of year 1-356 */
- X case 'j':
- X (void) sprintf(bp, "%03d", tm->tm_yday + 1);
- X while (*bp)
- X bp++;
- X break;
- X /* weekday 0-6 */
- X case 'w':
- X (void) sprintf(bp, "%d", tm->tm_wday);
- X while (*bp)
- X bp++;
- X break;
- X /* name of weekday 'Mon', 'Tue', ... , 'Sun' */
- X case 'a':
- X (void) strcpy(bp, weekdays[tm->tm_wday]);
- X while (*bp)
- X bp++;
- X break;
- X /* name of month 'Jan', 'Feb', ... , 'Dec' */
- X case 'h':
- X (void) strcpy(bp, months[tm->tm_mon]);
- X while (*bp)
- X bp++;
- X break;
- X /* name of timezone, e.g. EST */
- X case 'z':
- X (void) strcpy(bp, *tzname);
- X while (*bp)
- X bp++;
- X break;
- X /* numeric time zone, e.g. +0200 */
- X case 'o':
- X (void) sprintf(bp, "%c%02ld%02ld", (timezone <= 0l) ? '+' : '-',
- X (labs(timezone) / (60l * 60l)),
- X (labs(timezone) % (60l * 60l)));
- X while (*bp)
- X bp++;
- X break;
- X case 'l':
- X /* military time zone, Z = UT, A = -1, M = -12, (J not used),
- X N = +1, Y = +12.. */
- X *bp = (timezone == 0l) ? 'Z' : ((int) (labs(timezone) /
- X (60l * 60l)) +
- X ((timezone < 0l) ? 'M' : '@'));
- X if (timezone > 0l && *bp >= 'J')
- X (*bp)++;
- X *++bp = 0;
- X break;
- X default:
- X *bp++ = *fmt;
- X break;
- X }
- X break;
- X default:
- X *bp++ = *fmt;
- X break;
- X }
- X
- X *bp = 0;
- X return buffer;
- }
- X
- X
- X
- /*
- X * strerror() --- get string from sys_errlist[]
- X */
- X
- char *
- strerror(errnum)
- int errnum;
- {
- extern int sys_nerr;
- extern char *sys_errlist[];
- X
- X if (errnum > 0 && errnum < sys_nerr)
- X return sys_errlist[errnum];
- X return "";
- }
- X
- X
- X
- /*
- X * Log to logfile. If logfile is not open, open it.
- X *
- X * If first character in format string is '$', print also errno. If external
- X * variable verbose is set, logging will be done also to stderr.
- X */
- X
- /**VARARGS**/
- void
- log(va_alist)
- va_dcl
- {
- va_list args;
- char *fmt;
- X
- X va_start(args);
- X
- X fmt = va_arg(args, char *);
- X
- X if(!logfp)
- X if ((logfp = fopen(LOGFILE, "a")) == NULL) {
- X perror("Cannot open log file");
- X return;
- X }
- X
- X (void) fprintf(logfp, "%s: ", date("%d %h %y %H:%M", (long *) 0));
- X (void) vfprintf(logfp, *fmt == '$' ? fmt + 1 : fmt, args);
- X if (*fmt == '$')
- X (void) fprintf(logfp, "\n\t\terrno = %d (%s)\n", errno, strerror(errno));
- X else
- X (void) fprintf(logfp, "\n");
- X (void) fflush(logfp);
- X
- X /*
- X * if verbose is set, print also to stderr (without date)
- X */
- X if (verbose) {
- X (void) vfprintf(stderr, *fmt == '$' ? fmt + 1 : fmt, args);
- X if (*fmt == '$')
- X (void) fprintf(stderr, "\n\t\terrno = %d (%s)\n", errno, strerror(errno));
- X else
- X (void) fprintf(stderr, "\n");
- X (void) fflush(stderr);
- X }
- X
- X va_end(args);
- }
- X
- X
- X
- /*
- X * Debug output. First argument should be number, rest are used arguments
- X * for vfprintf(3S). If external variable verbose has equal or greater
- X * value than first number, vfprintf(3S) will be used to print other
- X * arguments to stderr.
- X */
- X
- /**VARARGS**/
- void
- debug(va_alist)
- va_dcl
- {
- va_list args;
- char *fmt;
- int debug_level;
- X
- X va_start(args);
- X
- X debug_level = va_arg(args, int);
- X fmt = va_arg(args, char *);
- X
- X if (debug_level <= verbose) {
- X if (*fmt != '>' && *fmt != '<')
- X (void) vfprintf(stderr, fmt, args);
- X (void) fprintf(stderr, "\n");
- X }
- X
- X va_end(args);
- }
- X
- X
- X
- /* Get next job number. New sequemnt number will be taken from file
- X LIBDIR/seq, which is in ascii-format and new number will be saved
- X back there. */
- X
- long
- job_number()
- {
- X return sequencer(JOBSEQ);
- }
- X
- /* General sequencer */
- X
- long
- sequencer(filename)
- X char *filename;
- {
- X char seqfile[128], buffer[14];
- X FILE *fp;
- X long seqn = 0;
- X
- X (void) sprintf(seqfile, "%s", filename);
- X if ((fp = fopen(seqfile, "r+")) == NULL)
- X {
- X if (errno == ENOENT)
- X {
- X if ((fp = fopen(seqfile, "w+")) == NULL)
- X {
- X log("$Can not create seq-file %s", seqfile);
- X exit(EX_OSFILE);
- X }
- X fputs("1", fp);
- X fclose(fp);
- X if ((fp = fopen(seqfile, "r+")) == NULL)
- X {
- X log("$Can not open new seq-file %s", seqfile);
- X exit(EX_OSFILE);
- X }
- X }
- X else
- X {
- X log("$Can not open seq-file %s", seqfile);
- X exit(EX_OSFILE);
- X }
- X }
- X
- X (void) lock(fileno(fp));
- X if (fgets(buffer, 14, fp))
- X seqn = atol(buffer);
- X else
- X seqn = 0; /* This can theoretically fail */
- X
- X seqn++;
- X (void) rewind(fp);
- X (void) fprintf(fp, "%ld\n", seqn);
- X (void) unlock(fileno(fp));
- X (void) fclose(fp);
- X return seqn;
- }
- X
- /* Returns current last sequence number */
- long
- getsequencer(filename)
- X char *filename;
- {
- X char seqfile[128], buffer[14];
- X FILE *fp;
- X long seqn = 0;
- X
- X (void) sprintf(seqfile, "%s", filename);
- X if ((fp = fopen(seqfile, "r+")) == NULL)
- X {
- X if (errno == ENOENT)
- X {
- X if ((fp = fopen(seqfile, "w+")) == NULL)
- X {
- X log("$Can not create seq-file %s", seqfile);
- X exit(EX_OSFILE);
- X }
- X fputs("1", fp);
- X fclose(fp);
- X if ((fp = fopen(seqfile, "r+")) == NULL)
- X {
- X log("$Can not open new seq-file %s", seqfile);
- X exit(EX_OSFILE);
- X }
- X }
- X else
- X {
- X log("$Can not open seq-file %s", seqfile);
- X exit(EX_OSFILE);
- X }
- X }
- X
- X (void) lock(fileno(fp));
- X if (fgets(buffer, 14, fp))
- X seqn = atol(buffer);
- X else
- X seqn = 0; /* This can theoretically fail */
- X
- X (void) unlock(fileno(fp));
- X (void) fclose(fp);
- X return seqn;
- }
- X
- /* Get full pathname for spoolfile with new job number. File is in
- X spool directory and contains prefix followed by four digit
- X job number. */
- X
- char *
- spoolfile(prefix)
- X char *prefix;
- {
- X static char file[BUFLEN];
- X
- X (void) sprintf(file, "%s/%s%08ld", SPOOL, prefix, job_number());
- X return file;
- }
- X
- /* Return basename of s */
- X
- char *
- basename(s)
- X register char *s;
- {
- X register char *p = s;
- X
- X while (*s)
- X if (*s++ == '/')
- X p = s;
- X return p;
- }
- X
- /* Open file with directory name and filename. */
- X
- FILE *
- pfopen(dir, name, mode)
- X char *dir, *name, *mode;
- {
- X char filename[128];
- X
- X (void) strcpy(filename, dir);
- X (void) strcat(filename, "/");
- X (void) strcat(filename, name);
- X
- X return fopen(filename, mode);
- }
- X
- char *baseit(n)
- X long n;
- {
- X static char tab[] =
- X "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- X int count = 0;
- X
- X SHUFFLEBUFFERS;
- X
- X while (n)
- X {
- X tcharp[count] = tab[n % strlen(tab)];
- X n = n / strlen(tab);
- X count++;
- X }
- X
- X tcharp[count] = 0;
- X return tcharp;
- }
- X
- /* Create packet name for node given */
- X
- sprintpacketname(s, node)
- X char *s;
- X Node node;
- {
- X sprintf(s, "%s%s.%s.%s", node.point ?
- X sprintfs("%s.", baseit( (long) node.point)) : "",
- X baseit( (long) node.node), baseit( (long) node.net),
- X baseit( (long) node.zone));
- }
- X
- /* Create packet name for inbound xx.xx.xx.xx.num. If point
- X number is 0, don't include it. All numbers are in ~63-base to squeeze
- X them to as small space as possible. It could be more sensible solution
- X to make them directory trees but I would need more time for that. This
- X trick makes finding packets difficult.
- X */
- X
- sprintipacketname(s, node)
- X char *s;
- X Node node;
- {
- X sprintf(s, "%s%s.%s.%s.%s", node.point ?
- X sprintfs("%s.", baseit( (long) node.point)) : "",
- X baseit( (long) node.node), baseit( (long) node.net),
- X baseit( (long) node.zone), baseit(sequencer(IPACKETSEQUENCE)));
- }
- X
- X
- X
- /*
- X * Get line from config file. If *-character is in first column, report
- X * EOF, and otherwise return line with comments stripped. This causes
- X * effect, that each section in configuration file looks like it's own
- X * file. Arguments and return value are the same than with fgets(3S).
- X */
- X
- char *
- getcl(buffer, len, fp)
- char *buffer;
- int len;
- FILE *fp;
- {
- char *cp;
- X
- X while (fgets(buffer, len, fp)) {
- X buffer[strlen(buffer) - 1] = 0;
- X if (*buffer == '*')
- X return (char *) NULL;
- X /* everything after #-sign is comment */
- X if (cp = strchr(buffer, '#'))
- X *cp = 0;
- X /* if there's something left, return it */
- X if (*buffer)
- X return buffer;
- X }
- X return (char *) NULL;
- }
- X
- X
- X
- /* Scan config file to specified section. This mechanism is not very
- X effective, but otherwise it would get too complicated. */
- X
- void
- section(number, config)
- X int number;
- X FILE *config;
- {
- X char buffer[BUFLEN];
- X
- X (void) rewind(config);
- X while (--number)
- X while (getcl(buffer, BUFLEN, config))
- X /* skip section */;
- }
- X
- /* Get header field from file. */
- X
- #define MAX_HEADER_LEN 256
- X
- char *mheader(fp, headername)
- X FILE *fp;
- X char *headername;
- {
- X static char header[MAX_HEADER_LEN];
- X long position;
- X
- X position = ftell(fp);
- X
- X rewind(fp);
- X
- X /* Blank line terminates also, there shouldn't be any headers
- X after it any more */
- X
- X while (fgets(header, MAX_HEADER_LEN, fp) && *header != '\n')
- X if (!strncmp(header, headername, strlen(headername)))
- X {
- X /* Remove \n at end */
- X header[strlen(header) - 1] = 0;
- X fseek(fp, position, 0);
- X return header + strlen(headername);
- X }
- X
- X /* Not found, return empty string */
- X
- X fseek(fp, position, 0);
- X return "";
- }
- SHAR_EOF
- chmod 0644 funcs.c ||
- echo 'restore of funcs.c failed'
- Wc_c="`wc -c < 'funcs.c'`"
- test 15896 -eq "$Wc_c" ||
- echo 'funcs.c: original size 15896, current size' "$Wc_c"
- fi
- # ============= rmail.c ==============
- if test -f 'rmail.c' -a X"$1" != X"-c"; then
- echo 'x - skipping rmail.c (File already exists)'
- else
- echo 'x - extracting rmail.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'rmail.c' &&
- /*:ts=4*/
- /*****************************************************************************
- X * FIDOGATE --- Gateway software UNIX <-> FIDO
- X *
- X * $Id: rmail.c,v 1.12 91/05/07 23:59:33 mj Exp $
- X *
- X * Replacement for rmail.
- X * This program performs two functions:
- X * - it checks for mail addressed to the FIDO domain (.fidonet.org)
- X * and passes these messages to rfmail
- X * - It does some rudimentary transforming for domain style addresses
- X *
- X * This is just a small hack. For real mail processing use
- X * sendmail or smail, which are much better at those things.
- X *
- X * $Log: rmail.c,v $
- X * Revision 1.12 91/05/07 23:59:33 mj
- X * Uses new function isfido() to determine wheter address is for FIDO or
- X * not. Also supports rerouting of UUCP bang addresses to UUCP feed.
- X *
- X * Revision 1.11 91/04/28 21:40:55 mj
- X * Reroute mail to .uucp also via UUCPFEED.
- X *
- X * Revision 1.10 91/03/29 18:13:50 mj
- X * Improved routing for new Reply-To: adresses.
- X *
- X * Revision 1.9 91/01/05 13:08:58 mj
- X * Recognize MY_HOSTNAME.MY_DOMAIN as local address.
- X *
- X * Revision 1.8 90/12/09 17:35:50 mj
- X * Readdress mail to UUCPFEED. Removed unnessary `GATEWAY' code.
- X *
- X * Revision 1.7 90/12/02 21:22:32 mj
- X * Changed program header to mention both authors of the original
- X * software posted to alt.sources.
- X *
- X * Revision 1.6 90/11/05 20:51:06 mj
- X * Changed my signature in all program headers.
- X *
- X * Revision 1.5 90/07/11 17:57:50 mj
- X * Removed an obscure bug while feeding letter to mail receiving
- X * process. Once in a while the result was garbage. The cause was
- X * that the temporary file was opened by both the parent and the
- X * child process. Even if the child never ever does something to
- X * this file, this seems to confuse the operating system.
- X *
- X * Revision 1.4 90/07/07 17:54:47 mj
- X * Improved version. Now rmail is able to get destination address
- X * from message header, `To: ...' line. This has been implemented
- X * to make rmail work with nn, 'cause this news reader doesn't pass
- X * the address as a command line argument to rmail.
- X *
- X * Revision 1.3 90/07/01 15:20:37 mj
- X * Fixed some bugs in funpack caused by the removal of alloca().
- X * No more core dumps, but heaven knows, why it works now. Strange.
- X *
- X * Revision 1.2 90/07/01 13:46:12 mj
- X * Removed all calls to alloca(). All unsave malloc()'s without
- X * checking the returned pointer are now done via xmalloc().
- X * Fixed a malloc() error in rmail.
- X *
- X * Revision 1.1 90/06/28 22:04:56 mj
- X * Much rework of the sources, no more hsu.h and other clean up.
- X * rmail improved, now handles special XENIX quirks.
- X *
- X * Revision 1.0 90/06/19 18:34:10 mj
- X * Initial revision
- X *
- X *
- X *****************************************************************************
- X * This version hacked and maintained by:
- X * _____ _____
- X * | |___ | Martin Junius FIDO: 2:242/6.1 2:242/6.0
- X * | | | | | | Republikplatz 3 DOMAIN: mju@dfv.rwth-aachen.de
- X * |_|_|_|_____| D-5100 Aachen Tel. (Voice) 0241-86931
- X *
- X * Original version of these programs and files:
- X *
- X * Teemu Torma
- X * Heikki Suonsivu FIDO: 2:504/1 UUCP: ...!mcsun!santra!hsu
- X *
- X *****************************************************************************/
- X
- #include "fidogate.h"
- X
- X
- X
- #define PROGRAMNAME "rmail $Revision: 1.12 $"
- X
- X
- X
- /*
- X * This is special to XENIX:
- X * On XENIX, one can't use rmail for sending mail, 'cause this
- X * program doesn't generate a correct `From user ...' line for
- X * locally created mail. One has to execute /usr/lib/mail/execmail
- X * instead. But execmail *always* generates it's own `From ...'
- X * line, even if there is already one in the mail. So for mail
- X * of remote origin, e.g. those messages created by funpack, one
- X * must instruct execmail to handle this right. This can be done
- X * with the `-f' flags of execmail, whose argument replaces user
- X * in `From user ...' line.
- X */
- #ifdef M_XENIX
- # define EXECMAIL /* Use -f from, if neccessary */
- # undef RECVMAIL
- # define RECVMAIL "/usr/lib/mail/execmail" /* Force use of execmail */
- #endif
- X
- X
- X
- /* verbosity */
- /* int verbose = 3; /**/
- int verbose = INIT_VERBOSE; /**/
- X
- X
- X
- /*
- X * For domain type addresses (name@system):
- X *
- X * Local adress converting:
- X * user@localhost.localdomain -> user
- X * [.uucp domain to bang converting: ]
- X * [ user@system.uucp -> system!user ] disabled
- X * [ user@system -> system!user ]
- X * Forward other messages to UUCP feed
- X * user@system.domain -> uucpfeed!domain!user
- X * UUCP rerouting via UUCP feed
- X * system!user -> uucpfeed!system!user
- X */
- X
- char *process_address(addr)
- char *addr;
- {
- static char hostname[256];
- static char address[256];
- static char newaddress[256];
- char *p;
- int len;
- int not_uucp = FALSE;
- X
- X gethostname(hostname, 20);
- X strcpy(address, addr);
- X debug(3, "Address to process: %s", addr);
- X
- X if(p = strchr(address, '@')) {
- X /*
- X * Domain address: name@system.domain
- X *
- X * Isolate user name, p points to system.domain
- X */
- X *p++ = 0;
- X /*
- X * Remove suffix ".uucp"
- X */
- X len = strlen(p);
- #if 0
- X if(len>5 && (!strcmp(p+len-5, ".uucp") || !strcmp(p+len-5, ".UUCP")))
- X p[len - 5] = 0;
- X else if(strchr(p, '.'))
- #endif
- X not_uucp = TRUE;
- X /*
- X * If addressed to our hostname or full domain name,
- X * just send to user name
- X */
- X if(!strcmp(p, hostname))
- X *p = 0;
- X else {
- X strcat(hostname, MY_DOMAIN);
- X if(!strcmp(p, hostname))
- X *p = 0;
- X }
- X /*
- X * Construct converted address
- X */
- X if(!*p) /* Local address */
- X strcpy(newaddress, address);
- X else if(not_uucp) /* Address domain via UUCPFEED */
- X sprintf(newaddress, "%s!%s!%s", UUCPFEED, p, address);
- X else /* UUCP address */
- X sprintf(newaddress, "%s!%s", p, address);
- X debug(2, "Renamed %s to %s", addr, newaddress);
- X return strsave(newaddress);
- X }
- X else if(strchr(address, '!')) {
- X /*
- X * Bang address: system!user
- X */
- X sprintf(newaddress, "%s!%s", UUCPFEED, address);
- X return strsave(newaddress);
- X }
- X else
- X return strsave(address);
- }
- X
- X
- X
- /*
- X * Get name from `From user ...' line.
- X * Understood format of From line is:
- X * `From USER day mon dd hh:mm:ss [zone] yyyy [remote from SYSTEM]'
- X * Destroys contents of buf!
- X */
- X
- char *get_from_name(buf)
- char *buf;
- {
- char *name, *system;
- static char from[64];
- X
- X name = "anonymous"; /* Defaults */
- X system = "";
- X
- X buf += 5; /* Skip `From ' */
- X if(*buf) {
- X name = buf;
- X while(*buf && *buf!=' ' && *buf!='\t')
- X buf++;
- X if(*buf) {
- X *buf++ = 0;
- X /* Scan for `remote from ' */
- X while(strlen(buf) >= 12) /* 12 = strlen("remote from") */
- X if(!strncmp(buf, "remote from ", 12)) { /* gefunden! */
- X buf += 12;
- X system = buf;
- X while(*buf && *buf!=' ' && *buf!='\t' && *buf!='\n')
- X buf++;
- X *buf = 0;
- X break;
- X }
- X else
- X buf++;
- X }
- X }
- X
- X if(*system) {
- X strcpy(from, system);
- X strcat(from, "!");
- X }
- X else
- X *from = 0;
- X strcat(from, name);
- X
- X return(from);
- }
- X
- X
- X
- /*
- X * get_to_name() --- Get destination address from `To: ...' line
- X */
- X
- char *get_to_name(buffer)
- char *buffer;
- {
- register char *cp, *np;
- register int cnt;
- static char to[64];
- X
- X buffer += strlen("To: ");
- X *to = 0;
- X
- X /*
- X * Parse the name from `To: ...' line. There are basically
- X * two formats:
- X * `User Name <address>' or
- X * `address (User Name)'
- X * We'll try to figure it out which format sender uses.
- X */
- X if ((cp = strchr(buffer, '<')) && (np = strchr(cp, '>'))) {
- X /*
- X * Format is 'From: Name <address>'
- X */
- X for(np=cp+1, cnt=0; *np && *np!='>'; np++, cnt++)
- X to[cnt] = *np;
- X to[cnt] = 0;
- X }
- X else if ((cp = strchr(buffer, '(')) && (np = strchr(cp, ')'))) {
- X /*
- X * Format is 'From: address (Name)'
- X */
- X for(np=buffer, cnt=0; *np && *np!='(' && !isspace(*np); np++, cnt++)
- X to[cnt] = *np;
- X to[cnt] = 0;
- X }
- X else {
- X /*
- X * Not a recognized format, just copy
- X */
- X strncpy(to, buffer, 64);
- X to[63] = 0;
- X cnt = strlen(to);
- X if(to[cnt - 1] == '\n')
- X to[cnt - 1] = 0;
- X }
- X
- X return( *to ? to : NULL);
- }
- X
- X
- X
- /*
- X * Open stream associated with programs standard input. Program is invoked
- X * with given argument list. Popen(3S) would invoke mailer thru sh(1),
- X * so this uses less memory and is faster.
- X */
- X
- FILE *
- open_mailer(program, args, pid)
- char *program, **args;
- int *pid;
- {
- FILE *fp;
- int fd[2];
- X
- X /* create pipe */
- X if (pipe(fd) == -1) {
- X perror("rmail: pipe");
- X exit(EX_OSERR);
- X }
- X
- X switch (*pid = fork()) {
- X case -1: /* Error */
- X perror("rmail: fork failed");
- X exit(EX_OSERR);
- X case 0: /* Child */
- X (void) close(0);
- X if (dup(fd[0]) == 0) {
- X (void) close(fd[0]);
- X (void) close(fd[1]);
- X (void) execvp(program, args);
- X perror(program);
- X }
- X else
- X perror("rmail: dup");
- X exit(EX_OSERR);
- X default: /* Parent */
- X (void) close(fd[0]);
- X if ((fp = fdopen(fd[1], "w")) == NULL) {
- X perror("rmail: fdopen");
- X exit(EX_OSERR);
- X }
- X }
- X return fp;
- }
- X
- X
- X
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- int cnt;
- char **rargs, **fargs;
- int rrec = 0, frec = 0, rargc = 1, fargc = 1;
- int status = EX_OK;
- FILE *mailer;
- static char buffer[BUFSIZ];
- int stat_loc, pid;
- char *from;
- char *to;
- static char tempname[64];
- FILE *temp;
- int in_header_flag;
- char *addr;
- X
- X /*
- X * Allocate memory for argument lists of RECVMAIL and RFMAIL.
- X * 2 extra pointers are needed, 'cause we eventually insert
- X * `-f user' for XENIX execmail. 1 more extra pointer for
- X * address from `To: ...' line.
- X */
- X rargs = (char **)xmalloc( (argc + 4) * sizeof(char *) );
- X fargs = (char **)xmalloc( (argc + 4) * sizeof(char *) );
- X
- X rargs[0] = RECVMAIL;
- X fargs[0] = RFMAIL;
- X
- X /*
- X * Scan thru receiver list and put all receivers in fidonet in fido-
- X * mailer's receiver-list and all others in real rmails one. No
- X * options can be passed to fidomailer thru this, because it would
- X * be too difficult to determine which one goes to which one and
- X * there might be same options also. Somehow it's good that fidomailer
- X * is well hidden under this...
- X */
- X for (cnt = 1; cnt < argc; cnt++)
- X if (*argv[cnt] == '-')
- X rargs[rargc++] = strsave(argv[cnt]);
- X else {
- X if(isfido(argv[cnt])) {
- X /*
- X * Mail for FIDO.
- X */
- X debug(2, "Argument %d (receiver %d) in fidomailer: %s",
- X fargc, frec + 1, argv[cnt]);
- X fargs[fargc++] = strsave(argv[cnt]);
- X frec++;
- X }
- X else {
- X /*
- X * Not a valid FIDO address, so this must be for UUCP.
- X * In this case process address further to convert
- X * internet domain address name@system.domain to
- X * UUCP bang address system!name.
- X * Beware: result of process_address() may be a FIDO
- X * address again, so another check is necessary.
- X */
- X addr = process_address(argv[cnt]);
- X if(isfido(addr)) {
- X debug(2, "Argument %d (receiver %d) in fidomailer: %s",
- X fargc, frec + 1, addr);
- X fargs[fargc++] = addr;
- X frec++;
- X }
- X else {
- X debug(2, "Argument %d (receiver %d) in rmail: %s",
- X rargc, rrec + 1, addr);
- X rargs[rargc++] = addr;
- X rrec++;
- X }
- X }
- X }
- X
- X /*
- X * Open temporary file and copy mail from stdin to there
- X */
- X tmpnam(tempname);
- X temp = fopen(tempname, "w");
- X if(!temp) {
- X log("$Can't create temporary file %s", tempname);
- X exit(1);
- X }
- X *buffer = 0;
- X from = to = NULL;
- X in_header_flag = TRUE;
- #ifdef EXECMAIL
- X /*
- X * Look form `From user ...' line
- X */
- X *buffer = 0;
- X fgets(buffer, BUFSIZ, stdin);
- X if(!strncmp(buffer, "From ", 5)) {
- X from = get_from_name(buffer);
- X debug(3, "from = %s", from);
- X *buffer = 0;
- X }
- X else {
- X from = NULL;
- X goto test_header;
- X }
- #endif
- X while(fgets(buffer, BUFSIZ, stdin)) {
- test_header:
- X if(in_header_flag) {
- X if(*buffer == '\n')
- X in_header_flag = FALSE;
- X else if(!strncmp(buffer, "To: ", 4)) {
- X to = get_to_name(buffer);
- X debug(3, "to = %s", to);
- X }
- X }
- X fputs(buffer, temp);
- X }
- X fclose(temp);
- X
- X /*
- X * If no address on command line, then use the one from
- X * get_to_name()
- X */
- X if(!frec && !rrec && to) {
- X if(isfido(to)) {
- X debug(2, "Argument %d (receiver %d) in fidomailer: %s",
- X fargc, frec + 1, to);
- X fargs[fargc++] = strsave(to);
- X frec++;
- X }
- X else {
- X addr = process_address(to);
- X if(isfido(addr)) {
- X debug(2, "Argument %d (receiver %d) in fidomailer: %s",
- X fargc, frec + 1, addr);
- X fargs[fargc++] = addr;
- X frec++;
- X }
- X else {
- X debug(2, "Argument %d (receiver %d) in rmail: %s",
- X rargc, rrec + 1, addr);
- X rargs[rargc++] = addr;
- X rrec++;
- X }
- X }
- X }
- X
- X /*
- X * NULL terminate arument lists
- X */
- X rargs[rargc] = NULL;
- X fargs[fargc] = NULL;
- X
- X
- X if (rrec) {
- X /*
- X * Mail to UUCP, use rmail (or XENIX special: execmail)
- X */
- X debug(1, "Mail to UUCP, executing %s", RECVMAIL);
- #ifdef EXECMAIL
- X /*
- X * Insert `-f FROM' into argument list of execmail (rargs[])
- X */
- X if(from) {
- X for(cnt=rargc; cnt>=1; cnt--)
- X rargs[cnt + 2] = rargs[cnt];
- X rargs[1] = "-f";
- X rargs[2] = from;
- X rargc += 2;
- X }
- #endif /**EXECMAIL**/
- X /*
- X * Open mailer and feed letter to it
- X */
- X mailer = open_mailer(RECVMAIL, rargs, &pid);
- X temp = fopen(tempname, "r");
- X if(!temp) {
- X log("$Can't open %s again", tempname);
- X unlink(tempname);
- X exit(1);
- X }
- X while (fgets(buffer, BUFSIZ, temp))
- X fputs(buffer, mailer);
- X fclose(mailer);
- X /*
- X * Wait for rmail to exit
- X */
- X wait(&stat_loc);
- X if(!status)
- X status = (stat_loc & 0xff) == 0 ? (stat_loc >> 8) & 0xff : 1;
- X }
- X
- X if (frec) {
- X /*
- X * Mail to FIDO, use rfmail
- X */
- X debug(1, "Mail to FIDO, executing %s", RFMAIL);
- X /*
- X * Open mailer and feed letter to it
- X */
- X mailer = open_mailer(RFMAIL, fargs, &pid);
- X temp = fopen(tempname, "r");
- X if(!temp) {
- X log("$Can't open %s again", tempname);
- X unlink(tempname);
- X exit(1);
- X }
- X while (fgets(buffer, BUFSIZ, temp))
- X fputs(buffer, mailer);
- X fclose(mailer);
- X /*
- X * Wait for rfmail to exit
- X */
- X wait(&stat_loc);
- X if(!status)
- X status = (stat_loc & 0xff) == 0 ? (stat_loc >> 8) & 0xff : 1;
- X }
- X
- X /*
- X * Remove temporary file
- X */
- X unlink(tempname);
- X
- X exit(status);
- }
- SHAR_EOF
- chmod 0644 rmail.c ||
- echo 'restore of rmail.c failed'
- Wc_c="`wc -c < 'rmail.c'`"
- test 14095 -eq "$Wc_c" ||
- echo 'rmail.c: original size 14095, current size' "$Wc_c"
- fi
- # ============= fpack.c ==============
- if test -f 'fpack.c' -a X"$1" != X"-c"; then
- echo 'x - skipping fpack.c (File already exists)'
- else
- echo 'x - extracting fpack.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'fpack.c' &&
- /*:ts=4*/
- /*****************************************************************************
- X * FIDOGATE --- Gateway software UNIX <-> FIDO
- X *
- X * $Id: fpack.c,v 2.4 91/05/21 08:47:41 mj Exp $
- X *
- X * Create and update fidomail packets. Read mail messages from
- X * spool directory and append them to packet. If packet doesn't
- X * exist already, it will be created.
- X *
- X * $Log: fpack.c,v $
- X * Revision 2.4 91/05/21 08:47:41 mj
- X * Moved log entry for NetMail to rfmail.
- X *
- X * Revision 2.3 91/03/29 18:10:14 mj
- X * No log entries for news.
- X *
- X * Revision 2.2 90/12/09 18:35:27 mj
- X * Rewrote some more code. Now support `X' header line and crash mail.
- X *
- X * Revision 2.1 90/12/02 21:21:53 mj
- X * Changed program header to mention both authors of the original
- X * software posted to alt.sources.
- X *
- X * Revision 2.0 90/11/23 21:49:24 mj
- X * Major rewrite of fpack started: no more ugly messing around with
- X * byte order, use machine independent function write_int() instead.
- X * Removed some functions and macros.
- X *
- X * Revision 1.3 90/11/05 20:49:38 mj
- X * Changed my signature in all program headers.
- X *
- X * Revision 1.2 90/07/29 18:10:52 mj
- X * Place real net/node in message header for FIDO netmail. Also
- X * a `^AFMPT x' kludge is generated in this case. Recipient of
- X * our mail now gets real address from message, which should
- X * make replying much easier.
- X *
- X * Revision 1.1 90/06/28 22:04:07 mj
- X * Much rework of the sources, no more hsu.h and other clean up.
- X * rmail improved, now handles special XENIX quirks.
- X *
- X * Revision 1.0 90/06/19 18:32:01 mj
- X * Initial revision
- X *
- X *
- X *****************************************************************************
- X * This version hacked and maintained by:
- X * _____ _____
- X * | |___ | Martin Junius FIDO: 2:242/6.1 2:242/6.0
- X * | | | | | | Republikplatz 3 DOMAIN: mju@dfv.rwth-aachen.de
- X * |_|_|_|_____| D-5100 Aachen Tel. (Voice) 0241-86931
- X *
- X * Original version of these programs and files:
- X *
- X * Teemu Torma
- X * Heikki Suonsivu FIDO: 2:504/1 UUCP: ...!mcsun!santra!hsu
- X *
- X *****************************************************************************/
- X
- #include "fidogate.h"
- /*
- #include <fcntl.h>
- #include <sys/stat.h>
- */
- X
- X
- #define PROGRAMNAME "fpack $Revision: 2.4 $"
- X
- X
- X
- extern time_t time();
- extern int getopt();
- extern int optind;
- extern char *optarg;
- extern unsigned sleep();
- extern void exit();
- extern void swab();
- X
- Node node;
- int verbose = INIT_VERBOSE;
- X
- X
- X
- /*
- X * Put string to file in null-terminated format.
- X */
- X
- int put_string(fp, s)
- FILE *fp;
- char *s;
- {
- X while (*s) {
- X putc(*s, fp);
- X s++;
- X }
- X putc(0, fp);
- }
- X
- X
- X
- /*
- X * Write 16-bit integer in 80x86 format, i.e. low byte first,
- X * then high byte. Machine independent function.
- X */
- X
- int write_int(value, fp)
- int value;
- FILE *fp;
- {
- X putc(value & 0xff, fp);
- X putc((value >> 8) & 0xff, fp);
- }
- X
- X
- /*
- X * Copy n-char String, force trailing `\0'
- X */
- X
- char *strncpy0(d, s, n)
- char *d, *s;
- int n;
- {
- char *p;
- X
- X p = strncpy(d, s, n);
- X d[n - 1] = 0;
- X return(p);
- }
- X
- X
- X
- /*
- X * Write FIDO message header to mail packet. Information is taken
- X * from input message header:
- X *
- X * N node Address to send to
- X * T name Name of recipient
- X * F name Name of sender
- X * S subject Subject of message
- X * D date Date of message (FTS-0001 format)
- X * X flags Message flags: P=private, C=crash
- X */
- X
- int write_hdr(source, packet)
- FILE *source, *packet;
- {
- int private_flag = FALSE;
- char buffer[BUFSIZ];
- char from[SIZE_FROM],
- X to[SIZE_TO],
- X subject[SIZE_SUBJECT],
- X date[SIZE_DATE];
- Node msg_node;
- int attr = 0;
- char *p;
- X
- X msg_node.zone = msg_node.net = msg_node.node = msg_node.point = -1;
- X
- X /* clean up from, to and subject */
- X *from = 0;
- X *to = 0;
- X *subject = 0;
- X *date = 0;
- X
- X while (fgets(buffer, BUFSIZ, source) && *buffer != '\n') {
- X buffer[strlen(buffer) - 1] = 0; /* strip newline */
- X switch(*buffer) {
- X case 'N':
- X if (parsefnetaddress(buffer, &msg_node)) {
- X log("Invalid destination: %s", buffer);
- X return FALSE;
- X }
- X break;
- X case 'F':
- X strncpy0(from, buffer + 2, SIZE_FROM);
- X break;
- X case 'T':
- X strncpy0(to, buffer + 2, SIZE_TO);
- X break;
- X case 'S':
- X strncpy0(subject, buffer + 2, SIZE_SUBJECT);
- X break;
- X case 'D':
- X strncpy0(date, buffer + 2, SIZE_DATE);
- X break;
- X case 'P': /* Old `private' header */
- X attr |= ATTR_PRIVATE;
- X private_flag = TRUE;
- X break;
- X case 'X': /* New flags header */
- X for(p=buffer+2; *p; p++)
- X switch(*p) {
- X case 'P':
- X attr |= ATTR_PRIVATE;
- X private_flag = TRUE;
- X break;
- X case 'C':
- X attr |= ATTR_CRASH;
- X break;
- X }
- X break;
- X }
- X }
- X
- X /* Save all header values */
- X write_int(MSGTYPE, packet); /* save msg type */
- X write_int(private_flag ? REAL_NODE : MY_NODE, packet);/* save our node */
- X write_int(msg_node.node, packet); /* save messages node */
- X write_int(private_flag ? REAL_NET : MY_NET, packet);/* save our net */
- X write_int(msg_node.net, packet); /* save messages net */
- X write_int(attr, packet); /* save attributes */
- X write_int(0, packet); /* cost, not used by us */
- X put_string(packet, date); /* save time of mail */
- X put_string(packet, to); /* save receiver */
- X put_string(packet, from); /* save sender */
- X put_string(packet, subject); /* save subject */
- X
- X /* done with this header */
- X return TRUE;
- }
- X
- X
- X
- /*
- X * Write packet header for new packet.
- X */
- X
- int write_pkthdr(packet)
- FILE *packet;
- {
- Packet header;
- int count;
- struct tm *tm;
- time_t clock = time((long *) 0);
- X
- X tm = localtime(&clock);
- X
- X /* create packet structure */
- X header.orig_node = MY_NODE;
- X header.dest_node = node.node;
- X header.orig_net = MY_NET;
- X header.dest_net = node.net;
- X
- X /* save time for header (why all these fields?) */
- X header.year = tm->tm_year + 1900;
- X header.month = tm->tm_mon;
- X header.day = tm->tm_mday;
- X header.hour = tm->tm_hour + 1;
- X header.minute = tm->tm_min;
- X header.second = tm->tm_sec;
- X
- X header.rate = MAXBAUD;
- X header.ver = HDRVER;
- X header.product = 0;
- X header.x1 = 0;
- #ifdef FIDO_V11w
- X for(count = 0; count < 16; count++)
- X header.fill[count] = 0;
- #else
- X for(count = 0; count < 8; count++)
- X header.pwd_kludge[count] = 0;
- X header.orig_zone = MY_ZONE;
- X header.dest_zone = node.zone;
- X for (count = 0; count < 16; count++)
- X header.B_fill2[count] = 0;
- X header.B_fill3 = 0;
- #endif
- X /* write header to file */
- X write_int(header.orig_node, packet);
- X write_int(header.dest_node, packet);
- X write_int(header.year , packet);
- X write_int(header.month , packet);
- X write_int(header.day , packet);
- X write_int(header.hour , packet);
- X write_int(header.minute , packet);
- X write_int(header.second , packet);
- X write_int(header.rate , packet);
- X write_int(header.ver , packet);
- X write_int(header.orig_net , packet);
- X write_int(header.dest_net , packet);
- X putc( header.product , packet);
- X putc( header.x1 , packet);
- X for(count = 0; count < 8; count++)
- X putc(header.pwd_kludge[count], packet);
- X write_int(header.orig_zone, packet);
- X write_int(header.dest_zone, packet);
- X for(count = 0; count < 16; count++)
- X putc(header.B_fill2[count], packet);
- X for(count = 0; count < 4; count++)
- X putc(header.B_fill3 << (8 * count), packet); /* pc long = 4 bytes! */
- X
- X if(ferror(packet) || feof(packet)) {
- X log("$Write error on packet header");
- X return FALSE;
- X }
- X
- X debug(1, "New packet created");
- X
- X return TRUE;
- }
- X
- X
- X
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- DIR *dp;
- struct dirent *dir;
- FILE *msg, *packet;
- char packet_name[16];
- int c;
- Node np;
- char *error;
- X
- X node.net = node.zone = -1;
- X
- X /* get options */
- X while ((c = getopt(argc, argv, "vf:")) != EOF)
- X switch (c) {
- X case 'f':
- X if (parsefnetaddress(optarg, &np)) exit(1);
- X node = np;
- X break;
- X case 'v':
- X verbose++;
- X break;
- X default:
- X fprintf(stderr, "%s\n\n", PROGRAMNAME);
- X fprintf(stderr, "Usage: fpack [-v] [-f Z:N/N.P]\n\n");
- X exit(EX_USAGE);
- X }
- X
- X /* make sure that we got net/node */
- X if (node.net == -1 || node.node == -1) {
- X node.zone = REM_ZONE;
- X node.net = REM_NET;
- X node.node = REM_NODE;
- X node.point = REM_POINT;
- X strcpy(node.name, REM_NAME);
- X }
- X
- #if 0
- X /* try to update nodelist-index */
- X if (error = update_index())
- X {
- X if (*error == '$')
- X log("$Cannot update nodelist-index: %s", error + 1);
- X else
- X log("Cannot update nodelist-index: %s", error);
- X exit(EX_OSERR);
- X }
- #endif
- X
- X /* goto spool directory, everything exiting happens there... */
- X if (chdir(SPOOL) == -1) {
- X log("$Can't chdir to %s", SPOOL);
- X exit(1);
- X }
- X
- #if 0
- X /* create packet name */
- X sprintpacketname(packet_name, node);
- #else
- X /* MSDOS compatible packet names */
- X sprintf(packet_name, "%04x%04x.out", node.net, node.node);
- #endif
- X
- X if (access(sprintfs("out/%s", packet_name), 0) == 0) {
- X debug(1, "Packet out/%s exists, append to it", packet_name);
- X if ((packet = fopen(sprintfs("out/%s", packet_name), "r+")) == NULL) {
- X log("$Can't open out/%s for update", packet_name);
- X exit(1);
- X }
- X fseek(packet, -2L, 2);
- X }
- X else {
- X debug(1, "New packet out/%s", packet_name);
- X if ((packet = fopen(sprintfs("out/%s", packet_name), "w")) == NULL) {
- X log("$Can't open out/%s for writing", packet_name);
- X exit(1);
- X }
- X /* protect packet from users...*/
- X chmod(sprintfs("out/%s", packet_name), 0600);
- X /* write packet-header, if it fails, exit */
- X if (!write_pkthdr(packet)) {
- X unlink(sprintfs("out/%s", packet_name));
- X exit(1);
- X }
- X }
- X
- X /* lock packet, wait if it's alredy locked */
- X while (lock(fileno(packet)) == -1 && errno == EAGAIN)
- X sleep(5);
- X
- X /* open spool directory */
- X dp = opendir(".");
- X if(!dp) {
- X log("$Can't open spool directory %s", SPOOL);
- X exit(1);
- X }
- X while (dir = readdir(dp)) {
- X /* check that file is for us */
- X if(dir->d_name[0]=='M' && dir->d_name[1]=='.') {
- X msg = fopen(dir->d_name, "r");
- X if(!msg) {
- X log("$Can't open mail %s for reading", dir->d_name);
- X continue;
- X }
- X debug(1, "Adding mailfile %s", dir->d_name);
- X
- X /* save header */
- X if(write_hdr(msg, packet)) {
- X /* copy mail text, replace newlines with <cr> <lf> */
- X while ((c = getc(msg)) && c != EOF) {
- X if (c == '\n')
- X putc('\r', packet);
- X putc(c, packet);
- X }
- X /* null-terminate msg text */
- X putc(0, packet);
- X }
- X fclose(msg);
- X if(unlink(dir->d_name) == -1)
- X log("$Unable to unlink %s", dir->d_name);
- X }
- X }
- X closedir(dp);
- X
- X /* msg type 0 indicates end of packet */
- X write_int(0, packet);
- X
- X fclose(packet);
- X
- X exit(0);
- }
- SHAR_EOF
- chmod 0644 fpack.c ||
- echo 'restore of fpack.c failed'
- Wc_c="`wc -c < 'fpack.c'`"
- test 10575 -eq "$Wc_c" ||
- echo 'fpack.c: original size 10575, current size' "$Wc_c"
- fi
- true || echo 'restore of funpack.c failed'
- echo End of part 4, continue with part 5
- exit 0
-
- --
- _____ _____
- | |___ | Martin Junius FIDO: 2:242/6.1 2:242/6.0
- | | | | | | Republikplatz 3 DOMAIN: mj@dfv.rwth-aachen.de
- |_|_|_|_____| D-5100 Aachen Tel. (Voice) 0241-86931
-