/[muddleftpd]/muddleftpd/src/ftp.c
ViewVC logotype

Diff of /muddleftpd/src/ftp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by ganneff, Thu Sep 26 07:55:42 2002 UTC revision 1.1.6.1 by ganneff, Mon Oct 21 19:52:58 2002 UTC
# Line 1  Line 1 
1    
2  /* Copyright (C) 1999 Beau Kuiper  /* Copyright (C) 1999 Beau Kuiper
3    
4     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
# Line 22  extern FTPCMD mainftpcmd[]; Line 23  extern FTPCMD mainftpcmd[];
23    
24  /* This will print a NICE! error to the user */  /* This will print a NICE! error to the user */
25    
26  void reporterror(FTPSTATE *peer, char *filename, int errorno)  void reporterror(FTPSTATE * peer,
27                                     char *filename,
28                                     int errorno)
29  {  {
30          ftp_write(peer, FALSE, 550, "'%s': %s", filename, strerror(errorno));          ftp_write(peer, FALSE, 550, "'%s': %s", filename, strerror(errorno));
31  }  }
32    
33  int readipstr(char *data, int *port, unsigned int *ip)  int readipstr(char *data,
34                              int *port,
35                              unsigned int *ip)
36  {  {
37          int a1,a2,a3,a4,a5,a6, result;          int a1, a2, a3, a4, a5, a6, result;
38            
39          result = sscanf(data, "%d,%d,%d,%d,%d,%d",&a1, &a2, &a3, &a4, &a5, &a6);          result = sscanf(data, "%d,%d,%d,%d,%d,%d", &a1, &a2, &a3, &a4, &a5, &a6);
40          if (result != 6)          if (result != 6)
41                  return(FALSE);                  return (FALSE);
42            
43          *ip = (a1 << 24) | (a2 << 16) | (a3 << 8) | (a4);          *ip = (a1 << 24) | (a2 << 16) | (a3 << 8) | (a4);
44          *port = (a5 * 256) + a6;          *port = (a5 * 256) + a6;
45          return(TRUE);          return (TRUE);
46  }  }
47    
48  int readeipstr(char *ip, unsigned int *outip)  int readeipstr(char *ip,
49                               unsigned int *outip)
50  {  {
51          int a1, a2, a3, a4, result;          int a1, a2, a3, a4, result;
52    
53          result = sscanf(ip, "%d.%d.%d.%d", &a1, &a2, &a3, &a4);          result = sscanf(ip, "%d.%d.%d.%d", &a1, &a2, &a3, &a4);
54          if (result != 4)          if (result != 4)
55                  return(FALSE);                  return (FALSE);
56            
57          *outip = (a1 << 24) | (a2 << 16) | (a3 << 8) | (a4);          *outip = (a1 << 24) | (a2 << 16) | (a3 << 8) | (a4);
58          return(TRUE);          return (TRUE);
59  }  }
60    
61  int ftp_dele(FTPSTATE *peer, char *filename)  int ftp_dele(FTPSTATE * peer,
62                             char *filename)
63  {  {
64          if (file_unlink(peer, filename) == 0)          if (file_unlink(peer, filename) == 0)
65                  ftp_write(peer, FALSE, 250, REPLY_DELETE(filename));                  ftp_write(peer, FALSE, 250, REPLY_DELETE(filename));
66          else          else
67                  reporterror(peer, filename, errno);                  reporterror(peer, filename, errno);
68    
69          return(FALSE);          return (FALSE);
70  }  }
71    
72  int ftp_chmod(FTPSTATE *peer, char *filename, int mode)  int ftp_chmod(FTPSTATE * peer,
73                              char *filename,
74                              int mode)
75  {  {
76          if (file_chmod(peer, filename, mode) == 0)          if (file_chmod(peer, filename, mode) == 0)
77                  ftp_write(peer, FALSE, 250, REPLY_CHMOD(filename, mode));                  ftp_write(peer, FALSE, 250, REPLY_CHMOD(filename, mode));
78          else          else
79                  reporterror(peer, filename, errno);                  reporterror(peer, filename, errno);
80    
81          return(FALSE);          return (FALSE);
82  }  }
83    
84  int ftp_size(FTPSTATE *peer, char *filename)  int ftp_size(FTPSTATE * peer,
85                             char *filename)
86  {  {
87          int filefd;          int filefd;
88          off_t size = 0;          off_t size = 0;
89          int asize;          int asize;
90          struct stat statdata;          struct stat statdata;
91            
92          if (peer->binary)          if (peer->binary)
93          {          {
94                  filefd = file_stat(peer, filename, &statdata);                  filefd = file_stat(peer, filename, &statdata);
95                  if (filefd == 0)                  if (filefd == 0)
96                          size = statdata.st_size;                          size = statdata.st_size;
97          }          }
98          else          else
99          {          {
100                  char *rname;                  char *rname;
101    
102                  size = 0;                  size = 0;
103                  filefd = file_readopen(peer, filename, &rname);                  filefd = file_readopen(peer, filename, &rname);
104                  freewrapper(rname);                  freewrapper(rname);
105                    
106                  if (filefd > 0)                  if (filefd > 0)
107                  {                  {
108                          char *chin, buffer[BUFFERSIZE];                          char *chin, buffer[BUFFERSIZE];
109                                    
110                          asize = read(filefd, buffer, BUFFERSIZE-1);                          asize = read(filefd, buffer, BUFFERSIZE - 1);
111                          while (asize > 0)                          while (asize > 0)
112                          {                          {
113                                  buffer[asize] = 0;                                  buffer[asize] = 0;
# Line 107  int ftp_size(FTPSTATE *peer, char *filen Line 118  int ftp_size(FTPSTATE *peer, char *filen
118                                          chin++;                                          chin++;
119                                          size++;                                          size++;
120                                  }                                  }
121                                  asize = read(filefd, buffer, BUFFERSIZE-1);                                  asize = read(filefd, buffer, BUFFERSIZE - 1);
122                          }                          }
123                          close(filefd);                          close(filefd);
124                  }                  }
125          }          }
126    
127          if (filefd >= 0)          if (filefd >= 0)
128                  ftp_write(peer, FALSE, 213, "%s", offt_tostr(size));                  ftp_write(peer, FALSE, 213, "%s", offt_tostr(size));
129          else          else
130                  reporterror(peer, filename, errno);                  reporterror(peer, filename, errno);
131    
132          return(FALSE);          return (FALSE);
133  }  }
134    
135  int ftp_mdtm(FTPSTATE *peer, char *filename)  int ftp_mdtm(FTPSTATE * peer,
136                             char *filename)
137  {  {
138          struct stat statdata;          struct stat statdata;
139            
140          if (file_stat(peer, filename, &statdata) == 0)          if (file_stat(peer, filename, &statdata) == 0)
141          {          {
142                  char timestr[20];                  char timestr[20];
143                  struct tm *resulttm = gmtime(&statdata.st_mtime);                  struct tm *resulttm = gmtime(&statdata.st_mtime);
144                    
145                  strftime(timestr, 20, "%Y%m%d%H%M%S", resulttm);                  strftime(timestr, 20, "%Y%m%d%H%M%S", resulttm);
146    
147                  ftp_write(peer, FALSE, 213, timestr);                  ftp_write(peer, FALSE, 213, timestr);
148          }          }
149          else          else
150                  reporterror(peer, filename, errno);                  reporterror(peer, filename, errno);
151    
152          return(FALSE);          return (FALSE);
153  }  }
154    
155  void setdumptokens(FTPSTATE *peer, TOKENSET *ts)  void setdumptokens(FTPSTATE * peer,
156                                       TOKENSET * ts)
157  {  {
158          char *outstr;          char *outstr;
159          time_t mytime = time(NULL);          time_t mytime = time(NULL);
160                    
161          outstr = ctime(&mytime);          outstr = ctime(&mytime);
162          outstr[strlen(outstr) - 1] = 0;          outstr[strlen(outstr) - 1] = 0;
163          tokenset_settoken(ts, 'T', strdupwrapper(outstr));          tokenset_settoken(ts, 'T', strdupwrapper(outstr));
164          tokenset_settoken(ts, 'U', strdupwrapper(peer->username));          tokenset_settoken(ts, 'U', strdupwrapper(peer->username));
165          if (peer->pwd)          if (peer->pwd)
166                  tokenset_settoken(ts, 'C', strdupwrapper(dir_getvirtual(peer, peer->pwd)));                  tokenset_settoken(ts, 'C',
167                                                      strdupwrapper(dir_getvirtual(peer, peer->pwd)));
168          tokenset_settoken(ts, 'E', strdupwrapper(peer->vserver->email));          tokenset_settoken(ts, 'E', strdupwrapper(peer->vserver->email));
169          tokenset_settoken(ts, 'M', safe_snprintf("%d", peer->maxusers));          tokenset_settoken(ts, 'M', safe_snprintf("%d", peer->maxusers));
170          if (peer->loggedin)          if (peer->loggedin)
# Line 159  void setdumptokens(FTPSTATE *peer, TOKEN Line 173  void setdumptokens(FTPSTATE *peer, TOKEN
173          tokenset_settoken(ts, 'L', strdupwrapper(peer->vserver->vhostname));          tokenset_settoken(ts, 'L', strdupwrapper(peer->vserver->vhostname));
174          tokenset_settoken(ts, 'f', safe_snprintf("%d", peer->downloadedfiles));          tokenset_settoken(ts, 'f', safe_snprintf("%d", peer->downloadedfiles));
175          tokenset_settoken(ts, 'F', safe_snprintf("%d", peer->uploadedfiles));          tokenset_settoken(ts, 'F', safe_snprintf("%d", peer->uploadedfiles));
176          tokenset_settoken(ts, 'b', safe_snprintf("%s", offt_tostr(peer->downloadedfilebytes)));          tokenset_settoken(ts, 'b',
177          tokenset_settoken(ts, 'B', safe_snprintf("%s", offt_tostr(peer->uploadedfilebytes)));                                            safe_snprintf("%s",
178          tokenset_settoken(ts, 'I', safe_snprintf("%s", offt_tostr(peer->listdownloadedbytes)));                                                                          offt_tostr(peer->downloadedfilebytes)));
179            tokenset_settoken(ts, 'B',
180                                              safe_snprintf("%s",
181                                                                            offt_tostr(peer->uploadedfilebytes)));
182            tokenset_settoken(ts, 'I',
183                                              safe_snprintf("%s",
184                                                                            offt_tostr(peer->listdownloadedbytes)));
185          tokenset_settoken(ts, 'i', safe_snprintf("%d", peer->listconns));          tokenset_settoken(ts, 'i', safe_snprintf("%d", peer->listconns));
186          tokenset_settoken(ts, 'D', safe_snprintf("%s", offt_tostr(peer->listdownloadedbytes + peer->downloadedfilebytes)));          tokenset_settoken(ts, 'D',
187          tokenset_settoken(ts, 't', safe_snprintf("%s", offt_tostr(peer->listdownloadedbytes + peer->downloadedfilebytes + peer->uploadedfilebytes)));                                            safe_snprintf("%s",
188          tokenset_settoken(ts, 'c', safe_snprintf("%d", peer->listconns + peer->downloadedfiles + peer->uploadedfiles));                                                                          offt_tostr(peer->listdownloadedbytes +
189          tokenset_settoken(ts, 'd', safe_snprintf("%d", peer->listconns + peer->downloadedfiles));                                                                                             peer->downloadedfilebytes)));
190            tokenset_settoken(ts, 't',
191                                              safe_snprintf("%s",
192                                                                            offt_tostr(peer->listdownloadedbytes +
193                                                                                               peer->downloadedfilebytes +
194                                                                                               peer->uploadedfilebytes)));
195            tokenset_settoken(ts, 'c',
196                                              safe_snprintf("%d",
197                                                                            peer->listconns + peer->downloadedfiles +
198                                                                            peer->uploadedfiles));
199            tokenset_settoken(ts, 'd',
200                                              safe_snprintf("%d",
201                                                                            peer->listconns + peer->downloadedfiles));
202          if (peer->ratioinfo)          if (peer->ratioinfo)
203                  ratio_settokens(peer->ratioinfo, ts);                  ratio_settokens(peer->ratioinfo, ts);
204          tokenset_settoken(ts, 'v', strdupwrapper(peer->vserver->sectionname));          tokenset_settoken(ts, 'v', strdupwrapper(peer->vserver->sectionname));
205  }  }
206    
207  int ftp_dumper(FTPSTATE *peer, NEWFILE *infile, int number, char *fmessage, int dotokens, int endtokens)  int ftp_dumper(FTPSTATE * peer,
208                               NEWFILE * infile,
209                               int number,
210                               char *fmessage,
211                               int dotokens,
212                               int endtokens)
213  {  {
214          TOKENSET *ts = NULL;          TOKENSET *ts = NULL;
215          char *inp, *tfmessage;          char *inp, *tfmessage;
# Line 184  int ftp_dumper(FTPSTATE *peer, NEWFILE * Line 221  int ftp_dumper(FTPSTATE *peer, NEWFILE *
221                          ts = tokenset_new();                          ts = tokenset_new();
222                          setdumptokens(peer, ts);                          setdumptokens(peer, ts);
223                  }                  }
224                    
225          if (infile != NULL)          if (infile != NULL)
226          {          {
227                  first = TRUE;                            first = TRUE;
228                  while ((inp = nfgetcs(infile, '\n')) != NULL)                  while ((inp = nfgetcs(infile, '\n')) != NULL)
229                  {                  {
230                          if (inp[strlen(inp)-1] == '\n')                          if (inp[strlen(inp) - 1] == '\n')
231                                  inp[strlen(inp)-1] = 0;                                  inp[strlen(inp) - 1] = 0;
232                            
233                          if (dotokens)                          if (dotokens)
234                                  inp = tokenset_apply(ts, inp, FALSE);                                  inp = tokenset_apply(ts, inp, FALSE);
235                                    
236                          if (first || config->altlongreplies)                          if (first || config->altlongreplies)
237                          {                          {
238                                  ftp_write(peer, TRUE, 0, "%d-%s", number, inp);                                  ftp_write(peer, TRUE, 0, "%d-%s", number, inp);
# Line 206  int ftp_dumper(FTPSTATE *peer, NEWFILE * Line 243  int ftp_dumper(FTPSTATE *peer, NEWFILE *
243    
244                          freewrapper(inp);                          freewrapper(inp);
245                  }                  }
246    
247                  nfclose(infile);                  nfclose(infile);
248          }          }
249            
250          if (endtokens)          if (endtokens)
251          {          {
252                  tfmessage = tokenset_apply(ts, strdupwrapper(fmessage), FALSE);                  tfmessage = tokenset_apply(ts, strdupwrapper(fmessage), FALSE);
# Line 218  int ftp_dumper(FTPSTATE *peer, NEWFILE * Line 255  int ftp_dumper(FTPSTATE *peer, NEWFILE *
255          }          }
256          else          else
257                  ftp_write(peer, FALSE, number, "%s", fmessage);                  ftp_write(peer, FALSE, number, "%s", fmessage);
258            
259          if (ts)          if (ts)
260                  tokenset_finish(ts);                  tokenset_finish(ts);
261    
262          return(FALSE);          return (FALSE);
263  }  }
264    
265  int ftp_dumpstr(FTPSTATE *peer, char *dumpstr, int number, char *fmessage, int endtokens)  int ftp_dumpstr(FTPSTATE * peer,
266                                    char *dumpstr,
267                                    int number,
268                                    char *fmessage,
269                                    int endtokens)
270  {  {
271          TOKENSET *ts = NULL;          TOKENSET *ts = NULL;
272          char *oldinp = dumpstr;          char *oldinp = dumpstr;
# Line 235  int ftp_dumpstr(FTPSTATE *peer, char *du Line 276  int ftp_dumpstr(FTPSTATE *peer, char *du
276    
277          ts = tokenset_new();          ts = tokenset_new();
278          setdumptokens(peer, ts);          setdumptokens(peer, ts);
279            
280          first = TRUE;          first = TRUE;
281          while (oldinp != NULL)          while (oldinp != NULL)
282          {          {
283                  inp = strchr(inp, '\n');                  inp = strchr(inp, '\n');
284                  if (inp != NULL)                  if (inp != NULL)
285                          *inp = 0;                          *inp = 0;
286                    
287                  datline = strdupwrapper(oldinp);                  datline = strdupwrapper(oldinp);
288                  if (inp != NULL)                  if (inp != NULL)
289                  {                  {
# Line 251  int ftp_dumpstr(FTPSTATE *peer, char *du Line 292  int ftp_dumpstr(FTPSTATE *peer, char *du
292                  }                  }
293                  oldinp = inp;                  oldinp = inp;
294                  datline = tokenset_apply(ts, datline, FALSE);                  datline = tokenset_apply(ts, datline, FALSE);
295                                    
296                  if (first || config->altlongreplies)                  if (first || config->altlongreplies)
297                  {                  {
298                          ftp_write(peer, TRUE, 0, "%d-%s", number, datline);                          ftp_write(peer, TRUE, 0, "%d-%s", number, datline);
# Line 262  int ftp_dumpstr(FTPSTATE *peer, char *du Line 303  int ftp_dumpstr(FTPSTATE *peer, char *du
303                  freewrapper(datline);                  freewrapper(datline);
304    
305          }          }
306    
307          if (endtokens)          if (endtokens)
308          {          {
309                  tfmessage = tokenset_apply(ts, strdupwrapper(fmessage), FALSE);                  tfmessage = tokenset_apply(ts, strdupwrapper(fmessage), FALSE);
# Line 272  int ftp_dumpstr(FTPSTATE *peer, char *du Line 313  int ftp_dumpstr(FTPSTATE *peer, char *du
313          else          else
314                  ftp_write(peer, FALSE, number, "%s", fmessage);                  ftp_write(peer, FALSE, number, "%s", fmessage);
315    
316          tokenset_finish(ts);          tokenset_finish(ts);
317          return(FALSE);          return (FALSE);
318  }  }
319    
320  VSERVER *find_vserver_byname(char *name)  VSERVER *find_vserver_byname(char *name)
321  {  {
322          VSERVER *v = config->vservers;          VSERVER *v = config->vservers;
323            
324          while((v != NULL) && (strcasecmp(v->vhostname, name) != 0))          while ((v != NULL) && (strcasecmp(v->vhostname, name) != 0))
325                  v = v->next;                  v = v->next;
326            
327          return(v);          return (v);
328  }  }
329    
330  int host_isip(char *name)  int host_isip(char *name)
331  {  {
332          while(((*name >= '0') && (*name <= '9')) || (*name == '.'))          while (((*name >= '0') && (*name <= '9')) || (*name == '.'))
333                  name++;                  name++;
334          return(*name == 0);          return (*name == 0);
335  }  }
336    
337  int ftp_host(FTPSTATE *peer, char *params)  int ftp_host(FTPSTATE * peer,
338                             char *params)
339  {  {
340          VSERVER *v;          VSERVER *v;
341          /* if there are no vservers, or hostname vservers are not defined,  
342             return with not implemented */          /*
343             * if there are no vservers, or hostname vservers are not defined,
344             * return with not implemented
345             */
346          if ((!config->vservers) || (!config->hostvservers))          if ((!config->vservers) || (!config->hostvservers))
347                  return(ftp_write(peer, FALSE, 502, REPLY_NOHOSTS));                  return (ftp_write(peer, FALSE, 502, REPLY_NOHOSTS));
348    
349          /* if a vserver has already been selected, return 530 */          /*
350             * if a vserver has already been selected, return 530
351             */
352          if (peer->vserver != config->defaults)          if (peer->vserver != config->defaults)
353                  return(ftp_write(peer, FALSE, 530, REPLY_HOSTSELECTED));                  return (ftp_write(peer, FALSE, 530, REPLY_HOSTSELECTED));
354            
355          if (config->defaulthost && (host_isip(params)))          if (config->defaulthost && (host_isip(params)))
356                  v = config->defaulthost;                  v = config->defaulthost;
357          else          else
358                  v = find_vserver_byname(params);                  v = find_vserver_byname(params);
359            
360          if (!v)          if (!v)
361                  return(ftp_write(peer, FALSE, 533, REPLY_HOSTNOTFOUND(params)));                  return (ftp_write(peer, FALSE, 533, REPLY_HOSTNOTFOUND(params)));
362    
363          switch(vserver_select(peer, v))          switch (vserver_select(peer, v))
364          {          {
365                  case 1:          case 1:
366                          return(ftp_write(peer, FALSE, 533, REPLY_HOSTMISCONF(params)));                  return (ftp_write(peer, FALSE, 533, REPLY_HOSTMISCONF(params)));
367                  case 2:          case 2:
368                          return(ftp_write(peer, FALSE, 533, REPLY_HOSTNOTFOUND(params)));                  return (ftp_write(peer, FALSE, 533, REPLY_HOSTNOTFOUND(params)));
369                  case 3:          case 3:
370                          ftp_write(peer, FALSE, 421, REPLY_HOSTTOOBUSY(params));                  ftp_write(peer, FALSE, 421, REPLY_HOSTTOOBUSY(params));
371                          return(TRUE);                  return (TRUE);
372          }          }
373            
374          ftp_write(peer, FALSE, 202, REPLY_HOSTSEL(v->vhostname));          ftp_write(peer, FALSE, 202, REPLY_HOSTSEL(v->vhostname));
375    
376          return(3);          return (3);
377  }  }
378    
379  int ftp_rnto(FTPSTATE *peer, char *filename)  int ftp_rnto(FTPSTATE * peer,
380  {                           char *filename)
381    {
382          char *badfile;          char *badfile;
383          char *oldname;          char *oldname;
384            
385          if (!peer->renameoldname)          if (!peer->renameoldname)
386                  return(ftp_write(peer, FALSE, 503, REPLY_RENAMENOSOURCE));                  return (ftp_write(peer, FALSE, 503, REPLY_RENAMENOSOURCE));
387            
388          oldname = dir_getvirtual(peer, peer->renameoldname);          oldname = dir_getvirtual(peer, peer->renameoldname);
389    
390          if ((badfile = file_rename(peer, oldname, filename)) == NULL)          if ((badfile = file_rename(peer, oldname, filename)) == NULL)
391                  ftp_write(peer, FALSE, 250, REPLY_RENAME(oldname,  filename));                  ftp_write(peer, FALSE, 250, REPLY_RENAME(oldname, filename));
392          else          else
393                  reporterror(peer, badfile, errno);                  reporterror(peer, badfile, errno);
394    
395          freewrapper(peer->renameoldname);          freewrapper(peer->renameoldname);
396          peer->renameoldname = NULL;          peer->renameoldname = NULL;
397    
398          return(FALSE);          return (FALSE);
399  }  }
400    
401  int ftp_mkd(FTPSTATE *peer, char *filename)  int ftp_mkd(FTPSTATE * peer,
402                            char *filename)
403  {  {
404          if (file_mkdir(peer, filename) == 0)          if (file_mkdir(peer, filename) == 0)
405          {          {
406                  char *newfile = file_expand(peer, filename);                  char *newfile = file_expand(peer, filename);
407                  ftp_write(peer, FALSE, 257, REPLY_MKDIR(dir_getvirtual(peer, newfile)));  
408                    ftp_write(peer, FALSE, 257,
409                                      REPLY_MKDIR(dir_getvirtual(peer, newfile)));
410                  freewrapper(newfile);                  freewrapper(newfile);
411          }          }
412          else          else
413                  reporterror(peer, filename, errno);                  reporterror(peer, filename, errno);
414    
415          return(FALSE);          return (FALSE);
416  }  }
417    
418  int ftp_rmd(FTPSTATE *peer, char *filename)  int ftp_rmd(FTPSTATE * peer,
419                            char *filename)
420  {  {
421          if (file_rmdir(peer, filename) == 0)          if (file_rmdir(peer, filename) == 0)
422                  ftp_write(peer, FALSE, 250, REPLY_RMDIR(filename));                  ftp_write(peer, FALSE, 250, REPLY_RMDIR(filename));
423          else          else
424                  reporterror(peer, filename, errno);                  reporterror(peer, filename, errno);
425    
426          return(FALSE);          return (FALSE);
427  }  }
428    
429  int ftp_cwddo(FTPSTATE *peer, char *newdir, int dump)  int ftp_cwddo(FTPSTATE * peer,
430                              char *newdir,
431                              int dump)
432  {  {
433          char *tmp = strdupwrapper(peer->pwd);          char *tmp = strdupwrapper(peer->pwd);
434            
435          dir_combine(peer, &tmp, newdir);          dir_combine(peer, &tmp, newdir);
436            
437          if (!checkchdir(peer, tmp))          if (!checkchdir(peer, tmp))
438          {          {
439                  freewrapper(tmp);                  freewrapper(tmp);
440                  reporterror(peer, newdir, errno);                  reporterror(peer, newdir, errno);
441                  return(FALSE);                  return (FALSE);
442          }          }
443          chdir(tmp);          chdir(tmp);
444            
445          if (peer->realdir)          if (peer->realdir)
446          {          {
447                  char *nt;                  char *nt;
448                  /* this relies on the side effect of checkchdir where  
449                     the server changes dir to check */                  /*
450                  nt = (char *)dir_getreal(peer);                   * this relies on the side effect of checkchdir where
451                     * the server changes dir to check
452                     */
453                    nt = (char *) dir_getreal(peer);
454                  if (nt != NULL)                  if (nt != NULL)
455                  {                  {
456                          freewrapper(tmp);                          freewrapper(tmp);
457                          tmp = nt;                          tmp = nt;
458                  }                  }
459          }          }
460                    
           
461          {          {
462                  NEWFILE *nfile = NULL;                  NEWFILE *nfile = NULL;
463                  char *outstr;                  char *outstr;
464                  int ret = 257;                  int ret = 257;
465                  /* If we need to print a file, then open it */  
466                  /* Oh bugger, crap, and other things, I left a big                  /*
467                     security hole here! :-(, now fixed */                   * If we need to print a file, then open it
468                     */
469                    /*
470                     * Oh bugger, crap, and other things, I left a big
471                     * security hole here! :-(, now fixed
472                     */
473                  if (dump)                  if (dump)
474                          ret = 250;                          ret = 250;
475                  freewrapper(peer->pwd);                  freewrapper(peer->pwd);
# Line 416  int ftp_cwddo(FTPSTATE *peer, char *newd Line 477  int ftp_cwddo(FTPSTATE *peer, char *newd
477                  if ((dump) && (peer->cwddump) && (!peer->cwddumpdata))                  if ((dump) && (peer->cwddump) && (!peer->cwddumpdata))
478                  {                  {
479                          if (peer->cwddump[0] == '/')                          if (peer->cwddump[0] == '/')
480                                  /* if it is an absolute file, don't worry                                  /*
481                                     about permissions accessing file */                                   * if it is an absolute file, don't worry
482                                     * about permissions accessing file
483                                     */
484                                  nfile = nfopen(peer->cwddump);                                  nfile = nfopen(peer->cwddump);
485                          else                          else
486                                  /* worry like hell and pass request via                                  /*
487                                     both ACL's and file permissions! */                                   * worry like hell and pass request via
488                                     * both ACL's and file permissions!
489                                     */
490                                  nfile = file_nfopen(peer, peer->cwddump);                                  nfile = file_nfopen(peer, peer->cwddump);
491                  }                  }
492                  outstr = safe_snprintf(REPLY_PWD(dir_getvirtual(peer, peer->pwd)));                  outstr = safe_snprintf(REPLY_PWD(dir_getvirtual(peer, peer->pwd)));
493                    
494                  if ((dump) && (peer->cwddumpdata))                  if ((dump) && (peer->cwddumpdata))
495                          ftp_dumpstr(peer, peer->cwddumpdata, ret, outstr, FALSE);                          ftp_dumpstr(peer, peer->cwddumpdata, ret, outstr, FALSE);
496                  else                  else
497                          ftp_dumper(peer, nfile, ret, outstr, TRUE, FALSE);                          ftp_dumper(peer, nfile, ret, outstr, TRUE, FALSE);
498                  freewrapper(outstr);                  freewrapper(outstr);
499          }          }
500            
501          return(FALSE);          return (FALSE);
502  }  }
503    
504  int ftp_cwd(FTPSTATE *peer, char *newdir)  int ftp_cwd(FTPSTATE * peer,
505                            char *newdir)
506  {  {
507          return(ftp_cwddo(peer, newdir, TRUE));          return (ftp_cwddo(peer, newdir, TRUE));
508  }  }
509    
510  int ftp_run(FTPSTATE *peer, INPUTLINE *cmd, char *token)  int ftp_run(FTPSTATE * peer,
511                            INPUTLINE * cmd,
512                            char *token)
513  {  {
514          if ((cmd->command->ftpfunc) == NULL)          if ((cmd->command->ftpfunc) == NULL)
515                  return(ftp_write(peer, FALSE, 500, REPLY_CMDNOTKNOWN(token)));                  return (ftp_write(peer, FALSE, 500, REPLY_CMDNOTKNOWN(token)));
516            
517          if (cmd->command->paramnum)          if (cmd->command->paramnum)
518          {          {
519                  if (cmd->parameters == NULL)                  if (cmd->parameters == NULL)
520                          return(ftp_write(peer, FALSE, 500, REPLY_NOPARAM(token)));                          return (ftp_write(peer, FALSE, 500, REPLY_NOPARAM(token)));
521                  else if (cmd->parameters[0] == 0)                  else if (cmd->parameters[0] == 0)
522                          return(ftp_write(peer, FALSE, 500, REPLY_NOPARAM(token)));                          return (ftp_write(peer, FALSE, 500, REPLY_NOPARAM(token)));
523          }          }
524            
525          if ((cmd->command->needslogin) && (peer->loggedin != TRUE))          if ((cmd->command->needslogin) && (peer->loggedin != TRUE))
526                  return(ftp_write(peer, FALSE, 530, REPLY_NOLOGIN));                  return (ftp_write(peer, FALSE, 530, REPLY_NOLOGIN));
527            
528          if ((!cmd->command->dataportok) && (peer->dport))          if ((!cmd->command->dataportok) && (peer->dport))
529                  return(ftp_write(peer, FALSE, 520, REPLY_DATACONNINVALID(token)));                  return (ftp_write(peer, FALSE, 520, REPLY_DATACONNINVALID(token)));
530          else          else
531                  return(cmd->command->ftpfunc(peer, cmd->parameters));                  return (cmd->command->ftpfunc(peer, cmd->parameters));
532  }  }
533    
534  int ftp_quit(FTPSTATE *peer, char *param)  int ftp_quit(FTPSTATE * peer,
535                             char *param)
536  {  {
537          if (peer->quitdump)          if (peer->quitdump)
538          {          {
539                  NEWFILE *nfile = nfopen(peer->quitdump);                  NEWFILE *nfile = nfopen(peer->quitdump);
540    
541                  ftp_dumper(peer, nfile, 221, REPLY_QUIT, TRUE, FALSE);                  ftp_dumper(peer, nfile, 221, REPLY_QUIT, TRUE, FALSE);
542          }          }
543          else if (peer->quitdumpdata)          else if (peer->quitdumpdata)
544                  ftp_dumpstr(peer, peer->quitdumpdata, 221, REPLY_QUIT, FALSE);                  ftp_dumpstr(peer, peer->quitdumpdata, 221, REPLY_QUIT, FALSE);
545          else          else
546                  ftp_write(peer, FALSE, 221, REPLY_QUIT);                  ftp_write(peer, FALSE, 221, REPLY_QUIT);
547          return(TRUE);          return (TRUE);
548  }  }
549    
550  int ftp_user(FTPSTATE *peer, char *param)  int ftp_user(FTPSTATE * peer,
551                             char *param)
552  {  {
553          if (peer->jailenabled)          if (peer->jailenabled)
554                  return(ftp_write(peer, FALSE, 530, REPLY_JAILUSER));                  return (ftp_write(peer, FALSE, 530, REPLY_JAILUSER));
555          if (peer->loginsleft == 0)          if (peer->loginsleft == 0)
556                  return(ftp_write(peer, FALSE, 530, REPLY_NOCREDITS));                  return (ftp_write(peer, FALSE, 530, REPLY_NOCREDITS));
557          if (peer->loggedin)          if (peer->loggedin)
558                  shinfo_delusergroup(peer->groupname);                  shinfo_delusergroup(peer->groupname);
559    
560          shinfo_changeuser(param);          shinfo_changeuser(param);
561          peer->loggedin = 0;          peer->loggedin = 0;
562            
563          freewrapper(peer->username);          freewrapper(peer->username);
564          peer->username = strdupwrapper(param);          peer->username = strdupwrapper(param);
565            
566          return(ftp_write(peer, FALSE, 331, REPLY_USER(peer->username)));          return (ftp_write(peer, FALSE, 331, REPLY_USER(peer->username)));
567  }  }
568    
569  int ftp_host_compat(FTPSTATE *peer)  int ftp_host_compat(FTPSTATE * peer)
570  {  {
571          VSERVER *v;          VSERVER *v;
572          char *name;          char *name;
573          /* if there are no vservers, or hostname vservers are not defined,  
574             return with not implemented */          /*
575             * if there are no vservers, or hostname vservers are not defined,
576             * return with not implemented
577             */
578          if ((!config->vservers) || (!config->hostvservers))          if ((!config->vservers) || (!config->hostvservers))
579                  return(1);                  return (1);
580    
581          /* if a vserver has already been selected, return 530 */          /*
582             * if a vserver has already been selected, return 530
583             */
584          if (peer->vserver != config->defaults)          if (peer->vserver != config->defaults)
585                  return(1);                  return (1);
586    
587          name = strchr(peer->username, '%');          name = strchr(peer->username, '%');
588            
589          if (!name)          if (!name)
590                  v = config->defaulthost;                  v = config->defaulthost;
591          else          else
592          {          {
593                  *name = 0;                  *name = 0;
594                  name++;                  name++;
595                    
596                  if (config->defaulthost && (host_isip(name)))                  if (config->defaulthost && (host_isip(name)))
597                          v = config->defaulthost;                          v = config->defaulthost;
598                  else                  else
599                          v = find_vserver_byname(name);                          v = find_vserver_byname(name);
600          }          }
601            
602          if (!v)          if (!v)
603                  return(0);                  return (0);
604    
605          switch(vserver_select(peer, v))          switch (vserver_select(peer, v))
606          {          {
607                  case 1:          case 1:
608                  case 2:          case 2:
609                          return(0);                  return (0);
610                  case 3:          case 3:
611                          return(2);                  return (2);
612          }          }
613            
614          return(1);          return (1);
615  }  }
616    
617  int ftp_pass(FTPSTATE *peer, char *param)  int ftp_pass(FTPSTATE * peer,
618                             char *param)
619  {  {
620          int result = FALSE;          int result = FALSE;
621          int loginok, oldnice = peer->nicevalue;          int loginok, oldnice = peer->nicevalue;
622          int toomany = FALSE;          int toomany = FALSE;
623          char *errmsg = NULL;          char *errmsg = NULL;
624            
625          switch(ftp_host_compat(peer))          switch (ftp_host_compat(peer))
626          {          {
627                  case 0:          case 0:
628                          return(ftp_write(peer, FALSE, 530, REPLY_LOGINFAIL(peer->username, "Bad password")));                  return (ftp_write
629                  case 2:                                  (peer, FALSE, 530,
630                          ftp_write(peer, FALSE, 421, REPLY_TOOMANYUSERS);                                   REPLY_LOGINFAIL(peer->username, "Bad password")));
631                          return(TRUE);          case 2:
632                    ftp_write(peer, FALSE, 421, REPLY_TOOMANYUSERS);
633                    return (TRUE);
634          }          }
635    
636          if (peer->loggedin)          if (peer->loggedin)
637                  return(ftp_write(peer, FALSE, 530, REPLY_ALREADYLOGGEDIN));                  return (ftp_write(peer, FALSE, 530, REPLY_ALREADYLOGGEDIN));
638    
639          if (strcmp(peer->username, "<unknown>") == 0)          if (strcmp(peer->username, "<unknown>") == 0)
640                  return(ftp_write(peer, FALSE, 503, REPLY_USEUSERFIRST));                  return (ftp_write(peer, FALSE, 503, REPLY_USEUSERFIRST));
641            
642          loginok = (param != NULL);          loginok = (param != NULL);
643            
644          if (loginok)          if (loginok)
645          {          {
646                  file_becomeroot(peer);                  file_becomeroot(peer);
# Line 570  int ftp_pass(FTPSTATE *peer, char *param Line 649  int ftp_pass(FTPSTATE *peer, char *param
649                  loginok = (errmsg == NULL);                  loginok = (errmsg == NULL);
650          }          }
651    
652          /* check some stuff, set basedir to real pathname */          /*
653             * check some stuff, set basedir to real pathname
654             */
655          if (loginok)          if (loginok)
656          {          {
657                  file_becomeuser(peer);                  file_becomeuser(peer);
658                  if (chdir(peer->basedir) == -1)                  if (chdir(peer->basedir) == -1)
659                  {                  {
660                          loginok = FALSE;                          loginok = FALSE;
661                          log_giveentry(MYLOG_INFO, NULL, safe_snprintf("rootdir(%s) for user '%s' is not accessable. Check rootdir and rootdir permissions", peer->basedir, peer->username));                          log_giveentry(MYLOG_INFO, NULL,
662                                                      safe_snprintf
663                                                      ("rootdir(%s) for user '%s' is not accessable. Check rootdir and rootdir permissions",
664                                                       peer->basedir, peer->username));
665                  }                  }
666                  else                  else
667                  {                  {
668                          char *curdir = getcwd2();                          char *curdir = getcwd2();
669    
670                          if (strcmp(curdir, peer->basedir) != 0)                          if (strcmp(curdir, peer->basedir) != 0)
671                          {                          {
672                                  log_giveentry(MYLOG_INFO, NULL, safe_snprintf("rootdir changed from '%s' to '%s', symbolic links resolved for user '%s'", peer->basedir, curdir, peer->username));                                  log_giveentry(MYLOG_INFO, NULL,
673                                                              safe_snprintf
674                                                              ("rootdir changed from '%s' to '%s', symbolic links resolved for user '%s'",
675                                                               peer->basedir, curdir, peer->username));
676                                  freewrapper(peer->basedir);                                  freewrapper(peer->basedir);
677                                  peer->basedir = curdir;                                  peer->basedir = curdir;
678                          }                          }
# Line 596  int ftp_pass(FTPSTATE *peer, char *param Line 684  int ftp_pass(FTPSTATE *peer, char *param
684    
685          if (loginok)          if (loginok)
686          {          {
687                  peer->usercount = toomany = shinfo_addusergroup(peer->groupname, peer->maxusers);                  peer->usercount = toomany =
688                            shinfo_addusergroup(peer->groupname, peer->maxusers);
689                  toomany = (toomany == -1);                  toomany = (toomany == -1);
690                  if (toomany)                  if (toomany)
691                          loginok = FALSE;                          loginok = FALSE;
# Line 606  int ftp_pass(FTPSTATE *peer, char *param Line 695  int ftp_pass(FTPSTATE *peer, char *param
695          {          {
696                  char *outstr;                  char *outstr;
697                  NEWFILE *nfile;                  NEWFILE *nfile;
698                    
699                  log_addentry(MYLOG_LOGIN, peer, "Login successful.");                  log_addentry(MYLOG_LOGIN, peer, "Login successful.");
700                  outstr = safe_snprintf(REPLY_PASSOK(peer->username));                  outstr = safe_snprintf(REPLY_PASSOK(peer->username));
701                    
702                  /* perform chroot if needed */                  /*
703                     * perform chroot if needed
704                     */
705                  if (peer->chroot)                  if (peer->chroot)
706                          dochroot(peer);                          dochroot(peer);
707    
708                  if (nice(peer->nicevalue + (-oldnice)) == -1)                  if (nice(peer->nicevalue + (-oldnice)) == -1)
709                  {                  {
710                          log_giveentry(MYLOG_INFO, NULL, safe_snprintf("nice(%d) gave error %s", peer->nicevalue + (-oldnice), strerror(errno)));                          log_giveentry(MYLOG_INFO, NULL,
711                                                      safe_snprintf("nice(%d) gave error %s",
712                                                                                    peer->nicevalue + (-oldnice),
713                                                                                    strerror(errno)));
714                          peer->nicevalue = oldnice;                          peer->nicevalue = oldnice;
715                  }                  }
716                    
717                  if (config->rootmode)                  if (config->rootmode)
718                          setgroups(peer->supgids[0], peer->supgids + 1);                          setgroups(peer->supgids[0], peer->supgids + 1);
719                    
720                  /* see if rootdir == "/", change to "" */                  /*
721                     * see if rootdir == "/", change to ""
722                     */
723                  if (peer->basedir[1] == 0)                  if (peer->basedir[1] == 0)
724                          peer->basedir[0] = 0;                          peer->basedir[0] = 0;
725                    
726                  if ((peer->droproot) && (config->rootmode))                  if ((peer->droproot) && (config->rootmode))
727                  {                  {
728                          if (giveuproot(peer->uidt_asuid, peer->gidt_asgid))                          if (giveuproot(peer->uidt_asuid, peer->gidt_asgid))
729                                  log_addentry(MYLOG_INFO, peer, "Failed to set capabilities!");                                  log_addentry(MYLOG_INFO, peer, "Failed to set capabilities!");
730                          peer->jailenabled = TRUE;                          peer->jailenabled = TRUE;
731                          /* we are not root anymore and can never be root                          /*
732                             again! */                           * we are not root anymore and can never be root
733                             * again!
734                             */
735                          config->rootmode = FALSE;                          config->rootmode = FALSE;
736                  }                  }
737                                                            
738                  file_becomeuser(peer);                  file_becomeuser(peer);
739                    
740                  nfile = nfopen(peer->logindump);                  nfile = nfopen(peer->logindump);
741                  peer->pwd = strdupwrapper(peer->basedir);                  peer->pwd = strdupwrapper(peer->basedir);
742                  dir_combine(peer, &(peer->pwd), peer->homedir);                  dir_combine(peer, &(peer->pwd), peer->homedir);
743                    
744                  if (peer->logindumpdata)                  if (peer->logindumpdata)
745                          result = ftp_dumpstr(peer, peer->logindumpdata, 230, outstr, FALSE);                          result =
746                                    ftp_dumpstr(peer, peer->logindumpdata, 230, outstr, FALSE);
747                  else                  else
748                          result = ftp_dumper(peer, nfile, 230, outstr, TRUE, FALSE);                          result = ftp_dumper(peer, nfile, 230, outstr, TRUE, FALSE);
749                  freewrapper(outstr);                  freewrapper(outstr);
# Line 657  int ftp_pass(FTPSTATE *peer, char *param Line 756  int ftp_pass(FTPSTATE *peer, char *param
756                  if (toomany)                  if (toomany)
757                  {                  {
758                          NEWFILE *nfile = nfopen(peer->busydump);                          NEWFILE *nfile = nfopen(peer->busydump);
759    
760                          logfullmessage(GROUPFULL, peer->remoteip);                          logfullmessage(GROUPFULL, peer->remoteip);
761                          if (peer->busydumpdata)                          if (peer->busydumpdata)
762                                  ftp_dumpstr(peer, peer->busydumpdata, 421, REPLY_TOOMANYUSERS, FALSE);                                  ftp_dumpstr(peer, peer->busydumpdata, 421, REPLY_TOOMANYUSERS,
763                                                            FALSE);
764                          else                          else
765                                  ftp_dumper(peer, nfile, 421, REPLY_TOOMANYUSERS, TRUE, FALSE);                                  ftp_dumper(peer, nfile, 421, REPLY_TOOMANYUSERS, TRUE, FALSE);
766                  }                  }
# Line 668  int ftp_pass(FTPSTATE *peer, char *param Line 769  int ftp_pass(FTPSTATE *peer, char *param
769                          usleep(peer->vserver->authwait);                          usleep(peer->vserver->authwait);
770                          if (errmsg == NULL)                          if (errmsg == NULL)
771                                  errmsg = strdupwrapper("Bad password");                                  errmsg = strdupwrapper("Bad password");
772                          result = ftp_write(peer, FALSE, 530, REPLY_LOGINFAIL(peer->username, errmsg));                          result =
773                                    ftp_write(peer, FALSE, 530,
774                                                      REPLY_LOGINFAIL(peer->username, errmsg));
775                          if (peer->loginsleft > 0)                          if (peer->loginsleft > 0)
776                                  peer->loginsleft--;                                  peer->loginsleft--;
777                          freewrapper(errmsg);                          freewrapper(errmsg);
# Line 677  int ftp_pass(FTPSTATE *peer, char *param Line 780  int ftp_pass(FTPSTATE *peer, char *param
780                  peer->username = strdupwrapper("<unknown>");                  peer->username = strdupwrapper("<unknown>");
781          }          }
782          if (toomany)          if (toomany)
783                  return(TRUE);   /* quit */                  return (TRUE);                  /* quit */
784          return(3);              /* make sure timeout gets updated */          return (3);                                     /* make sure timeout gets updated */
785  }  }
786    
787  int ftp_rest(FTPSTATE *peer, char *param)  int ftp_rest(FTPSTATE * peer,
788                             char *param)
789  {  {
790          off_t newpos;          off_t newpos;
791          int res;          int res;
792    
793          res = strto_offt(param, &newpos);          res = strto_offt(param, &newpos);
794            
795          if ((res != 0) || (newpos < 0))          if ((res != 0) || (newpos < 0))
796                  return(ftp_write(peer, FALSE, 501, REPLY_INVALIDREST));                  return (ftp_write(peer, FALSE, 501, REPLY_INVALIDREST));
797          else          else
798          {          {
799                  peer->restartpos = newpos;                  peer->restartpos = newpos;
800                  return(ftp_write(peer, FALSE, 350, REPLY_RESTOK(peer->restartpos)));                  return (ftp_write(peer, FALSE, 350, REPLY_RESTOK(peer->restartpos)));
801          }          }
802  }  }
803    
804  int ftp_syst(FTPSTATE *peer, char *param)  int ftp_syst(FTPSTATE * peer,
805                             char *param)
806  {  {
807          return(ftp_write(peer, FALSE, 215, "UNIX Type: L8"));          return (ftp_write(peer, FALSE, 215, "UNIX Type: L8"));
808  }  }
809            
810  int ftp_port(FTPSTATE *peer, char *param)  int ftp_port(FTPSTATE * peer,
811                             char *param)
812  {  {
813          if (peer->epsv_forced)          if (peer->epsv_forced)
814                  return(ftp_write(peer, FALSE, 500, REPLY_EPSVSET));                  return (ftp_write(peer, FALSE, 500, REPLY_EPSVSET));
815    
816          /* reset remoteport */          /*
817             * reset remoteport
818             */
819          peer->remoteport = 0;          peer->remoteport = 0;
820          if (peer->passiveport)          if (peer->passiveport)
821          {          {
# Line 720  int ftp_port(FTPSTATE *peer, char *param Line 828  int ftp_port(FTPSTATE *peer, char *param
828                  if ((peer->remoteport <= 1024) || (peer->remoteport >= 65536))                  if ((peer->remoteport <= 1024) || (peer->remoteport >= 65536))
829                  {                  {
830                          peer->remoteport = 0;                          peer->remoteport = 0;
831                          return(ftp_write(peer, FALSE, 500, REPLY_PORTBADPORT));                          return (ftp_write(peer, FALSE, 500, REPLY_PORTBADPORT));
832                  }                  }
833                  if ((peer->dataip != peer->remoteip) && (!peer->fxpallow))                  if ((peer->dataip != peer->remoteip) && (!peer->fxpallow))
834                  {                  {
835                          peer->remoteport = 0;                          peer->remoteport = 0;
836                          peer->dataip = peer->remoteip;                          peer->dataip = peer->remoteip;
837                          return(ftp_write(peer, FALSE, 500, REPLY_PORTBADFXP));                          return (ftp_write(peer, FALSE, 500, REPLY_PORTBADFXP));
838                  }                  }
839                  return(ftp_write(peer, FALSE, 200, REPLY_PORTOK(                  return (ftp_write
840                                   peer->dataip >> 24, peer->dataip >> 16 & 255, peer->dataip >> 8 & 255,                                  (peer, FALSE, 200,
841                                   peer->dataip & 255, peer->remoteport)));                                   REPLY_PORTOK(peer->dataip >> 24, peer->dataip >> 16 & 255,
842                                                              peer->dataip >> 8 & 255, peer->dataip & 255,
843                                                              peer->remoteport)));
844          }          }
845          else          else
846                  return(ftp_write(peer, FALSE, 501, REPLY_PORTBADPARM));                  return (ftp_write(peer, FALSE, 501, REPLY_PORTBADPARM));
847  }  }
848    
849  int ftp_eprt(FTPSTATE *peer, char *param)  int ftp_eprt(FTPSTATE * peer,
850                             char *param)
851  {  {
852          char *ipstr;          char *ipstr;
853          int proto, tcpport;          int proto, tcpport;
854          unsigned int remote_ip;          unsigned int remote_ip;
855            
856          if (peer->epsv_forced)          if (peer->epsv_forced)
857                  return(ftp_write(peer, FALSE, 500, REPLY_EPSVSET));                  return (ftp_write(peer, FALSE, 500, REPLY_EPSVSET));
858    
859          ipstr = mallocwrapper(strlen(param) + 1);          ipstr = mallocwrapper(strlen(param) + 1);
860    
861          /* clear off old ports */          /*
862             * clear off old ports
863             */
864          peer->remoteport = 0;          peer->remoteport = 0;
865          if (peer->passiveport)          if (peer->passiveport)
866          {          {
# Line 767  int ftp_eprt(FTPSTATE *peer, char *param Line 880  int ftp_eprt(FTPSTATE *peer, char *param
880                  ftp_write(peer, FALSE, 500, REPLY_EPRTBADFXP);                  ftp_write(peer, FALSE, 500, REPLY_EPRTBADFXP);
881          else          else
882          {          {
883                  /* everything seems to be ok */                  /*
884                     * everything seems to be ok
885                     */
886                  peer->remoteport = tcpport;                  peer->remoteport = tcpport;
887                  peer->dataip = remote_ip;                  peer->dataip = remote_ip;
888                  ftp_write(peer, FALSE, 200, REPLY_EPRTOK(                  ftp_write(peer, FALSE, 200,
889                                   peer->dataip >> 24, peer->dataip >> 16 & 255, peer->dataip >> 8 & 255,                                    REPLY_EPRTOK(peer->dataip >> 24, peer->dataip >> 16 & 255,
890                                   peer->dataip & 255, peer->remoteport));                                                             peer->dataip >> 8 & 255, peer->dataip & 255,
891                                                               peer->remoteport));
892          }          }
893          freewrapper(ipstr);          freewrapper(ipstr);
894          return(FALSE);          return (FALSE);
895  }  }
896    
897  int ftp_pwd(FTPSTATE *peer, char *param)  int ftp_pwd(FTPSTATE * peer,
898                            char *param)
899  {  {
900          return(ftp_cwddo(peer, ".", FALSE));          return (ftp_cwddo(peer, ".", FALSE));
901  }  }
902    
903  int ftp_type(FTPSTATE *peer, char *param)  int ftp_type(FTPSTATE * peer,
904                             char *param)
905  {  {
906          if ((param[0] & (255-32)) == 'A')          if ((param[0] & (255 - 32)) == 'A')
907          {          {
908                  peer->binary = FALSE;                  peer->binary = FALSE;
909                  return(ftp_write(peer, FALSE, 200, REPLY_TYPEASCII));                  return (ftp_write(peer, FALSE, 200, REPLY_TYPEASCII));
910          }          }
911          else if ((param[0] & (255-32)) == 'I')          else if ((param[0] & (255 - 32)) == 'I')
912          {          {
913                  peer->binary = TRUE;                  peer->binary = TRUE;
914                  return(ftp_write(peer, FALSE, 200, REPLY_TYPEBINARY));                  return (ftp_write(peer, FALSE, 200, REPLY_TYPEBINARY));
915          }          }
916          else          else
917                  return(ftp_write(peer, FALSE, 504, REPLY_TYPEUNIMP));                  return (ftp_write(peer, FALSE, 504, REPLY_TYPEUNIMP));
918  }  }
919    
920  int ftp_abor(FTPSTATE *peer, char *param)  int ftp_abor(FTPSTATE * peer,
921                             char *param)
922  {  {
923          /* abort any active or pending data port */          /*
924             * abort any active or pending data port
925             */
926          abortdatasocket(peer);          abortdatasocket(peer);
927          return(ftp_write(peer, FALSE, 226, REPLY_ABORT));          return (ftp_write(peer, FALSE, 226, REPLY_ABORT));
928  }  }
929    
930  int ftp_pasv(FTPSTATE *peer, char *param)  int ftp_pasv(FTPSTATE * peer,
931                             char *param)
932  {  {
933          unsigned int a1, a2, a3, a4, a5, a6;          unsigned int a1, a2, a3, a4, a5, a6;
934            
935          if (peer->epsv_forced)          if (peer->epsv_forced)
936                  return(ftp_write(peer, FALSE, 500, REPLY_EPSVSET));                  return (ftp_write(peer, FALSE, 500, REPLY_EPSVSET));
937            
938          if (peer->passiveport != 0)          if (peer->passiveport != 0)
939                  select_delfd(peer->sel, peer->passiveport);                  select_delfd(peer->sel, peer->passiveport);
940    
941          peer->remoteport = 0;          peer->remoteport = 0;
942            
943          peer->passiveport = listenparrelelport(peer->remotefd, &(peer->remoteport), &a1, 5);          peer->passiveport =
944                            listenparrelelport(peer->remotefd, &(peer->remoteport), &a1, 5);
945    
946          if (peer->passiveport == -1)          if (peer->passiveport == -1)
947          {          {
948                  peer->passiveport = 0;                  peer->passiveport = 0;
949                  reporterror(peer, "passive port", errno);                  reporterror(peer, "passive port", errno);
950                  return(FALSE);                  return (FALSE);
951          }          }
952          select_addfd(peer->sel, peer->passiveport);          select_addfd(peer->sel, peer->passiveport);
953          a2 = ((a1 >> 8) & 255);          a2 = ((a1 >> 8) & 255);
# Line 833  int ftp_pasv(FTPSTATE *peer, char *param Line 956  int ftp_pasv(FTPSTATE *peer, char *param
956          a1 = a1 & 255;          a1 = a1 & 255;
957          a5 = (peer->remoteport >> 8);          a5 = (peer->remoteport >> 8);
958          a6 = (peer->remoteport & 255);          a6 = (peer->remoteport & 255);
959          return(ftp_write(peer, FALSE, 227, REPLY_PASV(a4, a3, a2, a1, a5, a6)));          return (ftp_write(peer, FALSE, 227, REPLY_PASV(a4, a3, a2, a1, a5, a6)));
960  }  }
961    
962  int ftp_epsv(FTPSTATE *peer, char *param)  int ftp_epsv(FTPSTATE * peer,
963                             char *param)
964  {  {
965          int proto, a1;          int proto, a1;
966    
967          /* the all parameter means that only epsv can be used from now on */          /*
968             * the all parameter means that only epsv can be used from now on
969             */
970    
971          if (peer->passiveport != 0)          if (peer->passiveport != 0)
972                  select_delfd(peer->sel, peer->passiveport);                  select_delfd(peer->sel, peer->passiveport);
973    
974          peer->remoteport = 0;          peer->remoteport = 0;
975          peer->passiveport = 0;          peer->passiveport = 0;
976            
977          if (param)          if (param)
978          {          {
979                  if (strcasecmp(param, "ALL") == 0)                  if (strcasecmp(param, "ALL") == 0)
980                  {                  {
981                          peer->epsv_forced = 1;                          peer->epsv_forced = 1;
982                          return(ftp_write(peer, FALSE, 200, REPLY_EPSVON));                          return (ftp_write(peer, FALSE, 200, REPLY_EPSVON));
983                  }                  }
984                  else if (sscanf(param, "%d", &proto) == 1)                  else if (sscanf(param, "%d", &proto) == 1)
985                  {                  {
986                          if (proto != FTP_IPV4)                          if (proto != FTP_IPV4)
987                                  return(ftp_write(peer, FALSE, 522, REPLY_BADPROTO));                                  return (ftp_write(peer, FALSE, 522, REPLY_BADPROTO));
988                  }                  }
989                  else                  else
990                          return(ftp_write(peer, FALSE, 500, REPLY_EPSVERR));                          return (ftp_write(peer, FALSE, 500, REPLY_EPSVERR));
991          }          }
992                    
993          peer->passiveport = listenparrelelport(peer->remotefd, &(peer->remoteport), &a1, 5);          peer->passiveport =
994                            listenparrelelport(peer->remotefd, &(peer->remoteport), &a1, 5);
995    
996          if (peer->passiveport == -1)          if (peer->passiveport == -1)
997          {          {
998                  peer->passiveport = 0;                  peer->passiveport = 0;
999                  reporterror(peer, "passive port", errno);                  reporterror(peer, "passive port", errno);
1000                  return(FALSE);                  return (FALSE);
1001          }          }
1002          select_addfd(peer->sel, peer->passiveport);          select_addfd(peer->sel, peer->passiveport);
1003    
1004          return(ftp_write(peer, FALSE, 229, REPLY_EPSV(peer->remoteport)));          return (ftp_write(peer, FALSE, 229, REPLY_EPSV(peer->remoteport)));
1005  }  }
1006    
1007  int ftp_list(FTPSTATE *peer, char *param)  int ftp_list(FTPSTATE * peer,
1008                             char *param)
1009  {  {
1010          char *p = param;          char *p = param;
1011          int done = FALSE;          int done = FALSE;
1012          int parm = 0;          int parm = 0;
1013    
1014          while (!done)          while (!done)
1015          {          {
1016                  if (p == NULL)                  if (p == NULL)
# Line 897  int ftp_list(FTPSTATE *peer, char *param Line 1026  int ftp_list(FTPSTATE *peer, char *param
1026                  }                  }
1027          }          }
1028    
1029          return(ftp_lister(peer, p, FALSE, parm));          return (ftp_lister(peer, p, FALSE, parm));
1030  }  }
1031    
1032  int ftp_nlst(FTPSTATE *peer, char *param)  int ftp_nlst(FTPSTATE * peer,
1033                             char *param)
1034  {  {
1035          char *p = param;          char *p = param;
1036          int done = FALSE;          int done = FALSE;
1037          int parm = 0;          int parm = 0;
1038    
1039          while (!done)          while (!done)
1040          {          {
1041                  if (p == NULL)                  if (p == NULL)
# Line 920  int ftp_nlst(FTPSTATE *peer, char *param Line 1051  int ftp_nlst(FTPSTATE *peer, char *param
1051                  }                  }
1052          }          }
1053    
1054          return(ftp_lister(peer, p, TRUE, parm));          return (ftp_lister(peer, p, TRUE, parm));
1055  }  }
1056    
1057  int ftp_cdup(FTPSTATE *peer, char *param)  int ftp_cdup(FTPSTATE * peer,
1058                             char *param)
1059  {  {
1060          return(ftp_cwd(peer, ".."));          return (ftp_cwd(peer, ".."));
1061  }  }
1062    
1063  int ftp_rnfr(FTPSTATE *peer, char *param)  int ftp_rnfr(FTPSTATE * peer,
1064                             char *param)
1065  {  {
1066          freeifnotnull(peer->renameoldname);          freeifnotnull(peer->renameoldname);
1067          peer->renameoldname = file_expand(peer, param);          peer->renameoldname = file_expand(peer, param);
1068          return(ftp_write(peer, FALSE, 350, REPLY_RENAMESOURCE));          return (ftp_write(peer, FALSE, 350, REPLY_RENAMESOURCE));
1069  }  }
1070    
1071  int ftp_noop(FTPSTATE *peer, char *param)  int ftp_noop(FTPSTATE * peer,
1072                             char *param)
1073  {  {
1074          return(ftp_write(peer, FALSE, 200, REPLY_NOOP));          return (ftp_write(peer, FALSE, 200, REPLY_NOOP));
1075  }  }
1076    
1077  int ftp_rein(FTPSTATE *peer, char *param)  int ftp_rein(FTPSTATE * peer,
1078                             char *param)
1079  {  {
1080          if (peer->jailenabled)          if (peer->jailenabled)
1081                  return(ftp_write(peer, FALSE, 530, REPLY_JAILUSER));                  return (ftp_write(peer, FALSE, 530, REPLY_JAILUSER));
1082          if (peer->loggedin)          if (peer->loggedin)
1083                  shinfo_delusergroup(peer->groupname);                  shinfo_delusergroup(peer->groupname);
1084    
1085          peer->loggedin = FALSE;          peer->loggedin = FALSE;
1086          abortdatasocket(peer);          abortdatasocket(peer);
1087          return(ftp_write(peer, FALSE, 220, "Reinitialize successful, enter username."));          return (ftp_write
1088  }                          (peer, FALSE, 220, "Reinitialize successful, enter username."));
1089    }
1090    
1091  int ftp_none(FTPSTATE *peer, char *param)  int ftp_none(FTPSTATE * peer,
1092                             char *param)
1093  {  {
1094          return(FALSE);          return (FALSE);
1095  }  }
1096    
1097  int ftp_help(FTPSTATE *peer, char *param)  int ftp_help(FTPSTATE * peer,
1098                             char *param)
1099  {  {
1100          return(ftp_dohelp(peer, mainftpcmd, param, peer->cmddisableset));          return (ftp_dohelp(peer, mainftpcmd, param, peer->cmddisableset));
1101  }  }
1102    
1103  int ftp_dohelp(FTPSTATE *peer, FTPCMD *ftpcmds, char *command, int *disableset)  int ftp_dohelp(FTPSTATE * peer,
1104                               FTPCMD * ftpcmds,
1105                               char *command,
1106                               int *disableset)
1107  {  {
1108          char outstr[128];          char outstr[128];
1109          char cmd[10];          char cmd[10];
1110          int result = FALSE;          int result = FALSE;
1111          int count2,count = 0;          int count2, count = 0;
1112            
1113          if (command != NULL)          if (command != NULL)
1114          {          {
1115                  while(((strcasecmp(ftpcmds[count].command, command) != 0) &&                  while (((strcasecmp(ftpcmds[count].command, command) != 0) &&
1116                       (ftpcmds[count].ftpfunc != NULL)) ||                                  (ftpcmds[count].ftpfunc != NULL)) ||
1117                       (peer->loggedin ? disableset[count] : ftpcmds[count].needslogin))                             (peer->loggedin ? disableset[count] : ftpcmds[count].
1118                                    needslogin))
1119                          count++;                          count++;
1120                    
1121                  if (ftpcmds[count].ftpfunc == NULL)                  if (ftpcmds[count].ftpfunc == NULL)
1122                          ftp_write(peer, FALSE, 502, REPLY_HELPUNKNOWN(command));                          ftp_write(peer, FALSE, 502, REPLY_HELPUNKNOWN(command));
1123                  else                  else
1124                          ftp_write(peer, FALSE, 214, "%-8s : %s", ftpcmds[count].command, ftpcmds[count].helpdesc);                          ftp_write(peer, FALSE, 214, "%-8s : %s", ftpcmds[count].command,
1125                  return(FALSE);                                            ftpcmds[count].helpdesc);
1126                    return (FALSE);
1127          }          }
1128            
1129          ftp_write(peer, TRUE, 0, REPLY_HELPSTART);          ftp_write(peer, TRUE, 0, REPLY_HELPSTART);
1130          while (ftpcmds[count].ftpfunc != NULL)          while (ftpcmds[count].ftpfunc != NULL)
1131          {          {
# Line 991  int ftp_dohelp(FTPSTATE *peer, FTPCMD *f Line 1134  int ftp_dohelp(FTPSTATE *peer, FTPCMD *f
1134                          strcpy(outstr, "214-");                          strcpy(outstr, "214-");
1135                  else                  else
1136                          strcpy(outstr, "    ");                          strcpy(outstr, "    ");
1137                  /* now increment past disabled commands */                  /*
1138                  while((peer->loggedin ? disableset[count] : ftpcmds[count].needslogin))                   * now increment past disabled commands
1139                     */
1140                    while ((peer->loggedin ? disableset[count] : ftpcmds[count].
1141                                    needslogin))
1142                          count++;                          count++;
1143    
1144                  while ((count2 < 7) && (ftpcmds[count].ftpfunc != NULL))                  while ((count2 < 7) && (ftpcmds[count].ftpfunc != NULL))
# Line 1001  int ftp_dohelp(FTPSTATE *peer, FTPCMD *f Line 1147  int ftp_dohelp(FTPSTATE *peer, FTPCMD *f
1147                          strcat(outstr, cmd);                          strcat(outstr, cmd);
1148                          count2++;                          count2++;
1149                          count++;                          count++;
1150                          /* now increment past disabled commands */                          /*
1151                          while((peer->loggedin ? disableset[count] : ftpcmds[count].needslogin))                           * now increment past disabled commands
1152                             */
1153                            while ((peer->loggedin ? disableset[count] : ftpcmds[count].
1154                                            needslogin))
1155                                  count++;                                  count++;
1156                  }                  }
1157                  ftp_write(peer, TRUE, 0, outstr);                  ftp_write(peer, TRUE, 0, outstr);
1158          }          }
           
         result = ftp_write(peer, FALSE, 214, REPLY_HELPEND(peer->vserver->email));  
1159    
1160          return(result);          result = ftp_write(peer, FALSE, 214, REPLY_HELPEND(peer->vserver->email));
1161    
1162            return (result);
1163  }  }
1164    
1165  int ftp_allo(FTPSTATE *peer, char *param)  int ftp_allo(FTPSTATE * peer,
1166                             char *param)
1167  {  {
1168          return(ftp_write(peer, FALSE, 202, REPLY_ALLO));          return (ftp_write(peer, FALSE, 202, REPLY_ALLO));
1169  }  }
1170    
1171  int ftp_acct(FTPSTATE *peer, char *param)  int ftp_acct(FTPSTATE * peer,
1172                             char *param)
1173  {  {
1174          return(ftp_write(peer, FALSE, 200, REPLY_ACCT));          return (ftp_write(peer, FALSE, 200, REPLY_ACCT));
1175  }  }
1176    
1177  int ftp_stru(FTPSTATE *peer, char *param)  int ftp_stru(FTPSTATE * peer,
1178                             char *param)
1179  {  {
1180          if ((param[0] & (255-32)) == 'F')          if ((param[0] & (255 - 32)) == 'F')
1181                  return(ftp_write(peer, FALSE, 200, REPLY_STRUFILE));                  return (ftp_write(peer, FALSE, 200, REPLY_STRUFILE));
1182          else          else
1183                  return(ftp_write(peer, FALSE, 500, REPLY_STRUUNKNOWN));                  return (ftp_write(peer, FALSE, 500, REPLY_STRUUNKNOWN));
1184  }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.6.1

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26