ReactOS  0.4.14-dev-49-gfb4591c
util.c
Go to the documentation of this file.
1 /* util.c
2  *
3  * Copyright (c) 1996-2001 Mike Gleason, NCEMRSoft.
4  * All rights reserved.
5  *
6  */
7 
8 #include "syshdrs.h"
9 
10 #if defined(WIN32) || defined(_WINDOWS)
11 #include <conio.h>
12 extern void GetSpecialDir(char *dst, size_t size, int whichDir);
13 #endif
14 
15 
16 /* static void *
17 Realloc(void *ptr, size_t siz)
18 {
19  if (ptr == NULL)
20  return (void *) malloc(siz);
21  return ((void *) realloc(ptr, siz));
22 }*/
23 
24 
25 /* Use getcwd/getwd to get the full path of the current local
26  * working directory.
27  */
28 char *
29 FTPGetLocalCWD(char *buf, size_t size)
30 {
31 #ifdef HAVE_GETCWD
32  static char *cwdBuf = NULL;
33  static size_t cwdBufSize = 0;
34 
35  if (cwdBufSize == 0) {
36  cwdBufSize = (size_t) 128;
37  cwdBuf = (char *) malloc(cwdBufSize);
38  }
39 
40  for (errno = 0; ; ) {
41  if (cwdBuf == NULL) {
42  return NULL;
43  }
44 
45  if (getcwd(cwdBuf, cwdBufSize) != NULL)
46  break;
47  if (errno != ERANGE) {
48  (void) Strncpy(buf, ".", size);
49  return NULL;
50  }
51  cwdBufSize *= 2;
52  cwdBuf = (char *) Realloc(cwdBuf, cwdBufSize);
53  }
54 
55  return (Strncpy(buf, cwdBuf, size));
56 #else
57 #ifdef HAVE_GETWD
58  static char *cwdBuf = NULL;
59  char *dp;
60 
61  /* Due to the way getwd is usually implemented, it's
62  * important to have a buffer large enough to hold the
63  * whole thing. getwd usually starts at the end of the
64  * buffer, and works backwards, returning you a pointer
65  * to the beginning of it when it finishes.
66  */
67  if (size < MAXPATHLEN) {
68  /* Buffer not big enough, so use a temporary one,
69  * and then copy the first 'size' bytes of the
70  * temporary buffer to your 'buf.'
71  */
72  if (cwdBuf == NULL) {
73  cwdBuf = (char *) malloc((size_t) MAXPATHLEN);
74  if (cwdBuf == NULL) {
75  return NULL;
76  }
77  }
78  dp = cwdBuf;
79  } else {
80  /* Buffer is big enough already. */
81  dp = buf;
82  }
83  *dp = '\0';
84  if (getwd(dp) == NULL) {
85  /* getwd() should write the reason why in the buffer then,
86  * according to the man pages.
87  */
88  (void) Strncpy(buf, ".", size);
89  return (NULL);
90  }
91  return (Strncpy(buf, dp, size));
92 
93 #elif defined(WIN32) || defined(_WINDOWS)
94  if (GetCurrentDirectory((DWORD) size - 1, buf) < 1)
95  return NULL;
96  buf[size - 1] = '\0';
97  return buf;
98 #else
99  /* Not a solution, but does anybody not have either of
100  * getcwd or getwd?
101  */
102  --Error--;
103 #endif
104 #endif
105 } /* GetCWD */
106 
107 
108 
109 /* Read a line, and axe the end-of-line. */
110 char *
111 FGets(char *str, size_t size, FILE *fp)
112 {
113  char *cp, *nlptr;
114 
115  cp = fgets(str, ((int) size) - 1, fp);
116  if (cp != NULL) {
117  cp[((int) size) - 1] = '\0'; /* ensure terminator */
118  nlptr = cp + strlen(cp) - 1;
119  if (*nlptr == '\n')
120  *nlptr = '\0';
121  } else {
122  memset(str, 0, size);
123  }
124  return cp;
125 } /* FGets */
126 
127 
128 
129 
130 #if defined(WIN32) || defined(_WINDOWS)
131 
132 int gettimeofday(struct timeval *const tp, void *junk)
133 {
134  SYSTEMTIME systemTime;
135 
136  GetSystemTime(&systemTime);
137 
138  /* Create an arbitrary second counter;
139  * Note that this particular one creates
140  * a problem at the end of the month.
141  */
142  tp->tv_sec =
143  systemTime.wSecond +
144  systemTime.wMinute * 60 +
145  systemTime.wHour * 3600 +
146  systemTime.wDay * 86400;
147 
148  tp->tv_usec = systemTime.wMilliseconds * 1000;
149 
150  return 0;
151 } /* gettimeofday */
152 
153 #endif
154 
155 
156 
157 
158 #if defined(WIN32) || defined(_WINDOWS)
159 #else
160 /* This looks up the user's password entry, trying to look by the username.
161  * We have a couple of extra hacks in place to increase the probability
162  * that we can get the username.
163  */
164 struct passwd *
166 {
167  char *cp;
168  struct passwd *pw;
169 
170  cp = getlogin();
171  if (cp == NULL) {
172  cp = (char *) getenv("LOGNAME");
173  if (cp == NULL)
174  cp = (char *) getenv("USER");
175  }
176  pw = NULL;
177  if (cp != NULL)
178  pw = getpwnam(cp);
179  return (pw);
180 } /* GetPwByName */
181 #endif
182 
183 
184 
185 char *
186 GetPass(const char *const prompt)
187 {
188 #ifdef HAVE_GETPASS
189  return getpass(prompt);
190 #elif defined(_CONSOLE) && (defined(WIN32) || defined(_WINDOWS))
191  static char pwbuf[128];
192  char *dst, *dlim;
193  int c;
194 
195  (void) memset(pwbuf, 0, sizeof(pwbuf));
196  if (! _isatty(_fileno(stdout)))
197  return (pwbuf);
198  (void) fputs(prompt, stdout);
199  (void) fflush(stdout);
200 
201  for (dst = pwbuf, dlim = dst + sizeof(pwbuf) - 1;;) {
202  c = _getch();
203  if ((c == 0) || (c == 0xe0)) {
204  /* The key is a function or arrow key; read and discard. */
205  (void) _getch();
206  }
207  if ((c == '\r') || (c == '\n'))
208  break;
209  if (dst < dlim)
210  *dst++ = c;
211  }
212  *dst = '\0';
213 
214  (void) fflush(stdout);
215  (void) fflush(stdin);
216  return (pwbuf);
217 #else
218  static char pwbuf[128];
219 
220  (void) memset(pwbuf, 0, sizeof(pwbuf));
221 #if defined(WIN32) || defined(_WINDOWS)
222  if (! _isatty(_fileno(stdout)))
223 #else
224  if (! isatty(1))
225 #endif
226  return (pwbuf);
227  (void) fputs(prompt, stdout);
228  (void) fflush(stdout);
229  (void) FGets(pwbuf, sizeof(pwbuf), stdin);
230  (void) fflush(stdout);
231  (void) fflush(stdin);
232  return (pwbuf);
233 #endif
234 } /* GetPass */
235 
236 
237 
238 
239 void
240 GetHomeDir(char *dst, size_t size)
241 {
242 #if defined(WIN32) || defined(_WINDOWS)
243  const char *homedrive, *homepath;
244 
245  homedrive = getenv("HOMEDRIVE");
246  homepath = getenv("HOMEPATH");
247  if ((homedrive != NULL) && (homepath != NULL)) {
248  (void) Strncpy(dst, homedrive, size);
249  (void) Strncat(dst, homepath, size);
250  return;
251  }
252 
253 // GetSpecialDir(dst, size, CSIDL_PERSONAL /* "My Documents" */);
254 // if (dst[0] != '\0')
255 // return;
256 //
257 // dst[0] = '\0';
258 // if (GetWindowsDirectory(dst, size - 1) < 1)
259 // (void) Strncpy(dst, ".", size);
260 // else if (dst[1] == ':') {
261 // dst[2] = '\\';
262 // dst[3] = '\0';
263 // }
264 #else
265  const char *cp;
266  struct passwd *pw;
267 
268  pw = NULL;
269 #if defined(USE_GETPWUID)
270  /* Try to use getpwuid(), but if we have to, fall back to getpwnam(). */
271  if ((pw = getpwuid(getuid())) == NULL)
272  pw = GetPwByName(); /* Oh well, try getpwnam() then. */
273 #else
274  /* Try to use getpwnam(), but if we have to, fall back to getpwuid(). */
275  if ((pw = GetPwByName()) == NULL)
276  pw = getpwuid(getuid()); /* Try getpwnam() then. */
277 #endif
278  if (pw != NULL)
279  cp = pw->pw_dir;
280  else if ((cp = (const char *) getenv("LOGNAME")) == NULL)
281  cp = ".";
282  (void) Strncpy(dst, cp, size);
283 #endif
284 } /* GetHomeDir */
285 
286 
287 
288 
289 void
290 GetUsrName(char *dst, size_t size)
291 {
292 #if defined(WIN32) || defined(_WINDOWS)
293  DWORD size1;
294 
295  size1 = size - 1;
296  if (! GetUserName(dst, &size1))
297  (void) strncpy(dst, "unknown", size);
298  dst[size - 1] = '\0';
299 #else
300  const char *cp;
301  struct passwd *pw;
302 
303  pw = NULL;
304 #ifdef USE_GETPWUID
305  /* Try to use getpwuid(), but if we have to, fall back to getpwnam(). */
306  if ((pw = getpwuid(getuid())) == NULL)
307  pw = GetPwByName(); /* Oh well, try getpwnam() then. */
308 #else
309  /* Try to use getpwnam(), but if we have to, fall back to getpwuid(). */
310  if ((pw = GetPwByName()) == NULL)
311  pw = getpwuid(getuid()); /* Try getpwnam() then. */
312 #endif
313  if (pw != NULL)
314  cp = pw->pw_name;
315  else if ((cp = (const char *) getenv("LOGNAME")) == NULL)
316  cp = "UNKNOWN";
317  (void) Strncpy(dst, cp, size);
318 #endif
319 } /* GetUserName */
320 
321 
322 
323 
324 
325 /* Closes the file supplied, if it isn't a std stream. */
326 void
328 {
329  if (*f != NULL) {
330  if ((*f != stdout) && (*f != stdin) && (*f != stderr))
331  (void) fclose(*f);
332  *f = NULL;
333  }
334 } /* CloseFile */
335 
336 
337 
338 /*VARARGS*/
339 void
340 PrintF(const FTPCIPtr cip, const char *const fmt, ...)
341 {
342  va_list ap;
343  char buf[256];
344 
345  va_start(ap, fmt);
346  if (cip->debugLog != NULL) {
347  (void) vfprintf(cip->debugLog, fmt, ap);
348  (void) fflush(cip->debugLog);
349  }
350  if (cip->debugLogProc != NULL) {
351 #ifdef HAVE_VSNPRINTF
352  (void) vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
353  buf[sizeof(buf) - 1] = '\0';
354 #else
355  (void) vsprintf(buf, fmt, ap);
356 #endif
357  (*cip->debugLogProc)(cip, buf);
358  }
359  va_end(ap);
360 } /* PrintF */
361 
362 
363 
364 
365 
366 /*VARARGS*/
367 void
368 Error(const FTPCIPtr cip, const int pError, const char *const fmt, ...)
369 {
370  va_list ap;
371  int errnum;
372  size_t len;
373  char buf[256];
374  int endsinperiod;
375  int endsinnewline;
376 #ifndef HAVE_STRERROR
377  char errnostr[16];
378 #endif
379 
380  errnum = errno;
381  va_start(ap, fmt);
382 #ifdef HAVE_VSNPRINTF
383  vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
384  buf[sizeof(buf) - 1] = '\0';
385 #else
386  (void) vsprintf(buf, fmt, ap);
387 #endif
388  va_end(ap);
389 
390  if (pError != 0) {
391  len = strlen(buf);
392  endsinperiod = 0;
393  endsinnewline = 0;
394  if (len > 2) {
395  if (buf[len - 1] == '\n') {
396  endsinnewline = 1;
397  buf[len - 1] = '\0';
398  if (buf[len - 2] == '.') {
399  endsinperiod = 1;
400  buf[len - 2] = '\0';
401  }
402  } else if (buf[len - 1] == '.') {
403  endsinperiod = 1;
404  buf[len - 1] = '\0';
405  }
406  }
407 #ifdef HAVE_STRERROR
408  (void) STRNCAT(buf, ": ");
409  (void) STRNCAT(buf, strerror(errnum));
410 #else
411 # ifdef HAVE_SNPRINTF
412  sprintf(errnostr, sizeof(errnostr) - 1, " (errno = %d)", errnum);
413  errnostr[sizeof(errnostr) - 1] = '\0';
414 # else
415  sprintf(errnostr, " (errno = %d)", errnum);
416 # endif
417  STRNCAT(buf, errnostr);
418 #endif
419  if (endsinperiod != 0)
420  (void) STRNCAT(buf, ".");
421  if (endsinnewline != 0)
422  (void) STRNCAT(buf, "\n");
423  }
424 
425  if (cip->errLog != NULL) {
426  (void) fprintf(cip->errLog, "%s", buf);
427  (void) fflush(cip->errLog);
428  }
429  if ((cip->debugLog != NULL) && (cip->debugLog != cip->errLog)) {
430  if ((cip->errLog != stderr) || (cip->debugLog != stdout)) {
431  (void) fprintf(cip->debugLog, "%s", buf);
432  (void) fflush(cip->debugLog);
433  }
434  }
435  if (cip->errLogProc != NULL) {
436  (*cip->errLogProc)(cip, buf);
437  }
438  if ((cip->debugLogProc != NULL) && (cip->debugLogProc != cip->errLogProc)) {
439  (*cip->debugLogProc)(cip, buf);
440  }
441 } /* Error */
442 
443 
444 
445 
446 /* Cheezy, but somewhat portable way to get GMT offset. */
447 #ifdef HAVE_MKTIME
448 static
449 time_t GetUTCOffset(int mon, int mday)
450 {
451  struct tm local_tm, utc_tm, *utc_tmptr;
452  time_t local_t, utc_t, utcOffset;
453 
454  ZERO(local_tm);
455  ZERO(utc_tm);
456  utcOffset = 0;
457 
458  local_tm.tm_year = 94; /* Doesn't really matter. */
459  local_tm.tm_mon = mon;
460  local_tm.tm_mday = mday;
461  local_tm.tm_hour = 12;
462  local_tm.tm_isdst = -1;
463  local_t = mktime(&local_tm);
464 
465  if (local_t != (time_t) -1) {
466  utc_tmptr = gmtime(&local_t);
467  utc_tm.tm_year = utc_tmptr->tm_year;
468  utc_tm.tm_mon = utc_tmptr->tm_mon;
469  utc_tm.tm_mday = utc_tmptr->tm_mday;
470  utc_tm.tm_hour = utc_tmptr->tm_hour;
471  utc_tm.tm_isdst = -1;
472  utc_t = mktime(&utc_tm);
473 
474  if (utc_t != (time_t) -1)
475  utcOffset = (local_t - utc_t);
476  }
477  return (utcOffset);
478 } /* GetUTCOffset */
479 #endif /* HAVE_MKTIME */
480 
481 
482 
483 /* Converts a MDTM date, like "19930602204445"
484  * format to a time_t.
485  */
486 time_t UnMDTMDate(char *dstr)
487 {
488 #ifndef HAVE_MKTIME
489  return (kModTimeUnknown);
490 #else
491  struct tm ut, *t;
492  time_t mt, now;
494 
495  if (strncmp(dstr, "19100", 5) == 0) {
496  /* Server Y2K bug! */
497  return (result);
498  }
499 
500  (void) time(&now);
501  t = localtime(&now);
502 
503  /* Copy the whole structure of the 'tm' pointed to by t, so it will
504  * also set all fields we don't specify explicitly to be the same as
505  * they were in t. That way we copy non-standard fields such as
506  * tm_gmtoff, if it exists or not.
507  */
508  ut = *t;
509 
510  /* The time we get back from the server is (should be) in UTC. */
511  if (sscanf(dstr, "%04d%02d%02d%02d%02d%02d",
512  &ut.tm_year,
513  &ut.tm_mon,
514  &ut.tm_mday,
515  &ut.tm_hour,
516  &ut.tm_min,
517  &ut.tm_sec) == 6)
518  {
519  --ut.tm_mon;
520  ut.tm_year -= 1900;
521  mt = mktime(&ut);
522  if (mt != (time_t) -1) {
523  mt += GetUTCOffset(ut.tm_mon, ut.tm_mday);
524  result = (time_t) mt;
525  }
526  }
527  return result;
528 #endif /* HAVE_MKTIME */
529 } /* UnMDTMDate */
530 
531 
532 
533 int
534 GetSockBufSize(int sockfd, size_t *rsize, size_t *ssize)
535 {
536 #ifdef SO_SNDBUF
537  int rc = -1;
538  int opt;
539  int optsize;
540 
541  if (ssize != NULL) {
542  opt = 0;
543  optsize = sizeof(opt);
544  rc = getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *) &opt, &optsize);
545  if (rc == 0)
546  *ssize = (size_t) opt;
547  else
548  *ssize = 0;
549  }
550  if (rsize != NULL) {
551  opt = 0;
552  optsize = sizeof(opt);
553  rc = getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *) &opt, &optsize);
554  if (rc == 0)
555  *rsize = (size_t) opt;
556  else
557  *rsize = 0;
558  }
559  return (rc);
560 #else
561  if (ssize != NULL)
562  *ssize = 0;
563  if (rsize != NULL)
564  *rsize = 0;
565  return (-1);
566 #endif
567 } /* GetSockBufSize */
568 
569 
570 
571 int
572 SetSockBufSize(int sockfd, size_t rsize, size_t ssize)
573 {
574 #ifdef SO_SNDBUF
575  int rc = -1;
576  int opt;
577  int optsize;
578 
579 #ifdef TCP_RFC1323
580  /* This is an AIX-specific socket option to do RFC1323 large windows */
581  if (ssize > 0 || rsize > 0) {
582  opt = 1;
583  optsize = sizeof(opt);
584  rc = setsockopt(sockfd, IPPROTO_TCP, TCP_RFC1323, &opt, optsize);
585  }
586 #endif
587 
588  if (ssize > 0) {
589  opt = (int) ssize;
590  optsize = sizeof(opt);
591  rc = setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *) &opt, optsize);
592  }
593  if (rsize > 0) {
594  opt = (int) rsize;
595  optsize = sizeof(opt);
596  rc = setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *) &opt, optsize);
597  }
598  return (rc);
599 #else
600  return (-1);
601 #endif
602 } /* SetSockBufSize */
603 
604 
605 
606 void
607 Scramble(unsigned char *dst, size_t dsize, unsigned char *src, char *key)
608 {
609  int i;
610  unsigned int ch;
611  unsigned char *k2;
612  size_t keyLen;
613 
614  keyLen = strlen(key);
615  k2 = (unsigned char *) key;
616  for (i=0; i < (int) dsize - 1; i++) {
617  ch = src[i];
618  if (ch == 0)
619  break;
620  dst[i] = (unsigned char) (ch ^ (int) (k2[i % (int) keyLen]));
621  }
622  dst[i] = '\0';
623 } /* Scramble */
624 
625 
626 
627 
628 
629 #if defined(WIN32) || defined(_WINDOWS)
630 void WinSleep(unsigned int seconds)
631 {
632  DWORD now, deadline;
633  DWORD milliseconds = seconds * 1000;
634 
635  if (milliseconds > 0) {
636  now = GetTickCount();
637  deadline = now + milliseconds;
638  if (now < deadline) {
639  /* Typical case */
640  do {
641  milliseconds = deadline - now;
642  Sleep(milliseconds);
643  now = GetTickCount();
644  } while (now < deadline);
645  } else {
646  /* Overflow case */
647  deadline = now - 1;
648  milliseconds -= (0xFFFFFFFF - now);
649  do {
650  Sleep(0xFFFFFFFF - now);
651  now = GetTickCount();
652  } while (now > deadline);
653  /* Counter has now wrapped around */
654  deadline = now + milliseconds;
655  do {
656  milliseconds = deadline - now;
657  Sleep(milliseconds);
658  now = GetTickCount();
659  } while (now < deadline);
660  }
661  }
662 } /* WinSleep */
663 
664 
665 
666 
667 char *
668 StrFindLocalPathDelim(const char *src) /* TODO: optimize */
669 {
670  const char *first;
671  int c;
672 
673  first = NULL;
674  for (;;) {
675  c = *src++;
676  if (c == '\0')
677  break;
678  if (IsLocalPathDelim(c)) {
679  first = src - 1;
680  break;
681  }
682  }
683 
684  return ((char *) first);
685 } /* StrFindLocalPathDelim */
686 
687 
688 
689 char *
690 StrRFindLocalPathDelim(const char *src) /* TODO: optimize */
691 {
692  const char *last;
693  int c;
694 
695  last = NULL;
696  for (;;) {
697  c = *src++;
698  if (c == '\0')
699  break;
700  if (IsLocalPathDelim(c))
701  last = src - 1;
702  }
703 
704  return ((char *) last);
705 } /* StrRFindLocalPathDelim */
706 
707 
708 
709 
710 void
712 {
713  char *cp;
714 
716  if ((cp == NULL) || (cp[1] != '\0'))
717  return;
718 
719  /* Note: Do not destroy a path of "/" */
720  while ((cp > dst) && (IsLocalPathDelim(*cp)))
721  *cp-- = '\0';
722 } /* StrRemoveTrailingLocalPathDelim */
723 
724 
725 
726 void
728 {
729  int c;
730 
731  /* Note: Technically we don't need to do this,
732  * since Win32 accepts a / as equivalent to a \
733  * in a pathname.
734  */
735  if (dst != NULL) {
736  for (;;) {
737  c = *dst++;
738  if (c == '\0')
739  break;
740  if (c == '/')
741  dst[-1] = LOCAL_PATH_DELIM;
742  }
743  }
744 } /* TVFSPathToLocalPath */
745 
746 
747 void
749 {
750  int c;
751 
752  if (dst != NULL) {
753  for (;;) {
754  c = *dst++;
755  if (c == '\0')
756  break;
757  if (c == LOCAL_PATH_DELIM)
758  dst[-1] = '/';
759  }
760  }
761 } /* LocalPathToTVFSPath */
762 #endif /* WINDOWS */
763 
764 
765 
766 
767 void
769 {
770  char *cp;
771 
772  cp = strrchr(dst, '/');
773  if ((cp == NULL) || (cp[1] != '\0'))
774  return;
775 
776  /* Note: Do not destroy a path of "/" */
777  while ((cp > dst) && (*cp == '/'))
778  *cp-- = '\0';
779 } /* StrRemoveTrailingSlashes */
780 
781 
782 
783 
784 int
785 MkDirs(const char *const newdir, int mode1)
786 {
787  char s[512];
788  int rc;
789  char *cp, *sl;
790 #if defined(WIN32) || defined(_WINDOWS)
791  struct _stat st;
792  char *share;
793 #else
794  struct Stat st;
795  mode_t mode = (mode_t) mode1;
796 #endif
797 
798 #if defined(WIN32) || defined(_WINDOWS)
799  if ((isalpha(newdir[0])) && (newdir[1] == ':')) {
800  if (! IsLocalPathDelim(newdir[2])) {
801  /* Special case "c:blah", and errout.
802  * "c:\blah" must be used or _access GPFs.
803  */
804  errno = EINVAL;
805  return (-1);
806  } else if (newdir[3] == '\0') {
807  /* Special case root directory, which cannot be made. */
808  return (0);
809  }
810  } else if (IsUNCPrefixed(newdir)) {
811  share = StrFindLocalPathDelim(newdir + 2);
812  if ((share == NULL) || (StrFindLocalPathDelim(share + 1) == NULL))
813  return (-1);
814  }
815 
816  if (_access(newdir, 00) == 0) {
817  if (_stat(newdir, &st) < 0)
818  return (-1);
819  if (! S_ISDIR(st.st_mode)) {
820  errno = ENOTDIR;
821  return (-1);
822  }
823  return 0;
824  }
825 #else
826  if (access(newdir, F_OK) == 0) {
827  if (Stat(newdir, &st) < 0)
828  return (-1);
829  if (! S_ISDIR(st.st_mode)) {
830  errno = ENOTDIR;
831  return (-1);
832  }
833  return 0;
834  }
835 #endif
836 
837  (void) strncpy(s, newdir, sizeof(s));
838  if (s[sizeof(s) - 1] != '\0') {
839 #ifdef ENAMETOOLONG
841 #else
842  errno = EINVAL;
843  return (-1);
844 #endif
845  }
846 
848  if (cp == NULL) {
849 #if defined(WIN32) || defined(_WINDOWS)
850  if (! CreateDirectory(newdir, (LPSECURITY_ATTRIBUTES) 0))
851  return (-1);
852  return (0);
853 #else
854  rc = mkdir(newdir, mode);
855  return (rc);
856 #endif
857  } else if (cp[1] == '\0') {
858  /* Remove trailing slashes from path. */
859  --cp;
860  while (cp > s) {
861  if (! IsLocalPathDelim(*cp))
862  break;
863  --cp;
864  }
865  cp[1] = '\0';
867  if (cp == NULL) {
868 #if defined(WIN32) || defined(_WINDOWS)
870  return (-1);
871 #else
872  rc = mkdir(s, mode);
873  return (rc);
874 #endif
875  }
876  }
877 
878  /* Find the deepest directory in this
879  * path that already exists. When
880  * we do, we want to have the 's'
881  * string as it was originally, but
882  * with 'cp' pointing to the first
883  * slash in the path that starts the
884  * part that does not exist.
885  */
886  sl = NULL;
887  for (;;) {
888  *cp = '\0';
889 #if defined(WIN32) || defined(_WINDOWS)
890  rc = _access(s, 00);
891 #else
892  rc = access(s, F_OK);
893 #endif
894  if (sl != NULL)
895  *sl = LOCAL_PATH_DELIM;
896  if (rc == 0) {
897  *cp = LOCAL_PATH_DELIM;
898  break;
899  }
900  sl = cp;
902  if (cp == NULL) {
903  /* We do not have any more
904  * slashes, so none of the
905  * new directory's components
906  * existed before, so we will
907  * have to make everything
908  * starting at the first node.
909  */
910  if (sl != NULL)
911  *sl = LOCAL_PATH_DELIM;
912 
913  /* We refer to cp + 1 below,
914  * so this is why we can
915  * set "cp" to point to the
916  * byte before the array starts.
917  */
918  cp = s - 1;
919  break;
920  }
921  }
922 
923  for (;;) {
924  /* Extend the path we have to
925  * include the next component
926  * to make.
927  */
928  sl = StrFindLocalPathDelim(cp + 1);
929  if (sl == s) {
930  /* If the next slash is pointing
931  * to the start of the string, then
932  * the path is an absolute path and
933  * we don't need to make the root node,
934  * and besides the next mkdir would
935  * try an empty string.
936  */
937  ++cp;
938  sl = StrFindLocalPathDelim(cp + 1);
939  }
940  if (sl != NULL) {
941  *sl = '\0';
942  }
943 #if defined(WIN32) || defined(_WINDOWS)
945  return (-1);
946 #else
947  rc = mkdir(s, mode);
948  if (rc < 0)
949  return rc;
950 #endif
951  if (sl == NULL)
952  break;
953  *sl = LOCAL_PATH_DELIM;
954  cp = sl;
955  }
956  return (0);
957 } /* MkDirs */
958 
959 
960 
961 
962 int
963 FilenameExtensionIndicatesASCII(const char *const pathName, const char *const extnList)
964 {
965  const char *extn;
966  char *cp;
967  int c;
968  char extnPattern[16];
969 
970  extn = pathName + strlen(pathName) - 1;
971  forever {
972  if (extn <= pathName)
973  return (0); /* End of pathname, no extension. */
974  c = (int) *--extn;
975  if (IsLocalPathDelim(c))
976  return (0); /* End of filename, no extension. */
977  if (c == '.') {
978  extn += 1;
979  break;
980  }
981  }
982  if (strlen(extn) > (sizeof(extnPattern) - 2 - 1 - 1)) {
983  return (0);
984  }
985 #ifdef HAVE_SNPRINTF
986  snprintf(extnPattern, sizeof(extnPattern),
987 #else
988  sprintf(extnPattern,
989 #endif
990  "|.%s|",
991  extn
992  );
993 
994  cp = extnPattern;
995  forever {
996  c = *cp;
997  if (c == '\0')
998  break;
999  if (isupper(c)) {
1000  c = tolower(c);
1001  *cp++ = (char) c;
1002  } else {
1003  cp++;
1004  }
1005  }
1006 
1007  /* Extension list is specially formatted, like this:
1008  *
1009  * |ext1|ext2|ext3|...|extN|
1010  *
1011  * I.e, each filename extension is delimited with
1012  * a pipe, and we always begin and end the string
1013  * with a pipe.
1014  */
1015  if (strstr(extnList, extnPattern) != NULL) {
1016  return (1);
1017  }
1018  return (0);
1019 } /* FilenameExtensionIndicatesASCII */
1020 
1021 
1022 
1023 
1024 
1025 #ifdef HAVE_SIGACTION
1026 void (*NcSignal(int signum, void (*handler)(int)))(int)
1027 {
1028  struct sigaction sa, osa;
1029 
1030  (void) sigemptyset(&sa.sa_mask);
1031  sa.sa_flags = 0;
1032  sa.sa_handler = handler;
1033  if (signum == SIGALRM) {
1034 #ifdef SA_INTERRUPT
1035  sa.sa_flags |= SA_INTERRUPT;
1036 #endif
1037  } else {
1038 #ifdef SA_RESTART
1039  sa.sa_flags |= SA_RESTART;
1040 #endif
1041  }
1042  if (sigaction(signum, &sa, &osa) < 0)
1043  return ((FTPSigProc) SIG_ERR);
1044  return (osa.sa_handler);
1045 }
1046 #endif /* HAVE_SIGACTION */
1047 
1048 /* eof */
static int
Definition: util.c:37
#define IsLocalPathDelim(c)
Definition: ncftp.h:497
#define vsnprintf
Definition: tif_win32.c:406
int tm_min
Definition: time.h:78
void GetHomeDir(char *dst, size_t size)
Definition: util.c:240
time_t UnMDTMDate(char *dstr)
Definition: util.c:486
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
char * GetPass(const char *const prompt)
Definition: util.c:186
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define LocalPathToTVFSPath(s)
Definition: ncftp.h:499
POINT last
Definition: font.c:46
#define GetUserName
Definition: winbase.h:3668
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
Definition: arc.h:39
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
const GLint * first
Definition: glext.h:5794
Definition: stat.h:40
int tm_mday
Definition: time.h:80
uint8_t junk[422]
Definition: fsck.fat.h:69
const char * fmt
Definition: wsprintf.c:30
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:445
GLdouble GLdouble t
Definition: gl.h:2047
#define snprintf
Definition: wintirpc.h:48
_Check_return_ _CRTIMP int __cdecl _isatty(_In_ int _FileHandle)
#define isalpha(c)
Definition: acclib.h:74
int MkDirs(const char *const newdir, int mode1)
Definition: util.c:785
FILE * stdin
#define SIG_ERR
Definition: signal.h:52
int tm_year
Definition: time.h:82
int errno
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
__u16 time
Definition: mkdosfs.c:366
#define SOL_SOCKET
Definition: winsock.h:398
const char * strerror(int err)
Definition: compat_str.c:23
void Error(const FTPCIPtr cip, const int pError, const char *const fmt,...)
Definition: util.c:368
FILE * stdout
FTPLogProc errLogProc
Definition: ncftp.h:148
char * FGets(char *str, size_t size, FILE *fp)
Definition: util.c:111
#define F_OK
Definition: util.h:52
#define sprintf(buf, format,...)
Definition: sprintf.c:55
char * Strncat(char *const, const char *const, const size_t)
Definition: Strncat.c:13
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
struct passwd * GetPwByName(void)
Definition: util.c:165
char * getpass(const char *prompt)
Definition: fake.c:231
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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
char * FTPGetLocalCWD(char *buf, size_t size)
Definition: util.c:29
#define va_end(ap)
Definition: acmsvcex.h:90
#define StrRemoveTrailingLocalPathDelim
Definition: ncftp.h:496
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
time_t now
Definition: finger.c:65
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
FILE * errLog
Definition: ncftp.h:146
#define GetCurrentDirectory
Definition: winbase.h:3622
_Check_return_ _CRTIMP int __cdecl isatty(_In_ int _FileHandle)
#define getwd
Definition: fake.h:7
const WCHAR * str
WORD wMinute
Definition: winbase.h:875
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:29
int FilenameExtensionIndicatesASCII(const char *const pathName, const char *const extnList)
Definition: util.c:963
char * va_list
Definition: acmsvcex.h:78
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
int tm_mon
Definition: time.h:81
_In_ uint64_t _In_ uint64_t _In_ uint64_t _In_opt_ traverse_ptr * tp
Definition: btrfs.c:2883
#define IsUNCPrefixed(s)
Definition: getline.c:59
Definition: arc.h:50
#define STRNCAT(d, s)
Definition: Strn.h:48
__kernel_size_t size_t
Definition: linux.h:237
GLfloat f
Definition: glext.h:7540
VOID WINAPI GetSystemTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:317
GLsizeiptr size
Definition: glext.h:5919
void GetUsrName(char *dst, size_t size)
Definition: util.c:290
#define isupper(c)
Definition: acclib.h:71
#define SO_RCVBUF
Definition: winsock.h:189
#define mkdir
Definition: acwin.h:101
_Check_return_ _CRTIMP int __cdecl _access(_In_z_ const char *_Filename, _In_ int _AccessMode)
#define S_ISDIR(mode)
Definition: various.h:18
static time_t GetUTCOffset(int mon, int mday)
Definition: util.c:449
const GLubyte * c
Definition: glext.h:8905
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
unsigned long DWORD
Definition: ntddk_ex.h:95
void(* FTPSigProc)(int)
Definition: ncftp.h:76
int GetSockBufSize(int sockfd, size_t *rsize, size_t *ssize)
Definition: util.c:534
Definition: texture.c:1662
char * getlogin(void)
WORD wSecond
Definition: winbase.h:876
WORD wMilliseconds
Definition: winbase.h:877
static void(WINAPI *pDeinitMapiUtil)(void)
#define ERANGE
Definition: acclib.h:92
FTPLogProc debugLogProc
Definition: ncftp.h:147
GLenum GLsizei len
Definition: glext.h:6722
#define forever
Definition: ncftp.h:73
GLdouble s
Definition: gl.h:2039
#define MAXPATHLEN
Definition: ftp_var.h:35
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
Definition: time.h:76
FILE * debugLog
Definition: ncftp.h:145
GLenum src
Definition: glext.h:6340
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:424
GLenum mode
Definition: glext.h:6217
_Check_return_ _Ret_opt_z_ _CRTIMP char *__cdecl getcwd(_Out_writes_opt_(_SizeInBytes) char *_DstBuf, _In_ int _SizeInBytes)
_CRTIMP int __cdecl _stat(_In_z_ const char *_Name, _Out_ struct _stat *_Stat)
int SetSockBufSize(int sockfd, size_t rsize, size_t ssize)
Definition: util.c:572
#define NcSignal
Definition: ncftp.h:604
INT WSAAPI getsockopt(IN SOCKET s, IN INT level, IN INT optname, OUT CHAR FAR *optval, IN OUT INT FAR *optlen)
Definition: sockctrl.c:271
void Scramble(unsigned char *dst, size_t dsize, unsigned char *src, char *key)
Definition: util.c:607
WORD wDay
Definition: winbase.h:873
void PrintF(const FTPCIPtr cip, const char *const fmt,...)
Definition: util.c:340
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
#define Stat
Definition: syshdrs.h:78
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
__kernel_mode_t mode_t
Definition: linux.h:199
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
__kernel_time_t time_t
Definition: linux.h:252
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
char * Strncpy(char *const, const char *const, const size_t)
Definition: Strncpy.c:11
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
GLenum GLenum dst
Definition: glext.h:6340
WORD wHour
Definition: winbase.h:874
_CRTIMP time_t __cdecl mktime(struct tm *_Tm)
Definition: time.h:426
#define va_start(ap, A)
Definition: acmsvcex.h:91
uid_t getuid()
Definition: uid.c:27
#define LOCAL_PATH_DELIM
Definition: ncftp.h:492
void StrRemoveTrailingSlashes(char *dst)
Definition: util.c:768
int tm_sec
Definition: time.h:77
void * Realloc(void *, size_t)
void CloseFile(FILE **f)
Definition: util.c:327
#define kModTimeUnknown
Definition: ncftp.h:377
POINT cp
Definition: magnifier.c:59
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
#define c
Definition: ke_i.h:80
int tm_hour
Definition: time.h:79
FILE * stderr
#define StrRFindLocalPathDelim(a)
Definition: ncftp.h:495
#define TVFSPathToLocalPath(s)
Definition: ncftp.h:498
#define malloc
Definition: debug_ros.c:4
_CRTIMP struct tm *__cdecl gmtime(const time_t *_Time)
Definition: time.h:423
UINT(* handler)(MSIPACKAGE *)
Definition: action.c:7786
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
int _getch()
Definition: getch.c:16
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
int tm_isdst
Definition: time.h:85
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
int tolower(int c)
Definition: utclib.c:902
#define SO_SNDBUF
Definition: winsock.h:188
#define StrFindLocalPathDelim(a)
Definition: ncftp.h:494
Definition: dsound.c:943
_Check_return_opt_ _CRTIMP int __cdecl fputs(_In_z_ const char *_Str, _Inout_ FILE *_File)
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
Definition: path.c:42