ReactOS 0.4.15-dev-7788-g1ad9096
spool.c
Go to the documentation of this file.
1/* spool.c
2 *
3 * Copyright (c) 1992-2001 by Mike Gleason.
4 * All rights reserved.
5 *
6 */
7
8#include "syshdrs.h"
9
10#ifdef HAVE_LONG_FILE_NAMES
11
12#include "spool.h"
13#ifdef ncftp
14# include "trace.h"
15#endif
16#include "util.h"
17
20int gJobs = 0;
21int gHaveSpool = -1;
22
23extern FTPLibraryInfo gLib;
25extern void CloseControlConnection(const FTPCIPtr);
26
27
28
29void
31{
32 char f[256];
33 struct stat st;
34 time_t t;
35 int fd;
36
37 if (gOurDirectoryPath[0] != '\0') {
38 time(&t);
39 t -= 86400;
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.
45 */
46 fd = open(f, O_WRONLY|O_TRUNC, 00600);
47 if (fd >= 0)
48 close(fd);
49 }
50 }
51} /* TruncBatchLog */
52
53
54
55int
56MkSpoolDir(char *sdir, size_t size)
57{
58 struct stat st;
59 *sdir = '\0';
60
61 /* Don't create in root directory. */
62 if (gOurDirectoryPath[0] != '\0') {
64 if ((stat(sdir, &st) < 0) && (MkDirs(sdir, 00700) < 0)) {
65 perror(sdir);
66 return (-1);
67 } else {
68 return (0);
69 }
70 }
71 return (-1);
72} /* MkSpoolDir */
73
74
75
76
77void
78SpoolName(const char *const sdir, char *sp, size_t size, int flag, int serial, time_t when)
79{
80 char sname[64];
81 char dstr[32];
82 struct tm *ltp;
83
84 if ((when == (time_t) 0) || (when == (time_t) -1))
85 (void) time(&when);
86 ltp = localtime(&when);
87 if (ltp == NULL) {
88 /* impossible */
89 (void) Strncpy(dstr, "19700101-000000", size);
90 } else {
91 (void) strftime(dstr, sizeof(dstr), "%Y%m%d-%H%M%S", ltp);
92 }
93 (void) Strncpy(sp, sdir, size);
94 (void) sprintf(sname, "/%c-%010u-%04x-%s",
95 flag,
96 (unsigned int) getpid(),
97 (serial % (16 * 16 * 16 * 16)),
98 dstr
99 );
100 (void) Strncat(sp, sname, size);
101} /* SpoolName */
102
103
104
105
106int
108{
109#if defined(WIN32) || defined(_WINDOWS)
110 char ncftpbatch[260];
111
112 if (gHaveSpool < 0) {
113 gHaveSpool = 0;
114 if (gOurInstallationPath[0] != '\0') {
115 OurInstallationPath(ncftpbatch, sizeof(ncftpbatch), "ncftpbatch.exe");
116 gHaveSpool = (_access(ncftpbatch, F_OK) == 0) ? 1 : 0;
117 }
118 }
119#elif defined(BINDIR)
120 char ncftpbatch[256];
121
122 if (gHaveSpool < 0) {
123 STRNCPY(ncftpbatch, BINDIR);
124 STRNCAT(ncftpbatch, "/");
125 STRNCAT(ncftpbatch, "ncftpbatch");
126 gHaveSpool = (access(ncftpbatch, X_OK) == 0) ? 1 : 0;
127 }
128#else /* BINDIR */
129 if (gHaveSpool < 0) {
130 if (geteuid() == 0) {
131 gHaveSpool = (access("/usr/bin/ncftpbatch", X_OK) == 0) ? 1 : 0;
132 } else {
133 gHaveSpool = (system("ncftpbatch -X") == 0) ? 1 : 0;
134 }
135 }
136#endif /* BINDIR */
137
138 return (gHaveSpool);
139} /* HaveSpool */
140
141
142
143
144int
146{
147 char sdir[256];
148
149 if (gOurDirectoryPath[0] == '\0') {
150 return (-1);
151 }
152 if (MkSpoolDir(sdir, sizeof(sdir)) < 0)
153 return (-1);
154 return (0);
155} /* CanSpool */
156
157
158
159
160int
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,
172 int xtype,
173 int recursive,
174 int delete,
175 int passive,
176 const char *const precmd,
177 const char *const perfilecmd,
178 const char *const postcmd,
179 time_t when)
180{
181 char sdir[256];
182 char pass[160];
183 char spathname[256];
184 char spathname2[256];
185 char ldir2[256];
186 FILE *fp;
187#if defined(WIN32) || defined(_WINDOWS)
188#else
189 mode_t um;
190#endif
191
192 if (MkSpoolDir(sdir, sizeof(sdir)) < 0)
193 return (-1);
194
195 gSpoolSerial++;
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);
200#else
201 um = umask(077);
202 fp = fopen(spathname, FOPEN_WRITE_TEXT);
203 (void) umask(um);
204#endif
205 if (fp == NULL)
206 return (-1);
207
208 if (fprintf(fp, "# This is a NcFTP spool file entry.\n# Run the \"ncftpbatch\" program to process the spool directory.\n#\n") < 0)
209 goto err;
210 if (fprintf(fp, "op=%s\n", op) < 0)
211 goto err;
212 if (fprintf(fp, "hostname=%s\n", host) < 0)
213 goto err;
214 if ((ip != NULL) && (ip[0] != '\0') && (fprintf(fp, "host-ip=%s\n", ip) < 0))
215 goto err;
216 if ((port > 0) && (port != (unsigned int) kDefaultFTPPort) && (fprintf(fp, "port=%u\n", port) < 0))
217 goto err;
218 if ((user != NULL) && (user[0] != '\0') && (strcmp(user, "anonymous") != 0) && (fprintf(fp, "user=%s\n", user) < 0))
219 goto err;
220 if ((strcmp(user, "anonymous") != 0) && (passclear != NULL) && (passclear[0] != '\0')) {
222 ToBase64(pass + kPasswordMagicLen, passclear, strlen(passclear), 1);
223 if (fprintf(fp, "pass=%s\n", pass) < 0)
224 goto err;
225 } else if ((strcmp(user, "anonymous") == 0) && (gLib.defaultAnonPassword[0] != '\0')) {
226 if (fprintf(fp, "anon-pass=%s\n", gLib.defaultAnonPassword) < 0)
227 goto err;
228 }
229 if (fprintf(fp, "xtype=%c\n", xtype) < 0)
230 goto err;
231 if ((recursive != 0) && (fprintf(fp, "recursive=%s\n", YESNO(recursive)) < 0))
232 goto err;
233 if ((delete != 0) && (fprintf(fp, "delete=%s\n", YESNO(delete)) < 0))
234 goto err;
235 if (fprintf(fp, "passive=%d\n", passive) < 0)
236 goto err;
237 if (fprintf(fp, "remote-dir=%s\n", rdir) < 0)
238 goto err;
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)
243 goto err;
244 } else {
245 if (fprintf(fp, "local-dir=%s\n", ldir) < 0)
246 goto err;
247 }
248 if (fprintf(fp, "remote-file=%s\n", rfile) < 0)
249 goto err;
250 if (fprintf(fp, "local-file=%s\n", lfile) < 0)
251 goto err;
252 if ((precmd != NULL) && (precmd[0] != '\0') && (fprintf(fp, "pre-command=%s\n", precmd) < 0))
253 goto err;
254 if ((perfilecmd != NULL) && (perfilecmd[0] != '\0') && (fprintf(fp, "per-file-command=%s\n", perfilecmd) < 0))
255 goto err;
256 if ((postcmd != NULL) && (postcmd[0] != '\0') && (fprintf(fp, "post-command=%s\n", postcmd) < 0))
257 goto err;
258
259 if (fclose(fp) < 0)
260 goto err2;
261
262 /* Move the spool file into its "live" name. */
263 if (rename(spathname, spathname2) < 0) {
264 perror("rename spoolfile failed");
265 goto err3;
266 }
268 return (0);
269
270err:
271 (void) fclose(fp);
272err2:
273 perror("write to spool file failed");
274err3:
275 (void) unlink(spathname);
276 return (-1);
277}
278
279
280
281#if defined(WIN32) || defined(_WINDOWS)
282#else
283static int
284PWrite(int sfd, const char *const buf0, size_t size)
285{
286 int nleft;
287 const char *buf = buf0;
288 int nwrote;
289
290 nleft = (int) size;
291 for (;;) {
292 nwrote = (int) write(sfd, buf, nleft);
293 if (nwrote < 0) {
294 if (errno != EINTR) {
295 nwrote = (int) size - nleft;
296 if (nwrote == 0)
297 nwrote = -1;
298 return (nwrote);
299 } else {
300 errno = 0;
301 nwrote = 0;
302 /* Try again. */
303 }
304 }
305 nleft -= nwrote;
306 if (nleft <= 0)
307 break;
308 buf += nwrote;
309 }
310 nwrote = (int) size - nleft;
311 return (nwrote);
312} /* PWrite */
313#endif
314
315
316
317void
318Jobs(void)
319{
320#if defined(WIN32) || defined(_WINDOWS)
321 assert(0); // Not supported
322#else
323 char *argv[8];
324 pid_t pid;
325#ifdef BINDIR
326 char ncftpbatch[256];
327
328 STRNCPY(ncftpbatch, BINDIR);
329 STRNCAT(ncftpbatch, "/");
330 STRNCAT(ncftpbatch, "ncftpbatch");
331#endif /* BINDIR */
332
333 pid = fork();
334 if (pid < 0) {
335 perror("fork");
336 } else if (pid == 0) {
337 argv[0] = (char *) "ncftpbatch";
338 argv[1] = (char *) "-l";
339 argv[2] = NULL;
340
341#ifdef BINDIR
342 (void) execv(ncftpbatch, argv);
343 (void) fprintf(stderr, "Could not run %s. Is it in installed as %s?\n", argv[0], ncftpbatch);
344#else /* BINDIR */
345 (void) execvp(argv[0], argv);
346 (void) fprintf(stderr, "Could not run %s. Is it in your $PATH?\n", argv[0]);
347#endif /* BINDIR */
348 perror(argv[0]);
349 exit(1);
350 } else {
351#ifdef HAVE_WAITPID
352 (void) waitpid(pid, NULL, 0);
353#else
354 (void) wait(NULL);
355#endif
356 }
357#endif
358} /* Jobs */
359
360
361
362
363void
364RunBatch(int Xstruct, const FTPCIPtr cip)
365{
366#if defined(WIN32) || defined(_WINDOWS)
367 char ncftpbatch[260];
368 const char *prog;
369 int winExecResult;
370
371 if (gOurInstallationPath[0] == '\0') {
372 (void) fprintf(stderr, "Cannot find path to %s. Please re-run Setup.\n", "ncftpbatch.exe");
373 return;
374 }
375 prog = ncftpbatch;
376 OurInstallationPath(ncftpbatch, sizeof(ncftpbatch), "ncftpbatch.exe");
377
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");
382 return;
384 fprintf(stderr, "Could not run %s: %s\n", prog, "The specified file was not found.");
385 return;
387 fprintf(stderr, "Could not run %s: %s\n", prog, "The specified path was not found.");
388 return;
389 default:
390 fprintf(stderr, "Could not run %s: Unknown error #%d.\n", prog, winExecResult);
391 return;
392 }
393#else
394 int pfd[2];
395 char pfdstr[32];
396 char *argv[8];
397 pid_t pid = 0;
398#ifdef BINDIR
399 char ncftpbatch[256];
400
401 STRNCPY(ncftpbatch, BINDIR);
402 STRNCAT(ncftpbatch, "/");
403 STRNCAT(ncftpbatch, "ncftpbatch");
404#endif /* BINDIR */
405
406 if (Xstruct != 0) {
407 if (pipe(pfd) < 0) {
408 perror("pipe");
409 }
410
411 (void) sprintf(pfdstr, "%d", pfd[0]);
412 pid = fork();
413 if (pid < 0) {
414 (void) close(pfd[0]);
415 (void) close(pfd[1]);
416 perror("fork");
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";
422#else
423 argv[1] = (char *) "-d";
424#endif
425 argv[2] = (char *) "-|";
426 argv[3] = pfdstr;
427 argv[4] = NULL;
428
429#ifdef BINDIR
430 (void) execv(ncftpbatch, argv);
431 (void) fprintf(stderr, "Could not run %s. Is it in installed as %s?\n", argv[0], ncftpbatch);
432#else /* BINDIR */
433 (void) execvp(argv[0], argv);
434 (void) fprintf(stderr, "Could not run %s. Is it in your $PATH?\n", argv[0]);
435#endif /* BINDIR */
436 perror(argv[0]);
437 exit(1);
438 }
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. */
443
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.
447 */
449 } else {
450 pid = fork();
451 if (pid < 0) {
452 perror("fork");
453 } else if (pid == 0) {
454 argv[0] = (char *) "ncftpbatch";
455 argv[1] = (char *) "-d";
456 argv[2] = NULL;
457#ifdef BINDIR
458 (void) execv(ncftpbatch, argv);
459 (void) fprintf(stderr, "Could not run %s. Is it in installed as %s?\n", argv[0], ncftpbatch);
460#else /* BINDIR */
461 (void) execvp(argv[0], argv);
462 (void) fprintf(stderr, "Could not run %s. Is it in your $PATH?\n", argv[0]);
463#endif /* BINDIR */
464 perror(argv[0]);
465 exit(1);
466 }
467 }
468
469 if (pid > 1) {
470#ifdef HAVE_WAITPID
471 (void) waitpid(pid, NULL, 0);
472#else
473 (void) wait(NULL);
474#endif
475 }
476#endif
477} /* RunBatch */
478
479
480
481void
483{
484 if (gUnprocessedJobs > 0) {
485#ifdef ncftp
486 Trace(0, "Running ncftp_batch for %d job%s.\n", gUnprocessedJobs, gUnprocessedJobs > 0 ? "s" : "");
488 RunBatch(1, cip);
489#else
491 RunBatch(0, cip);
492#endif
493 }
494} /* RunBatchIfNeeded */
495
496#endif /* HAVE_LONG_FILE_NAMES */
#define STRNCAT(d, s)
Definition: Strn.h:48
char * Strncat(char *const, const char *const, const size_t)
Definition: Strncat.c:13
char * Strncpy(char *const, const char *const, const size_t)
Definition: Strncpy.c:11
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define EINTR
Definition: acclib.h:80
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define O_WRONLY
Definition: acwin.h:111
#define stat
Definition: acwin.h:99
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define write
Definition: acwin.h:97
#define O_TRUNC
Definition: acwin.h:112
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define NULL
Definition: types.h:112
DWORD pid_t
Definition: types.h:91
UINT op
Definition: effect.c:236
#define Trace(x)
Definition: inflate.c:42
UINT WINAPI DECLSPEC_HOTPATCH WinExec(LPCSTR lpCmdLine, UINT uCmdShow)
Definition: proc.c:4773
USHORT port
Definition: uri.c:228
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define assert(x)
Definition: debug.h:53
__kernel_time_t time_t
Definition: linux.h:252
__kernel_mode_t mode_t
Definition: linux.h:199
uint32_t serial
Definition: fsck.fat.h:29
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLfloat f
Definition: glext.h:7540
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
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 flag
Definition: glfuncs.h:52
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
char * prog
Definition: isohybrid.c:47
#define unlink
Definition: syshdrs.h:54
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define F_OK
Definition: util.h:52
void ToBase64(void *dst0, const void *src0, size_t n, int terminate)
Definition: util.c:83
char * OurInstallationPath(char *const dst, const size_t siz, const char *const fname)
Definition: util.c:494
char * OurDirectoryPath(char *const dst, const size_t siz, const char *const fname)
Definition: util.c:486
#define kPasswordMagic
Definition: util.h:47
#define kPasswordMagicLen
Definition: util.h:48
#define YESNO(i)
Definition: util.h:28
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const WCHAR sp[]
Definition: suminfo.c:287
#define argv
Definition: mplay32.c:18
#define FOPEN_WRITE_TEXT
Definition: syshdrs.h:83
char * FTPGetLocalCWD(char *buf, size_t size)
Definition: util.c:29
int MkDirs(const char *const, int mode1)
Definition: util.c:785
#define kDefaultFTPPort
Definition: ncftp.h:312
#define err(...)
#define errno
Definition: errno.h:18
_Check_return_ _CRTIMP int __cdecl _access(_In_z_ const char *_Filename, _In_ int _AccessMode)
#define X_OK
Definition: io.h:169
_CRTIMP int __cdecl umask(_In_ int _Mode)
_Check_return_ int __cdecl rename(_In_z_ const char *_OldFilename, _In_z_ const char *_NewFilename)
_CRTIMP intptr_t __cdecl execv(_In_z_ const char *_Filename, _In_z_ char *const _ArgList[])
_CRTIMP intptr_t __cdecl execvp(_In_z_ const char *_Filename, _In_z_ char *const _ArgList[])
int __cdecl system(_In_opt_z_ const char *_Command)
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:416
#define exit(n)
Definition: config.h:202
static int fd
Definition: io.c:51
int gUnprocessedJobs
Definition: spool.c:19
int gJobs
Definition: spool.c:20
static int PWrite(int sfd, const char *const buf0, size_t size)
Definition: spool.c:284
char gOurInstallationPath[]
Definition: spool.c:24
int HaveSpool(void)
Definition: spool.c:107
int SpoolX(const char *const op, const char *const rfile, const char *const rdir, const char *const lfile, const char *const ldir, const char *const host, const char *const ip, const unsigned int port, const char *const user, const char *const passclear, int xtype, int recursive, int delete, int passive, const char *const precmd, const char *const perfilecmd, const char *const postcmd, time_t when)
Definition: spool.c:161
int CanSpool(void)
Definition: spool.c:145
FTPLibraryInfo gLib
Definition: main.c:36
void Jobs(void)
Definition: spool.c:318
int gHaveSpool
Definition: spool.c:21
void TruncBatchLog(void)
Definition: spool.c:30
void SpoolName(const char *const sdir, char *sp, size_t size, int flag, int serial, time_t when)
Definition: spool.c:78
void CloseControlConnection(const FTPCIPtr)
Definition: ftp.c:197
void RunBatchIfNeeded(const FTPCIPtr cip)
Definition: spool.c:482
int MkSpoolDir(char *sdir, size_t size)
Definition: spool.c:56
int gSpoolSerial
Definition: spool.c:18
void RunBatch(int Xstruct, const FTPCIPtr cip)
Definition: spool.c:364
char gOurDirectoryPath[]
Definition: util.c:17
#define kSpoolLog
Definition: spool.h:12
#define kSpoolDir
Definition: spool.h:8
static PIXELFORMATDESCRIPTOR pfd
Definition: ssstars.c:67
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
FTPLIPtr lip
Definition: ncftp.h:149
char defaultAnonPassword[80]
Definition: ncftp.h:121
Definition: dhcpd.h:62
Definition: stat.h:55
time_t st_mtime
Definition: stat.h:65
Definition: time.h:68
pass
Definition: typegen.h:25
EXPORT uid_t geteuid()
Definition: uid.c:37
char * host
Definition: whois.c:55
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_BAD_FORMAT
Definition: winerror.h:114
#define getpid
Definition: wintirpc.h:52
#define SW_SHOWNORMAL
Definition: winuser.h:770