From 3d44485e8945ef9b355fc1a87e41fcbac7a6a27f Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 24 Sep 2001 18:55:13 +0000 Subject: [PATCH] * Completed migrating the "netpoll" utility into the serv_network module. Removed this utility. --- citadel/.cvsignore | 1 - citadel/ChangeLog | 5 +- citadel/Makefile.in | 8 +- citadel/netpoll.c | 204 ----------------------------------- citadel/serv_network.c | 236 +++++++++++++++++++++++++++++++++++++++++ citadel/sysconfig.h | 8 ++ 6 files changed, 250 insertions(+), 212 deletions(-) delete mode 100644 citadel/netpoll.c diff --git a/citadel/.cvsignore b/citadel/.cvsignore index fc49e88b2..6c8c60cba 100644 --- a/citadel/.cvsignore +++ b/citadel/.cvsignore @@ -29,7 +29,6 @@ Makefile msgform netconfigs netmailer -netpoll netproc netsetup parsedate.c diff --git a/citadel/ChangeLog b/citadel/ChangeLog index 05c818984..44e058eae 100644 --- a/citadel/ChangeLog +++ b/citadel/ChangeLog @@ -1,4 +1,8 @@ $Log$ + Revision 580.47 2001/09/24 18:55:13 ajc + * Completed migrating the "netpoll" utility into the serv_network module. + Removed this utility. + Revision 580.46 2001/09/21 20:58:25 nbryant support different log_archive prototype in DB versions prior to 3.3 @@ -2758,4 +2762,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 d04dba2a2..879ed1199 100644 --- a/citadel/Makefile.in +++ b/citadel/Makefile.in @@ -41,7 +41,7 @@ SERV_MODULES=modules/libchat.la modules/libvcard.la \ modules/libvandelay.la \ modules/libical.la UTIL_TARGETS=aidepost netmailer netproc netsetup msgform readlog rcit \ - stats citmail netpoll mailinglist userlist sendcommand \ + stats citmail mailinglist userlist sendcommand \ base64 qpdecode prefix=@prefix@ @@ -84,7 +84,7 @@ 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 \ - netpoll.c netproc.c netsetup.c policy.c rcit.c readlog.c \ + netproc.c netsetup.c policy.c rcit.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 \ @@ -121,10 +121,6 @@ citadel$(EXEEXT): ipc_c_tcp$(CX) citadel$(CX) rooms$(CX) routines$(CX) \ client_passwords$(CX) md5$(CX) \ $(LIBOBJS) $(LDFLAGS) -o citadel $(NETLIBS) $(CLIENT_PTLIBS) -netpoll: netpoll.o config.o ipc_c_tcp.o tools.o $(LIBOBJS) - $(CC) netpoll.o config.o ipc_c_tcp.o tools.o \ - $(LIBOBJS) $(LDFLAGS) -o netpoll $(NETLIBS) - .c.o: $(CC) $(CFLAGS) $(CPPFLAGS) $(DEFS) -c $< diff --git a/citadel/netpoll.c b/citadel/netpoll.c deleted file mode 100644 index 527c7610f..000000000 --- a/citadel/netpoll.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * $Id$ - * - * Perform data transfer between our Citadel server and another. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include "citadel.h" -#include "tools.h" -#include "ipc.h" - -/* - * This variable defines the amount of network spool data that may be carried - * in one server transfer command. For some reason, some networks get hung - * up on larger packet sizes. We don't know why. In any case, never set the - * packet size higher than 4096 or your server sessions will crash. - */ -#define IGNET_PACKET_SIZE 4000 - -long atol(const char *); - -void serv_read(char *buf, int bytes); -void serv_write(char *buf, int nbytes); -void get_config(void); -struct config config; - - -void logoff(int code) -{ - exit(code); -} - - -/* - * receive network spool from the remote system - */ -void receive_spool(void) -{ - long download_len; - long bytes_received; - char buf[SIZ]; - static char pbuf[IGNET_PACKET_SIZE]; - char tempfilename[PATH_MAX]; - long plen; - FILE *fp; - - strcpy(tempfilename, tmpnam(NULL)); - serv_puts("NDOP"); - serv_gets(buf); - printf("%s\n", buf); - if (buf[0] != '2') - return; - download_len = extract_long(&buf[4], 0); - - bytes_received = 0L; - fp = fopen(tempfilename, "w"); - if (fp == NULL) { - perror("cannot open download file locally"); - return; - } - while (bytes_received < download_len) { - sprintf(buf, "READ %ld|%ld", - bytes_received, - ((download_len - bytes_received > IGNET_PACKET_SIZE) - ? IGNET_PACKET_SIZE : (download_len - bytes_received))); - serv_puts(buf); - serv_gets(buf); - if (buf[0] == '6') { - plen = extract_long(&buf[4], 0); - serv_read(pbuf, plen); - fwrite((char *) pbuf, plen, 1, fp); - bytes_received = bytes_received + plen; - } - } - - fclose(fp); - serv_puts("CLOS"); - serv_gets(buf); - printf("%s\n", buf); - sprintf(buf, "mv %s %s/network/spoolin/netpoll.%ld", - tempfilename, BBSDIR, (long) getpid()); - system(buf); - system("exec nohup ./netproc >/dev/null 2>&1 &"); -} - -/* - * transmit network spool to the remote system - */ -void transmit_spool(char *remote_nodename) -{ - char buf[SIZ]; - char pbuf[4096]; - long plen; - long bytes_to_write, thisblock; - int fd; - char sfname[128]; - - serv_puts("NUOP"); - serv_gets(buf); - printf("%s\n", buf); - if (buf[0] != '2') - return; - - sprintf(sfname, "%s/network/spoolout/%s", BBSDIR, remote_nodename); - fd = open(sfname, O_RDONLY); - if (fd < 0) { - if (errno == ENOENT) { - printf("Nothing to send.\n"); - } else { - perror("cannot open upload file locally"); - } - return; - } - while (plen = (long) read(fd, pbuf, IGNET_PACKET_SIZE), plen > 0L) { - bytes_to_write = plen; - while (bytes_to_write > 0L) { - sprintf(buf, "WRIT %ld", bytes_to_write); - serv_puts(buf); - serv_gets(buf); - thisblock = atol(&buf[4]); - if (buf[0] == '7') { - serv_write(pbuf, (int) thisblock); - bytes_to_write = bytes_to_write - thisblock; - } else { - goto ABORTUPL; - } - } - } - -ABORTUPL: - close(fd); - serv_puts("UCLS 1"); - serv_gets(buf); - printf("%s\n", buf); - if (buf[0] == '2') - unlink(sfname); -} - - - - -int main(int argc, char **argv) -{ - char buf[SIZ]; - char remote_nodename[32]; - int a; - - if (argc != 4) { - fprintf(stderr, - "%s: usage: %s
\n", - argv[0], argv[0]); - exit(1); - } - get_config(); - - attach_to_server(argc, argv, NULL, NULL); - serv_gets(buf); - printf("%s\n", buf); - if ((buf[0] != '2') && (strncmp(buf, "551", 3))) { - fprintf(stderr, "%s: %s\n", argv[0], &buf[4]); - logoff(atoi(buf)); - } - serv_puts("INFO"); - serv_gets(buf); - if (buf[0] == '1') { - a = 0; - while (serv_gets(buf), strcmp(buf, "000")) { - if (a == 1) - strcpy(remote_nodename, buf); - if (a == 1) - printf("Connected to: %s ", buf); - if (a == 2) - printf("(%s) ", buf); - if (a == 6) - printf("%s\n", buf); - ++a; - } - } - if (!strcmp(remote_nodename, config.c_nodename)) { - fprintf(stderr, "Connected to local system\n"); - } else { - sprintf(buf, "NETP %s|%s", config.c_nodename, argv[3]); - serv_puts(buf); - serv_gets(buf); - printf("%s\n", buf); - - /* only do the transfers if we authenticated correctly! */ - if (buf[0] == '2') { - receive_spool(); - transmit_spool(remote_nodename); - } - } - - serv_puts("QUIT"); - serv_gets(buf); - exit(0); -} diff --git a/citadel/serv_network.c b/citadel/serv_network.c index bcadcd917..d28b717e4 100644 --- a/citadel/serv_network.c +++ b/citadel/serv_network.c @@ -9,6 +9,13 @@ * */ +/* + * FIXME do something about concurrency issues: + * 1. Don't allow the two nodes to poll each other at the same time + * 2. Don't allow polls during network processing + * 3. Kill Bill Gates using either a chainsaw or a wood chipper + */ + #include "sysdep.h" #include #include @@ -48,6 +55,7 @@ #include "tools.h" #include "internet_addressing.h" #include "serv_network.h" +#include "clientsocket.h" /* @@ -814,6 +822,226 @@ void network_do_spoolin(void) { } + + + +/* + * receive network spool from the remote system + */ +void receive_spool(int sock, char *remote_nodename) { + long download_len; + long bytes_received; + char buf[SIZ]; + static char pbuf[IGNET_PACKET_SIZE]; + char tempfilename[PATH_MAX]; + long plen; + FILE *fp; + + strcpy(tempfilename, tmpnam(NULL)); + if (sock_puts(sock, "NDOP") < 0) return; + if (sock_gets(sock, buf) < 0) return; + lprintf(9, "<%s\n", buf); + if (buf[0] != '2') { + return; + } + download_len = extract_long(&buf[4], 0); + + bytes_received = 0L; + fp = fopen(tempfilename, "w"); + if (fp == NULL) { + lprintf(9, "cannot open download file locally: %s\n", + strerror(errno)); + return; + } + + while (bytes_received < download_len) { + sprintf(buf, "READ %ld|%ld", + bytes_received, + ((download_len - bytes_received > IGNET_PACKET_SIZE) + ? IGNET_PACKET_SIZE : (download_len - bytes_received))); + if (sock_puts(sock, buf) < 0) { + fclose(fp); + unlink(tempfilename); + return; + } + if (sock_gets(sock, buf) < 0) { + fclose(fp); + unlink(tempfilename); + return; + } + if (buf[0] == '6') { + plen = extract_long(&buf[4], 0); + if (sock_read(sock, pbuf, plen) < 0) { + fclose(fp); + unlink(tempfilename); + return; + } + fwrite((char *) pbuf, plen, 1, fp); + bytes_received = bytes_received + plen; + } + } + + fclose(fp); + if (sock_puts(sock, "CLOS") < 0) { + unlink(tempfilename); + return; + } + if (sock_gets(sock, buf) < 0) { + unlink(tempfilename); + return; + } + lprintf(9, "%s\n", buf); + sprintf(buf, "mv %s ./network/spoolin/%s.%ld", + tempfilename, remote_nodename, (long) getpid()); + system(buf); +} + + + +/* + * transmit network spool to the remote system + */ +void transmit_spool(int sock, char *remote_nodename) +{ + char buf[SIZ]; + char pbuf[4096]; + long plen; + long bytes_to_write, thisblock; + int fd; + char sfname[128]; + + if (sock_puts(sock, "NUOP") < 0) return; + if (sock_gets(sock, buf) < 0) return; + lprintf(9, "<%s\n", buf); + if (buf[0] != '2') { + return; + } + + sprintf(sfname, "./network/spoolout/%s", remote_nodename); + fd = open(sfname, O_RDONLY); + if (fd < 0) { + if (errno == ENOENT) { + lprintf(9, "Nothing to send.\n"); + } else { + lprintf(5, "cannot open upload file locally: %s\n", + strerror(errno)); + } + return; + } + while (plen = (long) read(fd, pbuf, IGNET_PACKET_SIZE), plen > 0L) { + bytes_to_write = plen; + while (bytes_to_write > 0L) { + sprintf(buf, "WRIT %ld", bytes_to_write); + if (sock_puts(sock, buf) < 0) { + close(fd); + return; + } + if (sock_gets(sock, buf) < 0) { + close(fd); + return; + } + thisblock = atol(&buf[4]); + if (buf[0] == '7') { + if (sock_write(sock, pbuf, + (int) thisblock) < 0) { + close(fd); + return; + } + bytes_to_write = bytes_to_write - thisblock; + } else { + goto ABORTUPL; + } + } + } + +ABORTUPL: + close(fd); + if (sock_puts(sock, "UCLS 1") < 0) return; + if (sock_gets(sock, buf) < 0) return; + lprintf(9, "<%s\n", buf); + if (buf[0] == '2') { + unlink(sfname); + } +} + + + +/* + * Poll one Citadel node (called by network_poll_other_citadel_nodes() below) + */ +void network_poll_node(char *node, char *secret, char *host, char *port) { + int sock; + char buf[SIZ]; + + lprintf(5, "Polling node <%s> at %s:%s\n", node, host, port); + + sock = sock_connect(host, port, "tcp"); + if (sock < 0) { + lprintf(7, "Could not connect: %s\n", strerror(errno)); + return; + } + + lprintf(9, "Connected!\n"); + + /* Read the server greeting */ + if (sock_gets(sock, buf) < 0) goto bail; + lprintf(9, ">%s\n", buf); + + /* Identify ourselves */ + sprintf(buf, "NETP %s|%s", config.c_nodename, secret); + lprintf(9, "<%s\n", buf); + if (sock_puts(sock, buf) <0) goto bail; + if (sock_gets(sock, buf) < 0) goto bail; + lprintf(9, ">%s\n", buf); + if (buf[0] != '2') goto bail; + + /* At this point we are authenticated. */ + receive_spool(sock, node); + transmit_spool(sock, node); + + sock_puts(sock, "QUIT"); +bail: sock_close(sock); +} + + + +/* + * Poll other Citadel nodes and transfer inbound/outbound network data. + */ +void network_poll_other_citadel_nodes(void) { + char *ignetcfg = NULL; + int i; + char linebuf[SIZ]; + char node[SIZ]; + char host[SIZ]; + char port[SIZ]; + char secret[SIZ]; + + ignetcfg = CtdlGetSysConfig(IGNETCFG); + if (ignetcfg == NULL) return; /* no nodes defined */ + + /* Use the string tokenizer to grab one line at a time */ + for (i=0; i 0) && (strlen(secret) > 0) + && (strlen(host) > 0) && strlen(port) > 0) { + network_poll_node(node, secret, host, port); + } + } + + phree(ignetcfg); +} + + + + + + + /* * network_do_queue() * @@ -839,6 +1067,14 @@ void network_do_queue(void) { doing_queue = 1; last_run = time(NULL); + /* + * Poll other Citadel nodes. + */ + network_poll_other_citadel_nodes(); + + /* + * Load the network map into memory. + */ read_network_map(); /* diff --git a/citadel/sysconfig.h b/citadel/sysconfig.h index 312b1f93a..611877f1f 100644 --- a/citadel/sysconfig.h +++ b/citadel/sysconfig.h @@ -96,6 +96,14 @@ */ #define NETWORK_QUEUE_FREQUENCY 3600 /* Once per hour */ +/* + * This variable defines the amount of network spool data that may be carried + * in one server transfer command. For some reason, some networks get hung + * up on larger packet sizes. We don't know why. In any case, never set the + * packet size higher than 4096 or your server sessions will crash. + */ +#define IGNET_PACKET_SIZE 4000 + /* * The names of rooms which are automatically created by the system */ -- 2.30.2