3 * Copyright (c) 1992-2001 by Mike Gleason.
10 #ifdef HAVE_LONG_FILE_NAMES
19 int gUnprocessedJobs
= 0;
23 extern FTPLibraryInfo gLib
;
24 extern char gOurDirectoryPath
[], gOurInstallationPath
[];
25 extern void CloseControlConnection(const FTPCIPtr
);
37 if (gOurDirectoryPath
[0] != '\0') {
40 (void) OurDirectoryPath(f
, sizeof(f
), kSpoolLog
);
41 if ((stat(f
, &st
) == 0) && (st
.st_mtime
< t
)) {
42 /* Truncate old log file.
43 * Do not remove it, since a process
44 * could still conceivably be going.
46 fd
= open(f
, O_WRONLY
|O_TRUNC
, 00600);
56 MkSpoolDir(char *sdir
, size_t size
)
61 /* Don't create in root directory. */
62 if (gOurDirectoryPath
[0] != '\0') {
63 (void) OurDirectoryPath(sdir
, size
, kSpoolDir
);
64 if ((stat(sdir
, &st
) < 0) && (MkDirs(sdir
, 00700) < 0)) {
78 SpoolName(const char *const sdir
, char *sp
, size_t size
, int flag
, int serial
, time_t when
)
84 if ((when
== (time_t) 0) || (when
== (time_t) -1))
86 ltp
= localtime(&when
);
89 (void) Strncpy(dstr
, "19700101-000000", size
);
91 (void) strftime(dstr
, sizeof(dstr
), "%Y%m%d-%H%M%S", ltp
);
93 (void) Strncpy(sp
, sdir
, size
);
94 (void) sprintf(sname
, "/%c-%010u-%04x-%s",
96 (unsigned int) getpid(),
97 (serial
% (16 * 16 * 16 * 16)),
100 (void) Strncat(sp
, sname
, size
);
109 #if defined(WIN32) || defined(_WINDOWS)
110 char ncftpbatch
[260];
112 if (gHaveSpool
< 0) {
114 if (gOurInstallationPath
[0] != '\0') {
115 OurInstallationPath(ncftpbatch
, sizeof(ncftpbatch
), "ncftpbatch.exe");
116 gHaveSpool
= (access(ncftpbatch
, F_OK
) == 0) ? 1 : 0;
119 #elif defined(BINDIR)
120 char ncftpbatch
[256];
122 if (gHaveSpool
< 0) {
123 STRNCPY(ncftpbatch
, BINDIR
);
124 STRNCAT(ncftpbatch
, "/");
125 STRNCAT(ncftpbatch
, "ncftpbatch");
126 gHaveSpool
= (access(ncftpbatch
, X_OK
) == 0) ? 1 : 0;
129 if (gHaveSpool
< 0) {
130 if (geteuid() == 0) {
131 gHaveSpool
= (access("/usr/bin/ncftpbatch", X_OK
) == 0) ? 1 : 0;
133 gHaveSpool
= (system("ncftpbatch -X") == 0) ? 1 : 0;
149 if (gOurDirectoryPath
[0] == '\0') {
152 if (MkSpoolDir(sdir
, sizeof(sdir
)) < 0)
162 const char *const op
,
163 const char *const rfile
,
164 const char *const rdir
,
165 const char *const lfile
,
166 const char *const ldir
,
167 const char *const host
,
168 const char *const ip
,
169 const unsigned int port
,
170 const char *const user
,
171 const char *const passclear
,
176 const char *const precmd
,
177 const char *const perfilecmd
,
178 const char *const postcmd
,
184 char spathname2
[256];
187 #if defined(WIN32) || defined(_WINDOWS)
192 if (MkSpoolDir(sdir
, sizeof(sdir
)) < 0)
196 SpoolName(sdir
, spathname2
, sizeof(spathname2
), op
[0], gSpoolSerial
, when
);
197 SpoolName(sdir
, spathname
, sizeof(spathname
), 'z', gSpoolSerial
, when
);
198 #if defined(WIN32) || defined(_WINDOWS)
199 fp
= fopen(spathname
, FOPEN_WRITE_TEXT
);
202 fp
= fopen(spathname
, FOPEN_WRITE_TEXT
);
208 if (fprintf(fp
, "# This is a NcFTP spool file entry.\n# Run the \"ncftpbatch\" program to process the spool directory.\n#\n") < 0)
210 if (fprintf(fp
, "op=%s\n", op
) < 0)
212 if (fprintf(fp
, "hostname=%s\n", host
) < 0)
214 if ((ip
!= NULL
) && (ip
[0] != '\0') && (fprintf(fp
, "host-ip=%s\n", ip
) < 0))
216 if ((port
> 0) && (port
!= (unsigned int) kDefaultFTPPort
) && (fprintf(fp
, "port=%u\n", port
) < 0))
218 if ((user
!= NULL
) && (user
[0] != '\0') && (strcmp(user
, "anonymous") != 0) && (fprintf(fp
, "user=%s\n", user
) < 0))
220 if ((strcmp(user
, "anonymous") != 0) && (passclear
!= NULL
) && (passclear
[0] != '\0')) {
221 (void) memcpy(pass
, kPasswordMagic
, kPasswordMagicLen
);
222 ToBase64(pass
+ kPasswordMagicLen
, passclear
, strlen(passclear
), 1);
223 if (fprintf(fp
, "pass=%s\n", pass
) < 0)
225 } else if ((strcmp(user
, "anonymous") == 0) && (gLib
.defaultAnonPassword
[0] != '\0')) {
226 if (fprintf(fp
, "anon-pass=%s\n", gLib
.defaultAnonPassword
) < 0)
229 if (fprintf(fp
, "xtype=%c\n", xtype
) < 0)
231 if ((recursive
!= 0) && (fprintf(fp
, "recursive=%s\n", YESNO(recursive
)) < 0))
233 if ((delete != 0) && (fprintf(fp
, "delete=%s\n", YESNO(delete)) < 0))
235 if (fprintf(fp
, "passive=%d\n", passive
) < 0)
237 if (fprintf(fp
, "remote-dir=%s\n", rdir
) < 0)
239 if ((ldir
== NULL
) || (ldir
[0] == '\0') || (strcmp(ldir
, ".") == 0)) {
240 /* Use current process' working directory. */
241 FTPGetLocalCWD(ldir2
, sizeof(ldir2
));
242 if (fprintf(fp
, "local-dir=%s\n", ldir2
) < 0)
245 if (fprintf(fp
, "local-dir=%s\n", ldir
) < 0)
248 if (fprintf(fp
, "remote-file=%s\n", rfile
) < 0)
250 if (fprintf(fp
, "local-file=%s\n", lfile
) < 0)
252 if ((precmd
!= NULL
) && (precmd
[0] != '\0') && (fprintf(fp
, "pre-command=%s\n", precmd
) < 0))
254 if ((perfilecmd
!= NULL
) && (perfilecmd
[0] != '\0') && (fprintf(fp
, "per-file-command=%s\n", perfilecmd
) < 0))
256 if ((postcmd
!= NULL
) && (postcmd
[0] != '\0') && (fprintf(fp
, "post-command=%s\n", postcmd
) < 0))
262 /* Move the spool file into its "live" name. */
263 if (rename(spathname
, spathname2
) < 0) {
264 perror("rename spoolfile failed");
273 perror("write to spool file failed");
275 (void) unlink(spathname
);
281 #if defined(WIN32) || defined(_WINDOWS)
284 PWrite(int sfd
, const char *const buf0
, size_t size
)
287 const char *buf
= buf0
;
292 nwrote
= (int) write(sfd
, buf
, nleft
);
294 if (errno
!= EINTR
) {
295 nwrote
= (int) size
- nleft
;
310 nwrote
= (int) size
- nleft
;
320 #if defined(WIN32) || defined(_WINDOWS)
321 assert(0); // Not supported
326 char ncftpbatch
[256];
328 STRNCPY(ncftpbatch
, BINDIR
);
329 STRNCAT(ncftpbatch
, "/");
330 STRNCAT(ncftpbatch
, "ncftpbatch");
336 } else if (pid
== 0) {
337 argv
[0] = (char *) "ncftpbatch";
338 argv
[1] = (char *) "-l";
342 (void) execv(ncftpbatch
, argv
);
343 (void) fprintf(stderr
, "Could not run %s. Is it in installed as %s?\n", argv
[0], ncftpbatch
);
345 (void) execvp(argv
[0], argv
);
346 (void) fprintf(stderr
, "Could not run %s. Is it in your $PATH?\n", argv
[0]);
352 (void) waitpid(pid
, NULL
, 0);
364 RunBatch(int Xstruct
, const FTPCIPtr cip
)
366 #if defined(WIN32) || defined(_WINDOWS)
367 char ncftpbatch
[260];
371 if (gOurInstallationPath
[0] == '\0') {
372 (void) fprintf(stderr
, "Cannot find path to %s. Please re-run Setup.\n", "ncftpbatch.exe");
376 OurInstallationPath(ncftpbatch
, sizeof(ncftpbatch
), "ncftpbatch.exe");
378 winExecResult
= WinExec(prog
, SW_SHOWNORMAL
);
379 if (winExecResult
<= 31) switch (winExecResult
) {
380 case ERROR_BAD_FORMAT
:
381 fprintf(stderr
, "Could not run %s: %s\n", prog
, "The .EXE file is invalid");
383 case ERROR_FILE_NOT_FOUND
:
384 fprintf(stderr
, "Could not run %s: %s\n", prog
, "The specified file was not found.");
386 case ERROR_PATH_NOT_FOUND
:
387 fprintf(stderr
, "Could not run %s: %s\n", prog
, "The specified path was not found.");
390 fprintf(stderr
, "Could not run %s: Unknown error #%d.\n", prog
, winExecResult
);
399 char ncftpbatch
[256];
401 STRNCPY(ncftpbatch
, BINDIR
);
402 STRNCAT(ncftpbatch
, "/");
403 STRNCAT(ncftpbatch
, "ncftpbatch");
411 (void) sprintf(pfdstr
, "%d", pfd
[0]);
414 (void) close(pfd
[0]);
415 (void) close(pfd
[1]);
417 } else if (pid
== 0) {
418 (void) close(pfd
[1]); /* Child closes write end. */
419 argv
[0] = (char *) "ncftpbatch";
420 #ifdef DEBUG_NCFTPBATCH
421 argv
[1] = (char *) "-SD";
423 argv
[1] = (char *) "-d";
425 argv
[2] = (char *) "-|";
430 (void) execv(ncftpbatch
, argv
);
431 (void) fprintf(stderr
, "Could not run %s. Is it in installed as %s?\n", argv
[0], ncftpbatch
);
433 (void) execvp(argv
[0], argv
);
434 (void) fprintf(stderr
, "Could not run %s. Is it in your $PATH?\n", argv
[0]);
439 (void) close(pfd
[0]); /* Parent closes read end. */
440 (void) PWrite(pfd
[1], (const char *) cip
->lip
, sizeof(FTPLibraryInfo
));
441 (void) PWrite(pfd
[1], (const char *) cip
, sizeof(FTPConnectionInfo
));
442 (void) close(pfd
[1]); /* Parent closes read end. */
444 /* Close it now, or else this process would send
445 * the server a QUIT message. This will cause it
446 * to think it already has.
448 CloseControlConnection(cip
);
453 } else if (pid
== 0) {
454 argv
[0] = (char *) "ncftpbatch";
455 argv
[1] = (char *) "-d";
458 (void) execv(ncftpbatch
, argv
);
459 (void) fprintf(stderr
, "Could not run %s. Is it in installed as %s?\n", argv
[0], ncftpbatch
);
461 (void) execvp(argv
[0], argv
);
462 (void) fprintf(stderr
, "Could not run %s. Is it in your $PATH?\n", argv
[0]);
471 (void) waitpid(pid
, NULL
, 0);
482 RunBatchIfNeeded(const FTPCIPtr cip
)
484 if (gUnprocessedJobs
> 0) {
486 Trace(0, "Running ncftp_batch for %d job%s.\n", gUnprocessedJobs
, gUnprocessedJobs
> 0 ? "s" : "");
487 gUnprocessedJobs
= 0;
490 gUnprocessedJobs
= 0;
494 } /* RunBatchIfNeeded */
496 #endif /* HAVE_LONG_FILE_NAMES */