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