3e9b96c095b23f780633f1228a9c648c4275d6fa
[citadel.git] / citadel / netpoll.c
1 #include <stdlib.h>
2 #include <unistd.h>
3 #include <stdio.h>
4 #include <fcntl.h>
5 #include <string.h>
6 #include <errno.h>
7 #include "citadel.h"
8
9 /*
10  * This variable defines the amount of network spool data that may be carried
11  * in one server transfer command.  For some reason, some networks get hung
12  * up on larger packet sizes.  We don't know why.  In any case, never set the
13  * packet size higher than 4096 or your server sessions will crash.
14  */
15 #define IGNET_PACKET_SIZE 64
16
17 long atol();
18
19 void attach_to_server();
20 void serv_read();
21 void serv_write();
22 void get_config();
23 struct config config;
24
25
26 /*
27  * num_parms()  -  discover number of parameters...
28  */
29 int num_parms(source)
30 char source[]; {
31         int a;
32         int count = 1;
33
34         for (a=0; a<strlen(source); ++a) 
35                 if (source[a]=='|') ++count;
36         return(count);
37         }
38
39
40 /*
41  * extract()  -  extract a parameter from a series of "|" separated...
42  */
43 void extract(dest,source,parmnum)
44 char dest[];
45 char source[];
46 int parmnum; {
47         char buf[256];
48         int count = 0;
49         int n;
50
51         n = num_parms(source);
52
53         if (parmnum >= n) {
54                 strcpy(dest,"");
55                 return;
56                 }
57         strcpy(buf,source);
58         if ( (parmnum == 0) && (n == 1) ) {
59                 strcpy(dest,buf);
60                 return;
61                 }
62
63         while (count++ < parmnum) do {
64                 strcpy(buf,&buf[1]);
65                 } while( (strlen(buf)>0) && (buf[0]!='|') );
66         if (buf[0]=='|') strcpy(buf,&buf[1]);
67         for (count = 0; count<strlen(buf); ++count)
68                 if (buf[count] == '|') buf[count] = 0;
69         strcpy(dest,buf);
70         }
71
72 /*
73  * extract_int()  -  extract an int parm w/o supplying a buffer
74  */
75 int extract_int(source,parmnum)
76 char *source;
77 int parmnum; {
78         char buf[256];
79         
80         extract(buf,source,parmnum);
81         return(atoi(buf));
82         }
83
84 /*
85  * extract_long()  -  extract a long parm w/o supplying a buffer
86  */
87 long extract_long(source,parmnum)
88 char *source;
89 int parmnum; {
90         char buf[256];
91         
92         extract(buf,source,parmnum);
93         return(atol(buf));
94         }
95
96
97 void logoff(code)
98 int code; {
99         exit(code);
100         }
101
102
103 /*
104  * receive network spool from the remote system
105  */
106 void receive_spool() {
107         long download_len;
108         long bytes_received;
109         char buf[256];
110         static char pbuf[IGNET_PACKET_SIZE];
111         char tempfilename[64];
112         long plen;
113         FILE *fp;
114
115         sprintf(tempfilename,"/tmp/netpoll.%d",getpid());
116         serv_puts("NDOP");
117         serv_gets(buf);
118         printf("%s\n",buf);
119         if (buf[0]!='2') return;
120         download_len = extract_long(&buf[4],0);
121
122         bytes_received = 0L;
123         fp = fopen(tempfilename,"w");
124         if (fp==NULL) {
125                 perror("cannot open download file locally");
126                 return;
127                 }
128
129         while (bytes_received < download_len) {
130                 sprintf(buf,"READ %ld|%ld",
131                         bytes_received,
132                         ( (download_len - bytes_received > IGNET_PACKET_SIZE)
133                           ? IGNET_PACKET_SIZE : (download_len - bytes_received) ) );
134                 serv_puts(buf);
135                 serv_gets(buf);
136                 if (buf[0]=='6') {
137                         plen = extract_long(&buf[4],0);
138                         serv_read(pbuf,plen);
139                         fwrite((char *)pbuf,plen,1,fp);
140                         bytes_received = bytes_received + plen;
141                         }
142                 }
143
144         fclose(fp);
145         serv_puts("CLOS");
146         serv_gets(buf);
147         printf("%s\n",buf);
148         sprintf(buf,"mv %s %s/network/spoolin/netpoll.%d",
149                 tempfilename,BBSDIR,getpid());
150         system(buf);
151         system("exec nohup ./netproc >/dev/null 2>&1 &");
152         }
153
154 /*
155  * transmit network spool to the remote system
156  */
157 void transmit_spool(remote_nodename)
158 char *remote_nodename; {
159         char buf[256];
160         char pbuf[4096];
161         long plen;
162         long bytes_to_write, thisblock;
163         int fd;
164         char sfname[128];
165
166         serv_puts("NUOP");
167         serv_gets(buf);
168         printf("%s\n",buf);
169         if (buf[0]!='2') return;
170
171         sprintf(sfname,"%s/network/spoolout/%s",BBSDIR,remote_nodename);
172         fd = open(sfname,O_RDONLY);
173         if (fd<0) {
174                 if (errno == ENOENT) {
175                         printf("Nothing to send.\n");
176                         }
177                 else {
178                         perror("cannot open upload file locally");
179                         }
180                 return;
181                 }
182
183         while ( plen=(long)read(fd,pbuf,IGNET_PACKET_SIZE), plen>0L) {
184                 bytes_to_write = plen; 
185                 while (bytes_to_write > 0L) {
186                         sprintf(buf,"WRIT %ld", bytes_to_write);
187                         serv_puts(buf);
188                         serv_gets(buf);
189                         thisblock = atol(&buf[4]);
190                         if (buf[0]=='7') {
191                                 serv_write(pbuf, (int)thisblock);
192                                 bytes_to_write = bytes_to_write - thisblock;
193                                 }
194                         else {
195                                 goto ABORTUPL;
196                                 }
197                         }
198                 }
199
200 ABORTUPL:
201         close(fd);
202         serv_puts("UCLS 1");
203         serv_gets(buf);
204         printf("%s\n",buf);
205         if (buf[0]=='2') unlink(sfname);
206         }
207
208
209
210
211 void main(argc,argv)
212 int argc;
213 char *argv[]; {
214         char buf[256];
215         char remote_nodename[32];
216         int a;
217
218         if (argc != 4) {
219                 fprintf(stderr,
220                 "%s: usage: %s <address> <port number> <remote netpassword>\n",
221                         argv[0],argv[0]);
222                 exit(1);
223                 }
224
225         get_config();
226
227         attach_to_server(argc,argv);
228         serv_gets(buf);
229         printf("%s\n",buf);
230         if ((buf[0]!='2')&&(strncmp(buf,"551",3))) {
231                 fprintf(stderr,"%s: %s\n",argv[0],&buf[4]);
232                 logoff(atoi(buf));
233                 }
234
235         serv_puts("INFO");
236         serv_gets(buf);
237         if (buf[0]=='1') {
238                 a = 0;
239                 while (serv_gets(buf), strcmp(buf,"000")) {
240                         if (a==1) strcpy(remote_nodename,buf);
241                         if (a==1) printf("Connected to: %s ",buf);
242                         if (a==2) printf("(%s) ",buf);
243                         if (a==6) printf("%s\n",buf);
244                         ++a;
245                         }
246                 }
247
248         if (!strcmp(remote_nodename,config.c_nodename)) {
249                 fprintf(stderr,"Connected to local system\n");
250                 }
251         else {
252                 sprintf(buf,"NETP %s|%s",config.c_nodename,argv[3]);
253                 serv_puts(buf);
254                 serv_gets(buf);
255                 printf("%s\n",buf);
256         
257                 /* only do the transfers if we authenticated correctly! */
258                 if (buf[0]=='2') {
259                         receive_spool();
260                         transmit_spool(remote_nodename);
261                         }
262                 }
263
264         serv_puts("QUIT");
265         serv_gets(buf);
266         exit(0);
267         }