1/* spool.c 2 * 3 * Copyright (c) 1992-2005 by Mike Gleason. 4 * All rights reserved. 5 * 6 */ 7 8#include "syshdrs.h" 9#ifdef PRAGMA_HDRSTOP 10# pragma hdrstop 11#endif 12 13#ifdef HAVE_LONG_FILE_NAMES 14 15#include "spool.h" 16#ifdef ncftp 17# include "trace.h" 18#endif 19#include "util.h" 20 21int gUnprocessedJobs = 0; 22int gJobs = 0; 23int gHaveSpool = -1; 24 25extern char gOurDirectoryPath[]; 26#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__) 27extern char gOurInstallationPath[]; 28#endif 29 30void 31TruncBatchLog(void) 32{ 33 char f[256]; 34 struct stat st; 35 time_t t; 36 int fd; 37 38 if (gOurDirectoryPath[0] != '\0') { 39 time(&t); 40 t -= 86400; 41 (void) OurDirectoryPath(f, sizeof(f), kSpoolLog); 42 if ((stat(f, &st) == 0) && (st.st_mtime < t)) { 43 /* Truncate old log file. 44 * Do not remove it, since a process 45 * could still conceivably be going. 46 */ 47 fd = open(f, O_WRONLY|O_TRUNC, 00600); 48 if (fd >= 0) 49 close(fd); 50 } 51 } 52} /* TruncBatchLog */ 53 54 55 56 57int 58HaveSpool(void) 59{ 60#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__) 61 char ncftpbatch[260]; 62 63 if (gHaveSpool < 0) { 64 gHaveSpool = 0; 65 if (gOurInstallationPath[0] != '\0') { 66 OurInstallationPath(ncftpbatch, sizeof(ncftpbatch), "ncftpbatch.exe"); 67 gHaveSpool = (_access(ncftpbatch, F_OK) == 0) ? 1 : 0; 68 } 69 } 70#elif (defined(BINDIR) || defined(PREFIX_BINDIR)) 71 char ncftpbatch[256]; 72 73 if (gHaveSpool < 0) { 74#ifdef PREFIX_BINDIR 75 STRNCPY(ncftpbatch, PREFIX_BINDIR); 76#else 77 STRNCPY(ncftpbatch, BINDIR); 78#endif 79 STRNCAT(ncftpbatch, "/"); 80 STRNCAT(ncftpbatch, "ncftpbatch"); 81 gHaveSpool = (access(ncftpbatch, X_OK) == 0) ? 1 : 0; 82 } 83#else /* BINDIR */ 84 if (gHaveSpool < 0) { 85 if (geteuid() == 0) { 86 gHaveSpool = (access("/usr/bin/ncftpbatch", X_OK) == 0) ? 1 : 0; 87 } else { 88 gHaveSpool = (system("ncftpbatch -X") == 0) ? 1 : 0; 89 } 90 } 91#endif /* BINDIR */ 92 93 return (gHaveSpool); 94} /* HaveSpool */ 95 96 97 98 99int 100CanSpool(void) 101{ 102 char sdir[256]; 103 104 if (gOurDirectoryPath[0] == '\0') { 105 return (-1); 106 } 107 if (MkSpoolDir(sdir, sizeof(sdir)) < 0) 108 return (-1); 109 return (0); 110} /* CanSpool */ 111 112 113 114 115void 116Jobs(void) 117{ 118#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__) 119 assert(0); // Not supported 120#else 121 char *argv[8]; 122 pid_t pid; 123#if (defined(BINDIR) || defined(PREFIX_BINDIR)) 124 char ncftpbatch[256]; 125 126#ifdef BINDIR 127 STRNCPY(ncftpbatch, BINDIR); 128#else 129 STRNCPY(ncftpbatch, PREFIX_BINDIR); 130#endif 131 STRNCAT(ncftpbatch, "/"); 132 STRNCAT(ncftpbatch, "ncftpbatch"); 133#endif /* BINDIR */ 134 135 pid = fork(); 136 if (pid < 0) { 137 perror("fork"); 138 } else if (pid == 0) { 139 argv[0] = strdup("ncftpbatch"); 140 argv[1] = strdup("-l"); 141 argv[2] = NULL; 142 143#if (defined(BINDIR) || defined(PREFIX_BINDIR)) 144 (void) execv(ncftpbatch, argv); 145 (void) fprintf(stderr, "Could not run %s. Is it in installed as %s?\n", argv[0], ncftpbatch); 146#else /* BINDIR */ 147 (void) execvp(argv[0], argv); 148 (void) fprintf(stderr, "Could not run %s. Is it in your $PATH?\n", argv[0]); 149#endif /* BINDIR */ 150 perror(argv[0]); 151 exit(1); 152 } else { 153#ifdef HAVE_WAITPID 154 (void) waitpid(pid, NULL, 0); 155#else 156 (void) wait(NULL); 157#endif 158 } 159#endif 160} /* Jobs */ 161 162 163 164 165void 166RunBatchWithCore(const FTPCIPtr cip) 167{ 168#if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__) 169 RunBatch(); 170#else /* UNIX */ 171 int pfd[2]; 172 char pfdstr[32]; 173 char *argv[8]; 174 pid_t pid = 0; 175#if (defined(BINDIR) || defined(PREFIX_BINDIR)) 176 char ncftpbatch[256]; 177 178#ifdef BINDIR 179 STRNCPY(ncftpbatch, BINDIR); 180#else 181 STRNCPY(ncftpbatch, PREFIX_BINDIR); 182#endif 183 STRNCAT(ncftpbatch, "/"); 184 STRNCAT(ncftpbatch, "ncftpbatch"); 185#endif /* BINDIR */ 186 187 if (pipe(pfd) < 0) { 188 perror("pipe"); 189 } 190 191 (void) sprintf(pfdstr, "%d", pfd[0]); 192 pid = fork(); 193 if (pid < 0) { 194 (void) close(pfd[0]); 195 (void) close(pfd[1]); 196 perror("fork"); 197 } else if (pid == 0) { 198 (void) close(pfd[1]); /* Child closes write end. */ 199 argv[0] = strdup("ncftpbatch"); 200#ifdef DEBUG_NCFTPBATCH 201 argv[1] = strdup("-D"); 202 argv[2] = strdup("-Z"); 203 argv[3] = strdup("15"); 204 argv[4] = strdup("-|"); 205 argv[5] = strdup(pfdstr); 206 argv[6] = NULL; 207#else 208 argv[1] = strdup("-d"); 209 argv[2] = strdup("-|"); 210 argv[3] = strdup(pfdstr); 211 argv[4] = NULL; 212#endif 213 214#if (defined(BINDIR) || defined(PREFIX_BINDIR)) 215 (void) execv(ncftpbatch, argv); 216 (void) fprintf(stderr, "Could not run %s. Is it in installed as %s?\n", argv[0], ncftpbatch); 217#else /* BINDIR */ 218 (void) execvp(argv[0], argv); 219 (void) fprintf(stderr, "Could not run %s. Is it in your $PATH?\n", argv[0]); 220#endif /* BINDIR */ 221 perror(argv[0]); 222 exit(1); 223 } 224 (void) close(pfd[0]); /* Parent closes read end. */ 225 (void) PWrite(pfd[1], (const char *) cip->lip, sizeof(FTPLibraryInfo)); 226 (void) PWrite(pfd[1], (const char *) cip, sizeof(FTPConnectionInfo)); 227 (void) close(pfd[1]); /* Parent closes read end. */ 228 229 /* Close it now, or else this process would send 230 * the server a QUIT message. This will cause it 231 * to think it already has. 232 */ 233 FTPCloseControlConnection(cip); 234 235 if (pid > 1) { 236#ifdef HAVE_WAITPID 237 (void) waitpid(pid, NULL, 0); 238#else 239 (void) wait(NULL); 240#endif /* HAVE_WAITPID */ 241 } 242#endif /* UNIX */ 243} /* RunBatchWithCore */ 244 245 246 247void 248RunBatchIfNeeded(const FTPCIPtr cip) 249{ 250 if (gUnprocessedJobs > 0) { 251#ifdef ncftp 252 Trace(0, "Running ncftp_batch for %d job%s.\n", gUnprocessedJobs, gUnprocessedJobs > 0 ? "s" : ""); 253 gUnprocessedJobs = 0; 254 RunBatchWithCore(cip); 255#else 256 gUnprocessedJobs = 0; 257 RunBatch(); 258#endif 259 } 260} /* RunBatchIfNeeded */ 261 262#else /* ! HAVE_LONG_FILE_NAMES */ 263 264int gUnprocessedJobs = 0; 265int gJobs = 0; 266int gHaveSpool = -1; 267 268void 269Jobs(void) 270{ 271 fprintf(stderr, "Background processing not available on this platform.\n"); 272} 273 274void 275RunBatchIfNeeded(const FTPCIPtr cip) 276{ 277} 278 279void 280RunBatchWithCore(const FTPCIPtr cip) 281{ 282} 283 284void 285TruncBatchLog(void) 286{ 287} 288 289int 290HaveSpool(void) 291{ 292 return (0); 293} 294 295int 296CanSpool(void) 297{ 298 return (-1); 299} 300 301#endif /* HAVE_LONG_FILE_NAMES */ 302