3 * Copyright (c) 1992-2001 by Mike Gleason.
23 #if defined(WIN32) || defined(_WINDOWS)
27 __inline
void DisposeWinsock(int aUNUSED
) { if (wsaInit
> 0) WSACleanup(); wsaInit
--; }
29 # define DisposeWinsock(a)
32 int gStartupUrlParameterGiven
= 0;
37 FTPConnectionInfo gConn
;
38 LineList gStartupURLCdList
;
39 int gTransferTypeInitialized
= 0;
42 extern int gUnprocessedJobs
;
43 char gLocalCWD
[512], gPrevLocalCWD
[512];
47 extern char gRemoteCWD
[512], gPrevRemoteCWD
[512];
50 extern int gFirstTimeUser
;
51 extern int gFirewallType
;
52 extern char gAutoAscii
[];
53 extern char gFirewallHost
[64];
54 extern char gFirewallUser
[32];
55 extern char gFirewallPass
[32];
56 extern char gFirewallExceptionList
[];
57 extern char gCopyright
[], gVersion
[];
58 extern unsigned int gFirewallPort
;
59 extern int gConnTimeout
, gXferTimeout
, gCtrlTimeout
;
60 extern int gDataPortMode
, gRedialDelay
;
62 extern int gNumProgramRuns
, gDoNotDisplayAds
;
63 extern int gSOBufsize
;
64 extern FTPProgressMeterProc gProgressMeter
;
75 (void) fprintf(fp
, "\nUsage: ncftp [flags] [<host> | <directory URL to browse>]\n");
76 (void) fprintf(fp
, "\nFlags:\n\
77 -u XX Use username XX instead of anonymous.\n\
78 -p XX Use password XX with the username.\n\
79 -P XX Use port number XX instead of the default FTP service port (21).\n\
80 -j XX Use account XX with the username (rarely needed).\n\
81 -F Dump a sample $HOME/.ncftp/firewall prefs file to stdout and exit.\n");
83 (void) fprintf(fp
, "\nProgram version: %s\nLibrary version: %s\n", gVersion
+ 5, gLibNcFTPVersion
+ 5);
85 AbbrevStr(s
, UNAME
, 60, 1);
86 (void) fprintf(fp
, "System: %s\n", s
);
88 (void) fprintf(fp
, "\nThis is a freeware program by Mike Gleason (ncftp@ncftp.com).\n");
89 (void) fprintf(fp
, "Use ncftpget and ncftpput for command-line FTP.\n\n");
97 DumpFirewallPrefsTemplate(void)
99 WriteDefaultFirewallPrefs(stdout
);
100 } /* DumpFirewallPrefsTemplate */
105 /* This resets our state information whenever we are ready to open a new
109 InitConnectionInfo(void)
113 result
= FTPInitConnectionInfo(&gLib
, &gConn
, kDefaultFTPBufSize
);
115 (void) fprintf(stderr
, "ncftp: init connection info error %d (%s).\n", result
, FTPStrError(result
));
119 gConn
.debugLog
= NULL
;
120 gConn
.errLog
= stderr
;
123 (void) STRNCPY(gConn
.user
, "anonymous");
124 gConn
.host
[0] = '\0';
125 gConn
.progress
= gProgressMeter
;
126 gTransferTypeInitialized
= 0;
127 gTransferType
= kTypeBinary
;
128 gConn
.leavePass
= 1; /* Don't let the lib zap it. */
129 gConn
.connTimeout
= gConnTimeout
;
130 gConn
.xferTimeout
= gXferTimeout
;
131 gConn
.ctrlTimeout
= gCtrlTimeout
;
132 gConn
.dataPortMode
= gDataPortMode
;
133 gConn
.maxDials
= (-1); /* Dial forever, until they hit ^C. */
134 gUnprocessedJobs
= 0;
135 gPrevRemoteCWD
[0] = '\0';
136 gConn
.dataSocketRBufSize
= gConn
.dataSocketSBufSize
= gSOBufsize
;
137 if (gRedialDelay
>= 10)
138 gConn
.redialDelay
= gRedialDelay
;
139 if ((gAutoAscii
[0] == '\0') || (ISTREQ(gAutoAscii
, "no")) || (ISTREQ(gAutoAscii
, "off")) || (ISTREQ(gAutoAscii
, "false"))) {
140 gConn
.asciiFilenameExtensions
= NULL
;
142 gConn
.asciiFilenameExtensions
= gAutoAscii
;
144 } /* InitConnectionInfo */
149 /* This lets us do things with our state information just before the
155 if (gConn
.connected
!= 0) {
156 if (gConn
.loggedIn
!= 0) {
157 SaveUnsavedBookmark();
159 RunBatchIfNeeded(&gConn
);
161 gConn
.ctrlTimeout
= 3;
162 (void) FTPCloseHost(&gConn
);
168 /* If the user specified a URL on the command-line, this initializes
169 * our state information based upon it.
172 SetStartupURL(const char *const urlgiven
)
179 (void) STRNCPY(url
, urlgiven
);
181 rc
= DecodeDirectoryURL(&gConn
, url
, &gStartupURLCdList
, urlfile
, sizeof(urlfile
));
182 if (rc
== kMalformedURL
) {
183 (void) fprintf(stderr
, "Malformed URL: %s\n", url
);
185 } else if (rc
== kNotURL
) {
186 /* This is what should happen most of the time. */
187 (void) STRNCPY(gConn
.host
, urlgiven
);
189 if (GetBookmark(gConn
.host
, &gBm
) >= 0) {
191 (void) STRNCPY(gConn
.host
, gBm
.name
);
192 (void) STRNCPY(gConn
.user
, gBm
.user
);
193 (void) STRNCPY(gConn
.pass
, gBm
.pass
);
194 (void) STRNCPY(gConn
.acct
, gBm
.acct
);
195 gConn
.hasSIZE
= gBm
.hasSIZE
;
196 gConn
.hasMDTM
= gBm
.hasMDTM
;
197 gConn
.hasPASV
= gBm
.hasPASV
;
198 gConn
.hasUTIME
= gBm
.hasUTIME
;
199 gConn
.port
= gBm
.port
;
201 SetBookmarkDefaults(&gBm
);
204 if (MayUseFirewall(gConn
.host
, gFirewallType
, gFirewallExceptionList
) != 0) {
205 gConn
.firewallType
= gFirewallType
;
206 (void) STRNCPY(gConn
.firewallHost
, gFirewallHost
);
207 (void) STRNCPY(gConn
.firewallUser
, gFirewallUser
);
208 (void) STRNCPY(gConn
.firewallPass
, gFirewallPass
);
209 gConn
.firewallPort
= gFirewallPort
;
213 if (urlfile
[0] != '\0') {
214 /* It was obviously not a directory */
215 (void) fprintf(stderr
, "Use ncftpget or ncftpput to handle file URLs.\n");
219 if (MayUseFirewall(gConn
.host
, gFirewallType
, gFirewallExceptionList
) != 0) {
220 gConn
.firewallType
= gFirewallType
;
221 (void) STRNCPY(gConn
.firewallHost
, gFirewallHost
);
222 (void) STRNCPY(gConn
.firewallUser
, gFirewallUser
);
223 (void) STRNCPY(gConn
.firewallPass
, gFirewallPass
);
224 gConn
.firewallPort
= gFirewallPort
;
227 } /* SetStartupURL */
239 SetBookmarkDefaults(&gBm
);
241 for (lp
= gStartupURLCdList
.first
; lp
!= NULL
; lp
= lp
->next
) {
242 result
= FTPChdir(&gConn
, lp
->line
);
243 if (result
!= kNoErr
) {
244 FTPPerror(&gConn
, result
, kErrCWDFailed
, "Could not chdir to", lp
->line
);
248 result
= FTPGetCWD(&gConn
, gRemoteCWD
, sizeof(gRemoteCWD
));
249 if (result
!= kNoErr
) {
250 FTPPerror(&gConn
, result
, kErrPWDFailed
, NULL
, NULL
);
252 (void) printf("Current remote directory is %s.\n", gRemoteCWD
);
255 } else if (gURLMode
== 2) {
263 /* These things are done first, before we even parse the command-line
271 #if defined(WIN32) || defined(_WINDOWS)
272 if (WSAStartup(MAKEWORD(1, 1), &wsaData
) != 0) {
273 fprintf(stderr
, "could not initialize winsock\n");
279 #ifdef HAVE_SETLOCALE
280 setlocale(LC_ALL
, "");
282 #if defined(WIN32) || defined(_WINDOWS)
286 gIsTTY
= ((isatty(2) != 0) && (getppid() > 1)) ? 1 : 0;
287 gIsTTYr
= ((isatty(0) != 0) && (getppid() > 1)) ? 1 : 0;
290 (void) NcSignal(SIGPOLL
, (FTPSigProc
) SIG_IGN
);
293 result
= FTPInitLibrary(&gLib
);
295 (void) fprintf(stderr
, "ncftp: init library error %d (%s).\n", result
, FTPStrError(result
));
298 #if defined(WIN32) || defined(_WINDOWS)
299 srand((unsigned int) (GetTickCount() & 0x7FFF));
301 srand((unsigned int) getpid());
303 InitLineList(&gStartupURLCdList
);
307 LoadFirewallPrefs(0);
309 InitConnectionInfo();
321 /* These things are done at startup, but after we parse the command-line
331 (void) FTPGetLocalCWD(gLocalCWD
, sizeof(gLocalCWD
));
332 gPrevLocalCWD
[0] = '\0';
333 PrintStartupBanner();
334 if (gNumProgramRuns
<= 1)
335 (void) printf("\n%s\n", gCopyright
+ 5);
337 Trace(0, "Fw: %s Type: %d User: %s Pass: %s Port: %u\n",
341 (gFirewallPass
[0] == '\0') ? "(none)" : "********",
344 Trace(0, "FwExceptions: %s\n", gFirewallExceptionList
);
345 if (strchr(gLib
.ourHostName
, '.') == NULL
) {
346 Trace(0, "NOTE: Your domain name could not be detected.\n");
347 if (gConn
.firewallType
!= kFirewallNotInUse
) {
348 Trace(0, " Make sure you manually add your domain name to firewall-exception-list.\n");
356 /* Try to get the user to evaluate my commercial offerings. */
360 #if defined(WIN32) || defined(_WINDOWS)
361 /* NcFTPd hasn't been ported to Windows. */
363 if ((gDoNotDisplayAds
== 0) && ((gNumProgramRuns
% 7) == 2)) {
364 (void) printf("\n\n\n\tThank you for using NcFTP Client.\n\tAsk your system administrator to try NcFTPd Server!\n\thttp://www.ncftpd.com\n\n\n\n");
372 /* These things are just before the program exits. */
376 SetXtermTitle("RESTORE");
390 main(int argc
, const char **const argv
)
396 while ((c
= Getopt(argc
, argv
, "P:u:p:J:rd:g:FVLD")) > 0) switch(c
) {
401 gStartupUrlParameterGiven
= 1;
415 if (gOptInd
< argc
) {
416 LoadFirewallPrefs(0);
417 SetStartupURL(argv
[gOptInd
]);
418 } else if (gStartupUrlParameterGiven
!= 0) {
419 /* One of the flags they specified
420 * requires a URL or hostname to
427 /* Allow command-line parameters to override
431 while ((c
= Getopt(argc
, argv
, "P:u:p:j:J:rd:g:FVLD")) > 0) switch(c
) {
433 gConn
.port
= atoi(gOptArg
);
436 (void) STRNCPY(gConn
.user
, gOptArg
);
439 (void) STRNCPY(gConn
.pass
, gOptArg
); /* Don't recommend doing this! */
443 (void) STRNCPY(gConn
.acct
, gOptArg
);
446 /* redial is always on */
449 gConn
.maxDials
= atoi(gOptArg
);
454 gConn
.redialDelay
= n
;
457 DumpFirewallPrefsTemplate();
466 /* silently ignore these legacy options */