ReactOS  0.4.10-dev-479-g13a3cf0
main.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1985, 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley. The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 /*
19  * FTP User Program -- Command Interface.
20  */
21 
22 #include "precomp.h"
23 
24 #include <fcntl.h>
25 
26 #ifndef lint
27 char copyright[] =
28 "@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
29  All rights reserved.\n";
30 #endif /* not lint */
31 
32 #ifndef lint
33 static char sccsid[] = "@(#)main.c based on 5.13 (Berkeley) 3/14/89";
34 #endif /* not lint */
35 
36 #if defined(sun) && !defined(FD_SET)
37 typedef int uid_t;
38 #endif
39 
40 uid_t getuid(void);
41 void intr(void);
42 void lostpeer(void);
43 char *getlogin(void);
44 
45 short portnum;
46 
47 char home[128];
48 char *globerr;
50 
51 
52 
53 /* Lot's of options... */
54 /*
55  * Options and other state info.
56  */
57 int trace; /* trace packets exchanged */
58 int hash; /* print # for each buffer transferred */
59 //int sendport; /* use PORT cmd for each data connection */
60 int verbose; /* print messages coming back from server */
61 int connected; /* connected to server */
62 int fromatty; /* input is from a terminal */
63 int interactive; /* interactively prompt on m* cmds */
64 int debug; /* debugging level */
65 int bell; /* ring bell on cmd completion */
66 int doglob; /* glob local file names */
67 int proxy; /* proxy server connection active */
69 int proxflag; /* proxy connection exists */
70 int sunique; /* store files on server with unique name */
71 int runique; /* store local files with unique name */
72 int mcase; /* map upper to lower case for mget names */
73 int ntflag; /* use ntin ntout tables for name translation */
74 int mapflag; /* use mapin mapout templates on file names */
75 int code; /* return/reply code for ftp command */
76 int crflag; /* if 1, strip car. rets. on ascii gets */
77 char pasv[64]; /* passive port for proxy data connection */
78 char *altarg; /* argv[1] with no shell-like preprocessing */
79 char ntin[17]; /* input translation table */
80 char ntout[17]; /* output translation table */
81 // #include <sys/param.h>
82 char mapin[MAXPATHLEN]; /* input map template */
83 char mapout[MAXPATHLEN]; /* output map template */
84 char typename[32]; /* name of file transfer type */
85 int type; /* file transfer type */
86 char structname[32]; /* name of file transfer structure */
87 int stru; /* file transfer structure */
88 char formname[32]; /* name of file transfer format */
89 int form; /* file transfer format */
90 char modename[32]; /* name of file transfer mode */
91 int mode; /* file transfer mode */
92 char bytename[32]; /* local byte size in ascii */
93 int bytesize; /* local byte size in binary */
94 
95 jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
96 
97 char line[200]; /* input line buffer */
98 char *stringbase; /* current scan point in line buffer */
99 char argbuf[200]; /* argument storage buffer */
100 char *argbase; /* current storage point in arg buffer */
101 int margc; /* count of arguments on input line */
102 const char *margv[20]; /* args parsed from input line */
103 int cpend; /* flag: if != 0, then pending server reply */
104 int mflag; /* flag: if != 0, then active multi command */
105 
106 int options; /* used during socket creation */
107 
108 int macnum; /* number of defined macros */
109 struct macel macros[16];
110 char macbuf[4096];
111 
112 /*
113  * Need to start a listen on the data channel
114  * before we send the command, otherwise the
115  * server's connect may fail.
116  */
117 int sendport = -1;
118 
119 static const char *slurpstring();
120 
121 
122 int main(int argc, const char *argv[])
123 {
124  const char *cp;
125  int top;
126 #if 0
127  char homedir[MAXPATHLEN];
128 #endif
129 
130  int err;
131  WORD wVerReq;
132 
134  struct servent *sp; /* service spec for tcp/ftp */
135 
136  /* Disable output buffering, for the benefit of Emacs. */
137  //setbuf(stdout, NULL);
138 
139  _fmode = O_BINARY; // This causes an error somewhere.
140 
141  wVerReq = MAKEWORD(1,1);
142 
143  err = WSAStartup(wVerReq, &WSAData);
144  if (err != 0)
145  {
146  fprintf(stderr, "Could not initialize Windows socket interface.");
147  exit(1);
148  }
149 
150  sp = getservbyname("ftp", "tcp");
151  if (sp == 0) {
152  fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
153  exit(1);
154  }
155 
156  portnum = sp->s_port;
157 
158 
159  doglob = 1;
160  interactive = 1;
161  autologin = 1;
162  argc--, argv++;
163  while (argc > 0 && **argv == '-') {
164  for (cp = *argv + 1; *cp; cp++)
165  switch (*cp) {
166 
167  case 'd':
168  options |= SO_DEBUG;
169  debug++;
170  break;
171 
172  case 'v':
173  verbose++;
174  break;
175 
176  case 't':
177  trace++;
178  break;
179 
180  case 'i':
181  interactive = 0;
182  break;
183 
184  case 'n':
185  autologin = 0;
186  break;
187 
188  case 'g':
189  doglob = 0;
190  break;
191 
192  default:
193  fprintf(stdout,
194  "ftp: %c: unknown option\n", *cp);
195  exit(1);
196  }
197  argc--, argv++;
198  }
199 // fromatty = isatty(fileno(stdin));
200  fromatty = 1; // Strengthen this test
201  /*
202  * Set up defaults for FTP.
203  */
204  (void) strcpy(typename, "ascii"), type = TYPE_A;
205  (void) strcpy(formname, "non-print"), form = FORM_N;
206  (void) strcpy(modename, "stream"), mode = MODE_S;
207  (void) strcpy(structname, "file"), stru = STRU_F;
208  (void) strcpy(bytename, "8"), bytesize = 8;
209  if (fromatty)
210  verbose++;
211  cpend = 0; /* no pending replies */
212  proxy = 0; /* proxy not active */
213  passivemode = 1; /* passive mode *is* active */
214  crflag = 1; /* strip c.r. on ascii gets */
215  /*
216  * Set up the home directory in case we're globbing.
217  */
218 #if 0
219  cp = getlogin();
220  if (cp != NULL) {
221  pw = getpwnam(cp);
222  }
223  if (pw == NULL)
224  pw = getpwuid(getuid());
225  if (pw != NULL) {
226  home = homedir;
227  (void) strcpy(home, pw->pw_dir);
228  }
229 #endif
230  strcpy(home, "C:/");
231  if (argc > 0) {
232  if (setjmp(toplevel))
233  exit(0);
234 // (void) signal(SIGINT, intr);
235 // (void) signal(SIGPIPE, lostpeer);
236  setpeer(argc + 1, argv - 1);
237  }
238  top = setjmp(toplevel) == 0;
239  if (top) {
240 // (void) signal(SIGINT, intr);
241 // (void) signal(SIGPIPE, lostpeer);
242  }
243  for (;;) {
244  cmdscanner(top);
245  top = 1;
246  }
247 }
248 
249 void intr(void)
250 {
251  longjmp(toplevel, 1);
252 }
253 
254 void lostpeer(void)
255 {
256  extern SOCKET cout;
257  extern int data;
258 
259  if (connected) {
260  if (cout) {
261  closesocket(cout);
262  cout = 0;
263  }
264  if (data >= 0) {
265  (void) shutdown(data, 1+1);
266  (void) close(data);
267  data = -1;
268  }
269  connected = 0;
270  }
271  pswitch(1);
272  if (connected) {
273  if (cout) {
274  closesocket(cout);
275  cout = 0;
276  }
277  connected = 0;
278  }
279  proxflag = 0;
280  pswitch(0);
281 }
282 
283 /*char *
284 tail(char *filename)
285 {
286  register char *s;
287 
288  while (*filename) {
289  s = rindex(filename, '/');
290  if (s == NULL)
291  break;
292  if (s[1])
293  return (s + 1);
294  *s = '\0';
295  }
296  return (filename);
297 }
298 */
299 /*
300  * Command parser.
301  */
302 void cmdscanner(int top)
303 {
304  register struct cmd *c;
305 
306  if (!top)
307  (void) putchar('\n');
308  for (;;) {
309  (void) fflush(stdout);
310  if (fromatty) {
311  printf("ftp> ");
312  (void) fflush(stdout);
313  }
314  if (gets(line) == 0) {
315  if (feof(stdin) || ferror(stdin))
316  quit(0, NULL);
317  break;
318  }
319  if (line[0] == 0)
320  break;
321  makeargv();
322  if (margc == 0) {
323  continue;
324  }
325  c = getcmd(margv[0]);
326  if (c == (struct cmd *)-1) {
327  printf("?Ambiguous command\n");
328  continue;
329  }
330  if (c == 0) {
331  printf("?Invalid command\n");
332  continue;
333  }
334  if (c->c_conn && !connected) {
335  printf ("Not connected.\n");
336  continue;
337  }
338  (*c->c_handler)(margc, margv);
339  if (bell && c->c_bell)
340  (void) putchar('\007');
341  if (c->c_handler != help)
342  break;
343  }
344  (void) fflush(stdout);
345 // (void) signal(SIGINT, intr);
346 // (void) signal(SIGPIPE, lostpeer);
347 }
348 
349 struct cmd *
350 getcmd(const char *name)
351 {
352  extern struct cmd cmdtab[];
353  const char *p, *q;
354  struct cmd *c, *found;
355  int nmatches, longest;
356 
357  longest = 0;
358  nmatches = 0;
359  found = 0;
360  for (c = cmdtab; (p = c->c_name); c++) {
361  for (q = name; *q == *p++; q++)
362  if (*q == 0) /* exact match? */
363  return (c);
364  if (!*q) { /* the name was a prefix */
365  if (q - name > longest) {
366  longest = q - name;
367  nmatches = 1;
368  found = c;
369  } else if (q - name == longest)
370  nmatches++;
371  }
372  }
373  if (nmatches > 1)
374  return ((struct cmd *)-1);
375  return (found);
376 }
377 
378 /*
379  * Slice a string up into argc/argv.
380  */
381 
383 
384 void makeargv(void)
385 {
386  const char **argp;
387 
388  margc = 0;
389  argp = margv;
390  stringbase = line; /* scan from first of buffer */
391  argbase = argbuf; /* store from first of buffer */
392  slrflag = 0;
393  while ((*argp++ = slurpstring()))
394  margc++;
395 }
396 
397 /*
398  * Parse string into argbuf;
399  * implemented with FSM to
400  * handle quoting and strings
401  */
402 static const char *
404 {
405  int got_one = 0;
406  register char *sb = stringbase;
407  register char *ap = argbase;
408  char *tmp = argbase; /* will return this if token found */
409 
410  if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
411  switch (slrflag) { /* and $ as token for macro invoke */
412  case 0:
413  slrflag++;
414  stringbase++;
415  return ((*sb == '!') ? "!" : "$");
416  /* NOTREACHED */
417  case 1:
418  slrflag++;
419  altarg = stringbase;
420  break;
421  default:
422  break;
423  }
424  }
425 
426 S0:
427  switch (*sb) {
428 
429  case '\0':
430  goto OUT1;
431 
432  case ' ':
433  case '\t':
434  sb++; goto S0;
435 
436  default:
437  switch (slrflag) {
438  case 0:
439  slrflag++;
440  break;
441  case 1:
442  slrflag++;
443  altarg = sb;
444  break;
445  default:
446  break;
447  }
448  goto S1;
449  }
450 
451 S1:
452  switch (*sb) {
453 
454  case ' ':
455  case '\t':
456  case '\0':
457  goto OUT1; /* end of token */
458 
459  case '\\':
460  sb++; goto S2; /* slurp next character */
461 
462  case '"':
463  sb++; goto S3; /* slurp quoted string */
464 
465  default:
466  *ap++ = *sb++; /* add character to token */
467  got_one = 1;
468  goto S1;
469  }
470 
471 S2:
472  switch (*sb) {
473 
474  case '\0':
475  goto OUT1;
476 
477  default:
478  *ap++ = *sb++;
479  got_one = 1;
480  goto S1;
481  }
482 
483 S3:
484  switch (*sb) {
485 
486  case '\0':
487  goto OUT1;
488 
489  case '"':
490  sb++; goto S1;
491 
492  default:
493  *ap++ = *sb++;
494  got_one = 1;
495  goto S3;
496  }
497 
498 OUT1:
499  if (got_one)
500  *ap++ = '\0';
501  argbase = ap; /* update storage pointer */
502  stringbase = sb; /* update scan pointer */
503  if (got_one) {
504  return(tmp);
505  }
506  switch (slrflag) {
507  case 0:
508  slrflag++;
509  break;
510  case 1:
511  slrflag++;
512  altarg = (char *) 0;
513  break;
514  default:
515  break;
516  }
517  return((char *)0);
518 }
519 
520 #define HELPINDENT (sizeof ("directory"))
521 
522 /*
523  * Help command.
524  * Call each command handler with argc == 0 and argv[0] == name.
525  */
526 void help(int argc, const char *argv[])
527 {
528  extern struct cmd cmdtab[];
529  struct cmd *c;
530 
531  if (argc == 1) {
532  register int i, j, w, k;
533  int columns, width = 0, lines;
534  extern int NCMDS;
535 
536  printf("Commands may be abbreviated. Commands are:\n\n");
537  for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
538  int len = strlen(c->c_name);
539 
540  if (len > width)
541  width = len;
542  }
543  width = (width + 8) &~ 7;
544  columns = 80 / width;
545  if (columns == 0)
546  columns = 1;
547  lines = (NCMDS + columns - 1) / columns;
548  for (i = 0; i < lines; i++) {
549  for (j = 0; j < columns; j++) {
550  c = cmdtab + j * lines + i;
551  if (c->c_name && (!proxy || c->c_proxy)) {
552  printf("%s", c->c_name);
553  }
554  else if (c->c_name) {
555  for (k=0; k < (int) strlen(c->c_name); k++) {
556  (void) putchar(' ');
557  }
558  }
559  if (c + lines >= &cmdtab[NCMDS]) {
560  printf("\n");
561  break;
562  }
563  w = strlen(c->c_name);
564  while (w < width) {
565  w = (w + 8) &~ 7;
566  (void) putchar('\t');
567  }
568  }
569  }
570  (void) fflush(stdout);
571  return;
572  }
573  while (--argc > 0) {
574  const char *arg;
575  arg = *++argv;
576  c = getcmd(arg);
577  if (c == (struct cmd *)-1)
578  printf("?Ambiguous help command %s\n", arg);
579  else if (c == (struct cmd *)0)
580  printf("?Invalid help command %s\n", arg);
581  else
582  printf("%-*s\t%s\n", (int)HELPINDENT,
583  c->c_name, c->c_help);
584  }
585  (void) fflush(stdout);
586 }
WSADATA WSAData
Definition: wintirpc.c:31
char formname[32]
Definition: main.c:88
int runique
Definition: main.c:71
char macbuf[4096]
Definition: main.c:110
static int argc
Definition: ServiceArgs.c:12
_Check_return_ _CRTIMP int __cdecl ferror(_In_ FILE *_File)
void setpeer(int argc, const char *argv[])
Definition: cmds.c:49
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
unsigned short WORD
Definition: ntddk_ex.h:93
int options
Definition: main.c:106
int hash
Definition: main.c:58
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
int mflag
Definition: main.c:104
char copyright[]
Definition: main.c:27
#define S1(x)
Definition: test.h:191
char mapin[MAXPATHLEN]
Definition: main.c:82
int bell
Definition: main.c:65
int proxflag
Definition: main.c:69
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MAKEWORD(a, b)
Definition: typedefs.h:247
Definition: ftp_var.h:139
_CRTIMP char *__cdecl gets(char *_Buffer)
Definition: file.c:3643
char argbuf[200]
Definition: main.c:99
void quit(int argc, const char *argv[])
Definition: cmds.c:1606
#define FORM_N
Definition: ftp_var.h:54
#define S2(x)
Definition: test.h:192
static const char * slurpstring()
Definition: main.c:403
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
void got_one(struct protocol *l)
Definition: dispatch.c:195
const char * name
Definition: main.c:224
FILE * stdin
void * arg
Definition: msvc.h:12
#define S3(x)
Definition: test.h:193
void cmdscanner(int top)
Definition: main.c:302
void(* c_handler)(int argc, const char *argv[])
Definition: ftp_var.h:145
long uid_t
Definition: various.h:8
char structname[32]
Definition: main.c:86
int autologin
Definition: main.c:49
static char ** argv
Definition: ServiceArgs.c:11
FILE * stdout
superblock * sb
Definition: btrfs.c:3841
int doglob
Definition: main.c:66
char * stringbase
Definition: main.c:98
int fromatty
Definition: main.c:62
int sendport
Definition: main.c:117
short portnum
Definition: main.c:45
char c_proxy
Definition: ftp_var.h:144
#define cout
Definition: iostream.cpp:38
GLenum GLclampf GLint i
Definition: glfuncs.h:14
int NCMDS
Definition: cmdtab.c:171
#define closesocket
Definition: main.c:39
char * argbase
Definition: main.c:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int crflag
Definition: main.c:76
int bytesize
Definition: main.c:93
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
int putchar(int c)
Definition: crtsupp.c:12
char line[200]
Definition: main.c:97
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
#define STRU_F
Definition: ftp_var.h:50
Definition: parser.c:48
int longjmp(jmp_buf buf, int retval)
void makeargv(void)
Definition: main.c:384
int mcase
Definition: main.c:72
int margc
Definition: main.c:101
#define uid_t
Definition: types.h:66
_Check_return_ _CRTIMP int __cdecl feof(_In_ FILE *_File)
PSERVENT WSAAPI getservbyname(IN const char FAR *name, IN const char FAR *proto)
Definition: getxbyxx.c:500
GLint GLint GLsizei width
Definition: gl.h:1546
Definition: tftpd.h:37
const char * c_name
Definition: ftp_var.h:140
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
Definition: sockctrl.c:506
void lostpeer(void)
Definition: main.c:254
int sunique
Definition: main.c:70
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
char * getlogin(void)
int main(int argc, const char *argv[])
Definition: main.c:122
int interactive
Definition: main.c:63
int macnum
Definition: main.c:108
int form
Definition: main.c:89
Definition: ftp_var.h:148
int slrflag
Definition: main.c:382
GLenum GLsizei len
Definition: glext.h:6722
int cpend
Definition: main.c:103
#define MAXPATHLEN
Definition: ftp_var.h:35
jmp_buf toplevel
Definition: main.c:95
#define close
Definition: acwin.h:74
#define err(...)
char pasv[64]
Definition: main.c:77
int mapflag
Definition: main.c:74
_CRTIMP int _fmode
Definition: txtmode.c:13
int debug
Definition: main.c:64
char c_conn
Definition: ftp_var.h:143
int passivemode
Definition: main.c:68
int type
Definition: main.c:85
char ntout[17]
Definition: main.c:80
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
uid_t getuid(void)
Definition: uid.c:27
#define MODE_S
Definition: ftp_var.h:46
short s_port
Definition: winsock.h:165
int mode
Definition: main.c:91
#define O_BINARY
Definition: acwin.h:83
int stru
Definition: main.c:87
int verbose
Definition: main.c:60
struct macel macros[16]
Definition: main.c:109
char modename[32]
Definition: main.c:90
#define setjmp
Definition: setjmp.h:183
static char sccsid[]
Definition: main.c:33
char mapout[MAXPATHLEN]
Definition: main.c:83
const char * c_help
Definition: ftp_var.h:141
void pswitch(int flag)
Definition: ftp.c:1310
int trace
Definition: main.c:57
int connected
Definition: main.c:61
char c_bell
Definition: ftp_var.h:142
POINT cp
Definition: magnifier.c:58
Definition: name.c:36
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define c
Definition: ke_i.h:80
char ntin[17]
Definition: main.c:79
FILE * stderr
int ntflag
Definition: main.c:73
const char * margv[20]
Definition: main.c:102
#define HELPINDENT
Definition: main.c:520
static const WCHAR sp[]
Definition: suminfo.c:288
UINT_PTR SOCKET
Definition: winsock.h:47
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
long jmp_buf[100]
Definition: of.h:11
int code
Definition: main.c:75
char * globerr
Definition: main.c:48
void exit(int exitcode)
Definition: _exit.c:33
GLfloat GLfloat p
Definition: glext.h:8902
struct cmd * getcmd(const char *name)
Definition: main.c:350
void help(int argc, const char *argv[])
Definition: main.c:526
int proxy
Definition: main.c:67
char * altarg
Definition: main.c:78
#define TYPE_A
Definition: ftp_var.h:36
int k
Definition: mpi.c:3369
char bytename[32]
Definition: main.c:92
void intr(void)
Definition: main.c:249
#define printf
Definition: config.h:203
#define SO_DEBUG
Definition: winsock.h:178
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29