ReactOS  0.4.14-dev-606-g14ebc0b
cmds.c
Go to the documentation of this file.
1 /* cmds.c
2  *
3  * Copyright (c) 1992-2001 by Mike Gleason.
4  * All rights reserved.
5  *
6  */
7 
8 #include "syshdrs.h"
9 #include "shell.h"
10 #include "util.h"
11 #include "ls.h"
12 #include "bookmark.h"
13 #include "cmds.h"
14 #include "main.h"
15 #include "trace.h"
16 #include "log.h"
17 #include "pref.h"
18 #include "spool.h"
19 #include "getline.h"
20 #include "readln.h"
21 #include "getopt.h"
22 
23 /* This was the directory path when the user logged in. For anonymous users,
24  * this should be "/", but for real users, it should be their home directory.
25  * This variable is used later when we want to calculate a relative path
26  * from the starting directory.
27  */
28 char gStartDir[512];
29 
30 /* The pathname to the current working directory. This always needs to be
31  * current, so whenever a directory change is done this should be changed.
32  */
33 char gRemoteCWD[512];
34 
35 /* Same, but the previous directory the user was in, or empty string if
36  * there is none.
37  */
38 char gPrevRemoteCWD[512];
39 
40 /* Another buffer we use just temporarily when switching directories. */
41 char gScratchCWD[512];
42 
43 /* The only reason we do this is to get gcc/lint to shut up
44  * about unused parameters.
45  */
47 #define ARGSUSED(x) x = (argc != 0) || (argv != 0) || (cmdp != 0) || (aip != 0)
48 
49 /* Used temporarily, but put it here because it's big. */
51 
52 /* If the user doesn't want to be prompted for a batch of files,
53  * they can tell us to answer this answer for each item in the batch.
54  */
56 
57 extern FTPLibraryInfo gLib;
59 extern char gOurDirectoryPath[];
60 extern Command gCommands[];
61 extern char gVersion[];
62 extern size_t gNumCommands;
63 extern int gDebug, gDoneApplication;
64 extern char *gOptArg;
65 extern int gOptInd, gGotSig;
66 extern int gFirstTimeUser;
67 extern unsigned int gFirewallPort;
68 extern int gFirewallType;
69 extern char gFirewallHost[64];
70 extern char gFirewallUser[32];
71 extern char gFirewallPass[32];
72 extern char gFirewallExceptionList[];
73 extern char gPager[], gHome[], gShell[];
74 extern char gOS[];
75 extern int gAutoResume, gRedialDelay;
77 extern Bookmark gBm;
79 extern char gLocalCWD[512], gPrevLocalCWD[512], gOurInstallationPath[];
80 extern int gMayCancelJmp;
81 #if defined(WIN32) || defined(_WINDOWS)
82 #elif defined(HAVE_SIGSETJMP)
83 extern sigjmp_buf gCancelJmp;
84 #else /* HAVE_SIGSETJMP */
85 extern jmp_buf gCancelJmp;
86 #endif /* HAVE_SIGSETJMP */
87 
88 
89 
90 
91 /* Open the users $PAGER, or just return stdout. Make sure to use
92  * ClosePager(), and not fclose/pclose directly.
93  */
94 static FILE *
95 OpenPager(void)
96 {
97  FILE *fp;
98  char *pprog;
99 
100  (void) fflush(stdout);
101  pprog = gPager;
102  fp = popen((pprog[0] == '\0') ? "more" : pprog, "w");
103  if (fp == NULL)
104  return (stdout);
105  return (fp);
106 } /* OpenPager */
107 
108 
109 
110 
111 /* Close (maybe) a file previously created by OpenPager. */
112 static void
113 ClosePager(FILE *pagerfp)
114 {
115 #ifdef SIGPIPE
116  sigproc_t osigpipe;
117 #endif
118 
119  if ((pagerfp != NULL) && (pagerfp != stdout)) {
120 #ifdef SIGPIPE
121  osigpipe = (sigproc_t) NcSignal(SIGPIPE, SIG_IGN);
122 #endif
123  (void) pclose(pagerfp);
124 #ifdef SIGPIPE
125  (void) NcSignal(SIGPIPE, osigpipe);
126 #endif
127  }
128 } /* ClosePager */
129 
130 
131 
132 
133 /* Fills in the bookmarkName field of the Bookmark. */
134 int
136 {
137  char dfltname[64];
138  char bmname[64];
139 
140  DefaultBookmarkName(dfltname, sizeof(dfltname), gConn.host);
141  if (dfltname[0] == '\0') {
142  (void) printf("Enter a name for this bookmark: ");
143  } else {
144  (void) printf("Enter a name for this bookmark, or hit enter for \"%s\": ", dfltname);
145  }
146  fflush(stdin);
147  (void) FGets(bmname, sizeof(bmname), stdin);
148  if (bmname[0] != '\0') {
149  (void) STRNCPY(bmp->bookmarkName, bmname);
150  return (0);
151  } else if (dfltname[0] != '\0') {
152  (void) STRNCPY(bmp->bookmarkName, dfltname);
153  return (0);
154  }
155  return (-1);
156 } /* PromptForBookmarkName */
157 
158 
159 
160 void
161 CurrentURL(char *dst, size_t dsize, int showpass)
162 {
163  Bookmark bm;
164  char dir[160];
165 
166  memset(&bm, 0, sizeof(bm));
167  (void) STRNCPY(bm.name, gConn.host);
168  if ((gConn.user[0] != '\0') && (! STREQ(gConn.user, "anonymous")) && (! STREQ(gConn.user, "ftp"))) {
169  (void) STRNCPY(bm.user, gConn.user);
170  (void) STRNCPY(bm.pass, (showpass == 0) ? "PASSWORD" : gConn.pass);
171  (void) STRNCPY(bm.acct, gConn.acct);
172  }
173 
174  bm.port = gConn.port;
175 
176  /* We now save relative paths, because the pathname in URLs are
177  * relative by nature. This makes non-anonymous FTP URLs shorter
178  * because it doesn't have to include the pathname of their
179  * home directory.
180  */
182  AbsoluteToRelative(bm.dir, sizeof(bm.dir), dir, gStartDir, strlen(gStartDir));
183 
184  BookmarkToURL(&bm, dst, dsize);
185 } /* CurrentURL */
186 
187 
188 
189 
190 /* Fills in the fields of the Bookmark structure, based on the FTP current
191  * session.
192  */
193 void
195 {
196  char dir[160];
197 
198  (void) STRNCPY(bmp->name, gConn.host);
199  if ((STREQ(gConn.user, "anonymous")) || (STREQ(gConn.user, "ftp"))) {
200  bmp->user[0] = '\0';
201  bmp->pass[0] = '\0';
202  bmp->acct[0] = '\0';
203  } else {
204  (void) STRNCPY(bmp->user, gConn.user);
205  (void) STRNCPY(bmp->pass, gConn.pass);
206  (void) STRNCPY(bmp->acct, gConn.acct);
207  }
208 
209  /* We now save relative paths, because the pathname in URLs are
210  * relative by nature. This makes non-anonymous FTP URLs shorter
211  * because it doesn't have to include the pathname of their
212  * home directory.
213  */
215  AbsoluteToRelative(bmp->dir, sizeof(bmp->dir), dir, gStartDir, strlen(gStartDir));
216  bmp->port = gConn.port;
217  (void) time(&bmp->lastCall);
218  bmp->hasSIZE = gConn.hasSIZE;
219  bmp->hasMDTM = gConn.hasMDTM;
220  bmp->hasPASV = gConn.hasPASV;
221  bmp->hasUTIME = gConn.hasUTIME;
223  (void) STRNCPY(bmp->lastIP, gConn.ip);
224 } /* FillBookmarkInfo */
225 
226 
227 
228 
229 /* Saves the current FTP session settings as a bookmark. */
230 void
232 {
233  int saveBm;
234  char ans[64];
235 
236  /* gBm.bookmarkName must already be set. */
238 
239  saveBm = gSavePasswords;
240  if (gLoadedBm != 0)
241  saveBm = 1;
242  if ((saveBm < 0) && (gBm.pass[0] != '\0')) {
243  (void) printf("\n\nYou logged into this site using a password.\nWould you like to save the password with this bookmark?\n\n");
244  (void) printf("Save? [no] ");
245  (void) memset(ans, 0, sizeof(ans));
246  fflush(stdin);
247  (void) fgets(ans, sizeof(ans) - 1, stdin);
248  if ((saveBm = StrToBool(ans)) == 0) {
249  (void) printf("\nNot saving the password.\n");
250  }
251  }
252  if (PutBookmark(&gBm, saveBm) < 0) {
253  (void) fprintf(stderr, "Could not save bookmark.\n");
254  } else {
255  /* Also marks whether we saved it. */
256  gLoadedBm = 1;
257  (void) printf("Bookmark \"%s\" saved.\n", gBm.bookmarkName);
258 
260  }
261 } /* SaveCurrentAsBookmark */
262 
263 
264 
265 
266 /* If the user did not explicitly bookmark this site already, ask
267  * the user if they want to save one.
268  */
269 void
271 {
272  char url[256];
273  char ans[64];
274  int c;
275 
276  if ((gConfirmClose != 0) && (gLoadedBm == 0) && (gOurDirectoryPath[0] != '\0')) {
278  BookmarkToURL(&gBm, url, sizeof(url));
279  (void) printf("\n\nYou have not saved a bookmark for this site.\n");
280  (void) sleep(1);
281  (void) printf("\nWould you like to save a bookmark to:\n\t%s\n\n", url);
282  for (;;) {
283  (void) printf("Save? (yes/no) ");
284  (void) memset(ans, 0, sizeof(ans));
285  fflush(stdin);
286  if (fgets(ans, sizeof(ans) - 1, stdin) == NULL) {
287  c = 'n';
288  break;
289  }
290  c = ans[0];
291  if ((c == 'n') || (c == 'y'))
292  break;
293  if (c == 'N') {
294  c = 'n';
295  break;
296  } else if (c == 'Y') {
297  c = 'y';
298  break;
299  }
300  }
301  if (c == 'n') {
302  (void) printf("Not saved. (If you don't want to be asked this, \"set confirm-close no\")\n\n\n");
303 
304  } else if (PromptForBookmarkName(&gBm) < 0) {
305  (void) printf("Nevermind.\n");
306  } else {
308  }
309  } else if ((gLoadedBm == 1) && (gOurDirectoryPath[0] != '\0') && (strcmp(gOurDirectoryPath, gBm.dir) != 0)) {
310  /* Bookmark has changed. */
313  }
314  }
315 } /* SaveUnsavedBookmark */
316 
317 
318 
319 /* Save the current host session settings for later as a "bookmark", which
320  * will be referred to by a bookmark abbreviation name.
321  */
322 void
323 BookmarkCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
324 {
325  /* The only reason we do this is to get gcc/lint to shut up
326  * about unused parameters.
327  */
329 
330  if (gOurDirectoryPath[0] == '\0') {
331  (void) printf("Sorry, configuration information is not saved for this user.\n");
332  } else if ((argc <= 1) || (argv[1][0] == '\0')) {
333  /* No name specified on the command line. */
334  if (gBm.bookmarkName[0] == '\0') {
335  /* Not previously bookmarked. */
336  if (PromptForBookmarkName(&gBm) < 0) {
337  (void) printf("Nevermind.\n");
338  } else {
340  }
341  } else {
342  /* User wants to update an existing bookmark. */
344  }
345  } else {
348  }
349 } /* BookmarkCmd */
350 
351 
352 
353 
354 /* Dump a remote file to the screen. */
355 void
356 CatCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
357 {
358  int result;
359  int i;
360 
362  for (i=1; i<argc; i++) {
365  }
366 } /* CatCmd */
367 
368 
369 
370 static void
372 {
373  LinePtr lp;
374  LineListPtr llp;
375 
376  gUnusedArg = (cipUNUSED != NULL);
377  if ((rp->printMode & kResponseNoPrint) != 0)
378  return;
379  llp = &rp->msg;
380  for (lp = llp->first; lp != NULL; lp = lp->next) {
381  if ((lp == llp->first) && (rp->codeType == 2)) {
382  if (ISTRNCMP(lp->line, "CWD command", 11) == 0)
383  continue;
384  if (lp->line[0] == '"')
385  continue; /* "/pub/foo" is... */
386  }
387  (void) printf("%s\n", lp->line);
388  }
389 } /* NcFTPCdResponseProc */
390 
391 
392 
393 
394 /* Manually print a response obtained from the remote FTP user. */
395 void
397 {
398  LinePtr lp;
399 
400  if (llp != NULL) {
401  for (lp = llp->first; lp != NULL; lp = lp->next) {
402  if ((lp == llp->first) && (ISTRNCMP(lp->line, "CWD command", 11) == 0))
403  continue;
404  (void) printf("%s\n", lp->line);
405  }
406  }
407 } /* PrintResp */
408 
409 
410 
411 
412 /* Do a chdir, and update our notion of the current directory.
413  * Some servers return it back as part of the CWD response,
414  * otherwise do a CWD command followed by a PWD.
415  */
416 int
417 nFTPChdirAndGetCWD(const FTPCIPtr cip, const char *cdCwd, const int quietMode)
418 {
419  ResponsePtr rp;
420  size_t cdCwdLen;
421  int result;
422 #ifdef USE_WHAT_SERVER_SAYS_IS_CWD
423  int foundcwd;
424  char *l, *r;
425 #endif
426 
427  if (cip == NULL)
428  return (kErrBadParameter);
429  if (strcmp(cip->magic, kLibraryMagic))
430  return (kErrBadMagic);
431 
432  if ((cdCwd == NULL) || (cdCwd[0] == '\0')) {
434  cip->errNo = kErrInvalidDirParam;
435  } else {
436  rp = InitResponse();
437  if (rp == NULL) {
439  cip->errNo = kErrMallocFailed;
440  /* Error(cip, kDontPerror, "Malloc failed.\n"); */
441  } else {
442  cdCwdLen = strlen(cdCwd);
443  if (strcmp(cdCwd, "..") == 0) {
444  result = RCmd(cip, rp, "CDUP");
445  } else {
446  result = RCmd(cip, rp, "CWD %s", cdCwd);
447  }
448  if (result == 2) {
449 #ifdef USE_WHAT_SERVER_SAYS_IS_CWD
451  foundcwd = 0;
452  if ((r = strrchr(rp->msg.first->line, '"')) != NULL) {
453  /* "xxxx" is current directory.
454  * Strip out just the xxxx to copy into the remote cwd.
455  *
456  * This is nice because we didn't have to do a PWD.
457  */
458  l = strchr(rp->msg.first->line, '"');
459  if ((l != NULL) && (l != r) && (l == rp->msg.first->line)) {
460  *r = '\0';
461  ++l;
462  (void) Strncpy(gRemoteCWD, l, sizeof(gRemoteCWD));
463  *r = '"'; /* Restore, so response prints correctly. */
464  foundcwd = 1;
465  result = kNoErr;
466  }
467  }
468  if (quietMode)
470  NcFTPCdResponseProc(cip, rp);
471  DoneWithResponse(cip, rp);
472  if (foundcwd == 0) {
473  result = FTPGetCWD(cip, gRemoteCWD, sizeof(gRemoteCWD));
474  if (result != kNoErr) {
475  PathCat(gRemoteCWD, sizeof(gRemoteCWD), gScratchCWD, cdCwd);
476  result = kNoErr;
477  }
478  }
479 #else /* USE_CLIENT_SIDE_CALCULATED_CWD */
480  if (quietMode)
482  NcFTPCdResponseProc(cip, rp);
483  DoneWithResponse(cip, rp);
485  PathCat(gRemoteCWD, sizeof(gRemoteCWD), gScratchCWD, cdCwd);
486  result = kNoErr;
487 #endif
488  } else if (result > 0) {
490  cip->errNo = kErrCWDFailed;
491  DoneWithResponse(cip, rp);
492  } else {
493  DoneWithResponse(cip, rp);
494  }
495  }
496  }
497  return (result);
498 } /* nFTPChdirAndGetCWD */
499 
500 
501 
502 
503 int
504 Chdirs(FTPCIPtr cip, const char *const cdCwd)
505 {
506  char *cp, *startcp;
507  int result;
508  int lastSubDir;
509 
510  if (cip == NULL)
511  return (kErrBadParameter);
512  if (strcmp(cip->magic, kLibraryMagic))
513  return (kErrBadMagic);
514 
515  if (cdCwd == NULL) {
517  cip->errNo = kErrInvalidDirParam;
518  return result;
519  }
520 
521  if ((cdCwd[0] == '\0') || (strcmp(cdCwd, ".") == 0)) {
522  result = 0;
523  return (result);
524  }
525 
526  cp = cip->buf;
527  cp[cip->bufSize - 2] = '\0';
528  if ((cdCwd[0] == '.') && (cdCwd[1] == '.') && ((cdCwd[2] == '\0') || IsLocalPathDelim(cdCwd[2]))) {
529  PathCat(cip->buf, cip->bufSize, gRemoteCWD, cdCwd);
530  } else {
531  (void) Strncpy(cip->buf, cdCwd, cip->bufSize);
532  }
533  if (cp[cip->bufSize - 2] != '\0')
534  return (kErrBadParameter);
535 
537  do {
538  startcp = cp;
539  cp = StrFindLocalPathDelim(cp + 0);
540  if (cp != NULL) {
541  *cp++ = '\0';
542  }
543  lastSubDir = (cp == NULL);
544  result = nFTPChdirAndGetCWD(cip, (*startcp != '\0') ? startcp : "/", lastSubDir ? 0 : 1);
545  if (result < 0) {
546  cip->errNo = result;
547  }
548  } while ((!lastSubDir) && (result == 0));
549 
550  return (result);
551 } /* Chdirs */
552 
553 
554 
555 
556 /* Remote change of working directory command. */
557 void
558 ChdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
559 {
560  int result;
561  LineList ll;
562  LinePtr lp;
563 
565 
566  if (argc <= 1) {
567  if (gStartDir[0] != '\0') {
570  if (result != kNoErr) {
571  /* State is incoherent if this happens! */
572  FTPPerror(&gConn, result, kErrCWDFailed, "Could not chdir to", gStartDir);
573  }
574  } else {
575  PrintCmdUsage(cmdp);
576  }
577  } else {
578  InitLineList(&ll);
579  result = FTPRemoteGlob(&gConn, &ll, argv[1], (aip->noglobargv[1] != 0) ? kGlobNo: kGlobYes);
580  if (result < 0) {
582  } else {
583  lp = ll.first;
584  if ((lp != NULL) && (lp->line != NULL)) {
585  if ((strcmp(lp->line, "-") == 0) && (gPrevRemoteCWD[0] != '\0')) {
586  free(lp->line);
587  lp->line = StrDup(gPrevRemoteCWD);
588  if (lp->line == NULL) {
591  } else {
593  result = Chdirs(&gConn, lp->line);
594  }
595  } else {
597  result = Chdirs(&gConn, lp->line);
598  }
599  if (result != kNoErr)
600  FTPPerror(&gConn, result, kErrCWDFailed, "Could not chdir to", lp->line);
601  }
602  }
604  }
605 } /* ChdirCmd */
606 
607 
608 
609 
610 /* Chmod files on the remote host, if it supports it. */
611 void
612 ChmodCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
613 {
614  int i, result;
615 
617  for (i=2; i<argc; i++) {
618  result = FTPChmod(
619  &gConn, argv[i], argv[1],
620  (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes
621  );
622  if (result < 0) {
623  FTPPerror(&gConn, result, kErrChmodFailed, "chmod", argv[i]);
624  /* but continue */
625  }
626  }
627 
628  /* Really should just flush only the modified directories... */
629  FlushLsCache();
630 } /* ChmodCmd */
631 
632 
633 
634 
635 /* Close the current session to a remote FTP server. */
636 void
637 CloseCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
638 {
640  if (gConn.connected == 0)
641  (void) printf("Already closed.\n");
642  else
643  CloseHost();
644 } /* CloseCmd */
645 
646 
647 
648 /* User interface to the program's debug-mode setting. */
649 void
650 DebugCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
651 {
653  if (argc > 1)
654  SetDebug(atoi(argv[1]));
655  else
656  SetDebug(!gDebug);
657 } /* DebugCmd */
658 
659 
660 
661 
662 /* Delete files on the remote host. */
663 void
664 DeleteCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
665 {
666  int result;
667  int i, c;
668  int recursive = kRecursiveNo;
669 
671  GetoptReset();
672  while ((c = Getopt(argc, argv, "rf")) > 0) switch(c) {
673  case 'r':
674  recursive = kRecursiveYes;
675  break;
676  case 'f':
677  /* ignore */
678  break;
679  default:
680  PrintCmdUsage(cmdp);
681  return;
682  }
683 
684  for (i=gOptInd; i<argc; i++) {
685  result = FTPDelete(
686  &gConn, argv[i], recursive,
687  (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes
688  );
689  if (result < 0) {
690  FTPPerror(&gConn, result, kErrDELEFailed, "delete", argv[i]);
691  /* but continue */
692  }
693  }
694 
695  /* Really should just flush only the modified directories... */
696  FlushLsCache();
697 } /* DeleteCmd */
698 
699 
700 
701 
702 /* Command shell echo command. This is mostly useful for testing the command
703  * shell, as a sample command which prints some output.
704  */
705 void
706 EchoCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
707 {
708  int i;
709  int result;
710  int np = 0;
711  LineList ll;
712  LinePtr lp;
713 
715  for (i=1; i<argc; i++) {
716  InitLineList(&ll);
717  result = FTPLocalGlob(&gConn, &ll, argv[i], (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes);
718  if (result < 0) {
719  FTPPerror(&gConn, result, kErrGlobFailed, "local glob", argv[i]);
720  } else {
721  for (lp = ll.first; lp != NULL; lp = lp->next) {
722  if (lp->line != NULL) {
723  if (np > 0)
724  (void) printf(" ");
725  (void) printf("%s", lp->line);
726  np++;
727  }
728  }
729  }
731  }
732  (void) printf("\n");
733 } /* EchoCmd */
734 
735 
736 
737 
738 static int
740  const char *volatile *localpath,
741  volatile longest_int localsize,
742  volatile time_t localmtime,
743  const char *volatile remotepath,
744  volatile longest_int remotesize,
745  volatile time_t remotemtime,
746  volatile longest_int *volatile startPoint)
747 {
748  int zaction = kConfirmResumeProcSaidBestGuess;
749  char tstr[80], ans[32];
750  static char newname[128]; /* arrggh... static. */
751 
753  return (gResumeAnswerAll);
754 
755  if (gAutoResume != 0)
757 
758  tstr[sizeof(tstr) - 1] = '\0';
759  (void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &localmtime));
760  (void) printf(
761 #if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
762  "\nThe local file \"%s\" already exists.\n\tLocal: %12lld bytes, dated %s.\n",
763 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
764  "\nThe local file \"%s\" already exists.\n\tLocal: %12qd bytes, dated %s.\n",
765 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
766  "\nThe local file \"%s\" already exists.\n\tLocal: %12I64d bytes, dated %s.\n",
767 #else
768  "\nThe local file \"%s\" already exists.\n\tLocal: %12ld bytes, dated %s.\n",
769 #endif
770  *localpath,
771  localsize,
772  tstr
773  );
774 
775  if ((remotemtime != kModTimeUnknown) && (remotesize != kSizeUnknown)) {
776  (void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &remotemtime));
777  (void) printf(
778 #if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
779  "\tRemote: %12lld bytes, dated %s.\n",
780 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
781  "\tRemote: %12qd bytes, dated %s.\n",
782 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
783  "\tRemote: %12I64d bytes, dated %s.\n",
784 #else
785  "\tRemote: %12ld bytes, dated %s.\n",
786 #endif
787  remotesize,
788  tstr
789  );
790  if ((remotemtime == localmtime) && (remotesize == localsize)) {
791  (void) printf("\t(Files are identical, skipped)\n\n");
793  }
794  } else if (remotesize != kSizeUnknown) {
795  (void) printf(
796 #if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
797  "\tRemote: %12lld bytes, date unknown.\n",
798 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
799  "\tRemote: %12qd bytes, date unknown.\n",
800 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
801  "\tRemote: %12I64d bytes, date unknown.\n",
802 #else
803  "\tRemote: %12ld bytes, date unknown.\n",
804 #endif
805  remotesize
806  );
807  } else if (remotemtime != kModTimeUnknown) {
808  (void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &remotemtime));
809  (void) printf(
810  "\tRemote: size unknown, dated %s.\n",
811  tstr
812  );
813  }
814 
815  printf("\n");
816  (void) memset(ans, 0, sizeof(ans));
817  for (;;) {
818  (void) printf("\t[O]verwrite?");
819  if ((gConn.hasREST == kCommandAvailable) && (remotesize != kSizeUnknown) && (remotesize > localsize))
820  printf(" [R]esume?");
821  printf(" [A]ppend to? [S]kip? [N]ew Name?\n");
822  (void) printf("\t[O!]verwrite all?");
823  if ((gConn.hasREST == kCommandAvailable) && (remotesize != kSizeUnknown) && (remotesize > localsize))
824  printf(" [R!]esume all?");
825  printf(" [S!]kip all? [C]ancel > ");
826  fflush(stdin);
827  (void) fgets(ans, sizeof(ans) - 1, stdin);
828  switch ((int) ans[0]) {
829  case 'c':
830  case 'C':
831  ans[0] = 'C';
832  ans[1] = '\0';
834  break;
835  case 'o':
836  case 'O':
837  ans[0] = 'O';
839  break;
840  case 'r':
841  case 'R':
842  if ((gConn.hasREST != kCommandAvailable) || (remotesize == kSizeUnknown)) {
843  printf("\tResume is not available on this server.\n\n");
844  ans[0] = '\0';
845  break;
846  } else if (remotesize < localsize) {
847  printf("\tCannot resume when local file is already larger than the remote file.\n\n");
848  ans[0] = '\0';
849  break;
850  } else if (remotesize <= localsize) {
851  printf("\tLocal file is already the same size as the remote file.\n\n");
852  ans[0] = '\0';
853  break;
854  }
855  ans[0] = 'R';
856  *startPoint = localsize;
858  if (OneTimeMessage("auto-resume") != 0) {
859  printf("\n\tNOTE: If you want NcFTP to guess automatically, \"set auto-resume yes\"\n\n");
860  }
861  break;
862  case 's':
863  case 'S':
864  ans[0] = 'S';
865  zaction = kConfirmResumeProcSaidSkip;
866  break;
867  case 'n':
868  case 'N':
869  ans[0] = 'N';
870  ans[1] = '\0';
872  break;
873  case 'a':
874  case 'A':
875  ans[0] = 'A';
876  ans[1] = '\0';
878  break;
879  case 'g':
880  case 'G':
881  ans[0] = 'G';
883  break;
884  default:
885  ans[0] = '\0';
886  }
887  if (ans[0] != '\0')
888  break;
889  }
890 
891  if (ans[0] == 'N') {
892  (void) memset(newname, 0, sizeof(newname));
893  printf("\tSave as: ");
894  fflush(stdin);
895  (void) fgets(newname, sizeof(newname) - 1, stdin);
896  newname[strlen(newname) - 1] = '\0';
897  if (newname[0] == '\0') {
898  /* Nevermind. */
899  printf("Skipped %s.\n", remotepath);
900  zaction = kConfirmResumeProcSaidSkip;
901  } else {
902  *localpath = newname;
903  }
904  }
905 
906  if (ans[1] == '!')
907  gResumeAnswerAll = zaction;
908  return (zaction);
909 } /* NcFTPConfirmResumeDownloadProc */
910 
911 
912 
913 
914 /* Download files from the remote system. */
915 void
916 GetCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
917 {
918  int opt;
919  int renameMode = 0;
920  int recurseFlag = kRecursiveNo;
921  int appendFlag = kAppendNo;
922  int resumeFlag = kResumeYes;
923  int tarflag = kTarYes;
924  const char *dstdir = NULL;
925  int rc;
926  int i;
927  int doGlob;
928  int xtype = gBm.xferType;
929  int nD = 0;
930  int deleteFlag = kDeleteNo;
931  char pattern[256];
932  vsigproc_t osigint;
933  ConfirmResumeDownloadProc confirmProc;
934 
935  confirmProc = NcFTPConfirmResumeDownloadProc;
936  gResumeAnswerAll = kConfirmResumeProcNotUsed; /* Ask at least once each time */
938  GetoptReset();
939  while ((opt = Getopt(argc, argv, "aAzfrRTD")) >= 0) switch (opt) {
940  case 'a':
941  xtype = kTypeAscii;
942  break;
943  case 'A':
944  /* Append to local files, instead of truncating
945  * them first.
946  */
947  appendFlag = kAppendYes;
948  break;
949  case 'f':
950  case 'Z':
951  /* Do not try to resume a download, even if it
952  * appeared that some of the file was transferred
953  * already.
954  */
955  resumeFlag = kResumeNo;
956  confirmProc = NoConfirmResumeDownloadProc;
957  break;
958  case 'z':
959  /* Special flag that lets you specify the
960  * destination file. Normally a "get" will
961  * write the file by the same name as the
962  * remote file's basename.
963  */
964  renameMode = 1;
965  break;
966  case 'r':
967  case 'R':
968  /* If the item is a directory, get the
969  * directory and all its contents.
970  */
971  recurseFlag = kRecursiveYes;
972  break;
973  case 'T':
974  /* If they said "-R", they may want to
975  * turn off TAR mode if they are trying
976  * to resume the whole directory.
977  * The disadvantage to TAR mode is that
978  * it always downloads the whole thing,
979  * which is why there is a flag to
980  * disable this.
981  */
982  tarflag = kTarNo;
983  break;
984  case 'D':
985  /* You can delete the remote file after
986  * you downloaded it successfully by using
987  * the -DD option. It requires two -D's
988  * to minimize the odds of accidentally
989  * using a single -D.
990  */
991  nD++;
992  break;
993  default:
994  PrintCmdUsage(cmdp);
995  return;
996  }
997 
998  if (nD >= 2)
999  deleteFlag = kDeleteYes;
1000 
1001  if (renameMode != 0) {
1002  if (gOptInd > argc - 2) {
1003  PrintCmdUsage(cmdp);
1004  (void) fprintf(stderr, "\nFor get with rename, try \"get -z remote-path-name local-path-name\".\n");
1005  return;
1006  }
1007  osigint = NcSignal(SIGINT, XferCanceller);
1008  rc = FTPGetOneFile3(&gConn, argv[gOptInd], argv[gOptInd + 1], xtype, (-1), resumeFlag, appendFlag, deleteFlag, NoConfirmResumeDownloadProc, 0);
1009  if (rc < 0)
1011  } else {
1012  osigint = NcSignal(SIGINT, XferCanceller);
1013  for (i=gOptInd; i<argc; i++) {
1014  doGlob = (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes;
1015  STRNCPY(pattern, argv[i]);
1017  rc = FTPGetFiles3(&gConn, pattern, dstdir, recurseFlag, doGlob, xtype, resumeFlag, appendFlag, deleteFlag, tarflag, confirmProc, 0);
1018  if (rc < 0)
1020  }
1021  }
1022  (void) NcSignal(SIGINT, osigint);
1023  (void) fflush(stdin);
1024 
1025  if (deleteFlag == kDeleteYes) {
1026  /* Directory is now out of date */
1027  FlushLsCache();
1028  }
1029 } /* GetCmd */
1030 
1031 
1032 
1033 
1034 /* Display some brief help for specified commands, or a list of commands. */
1035 void
1036 HelpCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1037 {
1038  CommandPtr c;
1039  int showall = 0, helpall = 0;
1040  int i, j, k, n;
1041  int nRows, nCols;
1042  int nCmds2Print;
1043  int screenColumns;
1044  int len, widestName;
1045  char *cp, spec[16];
1046  const char *cmdnames[64];
1047 
1049  assert(gNumCommands < (sizeof(cmdnames) / sizeof(char *)));
1050  if (argc == 2) {
1051  showall = (strcmp(argv[1], "showall") == 0);
1052  helpall = (strcmp(argv[1], "helpall") == 0);
1053  }
1054  if (argc == 1 || showall) {
1055  (void) printf("\
1056 Commands may be abbreviated. 'help showall' shows hidden and unsupported \n\
1057 commands. 'help <command>' gives a brief description of <command>.\n\n");
1058 
1059  /* First, see how many commands we will be printing to the screen.
1060  * Unless 'showall' was given, we won't be printing the hidden
1061  * (i.e. not very useful to the end-user) commands.
1062  */
1063  c = gCommands;
1064  nCmds2Print = 0;
1065  for (n = 0; n < (int) gNumCommands; c++, n++)
1066  if ((!iscntrl((int) c->name[0])) && (!(c->flags & kCmdHidden) || showall))
1067  nCmds2Print++;
1068 
1069  (void) memset((char *) cmdnames, 0, sizeof(cmdnames));
1070 
1071  /* Now form the list we'll be printing, and noting what the maximum
1072  * length of a command name was, so we can use that when determining
1073  * how to print in columns.
1074  */
1075  c = gCommands;
1076  i = 0;
1077  widestName = 0;
1078  for (n = 0; n < (int) gNumCommands; c++, n++) {
1079  if ((!iscntrl((int) c->name[0])) && (!(c->flags & kCmdHidden) || showall)) {
1080  cmdnames[i++] = c->name;
1081  len = (int) strlen(c->name);
1082  if (len > widestName)
1083  widestName = len;
1084  }
1085  }
1086 
1087  if ((cp = (char *) getenv("COLUMNS")) == NULL)
1088  screenColumns = 80;
1089  else
1090  screenColumns = atoi(cp);
1091 
1092  /* Leave an extra bit of whitespace for the margins between columns. */
1093  widestName += 2;
1094 
1095  nCols = (screenColumns + 0) / widestName;
1096  nRows = nCmds2Print / nCols;
1097  if ((nCmds2Print % nCols) > 0)
1098  nRows++;
1099 
1100  for (i = 0; i < nRows; i++) {
1101  for (j = 0; j < nCols; j++) {
1102  k = nRows * j + i;
1103  if (k < nCmds2Print) {
1104  (void) sprintf(spec, "%%-%ds",
1105  (j < nCols - 1) ? widestName : widestName - 2
1106  );
1107  (void) printf(spec, cmdnames[k]);
1108  }
1109  }
1110  (void) printf("\n");
1111  }
1112  } else if (helpall) {
1113  /* Really intended for me, so I can debug the help strings. */
1114  for (c = gCommands, n = 0; n < (int) gNumCommands; c++, n++) {
1115  PrintCmdHelp(c);
1116  PrintCmdUsage(c);
1117  }
1118  } else {
1119  /* For each command name specified, print its help stuff. */
1120  for (i=1; i<argc; i++) {
1121  c = GetCommandByName(argv[i], 0);
1122  if (c == kAmbiguousCommand) {
1123  (void) printf("%s: ambiguous command name.\n", argv[i]);
1124  } else if (c == kNoCommand) {
1125  (void) printf("%s: no such command.\n", argv[i]);
1126  } else {
1127  if (i > 1)
1128  (void) printf("\n");
1129  PrintCmdHelp(c);
1130  PrintCmdUsage(c);
1131  }
1132  }
1133  }
1134 } /* HelpCmd */
1135 
1136 
1137 
1138 
1139 /* Displays the list of saved bookmarks, so that the user can then choose
1140  * one by name.
1141  */
1142 static int
1144 {
1145  FILE *bookmarks;
1146  FILE *pager;
1147  int nbm = 0;
1148  Bookmark bm;
1149  char url[128];
1150 #ifdef SIGPIPE
1151  sigproc_t osigpipe;
1152 #endif
1153 
1154  bookmarks = OpenBookmarkFile(NULL);
1155  if (bookmarks == NULL)
1156  return (0);
1157 
1158 #ifdef SIGPIPE
1159  osigpipe = (sigproc_t) NcSignal(SIGPIPE, SIG_IGN);
1160 #endif
1161  pager = OpenPager();
1162 
1163  while (GetNextBookmark(bookmarks, &bm) == 0) {
1164  nbm++;
1165  if (nbm == 1) {
1166  /* header */
1167  (void) fprintf(pager, "--BOOKMARK----------URL--------------------------------------------------------\n");
1168  }
1169  BookmarkToURL(&bm, url, sizeof(url));
1170  (void) fprintf(pager, " %-16s %s\n", bm.bookmarkName, url);
1171  }
1172 
1173  ClosePager(pager);
1174  CloseBookmarkFile(bookmarks);
1175 
1176 #ifdef SIGPIPE
1177  (void) NcSignal(SIGPIPE, osigpipe);
1178 #endif
1179  return (nbm);
1180 } /* PrintHosts */
1181 
1182 
1183 
1184 
1185 
1186 static int
1187 RunBookmarkEditor(char *selectedBmName, size_t dsize)
1188 {
1189 #if defined(WIN32) || defined(_WINDOWS)
1190  char ncftpbookmarks[260];
1191  const char *prog;
1192  int winExecResult;
1193  HANDLE hMailSlot;
1194  char msg[kNcFTPBookmarksMailslotMsgSize];
1195  DWORD dwRead;
1196  BOOL rc;
1197 
1198  if (selectedBmName != NULL)
1199  memset(selectedBmName, 0, dsize);
1200  if (gOurInstallationPath[0] == '\0') {
1201  (void) fprintf(stderr, "Cannot find path to %s. Please re-run Setup.\n", "ncftpbookmarks.exe");
1202  return (-1);
1203  }
1204  prog = ncftpbookmarks;
1205  OurInstallationPath(ncftpbookmarks, sizeof(ncftpbookmarks), "ncftpbookmarks.exe");
1206 
1207 
1208  hMailSlot = CreateMailslot(kNcFTPBookmarksMailslot, kNcFTPBookmarksMailslotMsgSize, MAILSLOT_WAIT_FOREVER, NULL);
1209 
1210  if (hMailSlot == INVALID_HANDLE_VALUE) {
1211  SysPerror("CreateMailslot");
1212  (void) fprintf(stderr, "Could not create communication channel with %s.\n", "ncftpbookmarks.exe");
1213  (void) fprintf(stderr, "%s", "This means if you select a bookmark to connect to that NcFTP\n");
1214  (void) fprintf(stderr, "%s", "will not get the message from %s.\n");
1215  }
1216 
1217  winExecResult = WinExec(prog, SW_SHOWNORMAL);
1218  if (winExecResult <= 31) switch (winExecResult) {
1219  case ERROR_BAD_FORMAT:
1220  fprintf(stderr, "Could not run %s: %s\n", prog, "The .EXE file is invalid");
1221  return (-1);
1222  case ERROR_FILE_NOT_FOUND:
1223  fprintf(stderr, "Could not run %s: %s\n", prog, "The specified file was not found.");
1224  return (-1);
1225  case ERROR_PATH_NOT_FOUND:
1226  fprintf(stderr, "Could not run %s: %s\n", prog, "The specified path was not found.");
1227  return (-1);
1228  default:
1229  fprintf(stderr, "Could not run %s: Unknown error #%d.\n", prog, winExecResult);
1230  return (-1);
1231  }
1232 
1233  if (hMailSlot != INVALID_HANDLE_VALUE) {
1234  fprintf(stdout, "Waiting for %s to exit...\n", "ncftpbookmarks.exe");
1235  ZeroMemory(msg, sizeof(msg));
1236  dwRead = 0;
1237  rc = ReadFile(
1238  hMailSlot,
1239  msg,
1240  sizeof(msg),
1241  &dwRead,
1242  NULL
1243  );
1244 
1245  if (!rc) {
1246  SysPerror("ReadFile");
1247  } else {
1248  msg[sizeof(msg) - 1] = '\0';
1249  Strncpy(selectedBmName, msg, dsize);
1250  Trace(0, "Selected bookmark from editor: [%s]\n", selectedBmName);
1251  }
1252  CloseHandle(hMailSlot);
1253  }
1254  return (0);
1255 
1256 #else
1257 #ifdef BINDIR
1258  char ncftpbookmarks[256];
1259  char *av[8];
1260  int pid;
1261  int status;
1262  char bmSelectionFile[256];
1263  char pidStr[32];
1264  FILE *fp;
1265 
1266  if (selectedBmName != NULL)
1267  memset(selectedBmName, 0, dsize);
1268  STRNCPY(ncftpbookmarks, BINDIR);
1269  STRNCAT(ncftpbookmarks, "/");
1270  STRNCAT(ncftpbookmarks, "ncftpbookmarks");
1271 
1272  STRNCPY(bmSelectionFile, "view");
1273  if ((selectedBmName != NULL) && (gOurDirectoryPath[0] != '\0')) {
1274  sprintf(pidStr, ".%u", (unsigned int) getpid());
1275  OurDirectoryPath(bmSelectionFile, sizeof(bmSelectionFile), kOpenSelectedBookmarkFileName);
1276  STRNCAT(bmSelectionFile, pidStr);
1277  }
1278 
1279  if (access(ncftpbookmarks, X_OK) == 0) {
1280  pid = (int) fork();
1281  if (pid < 0) {
1282  return (-1);
1283  } else if (pid == 0) {
1284  /* child */
1285 
1286  av[0] = (char *) "ncftpbookmarks";
1287  av[1] = bmSelectionFile;
1288  av[2] = NULL;
1289  execv(ncftpbookmarks, av);
1290  exit(1);
1291  } else {
1292  /* parent NcFTP */
1293  for (;;) {
1294 #ifdef HAVE_WAITPID
1295  if ((waitpid(pid, &status, 0) < 0) && (errno != EINTR))
1296  break;
1297 #else
1298  if ((wait(&status) < 0) && (errno != EINTR))
1299  break;
1300 #endif
1301  if (WIFEXITED(status) || WIFSIGNALED(status))
1302  break; /* done */
1303  }
1304 
1305  if (strcmp(bmSelectionFile, "view") != 0) {
1306  fp = fopen(bmSelectionFile, FOPEN_READ_TEXT);
1307  if (fp != NULL) {
1308  (void) FGets(selectedBmName, dsize, fp);
1309  (void) fclose(fp);
1310  (void) unlink(bmSelectionFile);
1311  Trace(0, "Selected bookmark from editor: [%s]\n", selectedBmName);
1312  }
1313  }
1314  return (0);
1315  }
1316  }
1317  return (-1);
1318 #else /* BINDIR */
1319  /* Not installed. */
1320  return (-1);
1321 #endif /* BINDIR */
1322 #endif /* Windows */
1323 } /* RunBookmarkEditor */
1324 
1325 
1326 
1327 /* This just shows the list of saved bookmarks. */
1328 void
1329 HostsCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1330 {
1331  const char *av[3];
1332  char bm[128];
1333 
1335  /* Skip visual mode if "-l". */
1336  if ((argc == 1) && (RunBookmarkEditor(bm, sizeof(bm)) == 0)) {
1337  if (bm[0] != '\0') {
1338  av[0] = "open";
1339  av[1] = bm;
1340  av[2] = NULL;
1341  OpenCmd(2, av, (CommandPtr) 0, (ArgvInfoPtr) 0);
1342  }
1343  return;
1344  }
1345  if (PrintHosts() <= 0) {
1346  (void) printf("You haven't bookmarked any FTP sites.\n");
1347  (void) printf("Before closing a site, you can use the \"bookmark\" command to save the current\nhost and directory for next time.\n");
1348  } else {
1349  (void) printf("\nTo use a bookmark, use the \"open\" command with the name of the bookmark.\n");
1350  }
1351 } /* HostsCmd */
1352 
1353 
1354 
1355 
1356 /* Show active background ncftp (ncftpbatch) jobs. */
1357 void
1358 JobsCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1359 {
1361  Jobs();
1362 } /* JobsCmd */
1363 
1364 
1365 
1366 
1367 /* Do a "ls" on the remote system and display the directory contents to our
1368  * user. This command handles "dir" (ls -l), "ls", and "nlist" (ls -1).
1369  */
1370 void
1371 ListCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1372 {
1373  volatile int i;
1374  int j;
1375  char options[32];
1376  char option[2];
1377  volatile int listmode;
1378  FILE *stream;
1379  volatile int paging;
1380 #if defined(WIN32) || defined(_WINDOWS)
1381 #else
1382  int sj;
1383  vsigproc_t osigpipe, osigint;
1384 #endif
1385 
1387  stream = stdout;
1388  paging = 0;
1389 
1390  if (argv[0][0] == 'd') {
1391  /* dir */
1392  listmode = 'l';
1393  } else if (argv[0][0] == 'n') {
1394  /* nlist */
1395  listmode = '1';
1396  } else if (argv[0][0] == 'p') {
1397  /* pager */
1398  paging = 1;
1399 
1400  if (argv[0][1] == 'd') {
1401  /* dir */
1402  listmode = 'l';
1403  } else if (argv[0][1] == 'n') {
1404  /* nlist */
1405  listmode = '1';
1406  } else {
1407  /* ls */
1408  listmode = 'C';
1409  }
1410  } else {
1411  /* ls */
1412  listmode = 'C';
1413  }
1414  options[0] = '\0';
1415  option[1] = '\0';
1416 
1417  for (i=1; i<argc; i++) {
1418  if (argv[i][0] != '-')
1419  break;
1420  if (argv[i][1] == '-') {
1421  if (argv[i][2] == '\0') {
1422  /* end of options. */
1423  ++i;
1424  break;
1425  } else {
1426  /* GNU-esque long --option? */
1427  PrintCmdUsage(cmdp);
1428  }
1429  } else {
1430  for (j=1; ; j++) {
1431  option[0] = argv[i][j];
1432  if (argv[i][j] == '\0')
1433  break;
1434  switch (argv[i][j]) {
1435  case 'l':
1436  listmode = 'l';
1437  break;
1438  case '1':
1439  listmode = '1';
1440  break;
1441  case 'C':
1442  listmode = 'C';
1443  break;
1444  default:
1445  (void) STRNCAT(options, option);
1446  break;
1447  }
1448  }
1449  }
1450  }
1451 
1452 
1453  if (paging != 0) {
1454  stream = OpenPager();
1455  if (stream == NULL) {
1456  return;
1457  }
1458 
1459 #if defined(WIN32) || defined(_WINDOWS)
1460 #elif defined(HAVE_SIGSETJMP)
1461  osigpipe = osigint = (sigproc_t) 0;
1462  sj = sigsetjmp(gCancelJmp, 1);
1463 #else /* HAVE_SIGSETJMP */
1464  osigpipe = osigint = (sigproc_t) 0;
1465  sj = setjmp(gCancelJmp);
1466 #endif /* HAVE_SIGSETJMP */
1467 
1468 #if defined(WIN32) || defined(_WINDOWS)
1469 #else
1470  if (sj != 0) {
1471  /* Caught a signal. */
1473  ClosePager(stream);
1474  (void) NcSignal(SIGPIPE, osigpipe);
1475  (void) NcSignal(SIGINT, osigint);
1476  Trace(0, "Canceled because of signal %d.\n", gGotSig);
1477  (void) fprintf(stderr, "Canceled.\n");
1478  gMayCancelJmp = 0;
1479  return;
1480  } else {
1481  osigpipe = NcSignal(SIGPIPE, Cancel);
1482  osigint = NcSignal(SIGINT, Cancel);
1483  gMayCancelJmp = 1;
1484  }
1485 #endif
1486  }
1487 
1488  if (argv[i] == NULL) {
1489  /* No directory specified, use cwd. */
1490  Ls(NULL, listmode, options, stream);
1491  } else {
1492  /* List each item. */
1493  for ( ; i<argc; i++) {
1494  Ls(argv[i], listmode, options, stream);
1495  }
1496  }
1497 
1498  if (paging != 0) {
1499  ClosePager(stream);
1500 #if defined(WIN32) || defined(_WINDOWS)
1501 #else
1502  (void) NcSignal(SIGPIPE, osigpipe);
1503  (void) NcSignal(SIGINT, osigint);
1504 #endif
1505  }
1506  gMayCancelJmp = 0;
1507 } /* ListCmd */
1508 
1509 
1510 
1511 
1512 /* Does a change of working directory on the local host. */
1513 void
1514 LocalChdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1515 {
1516  int result;
1517  const char *dir;
1518  char buf[512];
1519 
1521  dir = ((argc < 2) ? gHome : argv[1]);
1522  if ((dir[0] == '-') && (dir[1] == '\0')) {
1523  if (gPrevLocalCWD[0] == '\0') {
1524  (void) fprintf(stderr, "No previous local working directory to switch to.\n");
1525  return;
1526  } else {
1527  dir = gPrevLocalCWD;
1528  }
1529  } else if (dir[0] == '~') {
1530  if (dir[1] == '\0') {
1531  dir = gHome;
1532  } else if (dir[1] == '/') {
1533  (void) STRNCPY(buf, gHome);
1534  dir = STRNCAT(buf, dir + 1);
1535  }
1536  }
1537  result = chdir(dir);
1538  if (result < 0) {
1539  perror(dir);
1540  } else {
1542  (void) FTPGetLocalCWD(gLocalCWD, sizeof(gLocalCWD));
1543 
1544  }
1545 } /* LocalChdirCmd */
1546 
1547 
1548 
1549 
1550 /* Does directory listing on the local host. */
1551 void
1552 LocalListCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1553 {
1554 #if defined(WIN32) || defined(_WINDOWS)
1555  volatile int i;
1556  int j;
1557  char options[32];
1558  char option[2];
1559  volatile int listmode;
1560  FILE *stream;
1561  volatile int paging;
1562 
1563 
1565  stream = stdout;
1566  paging = 0;
1567 
1568  if (argv[0][1] == 'd') {
1569  /* dir */
1570  listmode = 'l';
1571  } else if (argv[0][1] == 'n') {
1572  /* nlist */
1573  listmode = '1';
1574  } else {
1575  /* ls */
1576  listmode = 'C';
1577  }
1578  options[0] = '\0';
1579  option[1] = '\0';
1580 
1581  for (i=1; i<argc; i++) {
1582  if (argv[i][0] != '-')
1583  break;
1584  if (argv[i][1] == '-') {
1585  if (argv[i][2] == '\0') {
1586  /* end of options. */
1587  ++i;
1588  break;
1589  } else {
1590  /* GNU-esque long --option? */
1591  PrintCmdUsage(cmdp);
1592  }
1593  } else {
1594  for (j=1; ; j++) {
1595  option[0] = argv[i][j];
1596  if (argv[i][j] == '\0')
1597  break;
1598  switch (argv[i][j]) {
1599  case 'l':
1600  listmode = 'l';
1601  break;
1602  case '1':
1603  listmode = '1';
1604  break;
1605  case 'C':
1606  listmode = 'C';
1607  break;
1608  default:
1609  (void) STRNCAT(options, option);
1610  break;
1611  }
1612  }
1613  }
1614  }
1615 
1616 
1617  if (argv[i] == NULL) {
1618  /* No directory specified, use cwd. */
1619  LLs(NULL, listmode, options, stream);
1620  } else {
1621  /* List each item. */
1622  for ( ; i<argc; i++) {
1623  LLs(argv[i], listmode, options, stream);
1624  }
1625  }
1626 
1627 #else
1628  FILE *volatile outfp;
1629  FILE *volatile infp;
1630  int i;
1631  int sj;
1632  int dashopts;
1633  char incmd[256];
1634  char line[256];
1635  vsigproc_t osigpipe, osigint;
1636 
1638  (void) fflush(stdin);
1639  outfp = OpenPager();
1640 
1641  (void) STRNCPY(incmd, "/bin/ls");
1642  for (i=1, dashopts=0; i<argc; i++) {
1643  (void) STRNCAT(incmd, " ");
1644  if (argv[i][0] == '-')
1645  dashopts++;
1646  (void) STRNCAT(incmd, argv[i]);
1647  }
1648 
1649  if (dashopts == 0) {
1650  (void) STRNCPY(incmd, "/bin/ls -CF");
1651  for (i=1; i<argc; i++) {
1652  (void) STRNCAT(incmd, " ");
1653  (void) STRNCAT(incmd, argv[i]);
1654  }
1655  }
1656 
1657  infp = popen(incmd, "r");
1658  if (infp == NULL) {
1659  ClosePager(outfp);
1660  return;
1661  }
1662 
1663 
1664 #ifdef HAVE_SIGSETJMP
1665  sj = sigsetjmp(gCancelJmp, 1);
1666 #else /* HAVE_SIGSETJMP */
1667  sj = setjmp(gCancelJmp);
1668 #endif /* HAVE_SIGSETJMP */
1669 
1670  if (sj != 0) {
1671  /* Caught a signal. */
1673  ClosePager(outfp);
1674  if (infp != NULL)
1675  (void) pclose(infp);
1676  (void) NcSignal(SIGPIPE, osigpipe);
1677  (void) NcSignal(SIGINT, osigint);
1678  (void) fprintf(stderr, "Canceled.\n");
1679  Trace(0, "Canceled because of signal %d.\n", gGotSig);
1680  gMayCancelJmp = 0;
1681  return;
1682  } else {
1683  osigpipe = NcSignal(SIGPIPE, Cancel);
1684  osigint = NcSignal(SIGINT, Cancel);
1685  gMayCancelJmp = 1;
1686  }
1687 
1688  while (fgets(line, sizeof(line) - 1, infp) != NULL)
1689  (void) fputs(line, outfp);
1690  (void) fflush(outfp);
1691 
1692  (void) pclose(infp);
1693  infp = NULL;
1694  ClosePager(outfp);
1695  outfp = NULL;
1696 
1697  (void) NcSignal(SIGPIPE, osigpipe);
1698  (void) NcSignal(SIGINT, osigint);
1699  gMayCancelJmp = 0;
1700 #endif
1701 } /* LocalListCmd */
1702 
1703 
1704 
1705 
1706 /* static void
1707 Sys(const int argc, const char **const argv, const ArgvInfoPtr aip, const char *syscmd, int noDQuote)
1708 {
1709  char cmd[256];
1710  int i;
1711 
1712  (void) STRNCPY(cmd, syscmd);
1713  for (i = 1; i < argc; i++) {
1714  if (aip->noglobargv[i] != 0) {
1715  (void) STRNCAT(cmd, " '");
1716  (void) STRNCAT(cmd, argv[i]);
1717  (void) STRNCAT(cmd, "'");
1718  } else if (noDQuote != 0) {
1719  (void) STRNCAT(cmd, " ");
1720  (void) STRNCAT(cmd, argv[i]);
1721  } else {
1722  (void) STRNCAT(cmd, " \"");
1723  (void) STRNCAT(cmd, argv[i]);
1724  (void) STRNCAT(cmd, "\" ");
1725  }
1726  }
1727 #if defined(WIN32) || defined(_WINDOWS)
1728  fprintf(stderr, "Cannot run command: %s\n", cmd);
1729 #else
1730  Trace(0, "Sys: %s\n", cmd);
1731  (void) system(cmd);
1732 #endif
1733 }*/
1734 
1735 
1736 
1737 
1738 #if defined(WIN32) || defined(_WINDOWS)
1739 #else
1740 void
1741 LocalChmodCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1742 {
1744  Sys(argc, argv, aip, "/bin/chmod", 1);
1745 } /* LocalChmodCmd */
1746 #endif
1747 
1748 
1749 
1750 void
1751 LocalMkdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1752 {
1753 #if defined(WIN32) || defined(_WINDOWS)
1754  const char *arg;
1755  int i;
1756 
1757  for (i = 1; i < argc; i++) {
1758  arg = argv[i];
1759  if (MkDirs(arg, 00755) < 0) {
1760  perror(arg);
1761  }
1762  }
1763 #else
1765  Sys(argc, argv, aip, "/bin/mkdir", 0);
1766 #endif
1767 } /* LocalMkdirCmd */
1768 
1769 
1770 
1771 
1772 #if defined(WIN32) || defined(_WINDOWS)
1773 #else
1774 void
1775 LocalPageCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1776 {
1778  Sys(argc, argv, aip, gPager, 0);
1779 } /* LocalPageCmd */
1780 #endif
1781 
1782 
1783 
1784 
1785 void
1786 LocalRenameCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1787 {
1788 #if defined(WIN32) || defined(_WINDOWS)
1789  if (rename(argv[1], argv[2]) < 0) {
1790  perror("rename");
1791  }
1792 #else
1794  Sys(argc, argv, aip, "/bin/mv", 1);
1795 #endif
1796 } /* LocalRenameCmd */
1797 
1798 
1799 
1800 
1801 void
1802 LocalRmCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1803 {
1804 #if defined(WIN32) || defined(_WINDOWS)
1805  int i;
1806  int result;
1807  LineList ll;
1808  LinePtr lp;
1809 
1811  for (i=1; i<argc; i++) {
1812  InitLineList(&ll);
1813  result = FTPLocalGlob(&gConn, &ll, argv[i], (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes);
1814  if (result < 0) {
1815  FTPPerror(&gConn, result, kErrGlobFailed, "local glob", argv[i]);
1816  } else {
1817  for (lp = ll.first; lp != NULL; lp = lp->next) {
1818  if (lp->line != NULL) {
1819  if (remove(lp->line) < 0)
1820  perror(lp->line);
1821  }
1822  }
1823  }
1825  }
1826 #else
1828  Sys(argc, argv, aip, "/bin/rm", 1);
1829 #endif
1830 } /* LocalRmCmd */
1831 
1832 
1833 
1834 
1835 void
1836 LocalRmdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1837 {
1838 #if defined(WIN32) || defined(_WINDOWS)
1839  int i;
1840  int result;
1841  LineList ll;
1842  LinePtr lp;
1843 
1845  for (i=1; i<argc; i++) {
1846  InitLineList(&ll);
1847  result = FTPLocalGlob(&gConn, &ll, argv[i], (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes);
1848  if (result < 0) {
1849  FTPPerror(&gConn, result, kErrGlobFailed, "local glob", argv[i]);
1850  } else {
1851  for (lp = ll.first; lp != NULL; lp = lp->next) {
1852  if (lp->line != NULL) {
1853  if (rmdir(lp->line) < 0)
1854  perror(lp->line);
1855  }
1856  }
1857  }
1859  }
1860 #else
1862  Sys(argc, argv, aip, "/bin/rmdir", 1);
1863 #endif
1864 } /* LocalRmdirCmd */
1865 
1866 
1867 
1868 
1869 /* Displays the current local working directory. */
1870 void
1871 LocalPwdCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1872 {
1874  if (FTPGetLocalCWD(gLocalCWD, sizeof(gLocalCWD)) != NULL) {
1875  Trace(-1, "%s\n", gLocalCWD);
1876  }
1877 } /* LocalPwdCmd */
1878 
1879 
1880 
1881 
1882 /* This is a simple interface to name service. I prefer using this instead
1883  * of nslookup.
1884  */
1885 void
1886 LookupCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1887 {
1888  int i, j;
1889  struct hostent *hp;
1890  const char *host;
1891  char **cpp;
1892  struct in_addr ip_address;
1893  int shortMode, opt;
1894  char ipStr[16];
1895 
1897  shortMode = 1;
1898 
1899  GetoptReset();
1900  while ((opt = Getopt(argc, argv, "v")) >= 0) {
1901  if (opt == 'v')
1902  shortMode = 0;
1903  else {
1904  PrintCmdUsage(cmdp);
1905  return;
1906  }
1907  }
1908 
1909  for (i=gOptInd; i<argc; i++) {
1910  hp = GetHostEntry((host = argv[i]), &ip_address);
1911  if ((i > gOptInd) && (shortMode == 0))
1912  Trace(-1, "\n");
1913  if (hp == NULL) {
1914  Trace(-1, "Unable to get information about site %s.\n", host);
1915  } else if (shortMode) {
1916  MyInetAddr(ipStr, sizeof(ipStr), hp->h_addr_list, 0);
1917  Trace(-1, "%-40s %s\n", hp->h_name, ipStr);
1918  } else {
1919  Trace(-1, "%s:\n", host);
1920  Trace(-1, " Name: %s\n", hp->h_name);
1921  for (cpp = hp->h_aliases; *cpp != NULL; cpp++)
1922  Trace(-1, " Alias: %s\n", *cpp);
1923  for (j = 0, cpp = hp->h_addr_list; *cpp != NULL; cpp++, ++j) {
1924  MyInetAddr(ipStr, sizeof(ipStr), hp->h_addr_list, j);
1925  Trace(-1, " Address: %s\n", ipStr);
1926  }
1927  }
1928  }
1929 } /* LookupCmd */
1930 
1931 
1932 
1933 /* Directory listing in a machine-readable format;
1934  * Mostly for debugging, since NcFTP uses MLSD automatically when it needs to.
1935  */
1936 void
1937 MlsCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
1938 {
1939  int i;
1940  int opt;
1941  LinePtr linePtr, nextLinePtr;
1942  int result;
1943  LineList dirContents;
1944  int mlsd = 1, x;
1945  const char *item;
1946 
1948  GetoptReset();
1949  while ((opt = Getopt(argc, argv, "dt")) >= 0) {
1950  if ((opt == 'd') || (opt == 't')) {
1951  /* Use MLST instead of MLSD,
1952  * which is similar to using "ls -d" instead of "ls".
1953  */
1954  mlsd = 0;
1955  } else {
1956  PrintCmdUsage(cmdp);
1957  return;
1958  }
1959  }
1960 
1961  i = gOptInd;
1962  if (i == argc) {
1963  /* No args, do current directory. */
1964  x = 1;
1965  item = "";
1966  if ((result = FTPListToMemory2(&gConn, item, &dirContents, (mlsd == 0) ? "-d" : "", 1, &x)) < 0) {
1967  if (mlsd != 0) {
1968  FTPPerror(&gConn, result, 0, "Could not MLSD", item);
1969  } else {
1970  FTPPerror(&gConn, result, 0, "Could not MLST", item);
1971  }
1972  } else {
1973  for (linePtr = dirContents.first;
1974  linePtr != NULL;
1975  linePtr = nextLinePtr)
1976  {
1977  nextLinePtr = linePtr->next;
1978  (void) fprintf(stdout, "%s\n", linePtr->line);
1979  Trace(0, "%s\n", linePtr->line);
1980  }
1981  }
1982  }
1983 
1984  for ( ; i<argc; i++) {
1985  x = 1;
1986  item = argv[i];
1987  if ((result = FTPListToMemory2(&gConn, item, &dirContents, (mlsd == 0) ? "-d" : "", 1, &x)) < 0) {
1988  if (mlsd != 0) {
1989  FTPPerror(&gConn, result, 0, "Could not MLSD", item);
1990  } else {
1991  FTPPerror(&gConn, result, 0, "Could not MLST", item);
1992  }
1993  } else {
1994  for (linePtr = dirContents.first;
1995  linePtr != NULL;
1996  linePtr = nextLinePtr)
1997  {
1998  nextLinePtr = linePtr->next;
1999  (void) fprintf(stdout, "%s\n", linePtr->line);
2000  Trace(0, "%s\n", linePtr->line);
2001  }
2002  }
2003  }
2004 } /* MlsCmd */
2005 
2006 
2007 
2008 
2009 /* Create directories on the remote system. */
2010 void
2011 MkdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2012 {
2013  int i;
2014  int opt;
2015  int result;
2016  int recurseFlag = kRecursiveNo;
2017 
2019  GetoptReset();
2020  while ((opt = Getopt(argc, argv, "p")) >= 0) {
2021  if (opt == 'p') {
2022  /* Try creating intermediate directories if they
2023  * don't exist.
2024  *
2025  * For example if only /pub/stuff existed, and you
2026  * do a "mkdir -p /pub/stuff/a/b/c", the "a" and "b"
2027  * directories would also be created.
2028  */
2029  recurseFlag = kRecursiveYes;
2030  } else {
2031  PrintCmdUsage(cmdp);
2032  return;
2033  }
2034  }
2035 
2036  for (i=gOptInd; i<argc; i++) {
2037  result = FTPMkdir(&gConn, argv[i], recurseFlag);
2038  if (result < 0)
2039  FTPPerror(&gConn, result, kErrMKDFailed, "Could not mkdir", argv[i]);
2040  }
2041 
2042  /* Really should just flush only the modified directories... */
2043  FlushLsCache();
2044 } /* MkdirCmd */
2045 
2046 
2047 
2048 /*VARARGS*/
2049 static void
2050 OpenMsg(const char *const fmt, ...)
2051 {
2052  va_list ap;
2053  char buf[512];
2054  size_t len, padlim;
2055 
2056  padlim = (size_t) gScreenColumns;
2057  if ((size_t) gScreenColumns > (sizeof(buf) - 1))
2058  padlim = sizeof(buf) - 1;
2059 
2060  va_start(ap, fmt);
2061 #ifdef HAVE_VSNPRINTF
2062  len = (size_t) vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
2063  va_end(ap);
2064  buf[sizeof(buf) - 1] = '\0';
2065 #else
2066  (void) vsprintf(buf, fmt, ap);
2067  va_end(ap);
2068  len = strlen(buf);
2069 #endif
2070  buf[len] = '\0';
2071  Trace(9, "%s\n", buf);
2072  for (; len < padlim; len++)
2073  buf[len] = ' ';
2074  buf[len] = '\0';
2075 
2076 #if 0
2077  (void) fprintf(stdout, "\r%s", buf);
2078 #else
2079  (void) fprintf(stdout, "%s\r", buf);
2080 #endif
2081  (void) fflush(stdout);
2082 } /* OpenMsg */
2083 
2084 
2085 
2086 
2087 static void
2089 {
2090  gUnusedArg = (cipUNUSED != NULL);
2091  if ((rp->printMode & kResponseNoPrint) != 0)
2092  return;
2093 #if 0
2094  if (rp->code == 331) /* Skip: "331 User name okay, need password." */
2095  return;
2096 #else
2097  /* This is only used to print errors. */
2098  if (rp->code < 400)
2099  return;
2100 #endif
2101  PrintResp(&rp->msg);
2102 } /* NcFTPOpenPrintResponseProc */
2103 
2104 
2105 
2106 static void
2108 {
2109  gUnusedArg = (cipUNUSED != NULL);
2110  (void) printf("\n");
2111  PrintResp(&rp->msg);
2112  OpenMsg("Logging in...");
2113 } /* NcFTPOnConnectMessageProc */
2114 
2115 
2116 
2117 static void
2119 {
2120  gUnusedArg = (cipUNUSED != NULL);
2121  (void) printf("\n");
2122  PrintResp(&rp->msg);
2123  OpenMsg("Logging in...");
2124 } /* NcFTPOnLoginMessageProc */
2125 
2126 
2127 
2128 
2129 static void
2130 NcFTPRedialStatusProc(const FTPCIPtr cipUNUSED, int mode, int val)
2131 {
2132  gUnusedArg = (cipUNUSED != NULL);
2133  if (mode == kRedialStatusDialing) {
2134  if (val > 0) {
2135  OpenMsg("Redialing (try %d)...", val);
2136  sleep(1); /* Give time for message to stay */
2137  }
2138  } else if (mode == kRedialStatusSleeping) {
2139  OpenMsg("Sleeping %d seconds...", val);
2140  }
2141 } /* NcFTPRedialStatusProc */
2142 
2143 
2144 
2145 
2146 static void
2147 NcFTPGetPassphraseProc(const FTPCIPtr cip, LineListPtr pwPrompt, char *pass, size_t dsize)
2148 {
2149  LinePtr lp;
2150 
2151  (void) printf("\nPassword requested by %s for user \"%s\".\n\n",
2152  cip->host,
2153  cip->user
2154  );
2155 
2156  for (lp = pwPrompt->first; lp != NULL; lp = lp->next) {
2157  (void) printf(" %s\n", lp->line);
2158  }
2159  (void) printf("\n");
2160  (void) gl_getpass("Password: ", pass, (int) dsize);
2161 } /* NcFTPGetPassphraseProc */
2162 
2163 
2164 
2165 
2166 /* Attempts to establish a new FTP connection to a remote host. */
2167 int
2168 DoOpen(void)
2169 {
2170  int result;
2171  char ipstr[128];
2172  char ohost[128];
2173 #ifdef SIGALRM
2174  sigproc_t osigalrm;
2175 #endif
2176  char prompt[256];
2177 
2179  (void) STRNCPY(ohost, gConn.host);
2180  OpenMsg("Resolving %s...", ohost);
2181  if ((gLoadedBm != 0) && (gBm.lastIP[0] != '\0')) {
2182  result = GetHostByName(ipstr, sizeof(ipstr), ohost, 3);
2183  if (result < 0) {
2184  (void) STRNCPY(ipstr, gBm.lastIP);
2185  result = 0;
2186  } else {
2187  result = GetHostByName(ipstr, sizeof(ipstr), ohost, 7);
2188  }
2189  } else {
2190  result = GetHostByName(ipstr, sizeof(ipstr), ohost, 10);
2191  }
2192  if (result < 0) {
2193  (void) printf("\n");
2194  (void) printf("Unknown host \"%s\".\n", ohost);
2195  return (-1);
2196  }
2197  (void) STRNCPY(gConn.host, ipstr);
2198  OpenMsg("Connecting to %s...", ipstr);
2199  } else {
2200  OpenMsg("Connecting to %s via %s...", gConn.host, gConn.firewallHost);
2201  Trace(0, "Fw: %s Type: %d User: %s Pass: %s Port: %u\n",
2205  (gConn.firewallPass[0] == '\0') ? "(none)" : "********",
2207  );
2208  Trace(0, "FwExceptions: %s\n", gFirewallExceptionList);
2209  if (strchr(gLib.ourHostName, '.') == NULL) {
2210  Trace(0, "NOTE: Your domain name could not be detected.\n");
2212  Trace(0, " Make sure you manually add your domain name to firewall-exception-list.\n");
2213  }
2214  }
2215  }
2216 
2217  if (gConn.firewallPass[0] == '\0') {
2218  switch (gConn.firewallType) {
2219  case kFirewallNotInUse:
2220  break;
2221  case kFirewallUserAtSite:
2222  break;
2224  case kFirewallSiteSite:
2225  case kFirewallOpenSite:
2229  (void) printf("\n");
2230  (void) STRNCPY(prompt, "Password for firewall user \"");
2231  (void) STRNCAT(prompt, gConn.firewallUser);
2232  (void) STRNCAT(prompt, "\" at ");
2233  (void) STRNCAT(prompt, gConn.firewallHost);
2234  (void) STRNCAT(prompt, ": ");
2235  (void) gl_getpass(prompt, gConn.firewallPass, sizeof(gConn.firewallPass));
2236  break;
2237  }
2238  }
2239 
2240  if ((gConn.user[0] != '\0') && (strcmp(gConn.user, "anonymous") != 0) && (strcmp(gConn.user, "ftp") != 0)) {
2242  }
2243 
2244  /* Register our callbacks. */
2249 
2250 #ifdef SIGALRM
2251  osigalrm = NcSignal(SIGALRM, (FTPSigProc) SIG_IGN);
2252  result = FTPOpenHost(&gConn);
2253  (void) NcSignal(SIGALRM, osigalrm);
2254 #else
2255  result = FTPOpenHost(&gConn);
2256 #endif
2257 
2259  (void) STRNCPY(gConn.host, ohost); /* Put it back. */
2260  if (result >= 0) {
2261  (void) time(&gBm.lastCall);
2262  LogOpen(gConn.host);
2263  OpenMsg("Logged in to %s.", gConn.host);
2264  (void) printf("\n");
2265 
2266  /* Remove callback. */
2268 
2269  /* Need to note what our "root" was before we change it. */
2271  (void) STRNCPY(gRemoteCWD, "/"); /* Guess! */
2272  } else {
2274  }
2276 
2277  /* If the bookmark specified a remote directory, change to it now. */
2278  if ((gLoadedBm != 0) && (gBm.dir[0] != '\0')) {
2279  result = Chdirs(&gConn, gBm.dir);
2280  if (result < 0) {
2281  FTPPerror(&gConn, result, kErrCWDFailed, "Could not chdir to previous directory", gBm.dir);
2282  }
2283  Trace(-1, "Current remote directory is %s.\n", gRemoteCWD);
2284  }
2285 
2286  /* If the bookmark specified a local directory, change to it now. */
2287  if ((gLoadedBm != 0) && (gBm.ldir[0] != '\0')) {
2288  (void) chdir(gBm.ldir);
2290  if (FTPGetLocalCWD(gLocalCWD, sizeof(gLocalCWD)) != NULL) {
2291  Trace(-1, "Current local directory is %s.\n", gLocalCWD);
2292  }
2293  }
2294 
2295  /* Identify the FTP client type to the server. Most don't understand this yet. */
2297  (void) FTPCmd(&gConn, "CLNT NcFTP %.5s %s", gVersion + 11, gOS);
2298  return (0);
2299  } else {
2300  FTPPerror(&gConn, result, 0, "Could not open host", gConn.host);
2301  }
2302 
2303  /* Remove callback. */
2305  (void) printf("\n");
2306  return (-1);
2307 } /* Open */
2308 
2309 
2310 
2311 
2312 /* Chooses a new remote system to connect to, and attempts to establish
2313  * a new FTP connection. This function is in charge of collecting the
2314  * information needed to do the open, and then doing it.
2315  */
2316 void
2317 OpenCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2318 {
2319  int c;
2320  int opts = 0;
2321  int uOptInd = 0;
2322  int n;
2323  int rc;
2324  char url[256];
2325  char urlfile[128];
2326  int directoryURL = 0;
2327  LineList cdlist;
2328  LinePtr lp;
2329  char prompt[256];
2330 
2332  FlushLsCache();
2333  CloseHost();
2334  gLoadedBm = 0;
2336 
2337  /* Need to find the host argument first. */
2338  GetoptReset();
2339  while ((c = Getopt(argc, argv, "aP:u:p:J:rd:g:")) > 0) switch(c) {
2340  case 'u':
2341  uOptInd = gOptInd + 1;
2342  opts++;
2343  break;
2344  default:
2345  opts++;
2346  }
2347  if (gOptInd < argc) {
2349  (void) STRNCPY(url, argv[gOptInd]);
2350  } else if (uOptInd > argc) {
2351  /* Special hack for v2.4.2 compatibility */
2352  (void) STRNCPY(gConn.host, argv[argc - 1]);
2353  (void) STRNCPY(url, argv[argc - 1]);
2354  } else {
2355  /* No host arg */
2356  if (opts > 0) {
2357  PrintCmdUsage(cmdp);
2358  } else if (RunBookmarkEditor(gConn.host, sizeof(gConn.host)) == 0) {
2359  if (gConn.host[0] != '\0') {
2360  gLoadedBm = 1;
2361  /* okay, now fall through */
2362  } else {
2363  return;
2364  }
2365  } else if (PrintHosts() <= 0) {
2366  (void) printf("You haven't bookmarked any FTP sites.\n");
2367  (void) printf("Before closing a site, you can use the \"bookmark\" command to save the current\nhost and directory for next time.\n");
2368  return;
2369  } else {
2370  (void) printf("\nTo use a bookmark, use the \"open\" command with the name of the bookmark.\n");
2371  return;
2372  }
2373  }
2374 
2375  InitLineList(&cdlist);
2376 
2377  if (GetBookmark(gConn.host, &gBm) >= 0) {
2378  gLoadedBm = 1;
2379  (void) STRNCPY(gConn.host, gBm.name);
2380  (void) STRNCPY(gConn.user, gBm.user);
2381  (void) STRNCPY(gConn.pass, gBm.pass);
2382  (void) STRNCPY(gConn.acct, gBm.acct);
2386  gConn.port = gBm.port;
2387 
2388  /* Note: Version 3 only goes off of the
2389  * global "gDataPortMode" setting instead of
2390  * setting the dataPortMode on a per-site
2391  * basis.
2392  */
2394  } else {
2396 
2397  memcpy(&gTmpURLConn, &gConn, sizeof(gTmpURLConn));
2398  rc = DecodeDirectoryURL(&gTmpURLConn, url, &cdlist, urlfile, sizeof(urlfile));
2399  if (rc == kMalformedURL) {
2400  (void) fprintf(stdout, "Malformed URL: %s\n", url);
2401  DisposeLineListContents(&cdlist);
2402  return;
2403  } else if (rc == kNotURL) {
2404  directoryURL = 0;
2405  } else {
2406  /* It was a URL. */
2407  if (urlfile[0] != '\0') {
2408  /* It was obviously not a directory */
2409  (void) fprintf(stdout, "Use ncftpget or ncftpput to handle file URLs.\n");
2410  DisposeLineListContents(&cdlist);
2411  return;
2412  }
2413  memcpy(&gConn, &gTmpURLConn, sizeof(gConn));
2414  directoryURL = 1;
2415  }
2416  }
2417 
2424  }
2425 
2426  GetoptReset();
2427  while ((c = Getopt(argc, argv, "aP:u:p:J:j:rd:g:")) > 0) switch(c) {
2428  case 'J':
2429  case 'j':
2431  break;
2432  case 'a':
2433  (void) STRNCPY(gConn.user, "anonymous");
2434  (void) STRNCPY(gConn.pass, "");
2435  (void) STRNCPY(gConn.acct, "");
2436  break;
2437  case 'P':
2438  gConn.port = atoi(gOptArg);
2439  break;
2440  case 'u':
2441  if (uOptInd <= argc)
2443  break;
2444  case 'p':
2445  (void) STRNCPY(gConn.pass, gOptArg); /* Don't recommend doing this! */
2446  break;
2447  case 'r':
2448  /* redial is on by default */
2449  break;
2450  case 'g':
2451  n = atoi(gOptArg);
2452  gConn.maxDials = n;
2453  break;
2454  case 'd':
2455  n = atoi(gOptArg);
2456  if (n >= 10)
2457  gConn.redialDelay = n;
2458  break;
2459  default:
2460  PrintCmdUsage(cmdp);
2461  DisposeLineListContents(&cdlist);
2462  return;
2463  }
2464 
2465  if (uOptInd > argc) {
2466  (void) STRNCPY(prompt, "Username at ");
2467  (void) STRNCAT(prompt, gConn.host);
2468  (void) STRNCAT(prompt, ": ");
2469  (void) gl_getpass(prompt, gConn.user, sizeof(gConn.user));
2470  }
2471 
2472  rc = DoOpen();
2473  if ((rc >= 0) && (directoryURL != 0)) {
2474  for (lp = cdlist.first; lp != NULL; lp = lp->next) {
2475  rc = FTPChdir(&gConn, lp->line);
2476  if (rc != kNoErr) {
2477  FTPPerror(&gConn, rc, kErrCWDFailed, "Could not chdir to", lp->line);
2478  break;
2479  }
2480  }
2481  rc = FTPGetCWD(&gConn, gRemoteCWD, sizeof(gRemoteCWD));
2482  if (rc != kNoErr) {
2484  } else {
2485  (void) printf("Current remote directory is %s.\n", gRemoteCWD);
2486  }
2487  }
2488  DisposeLineListContents(&cdlist);
2489 } /* OpenCmd */
2490 
2491 
2492 
2493 
2494 /* View a remote file through the users $PAGER. */
2495 void
2496 PageCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2497 {
2498  int result;
2499  int i;
2500  FILE *volatile stream;
2501 #if defined(WIN32) || defined(_WINDOWS)
2502 #else
2503  int sj;
2504  vsigproc_t osigpipe, osigint;
2505 #endif
2506 
2508  stream = OpenPager();
2509  if (stream == NULL) {
2510  return;
2511  }
2512 
2513 #if defined(WIN32) || defined(_WINDOWS)
2514 #else
2515 
2516 #ifdef HAVE_SIGSETJMP
2517  osigpipe = osigint = (sigproc_t) 0;
2518  sj = sigsetjmp(gCancelJmp, 1);
2519 #else /* HAVE_SIGSETJMP */
2520  osigpipe = osigint = (sigproc_t) 0;
2521  sj = setjmp(gCancelJmp);
2522 #endif /* HAVE_SIGSETJMP */
2523 
2524  if (sj != 0) {
2525  /* Caught a signal. */
2527  ClosePager(stream);
2528  (void) NcSignal(SIGPIPE, osigpipe);
2529  (void) NcSignal(SIGINT, osigint);
2530  (void) fprintf(stderr, "Canceled.\n");
2531  Trace(0, "Canceled because of signal %d.\n", gGotSig);
2532  gMayCancelJmp = 0;
2533  return;
2534  } else {
2535  osigpipe = NcSignal(SIGPIPE, Cancel);
2536  osigint = NcSignal(SIGINT, Cancel);
2537  gMayCancelJmp = 1;
2538  }
2539 
2540 #endif
2541 
2542  for (i=1; i<argc; i++) {
2544  if (result < 0) {
2545  if (errno != EPIPE) {
2546  ClosePager(stream);
2547  stream = NULL;
2549  }
2550  break;
2551  }
2552  }
2553 
2554 #if defined(WIN32) || defined(_WINDOWS)
2555  ClosePager(stream);
2556 #else
2558  ClosePager(stream);
2559  (void) NcSignal(SIGPIPE, osigpipe);
2560  (void) NcSignal(SIGINT, osigint);
2561 #endif
2562  gMayCancelJmp = 0;
2563 } /* PageCmd */
2564 
2565 
2566 
2567 
2568 static int
2570  const char *volatile localpath,
2571  volatile longest_int localsize,
2572  volatile time_t localmtime,
2573  const char *volatile *remotepath,
2574  volatile longest_int remotesize,
2575  volatile time_t remotemtime,
2576  volatile longest_int *volatile startPoint)
2577 {
2578  int zaction = kConfirmResumeProcSaidBestGuess;
2579  char tstr[80], ans[32];
2580  static char newname[128]; /* arrggh... static. */
2581 
2583  return (gResumeAnswerAll);
2584 
2585  if (gAutoResume != 0)
2587 
2588  printf("\nThe remote file \"%s\" already exists.\n", *remotepath);
2589 
2590  if ((localmtime != kModTimeUnknown) && (localsize != kSizeUnknown)) {
2591  (void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &localmtime));
2592  (void) printf(
2593 #if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
2594  "\tLocal: %12lld bytes, dated %s.\n",
2595 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
2596  "\tLocal: %12qd bytes, dated %s.\n",
2597 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
2598  "\tLocal: %12I64d bytes, dated %s.\n",
2599 #else
2600  "\tLocal: %12ld bytes, dated %s.\n",
2601 #endif
2602  localsize,
2603  tstr
2604  );
2605  if ((remotemtime == localmtime) && (remotesize == localsize)) {
2606  (void) printf("\t(Files are identical, skipped)\n\n");
2607  return (kConfirmResumeProcSaidSkip);
2608  }
2609  } else if (localsize != kSizeUnknown) {
2610  (void) printf(
2611 #if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
2612  "\tLocal: %12lld bytes, date unknown.\n",
2613 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
2614  "\tLocal: %12qd bytes, date unknown.\n",
2615 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
2616  "\tLocal: %12I64d bytes, date unknown.\n",
2617 #else
2618  "\tLocal: %12ld bytes, date unknown.\n",
2619 #endif
2620  localsize
2621  );
2622  } else if (localmtime != kModTimeUnknown) {
2623  (void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &localmtime));
2624  (void) printf(
2625  "\tLocal: size unknown, dated %s.\n",
2626  tstr
2627  );
2628  }
2629 
2630  tstr[sizeof(tstr) - 1] = '\0';
2631  if ((remotemtime != kModTimeUnknown) && (remotesize != kSizeUnknown)) {
2632  (void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &remotemtime));
2633  (void) printf(
2634 #if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
2635  "\tRemote: %12lld bytes, dated %s.\n",
2636 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
2637  "\tRemote: %12qd bytes, dated %s.\n",
2638 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
2639  "\tRemote: %12I64d bytes, dated %s.\n",
2640 #else
2641  "\tRemote: %12ld bytes, dated %s.\n",
2642 #endif
2643  remotesize,
2644  tstr
2645  );
2646  } else if (remotesize != kSizeUnknown) {
2647  (void) printf(
2648 #if defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_LLD)
2649  "\tRemote: %12lld bytes, date unknown.\n",
2650 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_QD)
2651  "\tRemote: %12qd bytes, date unknown.\n",
2652 #elif defined(HAVE_LONG_LONG) && defined(PRINTF_LONG_LONG_I64D)
2653  "\tRemote: %12I64d bytes, date unknown.\n",
2654 #else
2655  "\tRemote: %12ld bytes, date unknown.\n",
2656 #endif
2657  remotesize
2658  );
2659  } else if (remotemtime != kModTimeUnknown) {
2660  (void) strftime(tstr, sizeof(tstr) - 1, "%c", localtime((time_t *) &remotemtime));
2661  (void) printf(
2662  "\tRemote: size unknown, dated %s.\n",
2663  tstr
2664  );
2665  }
2666 
2667  printf("\n");
2668  fflush(stdin);
2669  (void) memset(ans, 0, sizeof(ans));
2670  for (;;) {
2671  (void) printf("\t[O]verwrite?");
2672  if ((gConn.hasREST == kCommandAvailable) && (remotesize < localsize))
2673  printf(" [R]esume?");
2674  printf(" [A]ppend to? [S]kip? [N]ew Name?\n");
2675  (void) printf("\t[O!]verwrite all?");
2676  if ((gConn.hasREST == kCommandAvailable) && (remotesize < localsize))
2677  printf(" [R!]esume all?");
2678  printf(" [S!]kip all? [C]ancel > ");
2679  (void) fgets(ans, sizeof(ans) - 1, stdin);
2680  switch ((int) ans[0]) {
2681  case 'c':
2682  case 'C':
2683  ans[0] = 'C';
2684  ans[1] = '\0';
2685  zaction = kConfirmResumeProcSaidCancel;
2686  break;
2687  case 'o':
2688  case 'O':
2689  ans[0] = 'O';
2691  break;
2692  case 'r':
2693  case 'R':
2694  if (gConn.hasREST != kCommandAvailable) {
2695  printf("\tResume is not available on this server.\n\n");
2696  ans[0] = '\0';
2697  break;
2698  } else if (remotesize > localsize) {
2699  printf("\tCannot resume when remote file is already larger than the local file.\n\n");
2700  ans[0] = '\0';
2701  break;
2702  } else if (remotesize == localsize) {
2703  printf("\tRemote file is already the same size as the local file.\n\n");
2704  ans[0] = '\0';
2705  break;
2706  }
2707  ans[0] = 'R';
2708  *startPoint = remotesize;
2709  zaction = kConfirmResumeProcSaidResume;
2710  if (OneTimeMessage("auto-resume") != 0) {
2711  printf("\n\tNOTE: If you want NcFTP to guess automatically, \"set auto-resume yes\"\n\n");
2712  }
2713  break;
2714  case 's':
2715  case 'S':
2716  ans[0] = 'S';
2717  zaction = kConfirmResumeProcSaidSkip;
2718  break;
2719  case 'n':
2720  case 'N':
2721  ans[0] = 'N';
2722  ans[1] = '\0';
2724  break;
2725  case 'a':
2726  case 'A':
2727  ans[0] = 'A';
2728  ans[1] = '\0';
2729  zaction = kConfirmResumeProcSaidAppend;
2730  break;
2731  case 'g':
2732  case 'G':
2733  ans[0] = 'G';
2735  break;
2736  default:
2737  ans[0] = '\0';
2738  }
2739  if (ans[0] != '\0')
2740  break;
2741  }
2742 
2743  if (ans[0] == 'N') {
2744  (void) memset(newname, 0, sizeof(newname));
2745  printf("\tSave as: ");
2746  fflush(stdin);
2747  (void) fgets(newname, sizeof(newname) - 1, stdin);
2748  newname[strlen(newname) - 1] = '\0';
2749  if (newname[0] == '\0') {
2750  /* Nevermind. */
2751  printf("Skipped %s.\n", localpath);
2752  zaction = kConfirmResumeProcSaidSkip;
2753  } else {
2754  *remotepath = newname;
2755  }
2756  }
2757 
2758  if (ans[1] == '!')
2759  gResumeAnswerAll = zaction;
2760  return (zaction);
2761 } /* NcFTPConfirmResumeUploadProc */
2762 
2763 
2764 
2765 
2766 /* Upload files to the remote system, permissions permitting. */
2767 void
2768 PutCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2769 {
2770  int opt;
2771  int renameMode = 0;
2772  int recurseFlag = kRecursiveNo;
2773  int appendFlag = kAppendNo;
2774  const char *dstdir = NULL;
2775  int rc;
2776  int i;
2777  int doGlob;
2778  int xtype = gBm.xferType;
2779  int nD = 0;
2780  int deleteFlag = kDeleteNo;
2781  int resumeFlag = kResumeYes;
2782  char pattern[256];
2783  vsigproc_t osigint;
2784  ConfirmResumeUploadProc confirmProc;
2785 
2786  confirmProc = NcFTPConfirmResumeUploadProc;
2787  gResumeAnswerAll = kConfirmResumeProcNotUsed; /* Ask at least once each time */
2789  GetoptReset();
2790  while ((opt = Getopt(argc, argv, "AafZzrRD")) >= 0) switch (opt) {
2791  case 'a':
2792  xtype = kTypeAscii;
2793  break;
2794  case 'A':
2795  /* Append to remote files, instead of truncating
2796  * them first.
2797  */
2798  appendFlag = kAppendYes;
2799  break;
2800  case 'f':
2801  case 'Z':
2802  /* Do not try to resume a download, even if it
2803  * appeared that some of the file was transferred
2804  * already.
2805  */
2806  resumeFlag = kResumeNo;
2807  confirmProc = NoConfirmResumeUploadProc;
2808  break;
2809  case 'z':
2810  /* Special flag that lets you specify the
2811  * destination file. Normally a "put" will
2812  * write the file by the same name as the
2813  * local file's basename.
2814  */
2815  renameMode = 1;
2816  break;
2817  case 'r':
2818  case 'R':
2819  recurseFlag = kRecursiveYes;
2820  /* If the item is a directory, get the
2821  * directory and all its contents.
2822  */
2823  recurseFlag = kRecursiveYes;
2824  break;
2825  case 'D':
2826  /* You can delete the local file after
2827  * you uploaded it successfully by using
2828  * the -DD option. It requires two -D's
2829  * to minimize the odds of accidentally
2830  * using a single -D.
2831  */
2832  nD++;
2833  break;
2834  default:
2835  PrintCmdUsage(cmdp);
2836  return;
2837  }
2838 
2839  if (nD >= 2)
2840  deleteFlag = kDeleteYes;
2841 
2842  if (renameMode != 0) {
2843  if (gOptInd > (argc - 2)) {
2844  PrintCmdUsage(cmdp);
2845  (void) fprintf(stderr, "\nFor put with rename, try \"put -z local-path-name remote-path-name\".\n");
2846  return;
2847  }
2848  osigint = NcSignal(SIGINT, XferCanceller);
2849  rc = FTPPutOneFile3(&gConn, argv[gOptInd], argv[gOptInd + 1], xtype, (-1), appendFlag, NULL, NULL, resumeFlag, deleteFlag, confirmProc, 0);
2850  if (rc < 0)
2852  } else {
2853  osigint = NcSignal(SIGINT, XferCanceller);
2854  for (i=gOptInd; i<argc; i++) {
2855  doGlob = (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes;
2856  STRNCPY(pattern, argv[i]);
2858  rc = FTPPutFiles3(&gConn, pattern, dstdir, recurseFlag, doGlob, xtype, appendFlag, NULL, NULL, resumeFlag, deleteFlag, confirmProc, 0);
2859  if (rc < 0)
2861  }
2862  }
2863 
2864  /* Really should just flush only the modified directories... */
2865  FlushLsCache();
2866 
2867  (void) NcSignal(SIGINT, osigint);
2868  (void) fflush(stdin);
2869 } /* PutCmd */
2870 
2871 
2872 
2873 
2874 /* Displays the current remote working directory path. */
2875 void
2876 PwdCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2877 {
2878  int result;
2879  char url[256];
2880  char olddir[256];
2881 
2883 #ifdef USE_WHAT_SERVER_SAYS_IS_CWD
2884  result = FTPGetCWD(&gConn, gRemoteCWD, sizeof(gRemoteCWD));
2885  CurrentURL(url, sizeof(url), 0);
2886  if (result < 0) {
2887  FTPPerror(&gConn, result, kErrPWDFailed, "Could not get remote working directory", NULL);
2888  } else {
2889  Trace(-1, "%s\n", url);
2890  }
2891 #else /* USE_CLIENT_SIDE_CALCULATED_CWD */
2892 
2893  /* Display the current working directory, as
2894  * maintained by us.
2895  */
2896  CurrentURL(url, sizeof(url), 0);
2897  Trace(-1, " %s\n", url);
2898  olddir[sizeof(olddir) - 2] = '\0';
2899  STRNCPY(olddir, gRemoteCWD);
2900 
2901  /* Now see what the server reports as the CWD.
2902  * Because of symlinks, it could be different
2903  * from what we are using.
2904  */
2905  result = FTPGetCWD(&gConn, gRemoteCWD, sizeof(gRemoteCWD));
2906  if ((result == kNoErr) && (strcmp(gRemoteCWD, olddir) != 0)) {
2907  Trace(-1, "This URL is also valid on this server:\n");
2908  CurrentURL(url, sizeof(url), 0);
2909  Trace(-1, " %s\n", url);
2910  if (olddir[sizeof(olddir) - 2] == '\0') {
2911  /* Go back to using the non-resolved version. */
2912  STRNCPY(gRemoteCWD, olddir);
2913  }
2914  }
2915 #endif
2916 } /* PwdCmd */
2917 
2918 
2919 
2920 
2921 /* Sets a flag so that the command shell exits. */
2922 void
2923 QuitCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2924 {
2926  gDoneApplication = 1;
2927 } /* QuitCmd */
2928 
2929 
2930 
2931 
2932 /* Send a command string to the FTP server, verbatim. */
2933 void
2934 QuoteCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2935 {
2936  char cmdbuf[256];
2937  int i;
2938 
2940  (void) STRNCPY(cmdbuf, argv[1]);
2941  for (i=2; i<argc; i++) {
2942  (void) STRNCAT(cmdbuf, " ");
2943  (void) STRNCAT(cmdbuf, argv[i]);
2944  }
2945  (void) FTPCmd(&gConn, "%s", cmdbuf);
2947 } /* QuoteCmd */
2948 
2949 
2950 
2951 
2952 /* Expands a remote regex. Mostly a debugging command. */
2953 void
2954 RGlobCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2955 {
2956  int i;
2957  int result;
2958  int np = 0;
2959  LineList ll;
2960  LinePtr lp;
2961 
2963  for (i=1; i<argc; i++) {
2964  InitLineList(&ll);
2965  result = FTPRemoteGlob(&gConn, &ll, argv[i], (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes);
2966  if (result < 0) {
2967  FTPPerror(&gConn, result, kErrGlobFailed, "remote glob", argv[i]);
2968  } else {
2969  for (lp = ll.first; lp != NULL; lp = lp->next) {
2970  if (lp->line != NULL) {
2971  if (np > 0)
2972  (void) printf(" ");
2973  (void) printf("%s", lp->line);
2974  np++;
2975  }
2976  }
2977  }
2979  }
2980  (void) printf("\n");
2981 } /* RGlobCmd */
2982 
2983 
2984 
2985 
2986 /* Renames a remote file. */
2987 void
2988 RenameCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
2989 {
2990  int result;
2991 
2993  result = FTPRename(&gConn, argv[1], argv[2]);
2994  if (result < 0)
2995  FTPPerror(&gConn, result, kErrRenameFailed, "rename", argv[1]);
2996  else {
2997  /* Really should just flush only the modified directories... */
2998  FlushLsCache();
2999  }
3000 } /* RenameCmd */
3001 
3002 
3003 
3004 
3005 /* Removes a directory on the remote host. */
3006 void
3007 RmdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3008 {
3009  int result;
3010  int i, c;
3011  int recursive = kRecursiveNo;
3012 
3014  GetoptReset();
3015  while ((c = Getopt(argc, argv, "rf")) > 0) switch(c) {
3016  case 'r':
3017  recursive = kRecursiveYes;
3018  break;
3019  case 'f':
3020  /* ignore */
3021  break;
3022  default:
3023  PrintCmdUsage(cmdp);
3024  return;
3025  }
3026  for (i=gOptInd; i<argc; i++) {
3027  result = FTPRmdir(&gConn, argv[i], recursive, (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes);
3028  if (result < 0)
3029  FTPPerror(&gConn, result, kErrRMDFailed, "rmdir", argv[i]);
3030  }
3031 
3032  /* Really should just flush only the modified directories... */
3033  FlushLsCache();
3034 } /* RmdirCmd */
3035 
3036 
3037 
3038 
3039 /* Asks the remote server for help on how to use its server. */
3040 void
3041 RmtHelpCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3042 {
3043  int i, result;
3044  LineList ll;
3045  LinePtr lp;
3046 
3048  if (argc == 1) {
3049  result = FTPRemoteHelp(&gConn, NULL, &ll);
3050  if (result < 0)
3051  FTPPerror(&gConn, result, kErrHELPFailed, "HELP failed", NULL);
3052  else {
3053  for (lp = ll.first; lp != NULL; lp = lp->next)
3054  (void) printf("%s\n", lp->line);
3055  }
3057  } else {
3058  for (i=1; i<argc; i++) {
3059  result = FTPRemoteHelp(&gConn, argv[i], &ll);
3060  if (result < 0)
3061  FTPPerror(&gConn, result, kErrHELPFailed, "HELP failed for", argv[i]);
3062  else {
3063  for (lp = ll.first; lp != NULL; lp = lp->next)
3064  (void) printf("%s\n", lp->line);
3065  }
3067  }
3068  }
3069 } /* RmtHelpCmd */
3070 
3071 
3072 
3073 
3074 /* Show and/or change customizable program settings. These changes are saved
3075  * at the end of the program's run.
3076  */
3077 void
3078 SetCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3079 {
3081  if (argc < 2)
3082  Set(NULL, NULL);
3083  else if (argc == 2)
3084  Set(argv[1], NULL);
3085  else
3086  Set(argv[1], argv[2]);
3087 } /* SetCmd */
3088 
3089 
3090 
3091 
3092 /* Local shell escape. */
3093 void
3094 ShellCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3095 {
3096 #if defined(WIN32) || defined(_WINDOWS)
3097 #else
3098  const char *cp;
3099  pid_t pid;
3100  int status;
3101  vsigproc_t osigint;
3102 
3103  osigint = NcSignal(SIGINT, (FTPSigProc) SIG_IGN);
3105  pid = fork();
3106  if (pid < (pid_t) 0) {
3107  perror("fork");
3108  } else if (pid == 0) {
3109  cp = strrchr(gShell, '/');
3110  if (cp == NULL)
3111  cp = gShell; /* bug */
3112  else
3113  cp++;
3114  if (argc == 1) {
3115  execl(gShell, cp, NULL);
3116  perror(gShell);
3117  exit(1);
3118  } else {
3119  execvp(argv[1], (char **) argv + 1);
3120  perror(gShell);
3121  exit(1);
3122  }
3123  } else {
3124  /* parent */
3125  for (;;) {
3126 #ifdef HAVE_WAITPID
3127  if ((waitpid(pid, &status, 0) < 0) && (errno != EINTR))
3128  break;
3129 #else
3130  if ((wait(&status) < 0) && (errno != EINTR))
3131  break;
3132 #endif
3133  if (WIFEXITED(status) || WIFSIGNALED(status))
3134  break; /* done */
3135  }
3136  }
3137  (void) NcSignal(SIGINT, osigint);
3138 #endif
3139 } /* ShellCmd */
3140 
3141 
3142 
3143 
3144 /* Send a command string to the FTP server, verbatim. */
3145 void
3146 SiteCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3147 {
3148  char cmdbuf[256];
3149  int i;
3150 
3152  (void) STRNCPY(cmdbuf, "SITE");
3153  for (i=1; i<argc; i++) {
3154  (void) STRNCAT(cmdbuf, " ");
3155  (void) STRNCAT(cmdbuf, argv[i]);
3156  }
3157  (void) FTPCmd(&gConn, "%s", cmdbuf);
3159 } /* SiteCmd */
3160 
3161 
3162 
3163 
3164 static time_t
3165 GetStartSpoolDate(const char *s)
3166 {
3167  char *cp;
3168  char s2[64];
3169  time_t now, when;
3170  int toff, n, c, hr, min;
3171  struct tm lt, *ltp;
3172 
3173  STRNCPY(s2, s);
3174  cp = strchr(s2, ':');
3175  if ((s2[0] == 'n') || (s2[0] == '+')) {
3176  /* "now + XX hours" or
3177  * "+ XX hours"
3178  */
3179  cp = strchr(s2, '+');
3180  if (cp == NULL)
3181  return ((time_t) -1);
3182  ++cp;
3183  toff = 0;
3184  n = 0;
3185  (void) sscanf(cp, "%d%n", &toff, &n);
3186  if ((n <= 0) || (toff <= 0))
3187  return ((time_t) -1);
3188  cp += n;
3189  while ((*cp != '\0') && (!isalpha(*cp)))
3190  cp++;
3191  c = *cp;
3192  if (isupper(c))
3193  c = tolower(c);
3194  if (c == 's') {
3195  /* seconds */
3196  } else if (c == 'm') {
3197  /* minutes */
3198  toff *= 60;
3199  } else if (c == 'h') {
3200  /* hours */
3201  toff *= 3600;
3202  } else if (c == 'd') {
3203  /* days */
3204  toff *= 86400;
3205  } else {
3206  /* unrecognized unit */
3207  return ((time_t) -1);
3208  }
3209  time(&now);
3210  when = now + (time_t) toff;
3211  } else if (cp != NULL) {
3212  /* HH:MM, as in "23:38" */
3213  time(&now);
3214  ltp = localtime(&now);
3215  if (ltp == NULL)
3216  return ((time_t) -1); /* impossible */
3217  lt = *ltp;
3218  *cp = ' ';
3219  hr = -1;
3220  min = -1;
3221  (void) sscanf(s2, "%d%d", &hr, &min);
3222  if ((hr < 0) || (min < 0))
3223  return ((time_t) -1);
3224  lt.tm_hour = hr;
3225  lt.tm_min = min;
3226  when = mktime(&lt);
3227  if ((when == (time_t) -1) || (when == (time_t) 0))
3228  return (when);
3229  if (when < now)
3230  when += (time_t) 86400;
3231  } else {
3232  when = UnDate(s2);
3233  }
3234  return (when);
3235 } /* GetStartSpoolDate */
3236 
3237 
3238 
3239 static int
3241 {
3242  if (CanSpool() < 0) {
3243 #if defined(WIN32) || defined(_WINDOWS)
3244  (void) printf("Sorry, spooling isn't allowed until you run Setup.exe.\n");
3245 #else
3246  (void) printf("Sorry, spooling isn't allowed because this user requires that the NCFTPDIR\nenvironment variable be set to a directory to write datafiles to.\n");
3247 #endif
3248  return (-1);
3249  } else if (HaveSpool() == 0) {
3250 #if defined(WIN32) || defined(_WINDOWS)
3251  (void) printf("Sorry, the \"ncftpbatch\" program could not be found.\nPlease re-run Setup to correct this problem.\n");
3252 #else
3253  (void) printf("Sorry, the \"ncftpbatch\" program could not be found.\nThis program must be installed and in your PATH in order to use this feature.\n");
3254 #endif
3255  return (-1);
3256  }
3257  return (0);
3258 } /* SpoolCheck */
3259 
3260 
3261 
3262 /* Show and/or change customizable program settings. These changes are saved
3263  * at the end of the program's run.
3264  */
3265 void
3266 BGStartCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3267 {
3268  int i, n;
3269 
3271  if (SpoolCheck() < 0)
3272  return;
3273 
3274  if ((argc < 2) || ((n = atoi(argv[1])) < 2)) {
3275  RunBatch(0, &gConn);
3276  (void) printf("Background process started.\n");
3277 #if defined(WIN32) || defined(_WINDOWS)
3278 #else
3279  (void) printf("Watch the \"%s/batchlog\" file to see how it is progressing.\n", gOurDirectoryPath);
3280 #endif
3281  } else {
3282  for (i=0; i<n; i++)
3283  RunBatch(0, &gConn);
3284  (void) printf("Background processes started.\n");
3285 #if defined(WIN32) || defined(_WINDOWS)
3286 #else
3287  (void) printf("Watch the \"%s/batchlog\" file to see how it is progressing.\n", gOurDirectoryPath);
3288 #endif
3289  }
3290 } /* BGStart */
3291 
3292 
3293 
3294 
3295 /* This commands lets the user change the umask, if the server supports it. */
3296 /* (bgget) */
3297 void
3298 SpoolGetCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3299 {
3300  int opt;
3301  int renameMode = 0;
3302  int recurseFlag = kRecursiveNo;
3303  int rc;
3304  int i;
3305  int xtype = gBm.xferType;
3306  int nD = 0;
3307  int deleteFlag = kDeleteNo;
3308  time_t when = 0;
3309  char ldir[256];
3310  char pattern[256];
3311  char *lname;
3312  LineList ll;
3313  LinePtr lp;
3314 
3316 
3317  if ((gSavePasswords <= 0) && ((strcmp(gConn.user, "anonymous") != 0) && (strcmp(gConn.user, "ftp") != 0))) {
3318  (void) printf("Sorry, spooling isn't allowed when you're not logged in anonymously, because\nthe spool files would need to save your password.\n\nYou can override this by doing a \"set save-passwords yes\" if you're willing\nto live with the consequences.\n");
3319  return;
3320  } else if (SpoolCheck() < 0) {
3321  return;
3322  }
3323 
3324  GetoptReset();
3325  while ((opt = Getopt(argc, argv, "@:azfrRD")) >= 0) switch (opt) {
3326  case '@':
3327  when = GetStartSpoolDate(gOptArg);
3328  if ((when == (time_t) -1) || (when == (time_t) 0)) {
3329  (void) fprintf(stderr, "Bad date. It must be expressed as one of the following:\n\tYYYYMMDDHHMMSS\t\n\t\"now + N hours|min|sec|days\"\n\tHH:MM\n\nNote: Do not forget to quote the entire argument for the offset option.\nExample: bgget -@ \"now + 15 min\" ...\n");
3330  return;
3331  }
3332  break;
3333  case 'a':
3334  xtype = kTypeAscii;
3335  break;
3336  case 'z':
3337  /* Special flag that lets you specify the
3338  * destination file. Normally a "get" will
3339  * write the file by the same name as the
3340  * remote file's basename.
3341  */
3342  renameMode = 1;
3343  break;
3344  case 'r':
3345  case 'R':
3346  /* If the item is a directory, get the
3347  * directory and all its contents.
3348  */
3349  recurseFlag = kRecursiveYes;
3350  break;
3351  case 'D':
3352  /* You can delete the remote file after
3353  * you downloaded it successfully by using
3354  * the -DD option. It requires two -D's
3355  * to minimize the odds of accidentally
3356  * using a single -D.
3357  */
3358  nD++;
3359  break;
3360  default:
3361  PrintCmdUsage(cmdp);
3362  return;
3363  }
3364 
3365  if (nD >= 2)
3366  deleteFlag = kDeleteYes;
3367 
3368  if (FTPGetLocalCWD(ldir, sizeof(ldir)) == NULL) {
3369  perror("could not get current local directory");
3370  return;
3371  }
3372 
3373  if (renameMode != 0) {
3374  if (gOptInd > argc - 2) {
3375  PrintCmdUsage(cmdp);
3376  return;
3377  }
3378  rc = SpoolX(
3379  "get",
3380  argv[gOptInd],
3381  gRemoteCWD,
3382  argv[gOptInd + 1],
3383  ldir,
3384  gConn.host,
3385  gConn.ip,
3386  gConn.port,
3387  gConn.user,
3388  gConn.pass,
3389  xtype,
3390  recurseFlag,
3391  deleteFlag,
3393  NULL,
3394  NULL,
3395  NULL,
3396  when
3397  );
3398  if (rc == 0) {
3399  Trace(-1, " + Spooled: get %s as %s\n", argv[gOptInd], argv[gOptInd]);
3400  }
3401  } else {
3402  for (i=gOptInd; i<argc; i++) {
3403  STRNCPY(pattern, argv[i]);
3405  InitLineList(&ll);
3406  rc = FTPRemoteGlob(&gConn, &ll, pattern, (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes);
3407  if (rc < 0) {
3409  } else {
3410  for (lp = ll.first; lp != NULL; lp = lp->next) {
3411  if (lp->line != NULL) {
3412  lname = strrchr(lp->line, '/');
3413  if (lname == NULL)
3414  lname = lp->line;
3415  else
3416  lname++;
3417  rc = SpoolX(
3418  "get",
3419  lp->line,
3420  gRemoteCWD,
3421  lname,
3422  ldir,
3423  gConn.host,
3424  gConn.ip,
3425  gConn.port,
3426  gConn.user,
3427  gConn.pass,
3428  xtype,
3429  recurseFlag,
3430  deleteFlag,
3432  NULL,
3433  NULL,
3434  NULL,
3435  when
3436  );
3437  if (rc == 0) {
3438  Trace(-1, " + Spooled: get %s\n", lp->line);
3439  }
3440  }
3441  }
3442  }
3444  }
3445  }
3446 } /* SpoolGetCmd */
3447 
3448 
3449 
3450 
3451 /* This commands lets the user change the umask, if the server supports it. */
3452 /* (bgput) */
3453 void
3454 SpoolPutCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3455 {
3456  int opt;
3457  int renameMode = 0;
3458  int recurseFlag = kRecursiveNo;
3459  int rc;
3460  int i;
3461  int xtype = gBm.xferType;
3462  int nD = 0;
3463  int deleteFlag = kDeleteNo;
3464  time_t when = 0;
3465  char ldir[256];
3466  char pattern[256];
3467  LineList ll;
3468  LinePtr lp;
3469  char *rname;
3470 
3472 
3473  if ((gSavePasswords <= 0) && ((strcmp(gConn.user, "anonymous") != 0) && (strcmp(gConn.user, "ftp") != 0))) {
3474  (void) printf("Sorry, spooling isn't allowed when you're not logged in anonymously, because\nthe spool files would need to save your password.\n\nYou can override this by doing a \"set save-passwords yes\" if you're willing\nto live with the consequences.\n");
3475  return;
3476  } else if (SpoolCheck() < 0) {
3477  return;
3478  }
3479 
3480  GetoptReset();
3481  while ((opt = Getopt(argc, argv, "@:azrRD")) >= 0) switch (opt) {
3482  case '@':
3483  when = GetStartSpoolDate(gOptArg);
3484  if ((when == (time_t) -1) || (when == (time_t) 0)) {
3485  (void) fprintf(stderr, "Bad date. It must be expressed as one of the following:\n\tYYYYMMDDHHMMSS\t\n\t\"now + N hours|min|sec|days\"\n\tHH:MM\n\nNote: Do not forget to quote the entire argument for the offset option.\nExample: bgget -@ \"now + 15 min\" ...\n");
3486  return;
3487  }
3488  break;
3489  case 'a':
3490  xtype = kTypeAscii;
3491  break;
3492  case 'z':
3493  /* Special flag that lets you specify the
3494  * destination file. Normally a "get" will
3495  * write the file by the same name as the
3496  * remote file's basename.
3497  */
3498  renameMode = 1;
3499  break;
3500  case 'r':
3501  case 'R':
3502  /* If the item is a directory, get the
3503  * directory and all its contents.
3504  */
3505  recurseFlag = kRecursiveYes;
3506  break;
3507  case 'D':
3508  /* You can delete the remote file after
3509  * you downloaded it successfully by using
3510  * the -DD option. It requires two -D's
3511  * to minimize the odds of accidentally
3512  * using a single -D.
3513  */
3514  nD++;
3515  break;
3516  default:
3517  PrintCmdUsage(cmdp);
3518  return;
3519  }
3520 
3521  if (nD >= 2)
3522  deleteFlag = kDeleteYes;
3523 
3524  if (FTPGetLocalCWD(ldir, sizeof(ldir)) == NULL) {
3525  perror("could not get current local directory");
3526  return;
3527  }
3528 
3529  if (renameMode != 0) {
3530  if (gOptInd > argc - 2) {
3531  PrintCmdUsage(cmdp);
3532  return;
3533  }
3534  rc = SpoolX(
3535  "put",
3536  argv[gOptInd + 1],
3537  gRemoteCWD,
3538  argv[gOptInd + 0],
3539  ldir,
3540  gConn.host,
3541  gConn.ip,
3542  gConn.port,
3543  gConn.user,
3544  gConn.pass,
3545  xtype,
3546  recurseFlag,
3547  deleteFlag,
3549  NULL,
3550  NULL,
3551  NULL,
3552  when
3553  );
3554  if (rc == 0) {
3555  Trace(-1, " + Spooled: put %s as %s\n", argv[gOptInd], argv[gOptInd]);
3556  }
3557  } else {
3558  for (i=gOptInd; i<argc; i++) {
3559  STRNCPY(pattern, argv[i]);
3561  InitLineList(&ll);
3562  rc = FTPLocalGlob(&gConn, &ll, pattern, (aip->noglobargv[i] != 0) ? kGlobNo: kGlobYes);
3563  if (rc < 0) {
3564  FTPPerror(&gConn, rc, kErrGlobFailed, "local glob", pattern);
3565  } else {
3566  for (lp = ll.first; lp != NULL; lp = lp->next) {
3567  if (lp->line != NULL) {
3568  rname = strrchr(lp->line, '/');
3569  if (rname == NULL)
3570  rname = lp->line;
3571  else
3572  rname++;
3573  rc = SpoolX(
3574  "put",
3575  rname,
3576  gRemoteCWD,
3577  lp->line,
3578  ldir,
3579  gConn.host,
3580  gConn.ip,
3581  gConn.port,
3582  gConn.user,
3583  gConn.pass,
3584  xtype,
3585  recurseFlag,
3586  deleteFlag,
3588  NULL,
3589  NULL,
3590  NULL,
3591  when
3592  );
3593  if (rc == 0) {
3594  Trace(-1, " + Spooled: put %s\n", lp->line);
3595  }
3596  }
3597  }
3598  }
3600  }
3601  }
3602 } /* SpoolGetCmd */
3603 
3604 
3605 
3606 
3607 /* This commands lets the user change the umask, if the server supports it. */
3608 void
3609 SymlinkCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3610 {
3611  int result;
3612 
3614  result = FTPSymlink(&gConn, argv[1], argv[2]);
3615  if (result < 0)
3616  FTPPerror(&gConn, result, kErrSYMLINKFailed, "symlink", argv[1]);
3617 
3618  /* Really should just flush only the modified directories... */
3619  FlushLsCache();
3620 } /* SymlinkCmd */
3621 
3622 
3623 
3624 
3625 /* This commands lets the user change the transfer type to use. */
3626 void
3627 TypeCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3628 {
3629  int c;
3630  int result;
3631  const char *cs;
3632 
3634  if (argc < 2) {
3635  c = argv[0][0];
3636  if (c == 't') {
3637  if (gBm.xferType == kTypeAscii) {
3638  c = kTypeAscii;
3639  cs = "ASCII";
3640  } else if (gBm.xferType == kTypeEbcdic) {
3641  c = kTypeEbcdic;
3642  cs = "EBCDIC";
3643  } else {
3644  c = kTypeBinary;
3645  cs = "binary/image";
3646  }
3647  Trace(-1, "Type is %c (%s).\n", c, cs);
3648  } else {
3650  if (result < 0) {
3651  FTPPerror(&gConn, result, kErrTYPEFailed, "Type", argv[1]);
3652  } else {
3654  }
3655  }
3656  } else {
3657  c = argv[1][0];
3659  if (result < 0) {
3660  FTPPerror(&gConn, result, kErrTYPEFailed, "Type", argv[1]);
3661  } else {
3663  }
3664  }
3665 } /* TypeCmd */
3666 
3667 
3668 
3669 
3670 /* This commands lets the user change the umask, if the server supports it. */
3671 void
3672 UmaskCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3673 {
3674  int result;
3675 
3677  result = FTPUmask(&gConn, argv[1]);
3678  if (result < 0)
3679  FTPPerror(&gConn, result, kErrUmaskFailed, "umask", argv[1]);
3680 } /* UmaskCmd */
3681 
3682 
3683 
3684 
3685 /* Show the version information. */
3686 void
3687 VersionCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
3688 {
3690  (void) printf("Version: %s\n", gVersion + 5);
3691  (void) printf("Author: Mike Gleason (ncftp@ncftp.com)\n");
3692 #ifndef BETA
3693  (void) printf("Archived at: ftp://ftp.ncftp.com/ncftp/\n");
3694 #endif
3695  (void) printf("Library Version: %s\n", gLibNcFTPVersion + 5);
3696 #ifdef __DATE__
3697  (void) printf("Compile Date: %s\n", __DATE__);
3698 #endif
3699  if (gOS[0] != '\0')
3700  (void) printf("Platform: %s\n", gOS);
3701 } /* VersionCmd */
#define kFirewallSiteSite
Definition: ncftp.h:391
void ShellCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:3094
#define EPIPE
Definition: acclib.h:91
int gOptInd
Definition: getopt.c:14
void LocalListCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:1552
void CurrentURL(char *dst, size_t dsize, int showpass)
Definition: cmds.c:161
#define ERROR_BAD_FORMAT
Definition: winerror.h:114
#define IsLocalPathDelim(c)
Definition: ncftp.h:497
char gVersion[]
Definition: init.c:22
char dir[160]
Definition: bookmark.h:15
LineList lastFTPCmdResultLL
Definition: ncftp.h:215
#define vsnprintf
Definition: tif_win32.c:406
int printMode
Definition: ncftp.h:93
#define kErrInvalidDirParam
Definition: ncftp_errno.h:39
static int argc
Definition: ServiceArgs.c:12
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
void SpoolGetCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:3298
#define kErrHELPFailed
Definition: ncftp_errno.h:83
static void NcFTPCdResponseProc(const FTPCIPtr cipUNUSED, ResponsePtr rp)
Definition: cmds.c:371
char ** h_addr_list
Definition: winsock.h:138
jmp_buf sigjmp_buf
Definition: port.h:324
int tm_min
Definition: time.h:78
CommandPtr GetCommandByName(const char *const name, int wantExactMatch)
Definition: shell.c:156
struct S2 s2
#define kErrRMDFailed
Definition: ncftp_errno.h:43
#define kGlobNo
Definition: ncftp.h:361
#define CloseHandle
Definition: compat.h:406
time_t UnDate(char *dstr)
Definition: util.c:917
#define sleep
Definition: syshdrs.h:37
unsigned int port
Definition: ncftp.h:140
#define kErrBadParameter
Definition: ncftp_errno.h:56
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define kCommandAvailable
Definition: ncftp.h:380
void MlsCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:1937
#define kTarYes
Definition: ncftp.h:370
void SetDebug(int i)
Definition: trace.c:88
#define kConfirmResumeProcSaidSkip
Definition: ncftp.h:424
void LocalRmdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:1836
int FTPGetFiles3(const FTPCIPtr cip, const char *pattern1, const char *const dstdir1, const int recurse, int doGlob, const int xtype, const int resumeflag, int appendflag, const int deleteflag, const int tarflag, const ConfirmResumeDownloadProc resumeProc, int UNUSED(reserved))
Definition: io.c:2486
int FTPRemoteHelp(const FTPCIPtr cip, const char *const pattern, const LineListPtr llp)
Definition: cmds.c:739
HRESULT hr
Definition: shlfolder.c:183
#define kErrUmaskFailed
Definition: ncftp_errno.h:60
int gGotSig
Definition: shell.c:60
int RCmd(const FTPCIPtr, ResponsePtr, const char *,...)
Definition: rcmd.c:718
static int SpoolCheck(void)
Definition: cmds.c:3240
int nCols
Definition: appswitch.c:56
void PageCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:2496
static int PrintHosts(void)
Definition: cmds.c:1143
void FTPPerror(const FTPCIPtr cip, const int err, const int eerr, const char *const s1, const char *const s2)
Definition: errno.c:134
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
int FTPDelete(const FTPCIPtr cip, const char *const pattern, const int recurse, const int doGlob)
Definition: cmds.c:195
char pass[64]
Definition: ncftp.h:138
#define kAmbiguousCommand
Definition: shell.h:54
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define kFirewallUserAtSite
Definition: ncftp.h:389
int gAutoSaveChangesToExistingBookmarks
Definition: pref.c:36
char * prog
Definition: isohybrid.c:47
int FTPChmod(const FTPCIPtr cip, const char *const pattern, const char *const mode, const int doGlob)
Definition: cmds.c:46
void PrintCmdUsage(CommandPtr c)
Definition: shell.c:210
char * h_name
Definition: winsock.h:134
_CRTIMP intptr_t __cdecl execl(_In_z_ const char *_Filename, _In_z_ const char *_ArgList,...)
#define free
Definition: debug_ros.c:5
void HostsCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:1329
#define EINTR
Definition: acclib.h:80
#define kNoCommand
Definition: shell.h:55
volatile sigproc_t vsigproc_t
Definition: util.h:11
char * buf
Definition: ncftp.h:186
char * host
Definition: whois.c:55
FTPLoginMessageProc onLoginMsgProc
Definition: ncftp.h:227
char gFirewallExceptionList[]
Definition: preffw.c:21
const char * fmt
Definition: wsprintf.c:30
void BGStartCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:3266
char ** h_aliases
Definition: winsock.h:135
void DoneWithResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:114
char ourHostName[64]
Definition: ncftp.h:118
char user[64]
Definition: ncftp.h:137
GLdouble n
Definition: glext.h:7729
int gFirewallType
Definition: preffw.c:17
char name[64]
Definition: bookmark.h:11
#define unlink
Definition: syshdrs.h:54
char gScratchCWD[512]
Definition: cmds.c:41
LinePtr next
Definition: ncftp.h:80
char * OurDirectoryPath(char *const dst, const size_t siz, const char *const fname)
Definition: util.c:486
void LookupCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:1886
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
#define assert(x)
Definition: debug.h:53
DWORD pid_t
Definition: types.h:91
#define ZeroMemory
Definition: winbase.h:1642
#define kErrMKDFailed
Definition: ncftp_errno.h:57
void LLs(const char *const, int, const char *const, FILE *)
int FTPSetTransferType(const FTPCIPtr cip, int type)
Definition: cmds.c:836
int GetNextBookmark(FILE *fp, Bookmark *bmp)
Definition: bookmark.c:257
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define isalpha(c)
Definition: acclib.h:74
FILE * stdin
char gFirewallPass[32]
Definition: preffw.c:20
int gMayCancelJmp
Definition: shell.c:54
void * arg
Definition: msvc.h:10
#define kErrMallocFailed
Definition: ncftp_errno.h:40
#define SIGINT
Definition: signal.h:23
UINT WINAPI DECLSPEC_HOTPATCH WinExec(LPCSTR lpCmdLine, UINT uCmdShow)
Definition: proc.c:4774
int errno
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
Definition: shell.h:41
#define kErrGlobFailed
Definition: ncftp_errno.h:68
__u16 time
Definition: mkdosfs.c:366
int FTPMkdir(const FTPCIPtr cip, const char *const newDir, const int recurse)
Definition: cmds.c:641
#define kFirewallNotInUse
Definition: ncftp.h:388
static void OpenMsg(const char *const fmt,...)
Definition: cmds.c:2050
int hasMDTM
Definition: bookmark.h:21
#define argv
Definition: mplay32.c:18
static void ClosePager(FILE *pagerfp)
Definition: cmds.c:113
int hasPASV
Definition: bookmark.h:22
char magic[16]
Definition: ncftp.h:135
void BookmarkCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:323
char gShell[]
Definition: util.c:16
int gFirstTimeUser
void PrintResp(LineListPtr llp)
Definition: cmds.c:396
int hasSIZE
Definition: bookmark.h:20
char * gOptArg
Definition: getopt.c:16
void DeleteCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:664
unsigned int gFirewallPort
Definition: preffw.c:22
static int NcFTPConfirmResumeDownloadProc(const char *volatile *localpath, volatile longest_int localsize, volatile time_t localmtime, const char *volatile remotepath, volatile longest_int remotesize, volatile time_t remotemtime, volatile longest_int *volatile startPoint)
Definition: cmds.c:739
FILE * stdout
static BOOL Set
Definition: pageheap.c:10
#define kConfirmResumeProcSaidOverwrite
Definition: ncftp.h:426
int FTPGetOneFile2(const FTPCIPtr cip, const char *const file, const char *const dstfile, const int xtype, const int fdtouse, const int resumeflag, const int appendflag)
Definition: io.c:2721
int(* ConfirmResumeDownloadProc)(const char *volatile *localpath, volatile longest_int localsize, volatile time_t localmtime, const char *volatile remotepath, volatile longest_int remotesize, volatile time_t remotetime, volatile longest_int *volatile startPoint)
Definition: ncftp.h:431
#define kConfirmResumeProcSaidResume
Definition: ncftp.h:425
int FTPCmd(const FTPCIPtr cip, const char *const cmdspec,...)
Definition: rcmd.c:603
void SpoolPutCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:3454
void AbsoluteToRelative(char *const dst, const size_t dsize, const char *const dir, const char *const root, const size_t rootlen)
Definition: util.c:785
FTPLibraryInfo gLib
Definition: main.c:36
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define kErrPWDFailed
Definition: ncftp_errno.h:41
int FTPPutOneFile3(const FTPCIPtr cip, const char *const file, const char *const dstfile, const int xtype, const int fdtouse, const int appendflag, const char *const tmppfx, const char *const tmpsfx, const int resumeflag, const int deleteflag, const ConfirmResumeUploadProc resumeProc, int UNUSED(reserved))
Definition: io.c:1262
void DebugCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:650
pass
Definition: typegen.h:24
static void NcFTPGetPassphraseProc(const FTPCIPtr cip, LineListPtr pwPrompt, char *pass, size_t dsize)
Definition: cmds.c:2147
#define kConfirmResumeProcSaidCancel
Definition: ncftp.h:429
static void NcFTPRedialStatusProc(const FTPCIPtr cipUNUSED, int mode, int val)
Definition: cmds.c:2130
#define StrDup
Definition: shlwapi.h:1533
uint32_t cs
Definition: isohybrid.c:75
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static void NcFTPOnLoginMessageProc(const FTPCIPtr cipUNUSED, ResponsePtr rp)
Definition: cmds.c:2118
char bookmarkName[16]
Definition: bookmark.h:10
char host[64]
Definition: ncftp.h:136
static int RunBookmarkEditor(char *selectedBmName, size_t dsize)
Definition: cmds.c:1187
int OneTimeMessage(const char *const msg)
Definition: pref.c:508
#define chdir
Definition: syshdrs.h:69
#define va_end(ap)
Definition: acmsvcex.h:90
_Check_return_ int __cdecl rename(_In_z_ const char *_OldFilename, _In_z_ const char *_NewFilename)
FTPRedialStatusProc redialStatusProc
Definition: ncftp.h:225
int gScreenColumns
Definition: main.c:34
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
char gLocalCWD[512]
Definition: main.c:43
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned int port
Definition: bookmark.h:18
void UmaskCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:3672
#define StrRemoveTrailingLocalPathDelim
Definition: ncftp.h:496
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
int FTPUmask(const FTPCIPtr cip, const char *const umsk)
Definition: cmds.c:1602
void BookmarkToURL(BookmarkPtr bmp, char *url, size_t urlsize)
Definition: bookmark.c:36
time_t now
Definition: finger.c:65
int Chdirs(FTPCIPtr cip, const char *const cdCwd)
Definition: cmds.c:504
void QuitCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:2923
#define kFirewallUserAtSiteFwuPassFwp
Definition: ncftp.h:395
void GetCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:916
void GetoptReset(void)
Definition: getopt.c:21
char gStartDir[512]
Definition: cmds.c:28
void EchoCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:706
char firewallHost[64]
Definition: ncftp.h:217
#define HAVE_LONG_LONG
Definition: wincfg.h:29
char lastIP[32]
Definition: bookmark.h:24
char * gl_getpass(const char *const prompt, char *const pass, int dsize)
Definition: getline.c:2051
#define kMalformedURL
Definition: ncftp.h:385
void ReCacheBookmarks(void)
Definition: readln.c:515
FTPConnectMessageProc onConnectMsgProc
Definition: ncftp.h:224
int FTPLocalGlob(FTPCIPtr cip, LineListPtr fileList, const char *pattern, int doGlob)
Definition: glob.c:1580
void PathCat(char *const dst, const size_t dsize, const char *const cwd, const char *const src)
Definition: util.c:368
smooth NULL
Definition: ftsmooth.c:416
static struct hostent * GetHostEntry(char *host, struct in_addr *ip_address)
Definition: ftp.c:53
void MyInetAddr(char *, size_t, char **, int)
Definition: util.c:185
void MkdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:2011
Definition: getopt.h:108
#define kOpenSelectedBookmarkFileName
Definition: pref.h:28
char pass[64]
Definition: bookmark.h:13
int firewallType
Definition: ncftp.h:221
#define kRecursiveYes
Definition: ncftp.h:362
Definition: parser.c:48
char * va_list
Definition: acmsvcex.h:78
void PwdCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:2876
char gFirewallHost[64]
Definition: preffw.c:18
#define STDOUT_FILENO
Definition: syshdrs.h:89
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
unsigned int dir
Definition: maze.c:112
void PutCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:2768
void InitConnectionInfo(void)
Definition: main.c:109
#define X_OK
Definition: io.h:169
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
void SaveUnsavedBookmark(void)
Definition: cmds.c:270
GLuint GLfloat * val
Definition: glext.h:7180
char firewallPass[64]
Definition: ncftp.h:219
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
void LocalRenameCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:1786
#define kRecursiveNo
Definition: ncftp.h:363
#define FOPEN_READ_TEXT
Definition: syshdrs.h:82
r l[0]
Definition: byte_order.h:167
void SiteCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:3146
#define kDeleteNo
Definition: ncftp.h:369
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
#define STREQ(a, b)
Definition: util.h:20
#define STRNCAT(d, s)
Definition: Strn.h:48
char * startingWorkingDirectory
Definition: ncftp.h:158
int code
Definition: ncftp.h:92
char user[64]
Definition: bookmark.h:12
__kernel_size_t size_t
Definition: linux.h:237
#define kFirewallLoginThenUserAtSite
Definition: ncftp.h:390
#define kResumeYes
Definition: ncftp.h:366
char gOS[]
Definition: version.c:12
char * FGets(char *, size_t, FILE *)
Definition: util.c:111
int noglobargv[64]
Definition: shell.h:10
int gSavePasswords
Definition: pref.c:39
char gHome[]
Definition: util.c:15
int GetBookmark(const char *const bmabbr, Bookmark *bmp)
Definition: bookmark.c:387
void RmdirCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:3007
_CRTIMP int __cdecl getpid(void)
int gUnusedArg
Definition: cmds.c:46
int PromptForBookmarkName(BookmarkPtr bmp)
Definition: cmds.c:135
void Cancel(int sigNum)
Definition: shell.c:481
char acct[64]
Definition: ncftp.h:139
jmp_buf gCancelJmp
Definition: shell.c:45
#define isupper(c)
Definition: acclib.h:71
int GetHostByName(char *const volatile dst, size_t dsize, const char *const hn, int t)
Definition: util.c:826
int gConfirmClose
Definition: pref.c:33
#define kTarNo
Definition: ncftp.h:371
#define NoConfirmResumeUploadProc
Definition: ncftp.h:452
static const WCHAR url[]
Definition: encode.c:1432
#define kNotURL
Definition: ncftp.h:384
int MkDirs(const char *const, int mode1)
Definition: util.c:785
int FTPRename(const FTPCIPtr cip, const char *const oldname, const char *const newname)
Definition: cmds.c:703
#define longest_int
Definition: ncftp.h:68
#define kErrBadMagic
Definition: ncftp_errno.h:55
Definition: tcpip.h:125
#define kConfirmResumeProcSaidBestGuess
Definition: ncftp.h:428
int sigsetjmp(sigjmp_buf buf, int savesigs)
int FTPPutFiles3(const FTPCIPtr cip, const char *const pattern, const char *const dstdir1, const int recurse, const int doGlob, const int xtype, int appendflag, const char *const tmppfx, const char *const tmpsfx, const int resumeflag, const int deleteflag, const ConfirmResumeUploadProc resumeProc, int UNUSED(reserved))
Definition: io.c:1298
int(* ConfirmResumeUploadProc)(const char *volatile localpath, volatile longest_int localsize, volatile time_t localmtime, const char *volatile *remotepath, volatile longest_int remotesize, volatile time_t remotetime, volatile longest_int *volatile startPoint)
Definition: ncftp.h:441
char gPrevRemoteCWD[512]
Definition: cmds.c:38
int nFTPChdirAndGetCWD(const FTPCIPtr cip, const char *cdCwd, const int quietMode)
Definition: cmds.c:417
_CRTIMP intptr_t __cdecl execvp(_In_z_ const char *_Filename, _In_z_ char *const _ArgList[])
const GLubyte * c
Definition: glext.h:8905
#define kGlobYes
Definition: ncftp.h:360
void ChmodCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:612
unsigned long DWORD
Definition: ntddk_ex.h:95
char ldir[160]
Definition: bookmark.h:16
#define kTypeBinary
Definition: ncftp.h:354
static void NcFTPOnConnectMessageProc(const FTPCIPtr cipUNUSED, ResponsePtr rp)
Definition: cmds.c:2107
static int NcFTPConfirmResumeUploadProc(const char *volatile localpath, volatile longest_int localsize, volatile time_t localmtime, const char *volatile *remotepath, volatile longest_int remotesize, volatile time_t remotemtime, volatile longest_int *volatile startPoint)
Definition: cmds.c:2569
#define kFirewallFwuAtSiteFwpUserPass
Definition: ncftp.h:394
int gAutoResume
Definition: pref.c:30
char ip[32]
Definition: ncftp.h:154
void(* FTPSigProc)(int)
Definition: ncftp.h:76
int codeType
Definition: ncftp.h:91
BITMAP bmp
Definition: alphablend.c:62
Definition: ncftp.h:89
char gOurInstallationPath[]
Definition: util.c:18
void FillBookmarkInfo(BookmarkPtr bmp)
Definition: cmds.c:194
Bookmark gBm
Definition: bookmark.c:24
#define kErrChmodFailed
Definition: ncftp_errno.h:59
void RunBatch(int Xstruct, const FTPCIPtr cip)
Definition: spool.c:364
Definition: ncftp.h:79
char firewallUser[64]
Definition: ncftp.h:218
#define kTypeAscii
Definition: ncftp.h:353
#define kErrTYPEFailed
Definition: ncftp_errno.h:64
#define kTypeEbcdic
Definition: ncftp.h:355
#define kDeleteYes
Definition: ncftp.h:368
#define SIGPIPE
Definition: signal.h:35
char gFirewallUser[32]
Definition: preffw.c:19
Definition: ncftp.h:84
#define kCmdHidden
Definition: shell.h:58
FTPConnectionInfo gConn
Definition: main.c:37
Definition: parse.h:22
#define kRedialStatusSleeping
Definition: ncftp.h:347
GLuint GLuint stream
Definition: glext.h:7522
char gRemoteCWD[512]
Definition: cmds.c:33
FILE * OpenBookmarkFile(int *numBookmarks0)
Definition: bookmark.c:275
void OpenCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:2317
void LocalRmCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:1802
#define CreateMailslot
Definition: winbase.h:3589
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
void VersionCmd(const int argc, const char **const argv, const CommandPtr cmdp, const ArgvInfoPtr aip)
Definition: cmds.c:3687
int DecodeDirectoryURL(const FTPCIPtr cip, char *url, LineListPtr cdlist, char *fn, size_t fnsize)
Definition: util.c:1086
#define NoConfirmResumeDownloadProc
Definition: ncftp.h:451
GLdouble s
Definition: gl.h:2039
#define Trace(x)
Definition: zutil.h:197
LinePtr first
Definition: ncftp.h:85