]> code.citadel.org Git - citadel.git/blob - citadel/netpoll.c
d9d018cefe73785c8da6f187343fec51f31eb60a
[citadel.git] / citadel / netpoll.c
1 /* $Id$ */
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <stdio.h>
5 #include <fcntl.h>
6 #include <string.h>
7 #include <errno.h>
8 #include "citadel.h"
9 #include "tools.h"
10
11 /*
12  * This variable defines the amount of network spool data that may be carried
13  * in one server transfer command.  For some reason, some networks get hung
14  * up on larger packet sizes.  We don't know why.  In any case, never set the
15  * packet size higher than 4096 or your server sessions will crash.
16  */
17 #define IGNET_PACKET_SIZE 4000
18
19 long atol(const char *);
20
21 void attach_to_server(int argc, char **argv);
22 void serv_read(char *buf, int bytes);
23 void serv_write(char *buf, int nbytes);
24 void get_config(void);
25 struct config config;
26
27
28 void logoff(int code)
29 {
30         exit(code);
31 }
32
33
34 /*
35  * receive network spool from the remote system
36  */
37 void receive_spool(void)
38 {
39         long download_len;
40         long bytes_received;
41         char buf[256];
42         static char pbuf[IGNET_PACKET_SIZE];
43         char tempfilename[64];
44         long plen;
45         FILE *fp;
46
47         sprintf(tempfilename, "/tmp/netpoll.%ld", (long) getpid());
48         serv_puts("NDOP");
49         serv_gets(buf);
50         printf("%s\n", buf);
51         if (buf[0] != '2')
52                 return;
53         download_len = extract_long(&buf[4], 0);
54
55         bytes_received = 0L;
56         fp = fopen(tempfilename, "w");
57         if (fp == NULL) {
58                 perror("cannot open download file locally");
59                 return;
60         }
61         while (bytes_received < download_len) {
62                 sprintf(buf, "READ %ld|%ld",
63                         bytes_received,
64                      ((download_len - bytes_received > IGNET_PACKET_SIZE)
65                  ? IGNET_PACKET_SIZE : (download_len - bytes_received)));
66                 serv_puts(buf);
67                 serv_gets(buf);
68                 if (buf[0] == '6') {
69                         plen = extract_long(&buf[4], 0);
70                         serv_read(pbuf, plen);
71                         fwrite((char *) pbuf, plen, 1, fp);
72                         bytes_received = bytes_received + plen;
73                 }
74         }
75
76         fclose(fp);
77         serv_puts("CLOS");
78         serv_gets(buf);
79         printf("%s\n", buf);
80         sprintf(buf, "mv %s %s/network/spoolin/netpoll.%ld",
81                 tempfilename, BBSDIR, (long) getpid());
82         system(buf);
83         system("exec nohup ./netproc >/dev/null 2>&1 &");
84 }
85
86 /*
87  * transmit network spool to the remote system
88  */
89 void transmit_spool(char *remote_nodename)
90 {
91         char buf[256];
92         char pbuf[4096];
93         long plen;
94         long bytes_to_write, thisblock;
95         int fd;
96         char sfname[128];
97
98         serv_puts("NUOP");
99         serv_gets(buf);
100         printf("%s\n", buf);
101         if (buf[0] != '2')
102                 return;
103
104         sprintf(sfname, "%s/network/spoolout/%s", BBSDIR, remote_nodename);
105         fd = open(sfname, O_RDONLY);
106         if (fd < 0) {
107                 if (errno == ENOENT) {
108                         printf("Nothing to send.\n");
109                 } else {
110                         perror("cannot open upload file locally");
111                 }
112                 return;
113         }
114         while (plen = (long) read(fd, pbuf, IGNET_PACKET_SIZE), plen > 0L) {
115                 bytes_to_write = plen;
116                 while (bytes_to_write > 0L) {
117                         sprintf(buf, "WRIT %ld", bytes_to_write);
118                         serv_puts(buf);
119                         serv_gets(buf);
120                         thisblock = atol(&buf[4]);
121                         if (buf[0] == '7') {
122                                 serv_write(pbuf, (int) thisblock);
123                                 bytes_to_write = bytes_to_write - thisblock;
124                         } else {
125                                 goto ABORTUPL;
126                         }
127                 }
128         }
129
130 ABORTUPL:
131         close(fd);
132         serv_puts("UCLS 1");
133         serv_gets(buf);
134         printf("%s\n", buf);
135         if (buf[0] == '2')
136                 unlink(sfname);
137 }
138
139
140
141
142 int main(int argc, char **argv)
143 {
144         char buf[256];
145         char remote_nodename[32];
146         int a;
147
148         if (argc != 4) {
149                 fprintf(stderr,
150                         "%s: usage: %s <address> <port number> <remote netpassword>\n",
151                         argv[0], argv[0]);
152                 exit(1);
153         }
154         get_config();
155
156         attach_to_server(argc, argv);
157         serv_gets(buf);
158         printf("%s\n", buf);
159         if ((buf[0] != '2') && (strncmp(buf, "551", 3))) {
160                 fprintf(stderr, "%s: %s\n", argv[0], &buf[4]);
161                 logoff(atoi(buf));
162         }
163         serv_puts("INFO");
164         serv_gets(buf);
165         if (buf[0] == '1') {
166                 a = 0;
167                 while (serv_gets(buf), strcmp(buf, "000")) {
168                         if (a == 1)
169                                 strcpy(remote_nodename, buf);
170                         if (a == 1)
171                                 printf("Connected to: %s ", buf);
172                         if (a == 2)
173                                 printf("(%s) ", buf);
174                         if (a == 6)
175                                 printf("%s\n", buf);
176                         ++a;
177                 }
178         }
179         if (!strcmp(remote_nodename, config.c_nodename)) {
180                 fprintf(stderr, "Connected to local system\n");
181         } else {
182                 sprintf(buf, "NETP %s|%s", config.c_nodename, argv[3]);
183                 serv_puts(buf);
184                 serv_gets(buf);
185                 printf("%s\n", buf);
186
187                 /* only do the transfers if we authenticated correctly! */
188                 if (buf[0] == '2') {
189                         receive_spool();
190                         transmit_spool(remote_nodename);
191                 }
192         }
193
194         serv_puts("QUIT");
195         serv_gets(buf);
196         exit(0);
197 }