/* Tries to generate a bookmark abbreviation based off of the hostname. */ void DefaultBookmarkName(char *dst, size_t siz, char *src) { char str[128]; const char *token; const char *cp; (void) STRNCPY(str, src); /* Pick the first "significant" part of the hostname. Usually * this is the first word in the name, but if it's something like * ftp.unl.edu, we would want to choose "unl" and not "ftp." */ token = str; if ((token = strtok(str, ".")) == NULL) token = str; else if ((ISTRNEQ(token, "ftp", 3)) || (ISTRNEQ(token, "www", 3))) { if ((token = strtok(NULL, ".")) == NULL) token = ""; } for (cp = token; ; cp++) { if (*cp == '\0') { /* Token was all digits, like an IP address perhaps. */ token = ""; } if (!isdigit((int) *cp)) break; } (void) Strncpy(dst, token, siz); } /* DefaultBookmarkName */
static void FTPExamineMlstFeatures(const FTPCIPtr cip, const char *features) { char buf[256], *feat; int flags; flags = 0; STRNCPY(buf, features); feat = strtok(buf, ";*"); while (feat != NULL) { if (ISTRNEQ(feat, "OS.", 3)) feat += 3; if (ISTREQ(feat, "type")) { flags |= kMlsOptType; } else if (ISTREQ(feat, "size")) { flags |= kMlsOptSize; } else if (ISTREQ(feat, "modify")) { flags |= kMlsOptModify; } else if (ISTREQ(feat, "UNIX.mode")) { flags |= kMlsOptUNIXmode; } else if (ISTREQ(feat, "UNIX.owner")) { flags |= kMlsOptUNIXowner; } else if (ISTREQ(feat, "UNIX.group")) { flags |= kMlsOptUNIXgroup; } else if (ISTREQ(feat, "perm")) { flags |= kMlsOptPerm; } else if (ISTREQ(feat, "UNIX.uid")) { flags |= kMlsOptUNIXuid; } else if (ISTREQ(feat, "UNIX.gid")) { flags |= kMlsOptUNIXgid; } else if (ISTREQ(feat, "UNIX.gid")) { flags |= kMlsOptUnique; } feat = strtok(NULL, ";*"); } cip->mlsFeatures = flags; } /* FTPExamineMlstFeatures */
int UnMlsT(const FTPCIPtr UNUSED(cip), const char *const line0, const MLstItemPtr mlip) { char *cp, *val, *fact; int ec; size_t len; char line[1024]; LIBNCFTP_USE_VAR(cip); memset(mlip, 0, sizeof(MLstItem)); mlip->mode = -1; mlip->fsize = kSizeUnknown; mlip->ftype = '-'; mlip->ftime = kModTimeUnknown; len = strlen(line0); if (len > (sizeof(line) - 1)) return (-1); /* Line too long, sorry. */ /* This should be re-coded so does not need to make a * copy of the buffer; it could be done in place. */ memcpy(line, line0, len + 1); /* Skip leading whitespace. */ for (cp = line; *cp != '\0'; cp++) { if (! isspace((int) *cp)) break; } while (*cp != '\0') { for (fact = cp; ; cp++) { if ((*cp == '\0') || (*cp == ' ')) { /* protocol violation */ return (-1); } if (*cp == '=') { /* End of fact name. */ *cp++ = '\0'; break; } } for (val = cp; ; cp++) { if (*cp == '\0') { /* protocol violation */ return (-1); } if (*cp == ' ') { ec = ' '; *cp++ = '\0'; break; } else if (*cp == ';') { if (cp[1] == ' ') { ec = ' '; *cp++ = '\0'; *cp++ = '\0'; } else { ec = ';'; *cp++ = '\0'; } break; } } if (ISTRNEQ(fact, "OS.", 3)) fact += 3; if (ISTREQ(fact, "type")) { if (ISTREQ(val, "file")) { mlip->ftype = '-'; } else if (ISTREQ(val, "dir")) { mlip->ftype = 'd'; } else if (ISTREQ(val, "cdir")) { /* not supported: current directory */ return (-2); } else if (ISTREQ(val, "pdir")) { /* not supported: parent directory */ return (-2); } else { /* ? */ return (-1); } } else if (ISTREQ(fact, "UNIX.mode")) { if (val[0] == '0') sscanf(val, "%o", &mlip->mode); else sscanf(val, "%i", &mlip->mode); if (mlip->mode != (-1)) mlip->mode &= 00777; } else if (ISTREQ(fact, "perm")) { STRNCPY(mlip->perm, val); } else if (ISTREQ(fact, "size")) { #if defined(HAVE_LONG_LONG) && defined(SCANF_LONG_LONG) (void) sscanf(val, SCANF_LONG_LONG, &mlip->fsize); #elif defined(HAVE_LONG_LONG) && defined(HAVE_STRTOQ) mlip->fsize = (longest_int) strtoq(val, NULL, 0); #else { long fsize2 = 0L; (void) sscanf(val, "%ld", &fsize2); mlip->fsize = (longest_int) fsize2; } #endif } else if (ISTREQ(fact, "modify")) { mlip->ftime = UnMDTMDate(val); } else if (ISTREQ(fact, "UNIX.owner")) { STRNCPY(mlip->owner, val); } else if (ISTREQ(fact, "UNIX.group")) { STRNCPY(mlip->group, val); } else if (ISTREQ(fact, "UNIX.uid")) { mlip->uid = atoi(val); } else if (ISTREQ(fact, "UNIX.gid")) { mlip->gid = atoi(val); } else if (ISTREQ(fact, "perm")) { STRNCPY(mlip->perm, val); } /* End of facts? */ if (ec == ' ') break; } len = strlen(cp); if (len > (sizeof(mlip->fname) - 1)) { /* Filename too long */ return (-1); } memcpy(mlip->fname, cp, len); /* also set linkto here if used */ return (0); } /* UnMlsT */
void RemoteGlobCollapse(const FTPCIPtr cip, const char *pattern, FTPLineListPtr fileList) { FTPLinePtr lp, nextLine; char *patPrefix; char *patDir; char *cur, *prev; char *cp; char *newpath; size_t plen; /* Copy all characters before and including the last path delimiter. */ patDir = NULL; cp = StrRFindLocalPathDelim(pattern); if (cp != NULL) { patDir = StrDup(pattern); if (patDir == NULL) return; patDir[(cp - pattern) + 1] = '\0'; } /* Copy all characters before the first glob-char. */ cp = strpbrk(pattern, kGlobChars); patPrefix = StrDup(pattern); if (patPrefix == NULL) { free(patDir); return; } if (cp != NULL) { plen = (size_t) (cp - pattern); patPrefix[plen] = '\0'; } else { plen = strlen(patPrefix); } cur = prev = NULL; for (lp=fileList->first; lp != NULL; lp = nextLine) { nextLine = lp->next; if (ISTRNEQ(lp->line, patPrefix, plen)) { if (Dynsrecpy(&cur, lp->line + plen, 0) == NULL) goto done; cp = strpbrk(cur, "/\\"); if (cp != NULL) *cp = '\0'; if ((prev != NULL) && (STREQ(cur, prev))) { PrintF(cip, " Rglob omitted: [%s] (type 2)\n", lp->line); nextLine = RemoveLine(fileList, lp); } else if (PathContainsIntermediateDotDotSubDir(lp->line + plen)) { PrintF(cip, " Rglob omitted: [%s] (type 3)\n", lp->line); nextLine = RemoveLine(fileList, lp); } else { if (Dynsrecpy(&prev, cur, 0) == NULL) goto done; /* We are playing with a dynamically * allocated string, but since the * following expression is guaranteed * to be the same or shorter, we won't * overwrite the bounds. */ (void) sprintf(lp->line, "%s%s", patPrefix, cur); } } else if (strpbrk(lp->line, "/\\") == NULL) { if (patDir != NULL) { newpath = NULL; if (Dynsrecpy(&newpath, patDir, lp->line, 0) == NULL) goto done; PrintF(cip, " Rglob changed: [%s] to [%s]\n", lp->line, newpath); free(lp->line); lp->line = newpath; } } else { PrintF(cip, " Rglob omitted: [%s] (type 4)\n", lp->line); nextLine = RemoveLine(fileList, lp); } } done: StrFree(&patDir); StrFree(&patPrefix); StrFree(&cur); StrFree(&prev); } /* RemoteGlobCollapse */
/* Looks for a saved bookmark by the abbreviation given. */ int GetBookmark(const char *const bmabbr, Bookmark *bmp) { FILE *fp; char line[512]; Bookmark byHostName; Bookmark byHostAbbr; Bookmark byBmAbbr; size_t byBmNameFlag = 0; size_t byBmAbbrFlag = 0; size_t byHostNameFlag = 0; size_t byHostAbbrFlag = 0; int result = -1; int exactMatch = 0; size_t bmabbrLen; char *cp; fp = OpenBookmarkFile(NULL); if (fp == NULL) return (-1); bmabbrLen = strlen(bmabbr); while (FGets(line, sizeof(line), fp) != NULL) { if (ParseHostLine(line, bmp) < 0) continue; if (ISTREQ(bmp->bookmarkName, bmabbr)) { /* Exact match, done. */ byBmNameFlag = bmabbrLen; exactMatch = 1; break; } else if (ISTRNEQ(bmp->bookmarkName, bmabbr, bmabbrLen)) { /* Remember this one, it matched an abbreviated * bookmark name. */ byBmAbbr = *bmp; byBmAbbrFlag = bmabbrLen; } else if (ISTREQ(bmp->name, bmabbr)) { /* Remember this one, it matched a full * host name. */ byHostName = *bmp; byHostNameFlag = bmabbrLen; } else if ((cp = strchr(bmp->name, '.')) != NULL) { /* See if it matched part of the hostname. */ if (ISTRNEQ(bmp->name, "ftp", 3)) { cp = cp + 1; } else if (ISTRNEQ(bmp->name, "www", 3)) { cp = cp + 1; } else { cp = bmp->name; } if (ISTRNEQ(cp, bmabbr, bmabbrLen)) { /* Remember this one, it matched a full * host name. */ byHostAbbr = *bmp; byHostAbbrFlag = bmabbrLen; } } } if (gBookmarkMatchMode == 0) { /* Only use a bookmark when the exact * bookmark name was used. */ if (exactMatch != 0) { result = 0; } } else { /* Pick the best match, if any. */ if (byBmNameFlag != 0) { /* *bmp is already set. */ result = 0; } else if (byBmAbbrFlag != 0) { result = 0; *bmp = byBmAbbr; } else if (byHostNameFlag != 0) { result = 0; *bmp = byHostName; } else if (byHostAbbrFlag != 0) { result = 0; *bmp = byHostAbbr; } } if (result != 0) memset(bmp, 0, sizeof(Bookmark)); CloseBookmarkFile(fp); return (result); } /* GetBookmark */