From 6068b2454fe8dda29a89ddc346e94aeb79537f01 Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Sat, 6 Oct 2001 19:51:48 +0000 Subject: [PATCH] * Stripped the build of obsolete parts of the old networker no longer in use. --- citadel/ChangeLog | 4 +- citadel/Makefile.in | 31 +- citadel/aidepost.c | 7 +- citadel/file_ops.c | 2 +- citadel/internetmail.c | 123 --- citadel/mailinglist.c | 159 ---- citadel/msgbase.c | 2 +- citadel/netmailer.c | 321 -------- citadel/netproc.c | 1643 ---------------------------------------- citadel/serv_network.c | 4 +- citadel/serv_vcard.c | 5 - 11 files changed, 15 insertions(+), 2286 deletions(-) delete mode 100644 citadel/internetmail.c delete mode 100644 citadel/mailinglist.c delete mode 100644 citadel/netmailer.c delete mode 100644 citadel/netproc.c diff --git a/citadel/ChangeLog b/citadel/ChangeLog index e058bd5c5..6e0d0a159 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,7 @@ $Log$ + Revision 580.51 2001/10/06 19:51:47 ajc + * Stripped the build of obsolete parts of the old networker no longer in use. + Revision 580.50 2001/10/03 20:05:50 ajc * serv_smtp.c: implement RFC2920 ESMTP "pipelining" extension on the server side. (No changes required other than advertising the extension.) @@ -2772,4 +2775,3 @@ Sat Jul 11 00:20:48 EDT 1998 Nathan Bryant Fri Jul 10 1998 Art Cancro * Initial CVS import - diff --git a/citadel/Makefile.in b/citadel/Makefile.in index 879ed1199..66d2be574 100644 --- a/citadel/Makefile.in +++ b/citadel/Makefile.in @@ -40,8 +40,8 @@ SERV_MODULES=modules/libchat.la modules/libvcard.la \ modules/libexpire.la \ modules/libvandelay.la \ modules/libical.la -UTIL_TARGETS=aidepost netmailer netproc netsetup msgform readlog rcit \ - stats citmail mailinglist userlist sendcommand \ +UTIL_TARGETS=aidepost netsetup msgform readlog \ + stats citmail userlist sendcommand \ base64 qpdecode prefix=@prefix@ @@ -82,9 +82,9 @@ DOMAIN=@DOMAIN@ SOURCES=aidepost.c citadel.c citmail.c citserver.c client_chat.c commands.c \ config.c control.c $(DATABASE) dynloader.c file_ops.c \ - housekeeping.c internetmail.c ipc_c_tcp.c locate_host.c \ - logging.c mailinglist.c messages.c msgbase.c msgform.c netmailer.c \ - netproc.c netsetup.c policy.c rcit.c readlog.c \ + housekeeping.c ipc_c_tcp.c locate_host.c \ + logging.c messages.c msgbase.c msgform.c \ + netsetup.c policy.c readlog.c \ room_ops.c rooms.c routines.c routines2.c serv_chat.c \ serv_info.c serv_test.c setup.c snprintf.c stats.c serv_vcard.c \ support.c sysdep.c tools.c user_ops.c userlist.c serv_expire.c \ @@ -209,27 +209,9 @@ modules/libpas2.la: serv_pas2.lo md5.lo $(LIBTOOL) libcitserver.la modules/libical.la: serv_ical.lo $(LIBTOOL) libcitserver.la $(LTSHARE) -o libical.la ../serv_ical.lo ../libcitserver.la - - -# -# 'netmailer' needs to run setuid because it generates headers for Internet -# mail. If it is not run setuid, all outgoing mail may always show as coming -# from your BBSUID rather than the actual sending user. -# -netmailer: netmailer.o internetmail.o config.o genstamp.o - $(CC) netmailer.o config.o internetmail.o genstamp.o \ - $(LDFLAGS) -o netmailer - -netproc: netproc.o config.o ipc_c_tcp.o tools.o $(LIBOBJS) - $(CC) netproc.o config.o ipc_c_tcp.o tools.o \ - $(LIBOBJS) $(LDFLAGS) -o netproc $(NETLIBS) - citmail: citmail.o config.o $(CC) citmail.o config.o $(LDFLAGS) -o citmail $(NETLIBS) -mailinglist: mailinglist.o config.o internetmail.o - $(CC) mailinglist.o config.o internetmail.o $(LDFLAGS) -o mailinglist - setup: setup.o tools.o $(CC) setup.o tools.o $(CURSES) $(NETLIBS) $(LDFLAGS) -o setup @@ -262,9 +244,6 @@ msgform: msgform.o readlog: readlog.o config.o $(CC) readlog.o config.o $(LDFLAGS) -o readlog -rcit: rcit.o config.o - $(CC) rcit.o config.o $(LDFLAGS) -o rcit - stats: stats.o ipc_c_tcp.o libcitserver.la $(LIBOBJS) $(LIBTOOL) $(CC) stats.o ipc_c_tcp.o libcitserver.la $(LIBOBJS) $(LDFLAGS) -o stats $(NETLIBS) diff --git a/citadel/aidepost.c b/citadel/aidepost.c index 0ed777b66..c89714607 100644 --- a/citadel/aidepost.c +++ b/citadel/aidepost.c @@ -90,7 +90,8 @@ int main(int argc, char **argv) } - snprintf(tempspool, sizeof tempspool, "./network/spoolin/ap.%d", + snprintf(tempspool, sizeof tempspool, + "./network/spoolin/ap.%04x", getpid()); tempfp = tmpfile(); @@ -116,7 +117,5 @@ int main(int argc, char **argv) fclose(tempfp); fclose(spoolfp); - execlp("./netproc", "netproc", "-i", NULL); - perror("cannot run netproc"); - exit(errno); + exit(0); } diff --git a/citadel/file_ops.c b/citadel/file_ops.c index d701a443c..98f67994b 100644 --- a/citadel/file_ops.c +++ b/citadel/file_ops.c @@ -246,7 +246,7 @@ void cmd_netf(char *cmdbuf) cprintf("%d File '%s' has been sent to %s.\n", OK, filename, destsys); - system("nohup ./netproc -i >/dev/null 2>&1 &"); + /* FIXME start a network run here. */ return; } diff --git a/citadel/internetmail.c b/citadel/internetmail.c deleted file mode 100644 index c2aba231d..000000000 --- a/citadel/internetmail.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * $Id$ - * - * Internet mail configurator for Citadel/UX - * see copyright.doc for copyright information - * - */ - -#include -#include -#include -#include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#include -#include -#include -#include "citadel.h" - -extern struct config config; - -char metoo[10][128]; -int mecount = 0; - -extern char ALIASES[128]; -extern char CIT86NET[128]; -extern char SENDMAIL[128]; -extern char FALLBACK[128]; -extern char GW_DOMAIN[128]; -extern char TABLEFILE[128]; -extern int RUN_NETPROC; - -void StripLeadingAndTrailingWhitespace(char *str) -{ - if (strlen(str) == 0) - return; - while (isspace(str[0])) - strcpy(str, &str[1]); - while (isspace(str[strlen(str) - 1])) - str[strlen(str) - 1] = 0; -} - -void LoadInternetConfig(void) -{ - char ParamName[SIZ], ParamValue[SIZ], buf[SIZ]; - FILE *conf; - int a, eqpos; - - - conf = fopen("network/internetmail.config", "r"); - if (conf == NULL) { - syslog(LOG_NOTICE, "Couldn't load internetmail.config"); - exit(1); - } - while (fgets(buf, sizeof buf, conf) != NULL) { - if (strlen(buf) > 0) - buf[strlen(buf) - 1] = 0; - strcpy(ParamName, ""); - strcpy(ParamValue, ""); - if (buf[0] != '#') { - eqpos = (-1); - for (a = strlen(buf); a >= 0; --a) { - if (buf[a] == '=') - eqpos = a; - } - if (eqpos >= 0) { - strcpy(ParamName, buf); - ParamName[eqpos] = 0; - strcpy(ParamValue, &buf[eqpos + 1]); - } - StripLeadingAndTrailingWhitespace(ParamName); - StripLeadingAndTrailingWhitespace(ParamValue); - - if (!strcasecmp(ParamName, "aliases")) - strcpy(ALIASES, ParamValue); - if (!strcasecmp(ParamName, "cit86net spoolin")) - strcpy(CIT86NET, ParamValue); - if (!strcasecmp(ParamName, "sendmail")) - strcpy(SENDMAIL, ParamValue); - if (!strcasecmp(ParamName, "fallback")) - strcpy(FALLBACK, ParamValue); - if (!strcasecmp(ParamName, "gateway domain")) - strcpy(GW_DOMAIN, ParamValue); - if (!strcasecmp(ParamName, "table file")) - strcpy(TABLEFILE, ParamValue); - if (!strcasecmp(ParamName, "deliver local")) - strcpy(metoo[mecount++], ParamValue); - if (!strcasecmp(ParamName, "run netproc")) - RUN_NETPROC = atoi(ParamValue); - } - } - fclose(conf); -} - - -/* - * returns nonzero if the specified host is listed as local - */ -int IsHostLocal(char *WhichHost) -{ - int a; - - if (!strcasecmp(WhichHost, FQDN)) - return (1); - - if (mecount > 0) { - for (a = 0; a < mecount; ++a) { - if (!strcasecmp(WhichHost, metoo[a])) - return (1); - } - } - return (0); -} diff --git a/citadel/mailinglist.c b/citadel/mailinglist.c deleted file mode 100644 index b91d15f1d..000000000 --- a/citadel/mailinglist.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * $Id$ - * - * This program is designed to be a filter which allows two-way interaction - * between a traditional e-mail mailing list and a Citadel room. - * - * It only handles the outbound side. The inbound side is handled by the - * Citadel e-mail gateway. You should subscribe rooms to lists using the - * "room_roomname@node.dom" type address. - * - * Since some listprocs only accept postings from subscribed addresses, the - * messages which this program converts will all appear to be from the room - * address; however, the full name of the sender is set to the Citadel user - * name of the real message author. - * - * To prevent loops, this program only sends messages originating on the local - * system. Therefore it is not possible to carry a two-way mailing list room - * on a Citadel network. - */ - -#include -#include -#include -#include -#include -#include "citadel.h" - -void LoadInternetConfig(void); -void get_config(void); -struct config config; - -char ALIASES[128]; -char CIT86NET[128]; -char SENDMAIL[128]; -char FALLBACK[128]; -char GW_DOMAIN[128]; -char TABLEFILE[128]; -char OUTGOING_FQDN[128]; -int RUN_NETPROC = 1; - -/* - * Consult the mailinglists table to find out where we should send the - * mailing list postings to. - */ -void xref(char *room, char *listaddr) -{ /* xref table */ - FILE *fp; - int a; - char buf[128]; - - strcpy(listaddr, ""); - fp = fopen(TABLEFILE, "r"); - while (fgets(buf, 128, fp) != NULL) { - buf[strlen(buf) - 1] = 0; - for (a = 0; a < strlen(buf); ++a) { - if ((buf[a] == ',') && (!strcasecmp(&buf[a + 1], room))) { - strcpy(listaddr, buf); - listaddr[a] = 0; - } - } - } - fclose(fp); - return; -} - - -/* - * The main loop. We don't need any command-line parameters to this program. - */ -int main(void) -{ - - char header[3]; - char fields[32][1024]; - int num_fields; - int ch, p, a, i; - int in_header; - int is_good; - char listaddr[512]; - char mailcmd[SIZ]; - FILE *nm; - char tempfile[64]; - - get_config(); - LoadInternetConfig(); - strcpy(tempfile, tmpnam(NULL)); - - while (1) { - - /* seek to the next message */ - is_good = 0; - do { - if (feof(stdin)) { - unlink(tempfile); - exit(0); - } - } while (getc(stdin) != 255); - - header[0] = 255; - header[1] = getc(stdin); - header[2] = getc(stdin); - in_header = 1; - num_fields = 0; - - do { - fields[num_fields][0] = getc(stdin); - if (fields[num_fields][0] != 'M') { - p = 1; - do { - ch = getc(stdin); - fields[num_fields][p++] = ch; - } while ((ch != 0) && (!feof(stdin))); - - /**********************************************************/ - /* Only send messages which originated on the Citadel net */ - /* (In other words, from node names with no dots in them) */ - - if (fields[num_fields][0] == 'N') { - is_good = 1; - for (i = 1; i < strlen(&fields[num_fields][1]); ++i) { - if (fields[num_fields][i] == '.') { - is_good = 0; - } - } - } - /**********************************************************/ - - if (fields[num_fields][0] == 'O') { - xref(&fields[num_fields][1], listaddr); - } - if (fields[num_fields][0] != 'R') - ++num_fields; - } else { - /* flush the message out to the next program */ - - nm = fopen(tempfile, "wb"); - fprintf(nm, "%c%c%c", - header[0], header[1], header[2]); - for (a = 0; a < num_fields; ++a) { - fprintf(nm, "%s%c", &fields[a][0], 0); - } - fprintf(nm, "R%s%c", listaddr, 0); - - putc('M', nm); - do { - ch = getc(stdin); - putc(ch, nm); - } while ((ch != 0) && (!feof(stdin))); - in_header = 0; - fclose(nm); - if (is_good) { - sprintf(mailcmd, "exec ./netmailer %s mlist", tempfile); - system(mailcmd); - is_good = 0; - } - } - } while (in_header); - } -} diff --git a/citadel/msgbase.c b/citadel/msgbase.c index 8c3e06e80..6c92b64c1 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1811,7 +1811,7 @@ long CtdlSaveMsg(struct CtdlMessage *msg, /* message to save */ newmsgid = send_message(msg, network_fp); if (network_fp != NULL) { fclose(network_fp); - system("exec nohup ./netproc -i >/dev/null 2>&1 &"); + /* FIXME start a network run here */ } if (newmsgid <= 0L) return(-1); diff --git a/citadel/netmailer.c b/citadel/netmailer.c deleted file mode 100644 index 69309c511..000000000 --- a/citadel/netmailer.c +++ /dev/null @@ -1,321 +0,0 @@ -/* - * $Id$ - * - * netproc calls this to export Citadel mail to RFC822-compliant mailers. - */ - -#include -#include -#include -#include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#include -#include -#include -#include -#include "citadel.h" -#include "genstamp.h" - -void LoadInternetConfig(void); -void get_config(void); -struct config config; - -char temp[PATH_MAX]; - -char ALIASES[128]; -char CIT86NET[128]; -char SENDMAIL[128]; -char FALLBACK[128]; -char GW_DOMAIN[128]; -char TABLEFILE[128]; -int RUN_NETPROC = 1; - -int haschar(char *st, int ch) -{ - int a, b; - b = 0; - for (a = 0; a < strlen(st); ++a) - if (st[a] == ch) - ++b; - return (b); -} - - - -void fpgetfield(FILE * fp, char *string) -{ - int a, b; - strcpy(string, ""); - a = 0; - do { - b = getc(fp); - if (b < 1) { - string[a] = 0; - return; - } - string[a] = b; - ++a; - } while (b != 0); -} - - -/* This is NOT the same msgform() found in the main program. It has been - * modified to format 80 columns into a temporary file, and extract the - * sender and recipient names for use within the main() loop. - */ -void msgform(char *msgfile, FILE * mfout, char *sbuf, char *rbuf, char *nbuf, - char *pbuf, time_t * mid_buf, char *rmname, char *subj) - /* sender */ - /* recipient (in this case, an Internet address) */ - /* source node */ - /* path */ - /* message ID */ - /* room name */ - /* subject */ -{ - int a, b, c, e, old, mtype, aflag; - int real = 0; - char aaa[128], bbb[128]; - FILE *fp; - int width; - int generate_subject = 1; - - strcpy(subj, ""); - strcpy(pbuf, ""); - strcpy(nbuf, NODENAME); - strcpy(rmname, ""); - time(mid_buf); - width = 80; - fp = fopen(msgfile, "rb"); - if (fp == NULL) { - fprintf(stderr, "netmailer: can't open message file\n"); - return; - } - strcpy(aaa, ""); - old = 255; - c = 1; /* c is the current pos */ - e = getc(fp); - if (e != 255) { - fprintf(stderr, "netmailer: This is not a Citadel message.\n"); - goto END; - } - mtype = getc(fp); - aflag = getc(fp); - goto BONFGM; - -A: if (aflag == 1) - goto AFLAG; - old = real; - a = getc(fp); - real = a; - if (a == 0) - goto END; - if (a < 0) - goto END; - - /* generate subject... */ - if ((generate_subject == 1) && (strlen(subj) < 60)) { - subj[strlen(subj) + 1] = 0; - subj[strlen(subj)] = (((a > 31) && (a < 127)) ? a : 32); - } - if (((a == 13) || (a == 10)) && (old != 13) && (old != 10)) - a = 32; - if (((old == 13) || (old == 10)) && ((real == 32) || (real == 13) || (real == 10))) { - fprintf(mfout, "\n"); - c = 1; - } - if (a != 32) { - if (((strlen(aaa) + c) > (width - 5)) && (strlen(aaa) > (width - 5))) { - fprintf(mfout, "\n%s", aaa); - c = strlen(aaa); - aaa[0] = 0; - } - b = strlen(aaa); - aaa[b] = a; - aaa[b + 1] = 0; - } - if (a == 32) { - if ((strlen(aaa) + c) > (width - 5)) { - fprintf(mfout, "\n"); - c = 1; - } - fprintf(mfout, "%s ", aaa); - ++c; - c = c + strlen(aaa); - strcpy(aaa, ""); - goto A; - } - if ((a == 13) || (a == 10)) { - fprintf(mfout, "%s\n", aaa); - c = 1; - strcpy(aaa, ""); - goto A; - } - goto A; - -AFLAG: a = getc(fp); - if (a == 0) - goto END; - if (a == 13) { - putc(10, mfout); - } else { - putc(a, mfout); - } - goto AFLAG; - -END: fclose(fp); - return; - -BONFGM: b = getc(fp); - if (b < 0) - goto END; - if (b == 'M') - goto A; - fpgetfield(fp, bbb); - if (b == 'A') - strcpy(sbuf, bbb); - if (b == 'R') - strcpy(rbuf, bbb); - if (b == 'N') - strcpy(nbuf, bbb); - if (b == 'P') - strcpy(pbuf, bbb); - if (b == 'I') - *mid_buf = atol(bbb); - if (b == 'O') - strcpy(rmname, bbb); - if (b == 'U') { - strcpy(subj, bbb); - generate_subject = 0; /* have a real subj so don't gen one */ - } - goto BONFGM; -} - -int main(int argc, char **argv) -{ - int a; - FILE *fp, *rmail; - char sbuf[200], rbuf[200], cstr[100], fstr[128]; - char nbuf[64], pbuf[128], rmname[128], buf[128]; - char datestamp[SIZ]; - char subject[SIZ]; - time_t mid_buf; - time_t now; - int mlist = 0; - - openlog("netmailer", LOG_PID, LOG_USER); - get_config(); - LoadInternetConfig(); - strcpy(temp, tmpnam(NULL)); /* temp file name */ - - if ((argc < 2) || (argc > 3)) { - fprintf(stderr, "netmailer: usage: " - "netmailer [mlist]\n"); - exit(1); - } - /* - * If we are running in mailing list mode, the room is being two-way - * gatewayed to an Internet mailing list. Since many listprocs only - * accept postings from subscribed addresses, we must always use the - * room's address as the originating user. - */ - if ((argc == 3) && (!strcasecmp(argv[2], "mlist"))) { - mlist = 1; - } - /* convert to ASCII & get info */ - fp = fopen(temp, "w"); - msgform(argv[1], fp, sbuf, rbuf, nbuf, pbuf, &mid_buf, rmname, subject); - fclose(fp); - - strcpy(buf, rmname); - strcpy(rmname, "room_"); - strcat(rmname, buf); - for (a = 0; a < strlen(rmname); ++a) { - if (rmname[a] == ' ') - rmname[a] = '_'; - rmname[a] = tolower(rmname[a]); - } - - sprintf(cstr, SENDMAIL, rbuf); - rmail = (FILE *) popen(cstr, "w"); - - strcpy(fstr, sbuf); - for (a = 0; a < strlen(sbuf); ++a) - if (sbuf[a] == 32) - sbuf[a] = '_'; - for (a = 0; a < strlen(rbuf); ++a) - if (rbuf[a] == 32) - rbuf[a] = '_'; - - /* - * This logic attempts to compose From and From: lines that are - * as RFC822-compliant as possible. The return addresses are correct - * if you're using Citadel's 'citmail' delivery agent to allow BBS - * users to receive Internet mail. - */ - fprintf(rmail, "From "); - if (strcasecmp(nbuf, NODENAME)) - fprintf(rmail, "%s!", nbuf); - - if (!strcasecmp(nbuf, NODENAME)) - strcpy(nbuf, FQDN); - - if (mlist) { - fprintf(rmail, "%s\n", rmname); - fprintf(rmail, "From: %s@%s (%s)\n", rmname, FQDN, fstr); - } else { - - if (!strcasecmp(nbuf, NODENAME)) { /* from this system */ - fprintf(rmail, "%s\n", pbuf); - fprintf(rmail, "From: %s@%s (%s)\n", - sbuf, FQDN, fstr); - } else if (haschar(nbuf, '.')) { /* from an FQDN */ - fprintf(rmail, "%s\n", sbuf); - fprintf(rmail, "From: %s@%s (%s)\n", - sbuf, nbuf, fstr); - } else { /* from another Cit */ - fprintf(rmail, "%s\n", sbuf); - fprintf(rmail, "From: %s@%s.%s (%s)\n", - sbuf, nbuf, GW_DOMAIN, fstr); - } - - } - - /* - * Everything else is pretty straightforward. - */ - fprintf(rmail, "To: %s\n", rbuf); - time(&now); - datestring(datestamp, now, DATESTRING_RFC822); - fprintf(rmail, "Date: %s\n", datestamp); - fprintf(rmail, "Message-Id: <%ld@%s>\n", (long) mid_buf, nbuf); - fprintf(rmail, "X-Mailer: %s\n", CITADEL); - fprintf(rmail, "Subject: %s\n", subject); - fprintf(rmail, "\n"); - fp = fopen(temp, "r"); - if (fp != NULL) { - do { - a = getc(fp); - if (a >= 0) - putc(a, rmail); - } while (a >= 0); - fclose(fp); - } - fprintf(rmail, "\n"); - pclose(rmail); - - unlink(temp); /* get rid of the ASCII file */ - execlp("./netproc", "netproc", "-i", NULL); - exit(0); /* go back to the main program */ -} diff --git a/citadel/netproc.c b/citadel/netproc.c deleted file mode 100644 index d88898be7..000000000 --- a/citadel/netproc.c +++ /dev/null @@ -1,1643 +0,0 @@ -/* - * $Id$ - * - * Citadel/UX Intelligent Network Processor for IGnet/Open networks - * See copyright.txt for copyright information - * - */ - -/* How long it takes for an old node to drop off the network map */ -#define EXPIRY_TIME (2592000L) - -/* How long we keep recently arrived messages in the use table */ -#define USE_TIME (604800L) - -/* Where do we keep our lock file? */ -#define LOCKFILE "/tmp/netproc.LCK" - -/* Path to the 'uudecode' utility (needed for network file transfers) */ -#define UUDECODE "/usr/bin/uudecode" - -/* Files used by the networker */ -#define MAILSYSINFO "./network/mail.sysinfo" - -/* Uncomment the DEBUG def to see noisy traces */ -#define DEBUG 1 - - -#include "sysdep.h" -#include -#include -#include -#include -#include -#include -#include -#include - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#include -#include -#include -#include "citadel.h" -#include "tools.h" -#include "ipc.h" - -/* A list of users you wish to filter out of incoming traffic can be kept - * in ./network/filterlist -- messages from these users will be automatically - * moved to FILTERROOM. Normally this will be the same as TWITROOM (the - * room problem user messages are moved to) but you can override this by - * specifying a different room name here. - */ -#ifndef FILTERROOM -#define FILTERROOM TWITROOM -#endif - -struct msglist { - struct msglist *next; - long m_num; - char m_rmname[ROOMNAMELEN]; -}; - -struct rmlist { - struct rmlist *next; - char rm_name[ROOMNAMELEN]; - long rm_lastsent; -}; - -struct filterlist { - struct filterlist *next; - char f_person[64]; - char f_room[64]; - char f_system[64]; -}; - -struct syslist { - struct syslist *next; - char s_name[16]; - char s_type[4]; - char s_nexthop[128]; - time_t s_lastcontact; - char s_humannode[64]; - char s_phonenum[32]; - char s_gdom[64]; -}; - - - -/* - * This structure is used to hold all of the fields of a message - * during conversion, processing, or whatever. - */ -struct minfo { - char A[512]; - char B[512]; - char C[512]; - char D[512]; - char E[512]; - char G[512]; - char H[512]; - char I[512]; - char N[512]; - char O[512]; - char P[512]; - char R[512]; - char S[512]; - long T; - char U[512]; - char Z[512]; - char nexthop[512]; - }; - - -struct usetable { - struct usetable *next; - char msgid[256]; - time_t timestamp; -}; - - - - -void serv_read(char *buf, int bytes); -void serv_write(char *buf, int nbytes); -void get_config(void); - -struct filterlist *filter = NULL; -struct syslist *slist = NULL; -struct msglist *purgelist = NULL; -struct usetable *usetable = NULL; - -struct config config; -extern char bbs_home_directory[]; -extern int home_specified; - - -#ifndef HAVE_STRERROR -/* - * replacement strerror() for systems that don't have it - */ -char *strerror(int e) -{ - static char buf[32]; - - sprintf(buf, "errno = %d", e); - return (buf); -} -#endif - - -void strip_trailing_whitespace(char *buf) -{ - while (isspace(buf[strlen(buf) - 1])) - buf[strlen(buf) - 1] = 0; -} - - -/* - * we also load the mail.sysinfo table into memory, make changes - * as we learn more about the network from incoming messages, and write - * the table back to disk when we're done. - */ -int load_syslist(void) -{ - FILE *fp; - struct syslist *stemp; - char insys = 0; - char buf[128]; - - fp = fopen(MAILSYSINFO, "r"); - if (fp == NULL) - return (1); - - while (1) { - if (fgets(buf, 128, fp) == NULL) { - fclose(fp); - return (0); - } - buf[strlen(buf) - 1] = 0; - while (isspace(buf[0])) - strcpy(buf, &buf[1]); - if (buf[0] == '#') - buf[0] = 0; - if ((insys == 0) && (strlen(buf) != 0)) { - insys = 1; - stemp = (struct syslist *) malloc(sizeof(struct syslist)); - stemp->next = slist; - slist = stemp; - strcpy(slist->s_name, buf); - strcpy(slist->s_type, "bin"); - strcpy(slist->s_nexthop, "Mail"); - slist->s_lastcontact = 0L; - strcpy(slist->s_humannode, ""); - strcpy(slist->s_phonenum, ""); - strcpy(slist->s_gdom, ""); - } else if ((insys == 1) && (strlen(buf) == 0)) { - insys = 0; - } else if ((insys == 1) && (!strncasecmp(buf, "bin", 3))) { - strcpy(slist->s_type, "bin"); - strcpy(slist->s_nexthop, &buf[4]); - } else if ((insys == 1) && (!strncasecmp(buf, "use", 3))) { - strcpy(slist->s_type, "use"); - strcpy(slist->s_nexthop, &buf[4]); - } else if ((insys == 1) && (!strncasecmp(buf, "uum", 3))) { - strcpy(slist->s_type, "uum"); - strcpy(slist->s_nexthop, &buf[4]); - } else if ((insys == 1) && (!strncasecmp(buf, "lastcontact", 11))) { - long foo; - sscanf(&buf[12], "%ld", &foo); - slist->s_lastcontact = foo; - } else if ((insys == 1) && (!strncasecmp(buf, "humannode", 9))) { - strcpy(slist->s_humannode, &buf[10]); - } else if ((insys == 1) && (!strncasecmp(buf, "phonenum", 8))) { - strcpy(slist->s_phonenum, &buf[9]); - } else if ((insys == 1) && (!strncasecmp(buf, "gdom", 4))) { - strcpy(slist->s_gdom, &buf[5]); - } - } -} - -/* now we have to set up two "special" nodes on the list: one - * for the local node, and one for an Internet gateway - */ -void setup_special_nodes(void) -{ - struct syslist *stemp, *slocal; - - slocal = NULL; - for (stemp = slist; stemp != NULL; stemp = stemp->next) { - if (!strcasecmp(stemp->s_name, config.c_nodename)) - slocal = stemp; - } - if (slocal == NULL) { - slocal = (struct syslist *) malloc(sizeof(struct syslist)); - slocal->next = slist; - slist = slocal; - } - strcpy(slocal->s_name, config.c_nodename); - strcpy(slocal->s_type, "bin"); - strcpy(slocal->s_nexthop, "Mail"); - time(&slocal->s_lastcontact); - strcpy(slocal->s_humannode, config.c_humannode); - strcpy(slocal->s_phonenum, config.c_phonenum); - - slocal = NULL; - for (stemp = slist; stemp != NULL; stemp = stemp->next) { - if (!strcasecmp(stemp->s_name, "internet")) - slocal = stemp; - } - if (slocal == NULL) { - slocal = (struct syslist *) malloc(sizeof(struct syslist)); - slocal->next = slist; - slist = slocal; - } - strcpy(slocal->s_name, "internet"); - strcpy(slocal->s_type, "uum"); - strcpy(slocal->s_nexthop, "%s"); - time(&slocal->s_lastcontact); - strcpy(slocal->s_humannode, "Internet Gateway"); - strcpy(slocal->s_phonenum, ""); - strcpy(slocal->s_gdom, ""); - -} - -/* - * here's the routine to write the table back to disk. - */ -void rewrite_syslist(void) -{ - struct syslist *stemp; - FILE *newfp; - time_t now; - - time(&now); - newfp = fopen(MAILSYSINFO, "w"); - for (stemp = slist; stemp != NULL; stemp = stemp->next) { - if (!strcasecmp(stemp->s_name, config.c_nodename)) { - time(&stemp->s_lastcontact); - strcpy(stemp->s_type, "bin"); - strcpy(stemp->s_humannode, config.c_humannode); - strcpy(stemp->s_phonenum, config.c_phonenum); - } - /* remove systems we haven't heard from in a while */ - if ((stemp->s_lastcontact == 0L) - || (now - stemp->s_lastcontact < EXPIRY_TIME)) { - fprintf(newfp, "%s\n%s %s\n", - stemp->s_name, stemp->s_type, stemp->s_nexthop); - if (strlen(stemp->s_phonenum) > 0) - fprintf(newfp, "phonenum %s\n", stemp->s_phonenum); - if (strlen(stemp->s_gdom) > 0) - fprintf(newfp, "gdom %s\n", stemp->s_gdom); - if (strlen(stemp->s_humannode) > 0) - fprintf(newfp, "humannode %s\n", stemp->s_humannode); - if (stemp->s_lastcontact > 0L) - fprintf(newfp, "lastcontact %ld %s", - (long) stemp->s_lastcontact, - asctime(localtime(&stemp->s_lastcontact))); - fprintf(newfp, "\n"); - } - } - fclose(newfp); - /* now free the list */ - while (slist != NULL) { - stemp = slist; - slist = slist->next; - free(stemp); - } -} - - -/* call this function with the node name of a system and it returns a pointer - * to its syslist structure. - */ -struct syslist *get_sys_ptr(char *sysname) -{ - static char sysnambuf[16]; - static struct syslist *sysptrbuf = NULL; - struct syslist *stemp; - - if ((!strcmp(sysname, sysnambuf)) - && (sysptrbuf != NULL)) - return (sysptrbuf); - - strcpy(sysnambuf, sysname); - for (stemp = slist; stemp != NULL; stemp = stemp->next) { - if (!strcmp(sysname, stemp->s_name)) { - sysptrbuf = stemp; - return (stemp); - } - } - sysptrbuf = NULL; - return (NULL); -} - - -/* - * make sure only one copy of netproc runs at a time, using lock files - */ -int set_lockfile(void) -{ - FILE *lfp; - int onppid; - - if ((lfp = fopen(LOCKFILE, "r")) != NULL) { - fscanf(lfp, "%d", &onppid); - fclose(lfp); - if (!kill(onppid, 0) || errno == EPERM) - return 1; - } - lfp = fopen(LOCKFILE, "w"); - if (lfp == NULL) { - syslog(LOG_NOTICE, "Cannot create %s: %s", LOCKFILE, - strerror(errno)); - return(1); - } - fprintf(lfp, "%ld\n", (long) getpid()); - fclose(lfp); - return (0); -} - -void remove_lockfile(void) -{ - unlink(LOCKFILE); -} - -/* - * Why both cleanup() and nq_cleanup() ? Notice the alarm() call in - * cleanup() . If for some reason netproc hangs waiting for the server - * to clean up, the alarm clock goes off and the program exits anyway. - * The cleanup() routine makes a check to ensure it's not reentering, in - * case the ipc module looped it somehow. - */ -void nq_cleanup(int e) -{ - remove_lockfile(); - closelog(); - exit(e); -} - -void cleanup(int e) -{ - static int nested = 0; - - alarm(30); - signal(SIGALRM, nq_cleanup); - if (nested++ < 1) - serv_puts("QUIT"); - nq_cleanup(e); -} - -/* - * This is implemented as a function rather than as a macro because the - * client-side IPC modules expect logoff() to be defined. They call logoff() - * when a problem connecting or staying connected to the server occurs. - */ -void logoff(int e) -{ - cleanup(e); -} - -/* - * If there is a kill file in place, this function will process it. - */ -void load_filterlist(void) -{ - FILE *fp; - struct filterlist *fbuf; - char sbuf[256]; - int a, p; - fp = fopen("./network/filterlist", "r"); - if (fp == NULL) - return; - while (fgets(sbuf, sizeof sbuf, fp) != NULL) { - if (sbuf[0] != '#') { - sbuf[strlen(sbuf) - 1] = 0; - fbuf = (struct filterlist *) - malloc((long) sizeof(struct filterlist)); - fbuf->next = filter; - filter = fbuf; - strcpy(fbuf->f_person, "*"); - strcpy(fbuf->f_room, "*"); - strcpy(fbuf->f_system, "*"); - p = (-1); - for (a = strlen(sbuf); a >= 0; --a) - if (sbuf[a] == ',') - p = a; - if (p >= 0) { - sbuf[p] = 0; - strcpy(fbuf->f_person, sbuf); - strcpy(sbuf, &sbuf[p + 1]); - } - for (a = strlen(sbuf); a >= 0; --a) - if (sbuf[a] == ',') - p = a; - if (p >= 0) { - sbuf[p] = 0; - strcpy(fbuf->f_room, sbuf); - strcpy(sbuf, &sbuf[p + 1]); - } - strcpy(fbuf->f_system, sbuf); - } - } - fclose(fp); -} - -/* returns 1 if user/message/room combination is in the kill file */ -int is_banned(char *k_person, char *k_room, char *k_system) -{ - struct filterlist *fptr; - - for (fptr = filter; fptr != NULL; fptr = fptr->next) - if ( - ((!strcasecmp(fptr->f_person, k_person)) || (!strcmp(fptr->f_person, "*"))) - && - ((!strcasecmp(fptr->f_room, k_room)) || (!strcmp(fptr->f_room, "*"))) - && - ((!strcasecmp(fptr->f_system, k_system)) || (!strcmp(fptr->f_system, "*"))) - ) - return (1); - - return (0); -} - -/* - * Determine routing from sysinfo file - */ -int get_sysinfo_type(char *name) { - struct syslist *stemp; - -GETSN: for (stemp = slist; stemp != NULL; stemp = stemp->next) { - if (!strcasecmp(stemp->s_name, name)) { - if (!strcasecmp(stemp->s_type, "use")) { - strcpy(name, stemp->s_nexthop); - goto GETSN; - } - if (!strcasecmp(stemp->s_type, "bin")) { - return (MES_BINARY); - } - if (!strcasecmp(stemp->s_type, "uum")) { - return (MES_INTERNET); - } - } - } - syslog(LOG_ERR, "cannot find system '%s' in mail.sysinfo", name); - return (-1); -} - - -void fpgetfield(FILE *fp, char *string, int limit) -{ - int a, b; - - strcpy(string, ""); - a = 0; - do { - b = getc(fp); - if ((b < 1) || (a >= limit)) { - string[a] = 0; - return; - } - string[a] = b; - ++a; - } while (b != 0); -} - - - -/* - * Load all of the fields of a message, except the actual text, into a - * table in memory (so we know how to process the message). - */ -void fpmsgfind(FILE *fp, struct minfo *buffer) -{ - int b, e, mtype, aflag; - char bbb[1024]; - char userid[1024]; - - strcpy(userid, ""); - e = getc(fp); - if (e != 255) { - syslog(LOG_ERR, "Magic number check failed for this message"); - goto END; - } - - memset(buffer, 0, sizeof(struct minfo)); - mtype = getc(fp); - aflag = getc(fp); - -BONFGM: b = getc(fp); - if (b < 0) - goto END; - if (b == 'M') - goto END; - fpgetfield(fp, bbb, sizeof bbb); - while ((bbb[0] == ' ') && (strlen(bbb) > 1)) - strcpy(bbb, &bbb[1]); - if (b == 'A') { - strcpy(buffer->A, bbb); - if (strlen(userid) == 0) { - strcpy(userid, bbb); - for (e = 0; e < strlen(userid); ++e) - if (userid[e] == ' ') - userid[e] = '_'; - } - } - if (b == 'O') - strcpy(buffer->O, bbb); - if (b == 'C') - strcpy(buffer->C, bbb); - if (b == 'N') - strcpy(buffer->N, bbb); - if (b == 'S') - strcpy(buffer->S, bbb); - if (b == 'P') { - /* extract the user id from the path */ - for (e = 0; e < strlen(bbb); ++e) - if (bbb[e] == '!') - strcpy(userid, &bbb[e + 1]); - - /* now find the next hop */ - for (e = 0; e < strlen(bbb); ++e) - if (bbb[e] == '!') - bbb[e] = 0; - strcpy(buffer->nexthop, bbb); - } - if (b == 'R') { - for (e = 0; e < strlen(bbb); ++e) - if (bbb[e] == '_') - bbb[e] = ' '; - strcpy(buffer->R, bbb); - } - if (b == 'D') - strcpy(buffer->D, bbb); - if (b == 'T') - buffer->T = atol(bbb); - if (b == 'I') - strcpy(buffer->I, bbb); - if (b == 'H') - strcpy(buffer->H, bbb); - if (b == 'B') - strcpy(buffer->B, bbb); - if (b == 'G') - strcpy(buffer->G, bbb); - if (b == 'E') - strcpy(buffer->E, bbb); - if (b == 'Z') - strcpy(buffer->Z, bbb); - goto BONFGM; - -END:; - -} - - -/* - * msgfind() is the same as fpmsgfind() except it accepts a filename - * instead of a file handle. - */ -void msgfind(char *msgfile, struct minfo *buffer) { - FILE *fp; - - fp = fopen(msgfile, "rb"); - if (fp == NULL) { - syslog(LOG_ERR, "can't open %s: %s", msgfile, strerror(errno)); - return; - } - - fpmsgfind(fp, buffer); - fclose(fp); -} - - - - - -void ship_to(char *filenm, char *sysnm) -{ /* send spool file filenm to system sysnm */ - char sysflnm[100]; - char commbuf1[100]; - char commbuf2[100]; - FILE *sysflfd; - -#ifdef DEBUG - syslog(LOG_NOTICE, "shipping %s to %s", filenm, sysnm); -#endif - sprintf(sysflnm, "./network/systems/%s", sysnm); - sysflfd = fopen(sysflnm, "r"); - if (sysflfd == NULL) - syslog(LOG_ERR, "cannot open %s", sysflnm); - fgets(commbuf1, 99, sysflfd); - commbuf1[strlen(commbuf1) - 1] = 0; - fclose(sysflfd); - sprintf(commbuf2, commbuf1, filenm); - system(commbuf2); -} - -/* - * proc_file_transfer() - handle a simple file transfer packet - * - */ -void proc_file_transfer(char *tname) -{ /* name of temp file containing the whole message */ - char buf[256]; - char dest_room[ROOMNAMELEN]; - char subdir_name[256]; - FILE *tfp, *uud; - int a; - - syslog(LOG_NOTICE, "processing network file transfer..."); - - tfp = fopen(tname, "rb"); - if (tfp == NULL) - syslog(LOG_ERR, "cannot open %s", tname); - getc(tfp); - getc(tfp); - getc(tfp); - do { - a = getc(tfp); - if (a != 'M') { - fpgetfield(tfp, buf, sizeof buf); - if (a == 'O') { - strcpy(dest_room, buf); - } - } - } while ((a != 'M') && (a >= 0)); - if (a != 'M') { - fclose(tfp); - syslog(LOG_ERR, "no message text for file transfer"); - return; - } - strcpy(subdir_name, "---xxx---"); - sprintf(buf, "GOTO %s", dest_room); - serv_puts(buf); - serv_gets(buf); - if (buf[0] == '2') { - extract(subdir_name, &buf[4], 2); - if (strlen(subdir_name) == 0) - strcpy(subdir_name, "--xxx--"); - } - /* Change to the room's directory; if that fails, change to the - * bitbucket directory. Then run uudecode. - */ - sprintf(buf, "(cd %s/files/%s || cd %s/files/%s ) ; exec %s", - bbs_home_directory, subdir_name, - bbs_home_directory, config.c_bucket_dir, - UUDECODE); - - uud = (FILE *) popen(buf, "w"); - if (uud == NULL) { - syslog(LOG_ERR, "cannot open uudecode pipe"); - fclose(tfp); - return; - } - fgets(buf, 128, tfp); - buf[strlen(buf) - 1] = 0; - for (a = 0; a < strlen(buf); ++a) - if (buf[a] == '/') - buf[a] = '_'; - fprintf(uud, "%s\n", buf); - printf("netproc: %s\n", buf); - while (a = getc(tfp), a > 0) - putc(a, uud); - fclose(tfp); - pclose(uud); - return; -} - - -/* send a bounce message */ -void bounce(struct minfo *bminfo) -{ - - FILE *bounce; - char bfilename[64]; - static int bseq = 1; - time_t now; - - sprintf(bfilename, "./network/spoolin/bounce.%ld.%d", (long) getpid(), - bseq++); - bounce = fopen(bfilename, "wb"); - time(&now); - - fprintf(bounce, "%c%c%c", 0xFF, MES_NORMAL, 0); - fprintf(bounce, "Ppostmaster%c", 0); - fprintf(bounce, "T%ld%c", (long) now, 0); - fprintf(bounce, "APostmaster%c", 0); - fprintf(bounce, "OMail%c", 0); - fprintf(bounce, "N%s%c", config.c_nodename, 0); - fprintf(bounce, "H%s%c", config.c_humannode, 0); - - if (strlen(bminfo->E) > 0) { - fprintf(bounce, "R%s%c", bminfo->E, 0); - } else { - fprintf(bounce, "R%s%c", bminfo->A, 0); - } - - fprintf(bounce, "D%s%c", bminfo->N, 0); - fprintf(bounce, "M%s could not deliver your mail to:\n", - config.c_humannode); - fprintf(bounce, " \n %s\n \n", bminfo->R); - fprintf(bounce, " because there is no such user on this system.\n"); - fprintf(bounce, " (Unsent message does *not* follow. "); - fprintf(bounce, "Help to conserve bandwidth.)\n%c", 0); - fclose(bounce); -} - - - - -/* - * Generate a Message-ID string for the use table - */ -void strmsgid(char *buf, struct minfo *msginfo) { - int i; - - strcpy(buf, msginfo->I); - if (strchr(buf, '@') == NULL) { - strcat(buf, "@"); - strcat(buf, msginfo->N); - } - - for (i=0; iI)==0) { - return 0; - } - - strmsgid(buf, msginfo); - now = time(NULL); - - /* Set return value to 1 if message exists */ - for (u=usetable; u!=NULL; u=u->next) { - if (!strcasecmp(buf, u->msgid)) { - u->timestamp = time(NULL); /* keep it fresh */ - return(1); - } - } - - /* Not found, so we're ok, but add it to the use table now */ - u = (struct usetable *) malloc(sizeof (struct usetable)); - u->next = usetable; - u->timestamp = time(NULL); - strncpy(u->msgid, buf, 255); - usetable = u; - - return(0); -} - - -/* - * Load the use table from disk - */ -void read_use_table(void) { - struct usetable *u; - struct usetable ubuf; - FILE *fp; - - unlink("data/usetable.gdbm"); /* we don't use this anymore */ - - fp = fopen("usetable", "rb"); - if (fp == NULL) return; - - while (fread(&ubuf, sizeof (struct usetable), 1, fp) > 0) { - u = (struct usetable *) malloc(sizeof (struct usetable)); - memcpy(u, &ubuf, sizeof (struct usetable)); - u->next = usetable; - usetable = u; - } - - fclose(fp); -} - - - -/* - * Purge any old entries out of the use table as we write them back to disk. - * - */ -void write_use_table(void) { - struct usetable *u; - time_t now; - FILE *fp; - - now = time(NULL); - fp = fopen("usetable", "wb"); - if (fp == NULL) return; - for (u=usetable; u!=NULL; u=u->next) { - if ((now - u->timestamp) <= USE_TIME) { - fwrite(u, sizeof(struct usetable), 1, fp); - } - } - fclose(fp); -} - - - - - -/* - * process incoming files in ./network/spoolin - */ -void inprocess(void) -{ - FILE *fp, *message, *testfp, *ls, *duplist; - static struct minfo minfo; - char tname[128], aaa[1024], iname[256], sfilename[256], pfilename[256]; - int a, b; - int FieldID; - struct syslist *stemp; - char *ptr = NULL; - char buf[256]; - long msglen; - int bloklen; - int valid_msg; - - /* temp file names */ - sprintf(tname, "%s.netproc.%d", tmpnam(NULL), __LINE__); - sprintf(iname, "%s.netproc.%d", tmpnam(NULL), __LINE__); - - load_filterlist(); - - /* Make sure we're in the right directory */ - chdir(bbs_home_directory); - - /* temporary file to contain a log of rejected dups */ - duplist = tmpfile(); - - /* Let the shell do the dirty work. Get all data from spoolin */ - do { - sprintf(aaa, "cd %s/network/spoolin; ls", bbs_home_directory); - ls = popen(aaa, "r"); - if (ls == NULL) { - syslog(LOG_ERR, "could not open dir cmd: %s", strerror(errno)); - } - if (ls != NULL) { - do { -SKIP: ptr = fgets(sfilename, sizeof sfilename, ls); - if (ptr != NULL) { - sfilename[strlen(sfilename) - 1] = 0; -#ifdef DEBUG - syslog(LOG_DEBUG, - "Trying <%s>", sfilename); -#endif - if (!strcmp(sfilename, ".")) goto SKIP; - if (!strcmp(sfilename, "..")) goto SKIP; - if (!strcmp(sfilename, "CVS")) goto SKIP; - goto PROCESS_IT; - } - } while (ptr != NULL); -PROCESS_IT: pclose(ls); - } - if (ptr != NULL) { - sprintf(pfilename, "%s/network/spoolin/%s", bbs_home_directory, sfilename); - syslog(LOG_NOTICE, "processing <%s>", pfilename); - - fp = fopen(pfilename, "rb"); - if (fp == NULL) { - syslog(LOG_ERR, "cannot open %s: %s", pfilename, strerror(errno)); - fp = fopen("/dev/null", "rb"); - } -NXMSG: /* Seek to the beginning of the next message */ - do { - a = getc(fp); - } while ((a != 255) && (a >= 0)); - if (a < 0) - goto ENDSTR; - - /* This crates the temporary file. */ - valid_msg = 1; - message = fopen(tname, "wb"); - if (message == NULL) { - syslog(LOG_ERR, "error creating %s: %s", - tname, strerror(errno)); - goto ENDSTR; - } - putc(255, message); /* 0xFF (start-of-message) */ - a = getc(fp); - putc(a, message); /* type */ - a = getc(fp); - putc(a, message); /* mode */ - do { - FieldID = getc(fp); /* Header field ID */ - if (isalpha(FieldID)) { - putc(FieldID, message); - do { - a = getc(fp); - if (a < 127) putc(a, message); - } while (a > 0); - if (a != 0) putc(0, message); - } - else { /* Invalid field ID; flush it */ - do { - a = getc(fp); - } while (a > 0); - valid_msg = 0; - } - } while ((FieldID != 'M') && (a >= 0)); - /* M is always last */ - if (FieldID != 'M') valid_msg = 0; - - msglen = ftell(message); - fclose(message); - - if (!valid_msg) { - unlink(tname); - goto NXMSG; - } - - /* process the individual mesage */ - msgfind(tname, &minfo); - syslog(LOG_NOTICE, "#%ld fm <%s> in <%s> @ <%s>", - minfo.I, minfo.A, minfo.O, minfo.N); - if (strlen(minfo.R) > 0) { - syslog(LOG_NOTICE, " to <%s>", minfo.R); - if (strlen(minfo.D) > 0) { - syslog(LOG_NOTICE, " @ <%s>", - minfo.D); - } - } - if (!strcasecmp(minfo.D, FQDN)) - strcpy(minfo.D, NODENAME); - -/* this routine updates our info on the system that sent the message */ - stemp = get_sys_ptr(minfo.N); - if ((stemp == NULL) && (get_sys_ptr(minfo.nexthop) != NULL)) { - /* add non-neighbor system to map */ - syslog(LOG_NOTICE, "Adding non-neighbor system <%s> to map", - slist->s_name); - stemp = (struct syslist *) malloc((long) sizeof(struct syslist)); - stemp->next = slist; - slist = stemp; - strcpy(slist->s_name, minfo.N); - strcpy(slist->s_type, "use"); - strcpy(slist->s_nexthop, minfo.nexthop); - time(&slist->s_lastcontact); - } else if ((stemp == NULL) && (!strcasecmp(minfo.N, minfo.nexthop))) { - /* add neighbor system to map */ - syslog(LOG_NOTICE, "Adding neighbor system <%s> to map", - slist->s_name); - sprintf(aaa, "%s/network/systems/%s", bbs_home_directory, minfo.N); - testfp = fopen(aaa, "r"); - if (testfp != NULL) { - fclose(testfp); - stemp = (struct syslist *) - malloc((long) sizeof(struct syslist)); - stemp->next = slist; - slist = stemp; - strcpy(slist->s_name, minfo.N); - strcpy(slist->s_type, "bin"); - strcpy(slist->s_nexthop, "Mail"); - time(&slist->s_lastcontact); - } - } - /* now update last contact and long node name if we can */ - if (stemp != NULL) { - time(&stemp->s_lastcontact); - if (strlen(minfo.H) > 0) - strcpy(stemp->s_humannode, minfo.H); - if (strlen(minfo.B) > 0) - strcpy(stemp->s_phonenum, minfo.B); - if (strlen(minfo.G) > 0) - strcpy(stemp->s_gdom, minfo.G); - } - - /* Check the use table; reject message if it's been here before */ - if (already_received(&minfo)) { - syslog(LOG_NOTICE, "rejected duplicate message"); - fprintf(duplist, "#<%s> fm <%s> in <%s> @ <%s>\n", - minfo.I, minfo.A, minfo.O, minfo.N); - } - - - /* route the message if necessary */ - else if ((strcasecmp(minfo.D, NODENAME)) && (minfo.D[0] != 0)) { - a = get_sysinfo_type(minfo.D); - syslog(LOG_NOTICE, "routing message to system <%s>", minfo.D); - fflush(stdout); - if (a == MES_INTERNET) { - if (fork() == 0) { - syslog(LOG_NOTICE, "netmailer %s", tname); - fflush(stdout); - execlp("./netmailer", "netmailer", - tname, NULL); - syslog(LOG_ERR, "error running netmailer: %s", - strerror(errno)); - exit(errno); - } else - while (wait(&b) != (-1)); - } else if (a == MES_BINARY) { - ship_to(tname, minfo.D); - } else { - /* message falls into the bit bucket? */ - } - } - - /* check to see if it's a file transfer */ - else if (!strncasecmp(minfo.S, "FILE", 4)) { - proc_file_transfer(tname); - } - - /* otherwise process it as a normal message */ - else { - if (!strcasecmp(minfo.R, "postmaster")) { - strcpy(minfo.R, ""); - strcpy(minfo.C, "Aide"); - } - if (strlen(minfo.R) > 0) { - sprintf(buf, "GOTO _MAIL_"); - } - if (is_banned(minfo.A, minfo.C, minfo.N)) { - sprintf(buf, "GOTO %s", FILTERROOM); - } else { - if (strlen(minfo.C) > 0) { - sprintf(buf, "GOTO %s", minfo.C); - } else { - sprintf(buf, "GOTO %s", minfo.O); - } - } - serv_puts(buf); - serv_gets(buf); - if (buf[0] != '2') { - syslog(LOG_ERR, "%s", buf); - sprintf(buf, "GOTO _BITBUCKET_"); - serv_puts(buf); - serv_gets(buf); - } - /* Open the temporary file containing the message */ - message = fopen(tname, "rb"); - if (message == NULL) { - syslog(LOG_ERR, "cannot open %s: %s", - tname, strerror(errno)); - unlink(tname); - goto NXMSG; - } - /* Transmit the message to the server */ - sprintf(buf, "ENT3 1|%s|%ld", minfo.R, msglen); - serv_puts(buf); - serv_gets(buf); - if (!strncmp(buf, "570", 3)) { - /* no such user, do a bounce */ - bounce(&minfo); - } - if (buf[0] == '7') { - /* Always use the server's idea of the message length, - * even though they should both be identical */ - msglen = atol(&buf[4]); - while (msglen > 0L) { - bloklen = ((msglen >= 255L) ? 255 : ((int) msglen)); - if (fread(buf, bloklen, 1, message) < 1) { - syslog(LOG_ERR, - "error trying to read %d bytes: %s", - bloklen, strerror(errno)); - } - serv_write(buf, bloklen); - msglen = msglen - (long) bloklen; - } - serv_puts("NOOP"); - serv_gets(buf); - } else { - syslog(LOG_ERR, "%s", buf); - } - - fclose(message); - - } - - unlink(tname); - goto NXMSG; - -ENDSTR: fclose(fp); - unlink(pfilename); - } - } while (ptr != NULL); - unlink(iname); - - - /* - * If dups were rejected, post a message saying so - */ - if (ftell(duplist)!=0L) { - fp = fopen("./network/spoolin/ctdl_rejects", "ab"); - if (fp != NULL) { - fprintf(fp, "%cA%c", 255, 1); - fprintf(fp, "T%ld%c", time(NULL), 0); - fprintf(fp, "ACitadel%c", 0); - fprintf(fp, "OAide%cM", 0); - fprintf(fp, "The following duplicate messages" - " were rejected:\n \n"); - rewind(duplist); - while (fgets(buf, sizeof(buf), duplist) != NULL) { - buf[strlen(buf)-1] = 0; - fprintf(fp, " %s\n", buf); - } - fprintf(fp, "%c", 0); - pclose(fp); - } - } - - fclose(duplist); - -} - - -/* Checks to see whether its ok to send */ -/* Returns 1 for ok, send message */ -/* Returns 0 if message already there */ -int checkpath(char *path, char *sys) -{ - int a; - char sys2[512]; - strcpy(sys2, sys); - strcat(sys2, "!"); - -#ifdef DEBUG - syslog(LOG_NOTICE, "checkpath <%s> <%s> ... ", path, sys); -#endif - for (a = 0; a < strlen(path); ++a) { - if (!strncmp(&path[a], sys2, strlen(sys2))) - return (0); - } - return (1); -} - -/* - * Implement split horizon algorithm (prevent infinite spooling loops - * by refusing to send any node a message which already contains its - * nodename in the path). - */ -int ismsgok(FILE *mmfp, char *sysname) -{ - int a; - int ok = 0; /* fail safe - no path, don't send it */ - char fbuf[256]; - - fseek(mmfp, 0L, 0); - if (getc(mmfp) != 255) - return (0); - getc(mmfp); - getc(mmfp); - - while (a = getc(mmfp), ((a != 'M') && (a != 0))) { - fpgetfield(mmfp, fbuf, sizeof fbuf); - if (a == 'P') { - ok = checkpath(fbuf, sysname); - } - } -#ifdef DEBUG - syslog(LOG_NOTICE, "%s", ((ok) ? "SEND" : "(no)")); -#endif - return (ok); -} - - - - -/* - * Add a message to the list of messages to be deleted off the local server - * at the end of this run. - */ -void delete_locally(long msgid, char *roomname) { - struct msglist *mptr; - - mptr = (struct msglist *) malloc(sizeof(struct msglist)); - mptr->next = purgelist; - mptr->m_num = msgid; - strcpy(mptr->m_rmname, roomname); - purgelist = mptr; -} - - - -/* - * Delete all messages on the purge list from the local server. - */ -void process_purgelist(void) { - char curr_rm[ROOMNAMELEN]; - char buf[256]; - struct msglist *mptr; - - - strcpy(curr_rm, "__nothing__"); - while (purgelist != NULL) { - if (strcasecmp(curr_rm, purgelist->m_rmname)) { - sprintf(buf, "GOTO %s", purgelist->m_rmname); - serv_puts(buf); - serv_gets(buf); - if (buf[0] == '2') { - extract(curr_rm, &buf[4], 0); - } - else { - syslog(LOG_ERR, "%s", buf); - } - } - if (!strcasecmp(curr_rm, purgelist->m_rmname)) { - syslog(LOG_NOTICE, "Purging <%ld> in <%s>", - purgelist->m_num, purgelist->m_rmname); - sprintf(buf, "DELE %ld", purgelist->m_num); - serv_puts(buf); - serv_gets(buf); - if (buf[0] != '2') { - syslog(LOG_ERR, "%s", buf); - } - - } - mptr = purgelist->next; - free(purgelist); - purgelist = mptr; - } -} - - - - -/* spool list of messages to a file */ -/* returns # of msgs spooled */ -int spool_out(struct msglist *cmlist, FILE * destfp, char *sysname) -{ - struct msglist *cmptr; - FILE *mmfp; - char fbuf[1024]; - int a; - int msgs_spooled = 0; - long msg_len; - int blok_len; - static struct minfo minfo; - - char buf[256]; - char curr_rm[256]; - - strcpy(curr_rm, ""); - - /* for each message in the list... */ - for (cmptr = cmlist; cmptr != NULL; cmptr = cmptr->next) { - - /* make sure we're in the correct room... */ - if (strcasecmp(curr_rm, cmptr->m_rmname)) { - sprintf(buf, "GOTO %s", cmptr->m_rmname); - serv_puts(buf); - serv_gets(buf); - if (buf[0] == '2') { - strcpy(curr_rm, cmptr->m_rmname); - } else { - syslog(LOG_ERR, "%s", buf); - } - } - /* download the message from the server... */ - mmfp = tmpfile(); - if (mmfp == NULL) { - syslog(LOG_NOTICE, "tmpfile() failed: %s\n", - strerror(errno) ); - } - sprintf(buf, "MSG3 %ld", cmptr->m_num); - serv_puts(buf); - serv_gets(buf); - if (buf[0] == '6') { /* read the msg */ - msg_len = atol(&buf[4]); - while (msg_len > 0L) { - blok_len = ((msg_len >= 256L) ? 256 : (int) msg_len); - serv_read(buf, blok_len); - fwrite(buf, blok_len, 1, mmfp); - msg_len = msg_len - (long) blok_len; - } - } else { /* or print the err */ - syslog(LOG_ERR, "%s", buf); - } - - rewind(mmfp); - - if (ismsgok(mmfp, sysname)) { - ++msgs_spooled; - fflush(stdout); - fseek(mmfp, 0L, 0); - fread(fbuf, 3, 1, mmfp); - fwrite(fbuf, 3, 1, destfp); - while (a = getc(mmfp), ((a != 0) && (a != 'M'))) { - if (a != 'C') { - putc(a, destfp); - } - fpgetfield(mmfp, fbuf, sizeof fbuf); - if (a == 'P') { - fprintf(destfp, "%s!", NODENAME); - } - if (a != 'C') { - fwrite(fbuf, strlen(fbuf) + 1, 1, destfp); - } - if (a == 'S') if (!strcasecmp(fbuf, "CANCEL")) { - delete_locally(cmptr->m_num, cmptr->m_rmname); - } - } - if (a == 'M') { - fprintf(destfp, "C%s%c", - cmptr->m_rmname, 0); - putc('M', destfp); - do { - a = getc(mmfp); - putc(a, destfp); - } while (a > 0); - } - - /* Get this message into the use table, so we can reject it - * if a misconfigured remote system sends it back to us. - */ - fseek(mmfp, 0L, 0); - fpmsgfind(mmfp, &minfo); - already_received(&minfo); - - } - fclose(mmfp); - } - - return (msgs_spooled); -} - -void outprocess(char *sysname) -{ /* send new room messages to sysname */ - char sysflnm[64]; - char srmname[32]; - char shiptocmd[128]; - char lbuf[64]; - char tempflnm[64]; - char buf[256]; - struct msglist *cmlist = NULL; - struct msglist *cmlast = NULL; - struct rmlist *crmlist = NULL; - struct rmlist *rmptr, *rmptr2; - struct msglist *cmptr; - FILE *sysflfp, *tempflfp; - int outgoing_msgs = 0; - long thismsg; - - sprintf(tempflnm, "%s.netproc.%d", tmpnam(NULL), __LINE__); - tempflfp = fopen(tempflnm, "w"); - if (tempflfp == NULL) - return; - - -/* - * Read system file for node in question and put together room list - */ - sprintf(sysflnm, "%s/network/systems/%s", bbs_home_directory, sysname); - sysflfp = fopen(sysflnm, "r"); - if (sysflfp == NULL) - return; - fgets(shiptocmd, 128, sysflfp); - shiptocmd[strlen(shiptocmd) - 1] = 0; - while (!feof(sysflfp)) { - if (fgets(srmname, 32, sysflfp) == NULL) - break; - srmname[strlen(srmname) - 1] = 0; - fgets(lbuf, 32, sysflfp); - rmptr = (struct rmlist *) malloc(sizeof(struct rmlist)); - rmptr->next = NULL; - strcpy(rmptr->rm_name, srmname); - strip_trailing_whitespace(rmptr->rm_name); - rmptr->rm_lastsent = atol(lbuf); - if (crmlist == NULL) - crmlist = rmptr; - else if (!strcasecmp(rmptr->rm_name, "control")) { - /* control has to be first in room list */ - rmptr->next = crmlist; - crmlist = rmptr; - } else { - rmptr2 = crmlist; - while (rmptr2->next != NULL) - rmptr2 = rmptr2->next; - rmptr2->next = rmptr; - } - } - fclose(sysflfp); - -/* - * Assemble list of messages to be spooled - */ - for (rmptr = crmlist; rmptr != NULL; rmptr = rmptr->next) { - - sprintf(buf, "GOTO %s", rmptr->rm_name); - serv_puts(buf); - serv_gets(buf); - if (buf[0] != '2') { - syslog(LOG_ERR, "%s", buf); - } else { - sprintf(buf, "MSGS GT|%ld", rmptr->rm_lastsent); - serv_puts(buf); - serv_gets(buf); - if (buf[0] == '1') - while (serv_gets(buf), strcmp(buf, "000")) { - thismsg = atol(buf); - if (thismsg > (rmptr->rm_lastsent)) { - rmptr->rm_lastsent = thismsg; - - cmptr = (struct msglist *) - malloc(sizeof(struct msglist)); - cmptr->next = NULL; - cmptr->m_num = thismsg; - strcpy(cmptr->m_rmname, rmptr->rm_name); - - if (cmlist == NULL) { - cmlist = cmptr; - } - else { - cmlast->next = cmptr; - } - cmlast = cmptr; - ++outgoing_msgs; - } - } else { /* print error from "msgs all" */ - syslog(LOG_ERR, "%s", buf); - } - } - } - - syslog(LOG_NOTICE, "%d messages to be spooled to %s", - outgoing_msgs, sysname); - -/* - * Spool out the messages, but only if there are any. - */ - if (outgoing_msgs != 0) { - outgoing_msgs = spool_out(cmlist, tempflfp, sysname); - } - - syslog(LOG_NOTICE, "%d messages actually spooled", outgoing_msgs); - -/* - * Deallocate list of spooled messages. - */ - while (cmlist != NULL) { - cmptr = cmlist->next; - free(cmlist); - cmlist = cmptr; - } - -/* - * Rewrite system file and deallocate room list. - */ - syslog(LOG_NOTICE, "Spooling..."); - sysflfp = fopen(sysflnm, "w"); - fprintf(sysflfp, "%s\n", shiptocmd); - for (rmptr = crmlist; rmptr != NULL; rmptr = rmptr->next) - fprintf(sysflfp, "%s\n%ld\n", rmptr->rm_name, rmptr->rm_lastsent); - fclose(sysflfp); - while (crmlist != NULL) { - rmptr = crmlist->next; - free(crmlist); - crmlist = rmptr; - } - -/* - * Close temporary file, ship it out, and return - */ - fclose(tempflfp); - if (outgoing_msgs != 0) - ship_to(tempflnm, sysname); - unlink(tempflnm); -} - - -/* - * Connect netproc to the Citadel server running on this computer. - */ -void np_attach_to_server(void) -{ - char buf[256]; - char *args[] = - { "netproc", NULL }; - - syslog(LOG_NOTICE, "Attaching to server..."); - attach_to_server(1, args, NULL, NULL); - serv_gets(buf); - syslog(LOG_NOTICE, "%s", &buf[4]); - sprintf(buf, "IPGM %d", config.c_ipgm_secret); - serv_puts(buf); - serv_gets(buf); - syslog(LOG_NOTICE, "%s", &buf[4]); - if (buf[0] != '2') { - cleanup(2); - } -} - - - -/* - * main - */ -int main(int argc, char **argv) -{ - char allst[32]; - FILE *allfp; - int a; - int import_only = 0; /* if set to 1, don't export anything */ - - openlog("netproc", LOG_PID, LOG_USER); - strcpy(bbs_home_directory, BBSDIR); - - /* - * Change directories if specified - */ - for (a = 1; a < argc; ++a) { - if (!strncmp(argv[a], "-h", 2)) { - strcpy(bbs_home_directory, argv[a]); - strcpy(bbs_home_directory, &bbs_home_directory[2]); - home_specified = 1; - } else if (!strcmp(argv[a], "-i")) { - import_only = 1; - } else { - fprintf(stderr, "netproc: usage: "); - fprintf(stderr, "netproc [-hHomeDir] [-i]\n"); - exit(1); - } - } - -#ifdef DEBUG - syslog(LOG_DEBUG, "Calling get_config()"); -#endif - get_config(); - -#ifdef DEBUG - syslog(LOG_DEBUG, "Creating lock file"); -#endif - if (set_lockfile() != 0) { - syslog(LOG_NOTICE, "lock file exists: already running"); - cleanup(1); - } - signal(SIGINT, cleanup); - signal(SIGQUIT, cleanup); - signal(SIGHUP, cleanup); - signal(SIGTERM, cleanup); - - syslog(LOG_NOTICE, "started. pid=%d", getpid()); - fflush(stdout); - np_attach_to_server(); - fflush(stdout); - - if (load_syslist() != 0) - syslog(LOG_ERR, "cannot load sysinfo"); - setup_special_nodes(); - - /* Open the use table */ - read_use_table(); - - /* first collect incoming stuff */ - inprocess(); - - /* Now process outbound messages, but NOT if this is just a - * quick import-only run (i.e. the -i command-line option - * was specified) - */ - if (import_only != 1) { - allfp = (FILE *) popen("cd ./network/systems; ls", "r"); - if (allfp != NULL) { - while (fgets(allst, 32, allfp) != NULL) { - allst[strlen(allst) - 1] = 0; - if (strcmp(allst, "CVS")) - outprocess(allst); - } - pclose(allfp); - } - /* import again in case anything new was generated */ - inprocess(); - } - - /* Update mail.sysinfo with new information we learned */ - rewrite_syslist(); - - /* Delete any messages which need to be purged locally */ - syslog(LOG_NOTICE, "calling process_purgelist()"); - process_purgelist(); - - /* Close the use table */ - write_use_table(); - - syslog(LOG_NOTICE, "processing ended."); - cleanup(0); - return 0; -} diff --git a/citadel/serv_network.c b/citadel/serv_network.c index b18738f7f..134ff2559 100644 --- a/citadel/serv_network.c +++ b/citadel/serv_network.c @@ -1,8 +1,8 @@ /* * $Id$ * - * This module will eventually replace netproc and some of its utilities. In - * the meantime, it serves as a mailing list manager. + * This module handles shared rooms, inter-Citadel mail, and outbound + * mailing list processing. * * Copyright (C) 2000-2001 by Art Cancro and others. * This code is released under the terms of the GNU General Public License. diff --git a/citadel/serv_vcard.c b/citadel/serv_vcard.c index 2a67d9f87..102b2d766 100644 --- a/citadel/serv_vcard.c +++ b/citadel/serv_vcard.c @@ -453,11 +453,6 @@ void vcard_purge(char *username, long usernum) { CtdlSaveMsg(msg, "", ADDRESS_BOOK_ROOM, MES_LOCAL); CtdlFreeMessage(msg); - - /* Start a netproc run in the background, so the "purge" message - * gets flushed out of the room immediately - */ - system("./netproc &"); } -- 2.30.2