Tue Aug 18 00:42:33 EDT 1998 Nathan Bryant <bryant@cs.usm.maine.edu>
[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(const char *);
18
19 void attach_to_server(int argc, char **argv);
20 void serv_read(char *buf, int bytes);
21 void serv_write(char *buf, int nbytes);
22 void get_config(void);
23 struct config config;
24
25
26 /*
27  * num_parms()  -  discover number of parameters...
28  */
29 int num_parms(char *source)
30 {
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(char *dest, char *source, int parmnum)
44 {
45         char buf[256];
46         int count = 0;
47         int n;
48
49         n = num_parms(source);
50
51         if (parmnum >= n) {
52                 strcpy(dest,"");
53                 return;
54                 }
55         strcpy(buf,source);
56         if ( (parmnum == 0) && (n == 1) ) {
57                 strcpy(dest,buf);
58                 return;
59                 }
60
61         while (count++ < parmnum) do {
62                 strcpy(buf,&buf[1]);
63                 } while( (strlen(buf)>0) && (buf[0]!='|') );
64         if (buf[0]=='|') strcpy(buf,&buf[1]);
65         for (count = 0; count<strlen(buf); ++count)
66                 if (buf[count] == '|') buf[count] = 0;
67         strcpy(dest,buf);
68         }
69
70 /*
71  * extract_int()  -  extract an int parm w/o supplying a buffer
72  */
73 int extract_int(char *source, int parmnum)
74 {
75         char buf[256];
76         
77         extract(buf,source,parmnum);
78         return(atoi(buf));
79         }
80
81 /*
82  * extract_long()  -  extract a long parm w/o supplying a buffer
83  */
84 long extract_long(char *source, int parmnum)
85 {
86         char buf[256];
87         
88         extract(buf,source,parmnum);
89         return(atol(buf));
90         }
91
92
93 void logoff(int code)
94 {
95         exit(code);
96         }
97
98
99 /*
100  * receive network spool from the remote system
101  */
102 void receive_spool(void) {
103         long download_len;
104         long bytes_received;
105         char buf[256];
106         static char pbuf[IGNET_PACKET_SIZE];
107         char tempfilename[64];
108         long plen;
109         FILE *fp;
110
111         sprintf(tempfilename,"/tmp/netpoll.%d",getpid());
112         serv_puts("NDOP");
113         serv_gets(buf);
114         printf("%s\n",buf);
115         if (buf[0]!='2') return;
116         download_len = extract_long(&buf[4],0);
117
118         bytes_received = 0L;
119         fp = fopen(tempfilename,"w");
120         if (fp==NULL) {
121                 perror("cannot open download file locally");
122                 return;
123                 }
124
125         while (bytes_received < download_len) {
126                 sprintf(buf,"READ %ld|%ld",
127                         bytes_received,
128                         ( (download_len - bytes_received > IGNET_PACKET_SIZE)
129                           ? IGNET_PACKET_SIZE : (download_len - bytes_received) ) );
130                 serv_puts(buf);
131                 serv_gets(buf);
132                 if (buf[0]=='6') {
133                         plen = extract_long(&buf[4],0);
134                         serv_read(pbuf,plen);
135                         fwrite((char *)pbuf,plen,1,fp);
136                         bytes_received = bytes_received + plen;
137                         }
138                 }
139
140         fclose(fp);
141         serv_puts("CLOS");
142         serv_gets(buf);
143         printf("%s\n",buf);
144         sprintf(buf,"mv %s %s/network/spoolin/netpoll.%d",
145                 tempfilename,BBSDIR,getpid());
146         system(buf);
147         system("exec nohup ./netproc >/dev/null 2>&1 &");
148         }
149
150 /*
151  * transmit network spool to the remote system
152  */
153 void transmit_spool(char *remote_nodename)
154 {
155         char buf[256];
156         char pbuf[4096];
157         long plen;
158         long bytes_to_write, thisblock;
159         int fd;
160         char sfname[128];
161
162         serv_puts("NUOP");
163         serv_gets(buf);
164         printf("%s\n",buf);
165         if (buf[0]!='2') return;
166
167         sprintf(sfname,"%s/network/spoolout/%s",BBSDIR,remote_nodename);
168         fd = open(sfname,O_RDONLY);
169         if (fd<0) {
170                 if (errno == ENOENT) {
171                         printf("Nothing to send.\n");
172                         }
173                 else {
174                         perror("cannot open upload file locally");
175                         }
176                 return;
177                 }
178
179         while ( plen=(long)read(fd,pbuf,IGNET_PACKET_SIZE), plen>0L) {
180                 bytes_to_write = plen; 
181                 while (bytes_to_write > 0L) {
182                         sprintf(buf,"WRIT %ld", bytes_to_write);
183                         serv_puts(buf);
184                         serv_gets(buf);
185                         thisblock = atol(&buf[4]);
186                         if (buf[0]=='7') {
187                                 serv_write(pbuf, (int)thisblock);
188                                 bytes_to_write = bytes_to_write - thisblock;
189                                 }
190                         else {
191                                 goto ABORTUPL;
192                                 }
193                         }
194                 }
195
196 ABORTUPL:
197         close(fd);
198         serv_puts("UCLS 1");
199         serv_gets(buf);
200         printf("%s\n",buf);
201         if (buf[0]=='2') unlink(sfname);
202         }
203
204
205
206
207 void main(int argc, char **argv)
208 {
209         char buf[256];
210         char remote_nodename[32];
211         int a;
212
213         if (argc != 4) {
214                 fprintf(stderr,
215                 "%s: usage: %s <address> <port number> <remote netpassword>\n",
216                         argv[0],argv[0]);
217                 exit(1);
218                 }
219
220         get_config();
221
222         attach_to_server(argc,argv);
223         serv_gets(buf);
224         printf("%s\n",buf);
225         if ((buf[0]!='2')&&(strncmp(buf,"551",3))) {
226                 fprintf(stderr,"%s: %s\n",argv[0],&buf[4]);
227                 logoff(atoi(buf));
228                 }
229
230         serv_puts("INFO");
231         serv_gets(buf);
232         if (buf[0]=='1') {
233                 a = 0;
234                 while (serv_gets(buf), strcmp(buf,"000")) {
235                         if (a==1) strcpy(remote_nodename,buf);
236                         if (a==1) printf("Connected to: %s ",buf);
237                         if (a==2) printf("(%s) ",buf);
238                         if (a==6) printf("%s\n",buf);
239                         ++a;
240                         }
241                 }
242
243         if (!strcmp(remote_nodename,config.c_nodename)) {
244                 fprintf(stderr,"Connected to local system\n");
245                 }
246         else {
247                 sprintf(buf,"NETP %s|%s",config.c_nodename,argv[3]);
248                 serv_puts(buf);
249                 serv_gets(buf);
250                 printf("%s\n",buf);
251         
252                 /* only do the transfers if we authenticated correctly! */
253                 if (buf[0]=='2') {
254                         receive_spool();
255                         transmit_spool(remote_nodename);
256                         }
257                 }
258
259         serv_puts("QUIT");
260         serv_gets(buf);
261         exit(0);
262         }