ReactOS  0.4.14-dev-342-gdc047f9
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 
18 int gSpoolSerial = 0;
20 int gJobs = 0;
21 int gHaveSpool = -1;
22 
23 extern FTPLibraryInfo gLib;
25 extern void CloseControlConnection(const FTPCIPtr);
26 
27 
28 
29 void
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 
55 int
56 MkSpoolDir(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 
77 void
78 SpoolName(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 
106 int
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 
144 int
145 CanSpool(void)
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 
160 int
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 
270 err:
271  (void) fclose(fp);
272 err2:
273  perror("write to spool file failed");
274 err3:
275  (void) unlink(spathname);
276  return (-1);
277 }
278 
279 
280 
281 #if defined(WIN32) || defined(_WINDOWS)
282 #else
283 static int
284 PWrite(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 
317 void
318 Jobs(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 
363 void
364 RunBatch(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 
481 void
483 {
484  if (gUnprocessedJobs > 0) {
485 #ifdef ncftp
486  Trace(0, "Running ncftp_batch for %d job%s.\n", gUnprocessedJobs, gUnprocessedJobs > 0 ? "s" : "");
487  gUnprocessedJobs = 0;
488  RunBatch(1, cip);
489 #else
490  gUnprocessedJobs = 0;
491  RunBatch(0, cip);
492 #endif
493  }
494 } /* RunBatchIfNeeded */
495 
496 #endif /* HAVE_LONG_FILE_NAMES */
int gHaveSpool
Definition: spool.c:21
#define ERROR_BAD_FORMAT
Definition: winerror.h:114
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3835
int MkSpoolDir(char *sdir, size_t size)
Definition: spool.c:56
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define kDefaultFTPPort
Definition: ncftp.h:312
#define kPasswordMagic
Definition: util.h:47
void SpoolName(const char *const sdir, char *sp, size_t size, int flag, int serial, time_t when)
Definition: spool.c:78
#define open
Definition: acwin.h:95
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
char * prog
Definition: isohybrid.c:47
char gOurInstallationPath[]
Definition: util.c:18
#define EINTR
Definition: acclib.h:80
char * host
Definition: whois.c:55
#define kPasswordMagicLen
Definition: util.h:48
#define kSpoolDir
Definition: spool.h:8
GLdouble GLdouble t
Definition: gl.h:2047
#define unlink
Definition: syshdrs.h:54
char * OurDirectoryPath(char *const dst, const size_t siz, const char *const fname)
Definition: util.c:486
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
#define assert(x)
Definition: debug.h:53
#define FOPEN_WRITE_TEXT
Definition: syshdrs.h:83
DWORD pid_t
Definition: types.h:91
int gUnprocessedJobs
Definition: spool.c:19
static int fd
Definition: io.c:51
void CloseControlConnection(const FTPCIPtr)
Definition: ftp.c:197
UINT WINAPI DECLSPEC_HOTPATCH WinExec(LPCSTR lpCmdLine, UINT uCmdShow)
Definition: proc.c:4774
int errno
__u16 time
Definition: mkdosfs.c:366
#define kSpoolLog
Definition: spool.h:12
#define argv
Definition: mplay32.c:18
#define F_OK
Definition: util.h:52
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define write
Definition: acwin.h:97
pass
Definition: typegen.h:24
char * Strncat(char *const, const char *const, const size_t)
Definition: Strncat.c:13
int gSpoolSerial
Definition: spool.c:18
FTPLIPtr lip
Definition: ncftp.h:149
_Check_return_ int __cdecl rename(_In_z_ const char *_OldFilename, _In_z_ const char *_NewFilename)
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define O_WRONLY
Definition: acwin.h:111
smooth NULL
Definition: ftsmooth.c:416
int __cdecl system(_In_opt_z_ const char *_Command)
#define X_OK
Definition: io.h:169
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
struct FTPConnectionInfo FTPConnectionInfo
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
#define STRNCAT(d, s)
Definition: Strn.h:48
void ToBase64(void *dst0, const void *src0, size_t n, int terminate)
Definition: util.c:83
#define YESNO(i)
Definition: util.h:28
GLfloat f
Definition: glext.h:7540
_CRTIMP int __cdecl getpid(void)
GLsizeiptr size
Definition: glext.h:5919
Definition: dhcpd.h:61
void TruncBatchLog(void)
Definition: spool.c:30
int gJobs
Definition: spool.c:20
char gOurDirectoryPath[]
Definition: util.c:17
_Check_return_ _CRTIMP int __cdecl _access(_In_z_ const char *_Filename, _In_ int _AccessMode)
int MkDirs(const char *const, int mode1)
Definition: util.c:785
char defaultAnonPassword[80]
Definition: ncftp.h:121
_CRTIMP intptr_t __cdecl execvp(_In_z_ const char *_Filename, _In_z_ char *const _ArgList[])
void RunBatch(int Xstruct, const FTPCIPtr cip)
Definition: spool.c:364
static PIXELFORMATDESCRIPTOR pfd
Definition: ssstars.c:67
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
void RunBatchIfNeeded(const FTPCIPtr cip)
Definition: spool.c:482
Definition: stat.h:55
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define O_TRUNC
Definition: acwin.h:112
#define Trace(x)
Definition: zutil.h:197
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
Definition: time.h:76
#define close
Definition: acwin.h:98
#define err(...)
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:424
EXPORT uid_t geteuid()
Definition: uid.c:37
_CRTIMP int __cdecl stat(const char *_Filename, struct stat *_Stat)
Definition: stat.h:345
#define SW_SHOWNORMAL
Definition: winuser.h:764
uint32_t serial
Definition: fsck.fat.h:64
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
__kernel_mode_t mode_t
Definition: linux.h:199
__kernel_time_t time_t
Definition: linux.h:252
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
void Jobs(void)
Definition: spool.c:318
char * Strncpy(char *const, const char *const, const size_t)
Definition: Strncpy.c:11
char * OurInstallationPath(char *const dst, const size_t siz, const char *const fname)
Definition: util.c:494
static int PWrite(int sfd, const char *const buf0, size_t size)
Definition: spool.c:284
FILE * stderr
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
static const WCHAR sp[]
Definition: suminfo.c:288
_CRTIMP intptr_t __cdecl execv(_In_z_ const char *_Filename, _In_z_ char *const _ArgList[])
_CRTIMP int __cdecl umask(_In_ int _Mode)
UINT op
Definition: effect.c:223
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
void exit(int exitcode)
Definition: _exit.c:33
time_t st_mtime
Definition: stat.h:65
USHORT port
Definition: uri.c:227
void user(int argc, const char *argv[])
Definition: cmds.c:1350
int CanSpool(void)
Definition: spool.c:145
struct FTPLibraryInfo FTPLibraryInfo
int HaveSpool(void)
Definition: spool.c:107
char * FTPGetLocalCWD(char *buf, size_t size)
Definition: util.c:29
FTPLibraryInfo gLib
Definition: main.c:36
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31