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