home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / ncftp / older_versions / ncftp-3.2.2-src.tar.bz2 / ncftp-3.2.2-src.tar / ncftp-3.2.2 / libncftp / lglob.c < prev    next >
C/C++ Source or Header  |  2005-01-01  |  5KB  |  209 lines

  1. /* lglob.c
  2.  *
  3.  * Copyright (c) 1996-2005 Mike Gleason, NcFTP Software.
  4.  * All rights reserved.
  5.  *
  6.  */
  7.  
  8. #include "syshdrs.h"
  9. #ifdef PRAGMA_HDRSTOP
  10. #    pragma hdrstop
  11. #endif
  12.  
  13. /* This does "tilde-expansion."  Examples:
  14.  * ~/pub         -->  /usr/gleason/pub
  15.  * ~pdietz/junk  -->  /usr/pdietz/junk
  16.  */
  17. static void
  18. ExpandTilde(char *pattern, size_t siz)
  19. {
  20.     char pat[512];
  21.     char *cp, *rest, *firstent;
  22. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  23. #else
  24.     struct passwd pw;
  25.     char pwbuf[256];
  26. #endif
  27.     char hdir[512];
  28.  
  29.     if ((pattern[0] == '~') &&
  30.     (isalnum((int) pattern[1]) || IsLocalPathDelim(pattern[1]) || (pattern[1] == '\0'))) {
  31.         (void) STRNCPY(pat, pattern);
  32.         if ((cp = StrFindLocalPathDelim(pat)) != NULL) {
  33.             *cp = 0;
  34.             rest = cp + 1;    /* Remember stuff after the ~/ part. */
  35.         } else {
  36.             rest = NULL;    /* Was just a ~ or ~username.  */
  37.         }
  38.         if (pat[1] == '\0') {
  39.             /* Was just a ~ or ~/rest type.  */
  40.             GetHomeDir(hdir, sizeof(hdir));
  41.             firstent = hdir;
  42.         } else {
  43. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  44.             return;
  45. #else
  46.             /* Was just a ~username or ~username/rest type.  */
  47.             if (GetPwNam(&pw, pat + 1, pwbuf, sizeof(pwbuf)) == 0)
  48.                 firstent = pw.pw_dir;
  49.             else
  50.                 return;        /* Bad user -- leave it alone. */
  51. #endif
  52.         }
  53.         
  54.         (void) Strncpy(pattern, firstent, siz);
  55.         if (rest != NULL) {
  56.             (void) Strncat(pattern, LOCAL_PATH_DELIM_STR, siz);
  57.             (void) Strncat(pattern, rest, siz);
  58.         }
  59.     }
  60. }    /* ExpandTilde */
  61.  
  62.  
  63.  
  64.  
  65.  
  66. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  67.  
  68. static int
  69. WinLocalGlob(FTPCIPtr cip, FTPLineListPtr fileList, const char *const srcpat)
  70. {
  71.     char pattern[_MAX_PATH];
  72.     WIN32_FIND_DATA ffd;
  73.     HANDLE searchHandle;
  74.     DWORD dwErr;
  75.     char *cp;
  76.     const char *file;
  77.     int result;
  78.  
  79.     STRNCPY(pattern, srcpat);
  80.  
  81.     /* Get rid of trailing slashes. */
  82.     cp = pattern + strlen(pattern) - 1;
  83.     while ((cp >= pattern) && IsLocalPathDelim(*cp))
  84.         *cp-- = '\0';
  85.  
  86.     memset(&ffd, 0, sizeof(ffd));
  87.  
  88.     /* "Open" the directory. */
  89.     searchHandle = FindFirstFile(pattern, &ffd);
  90.     if (searchHandle == INVALID_HANDLE_VALUE) {
  91.         dwErr = GetLastError();
  92.         return ((dwErr == 0) ? 0 : -1);
  93.     }
  94.  
  95.     /* Get rid of basename. */
  96.     cp = StrRFindLocalPathDelim(pattern);
  97.     if (cp == NULL)
  98.         cp = pattern;
  99.     else
  100.         cp++;
  101.     *cp = '\0';
  102.  
  103.     for (result = 0;;) {
  104.         file = ffd.cFileName;
  105.         if ((file[0] == '.') && ((file[1] == '\0') || ((file[1] == '.') && (file[2] == '\0')))) {
  106.             /* skip */
  107.         } else {
  108.             Strncpy(cp, ffd.cFileName, sizeof(pattern) - (cp - pattern));
  109.             PrintF(cip, "  Lglob [%s]\n", pattern);
  110.             (void) AddLine(fileList, pattern);
  111.         }
  112.  
  113.         if (!FindNextFile(searchHandle, &ffd)) {
  114.             dwErr = GetLastError();
  115.             if (dwErr != ERROR_NO_MORE_FILES) {
  116.                 result = ((dwErr == 0) ? 0 : -1);
  117.             }
  118.             break;
  119.         }
  120.     }
  121.  
  122.     FindClose(searchHandle);
  123.     return (result);
  124. }    // WinLocalGlob
  125.  
  126. #else
  127.  
  128. static int
  129. LazyUnixLocalGlob(FTPCIPtr cip, FTPLineListPtr fileList, const char *const pattern)
  130. {
  131.     char cmd[512];
  132.     longstring gfile;
  133.     FILE *fp;
  134.     FTPSigProc sp;
  135.     
  136.     /* Do it the easy way and have the shell do the dirty
  137.      * work for us.
  138.      */
  139. #ifdef HAVE_SNPRINTF
  140.     (void) snprintf(cmd, sizeof(cmd) - 1, "%s -c \"%s %s %s\"", "/bin/sh", "/bin/ls",
  141.         "-d", pattern);
  142.     cmd[sizeof(cmd) - 1] = '\0';
  143. #else
  144.     (void) sprintf(cmd, "%s -c \"%s %s %s\"", "/bin/sh", "/bin/ls",
  145.         "-d", pattern);
  146. #endif
  147.     
  148.     fp = (FILE *) popen(cmd, "r");
  149.     if (fp == NULL) {
  150.         FTPLogError(cip, kDoPerror, "Could not Lglob: [%s]\n", cmd);
  151.         cip->errNo = kErrGlobFailed;
  152.         return (kErrGlobFailed);
  153.     }
  154.     sp = NcSignal(SIGPIPE, (FTPSigProc) SIG_IGN);
  155.     while (FGets(gfile, sizeof(gfile), (FILE *) fp) != NULL) {
  156.         PrintF(cip, "  Lglob [%s]\n", gfile);
  157.         (void) AddLine(fileList, gfile);
  158.     }
  159.     (void) pclose(fp);
  160.     (void) NcSignal(SIGPIPE, sp);
  161.     return (kNoErr);
  162. }    /* LazyUnixLocalGlob */
  163.  
  164. #endif
  165.  
  166.  
  167.  
  168.  
  169. int
  170. FTPLocalGlob(FTPCIPtr cip, FTPLineListPtr fileList, const char *pattern, int doGlob)
  171. {
  172.     char pattern2[512];
  173.     int result;
  174.  
  175.     if (cip == NULL)
  176.         return (kErrBadParameter);
  177.     if (strcmp(cip->magic, kLibraryMagic))
  178.         return (kErrBadMagic);
  179.  
  180.     if (fileList == NULL)
  181.         return (kErrBadParameter);
  182.     InitLineList(fileList);
  183.  
  184.     if ((pattern == NULL) || (pattern[0] == '\0'))
  185.         return (kErrBadParameter);
  186.  
  187.     (void) STRNCPY(pattern2, pattern);    /* Don't nuke the original. */
  188.     
  189.     /* Pre-process for ~'s. */ 
  190.     ExpandTilde(pattern2, sizeof(pattern2));
  191.     InitLineList(fileList);
  192.     result = kNoErr;
  193.  
  194.     if ((doGlob == 1) && (GLOBCHARSINSTR(pattern2))) {
  195. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  196.         result = WinLocalGlob(cip, fileList, pattern2);
  197. #else
  198.         result = LazyUnixLocalGlob(cip, fileList, pattern2);
  199. #endif
  200.     } else {
  201.         /* Or, if there were no globbing characters in 'pattern', then
  202.          * the pattern is really just a single pathname.
  203.          */
  204.         (void) AddLine(fileList, pattern2);
  205.     }
  206.  
  207.     return (result);
  208. }    /* FTPLocalGlob */
  209.