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