/* This does "tilde-expansion." Examples: * ~/pub --> /usr/gleason/pub * ~pdietz/junk --> /usr/pdietz/junk */ void ExpandTilde(char *pattern, size_t siz) { string pat; char *cp, *rest, *firstent; struct passwd *pw; if ((pattern[0] == '~') && (isalnum(pattern[1]) || (pattern[1] == '/') || (pattern[1] == '\0'))) { STRNCPY(pat, pattern); if ((cp = strchr(pat, '/')) != NULL) { *cp = 0; rest = cp + 1; /* Remember stuff after the ~/ part. */ } else { rest = NULL; /* Was just a ~ or ~username. */ } if (pat[1] == '\0') { /* Was just a ~ or ~/rest type. */ firstent = gUserInfo.home; } else { /* Was just a ~username or ~username/rest type. */ pw = getpwnam(pat + 1); if (pw != NULL) firstent = pw->pw_dir; else return; /* Bad user -- leave it alone. */ } Strncpy(pattern, firstent, siz); if (rest != NULL) { Strncat(pattern, "/", siz); Strncat(pattern, rest, siz); } } } /* ExpandTilde */
/* Print the command shell's prompt. */ void MakePrompt(char *dst, size_t dsize) { char acwd[64]; # ifdef HAVE_SNPRINTF if (gConn.loggedIn != 0) { AbbrevStr(acwd, gRemoteCWD, 25, 0); snprintf(dst, dsize, "%sncftp%s %s %s>%s ", tcap_boldface, tcap_normal, acwd, tcap_boldface, tcap_normal); } else { snprintf(dst, dsize, "%sncftp%s> ", tcap_boldface, tcap_normal); } # else /* HAVE_SNPRINTF */ (void) Strncpy(dst, tcap_boldface, dsize); (void) Strncat(dst, "ncftp", dsize); (void) Strncat(dst, tcap_normal, dsize); if (gConn.loggedIn != 0) { AbbrevStr(acwd, gRemoteCWD, 25, 0); (void) Strncat(dst, " ", dsize); (void) Strncat(dst, acwd, dsize); (void) Strncat(dst, " ", dsize); } (void) Strncat(dst, tcap_boldface, dsize); (void) Strncat(dst, ">", dsize); (void) Strncat(dst, tcap_normal, dsize); (void) Strncat(dst, " ", dsize); # endif /* HAVE_SNPRINTF */ } /* MakePrompt */
void SpoolName(const char *const sdir, char *sp, size_t size, int flag, int serial, time_t when) { char sname[64]; char dstr[32]; struct tm *ltp; if ((when == (time_t) 0) || (when == (time_t) -1)) (void) time(&when); ltp = localtime(&when); if (ltp == NULL) { /* impossible */ (void) Strncpy(dstr, "19700101-000000", size); } else { (void) strftime(dstr, sizeof(dstr), "%Y%m%d-%H%M%S", ltp); } (void) Strncpy(sp, sdir, size); (void) sprintf(sname, "/%c-%010u-%04x-%s", flag, (unsigned int) getpid(), (serial % (16 * 16 * 16 * 16)), dstr ); (void) Strncat(sp, sname, size); } /* SpoolName */
static int UnDosLine( char *const line, const char *const curdir, size_t curdirlen, char *fname, size_t fnamesize, int *ftype, longest_int *fsize, time_t *ftime) { char *cp; int hour, year; char *filestart; char *sizestart; struct tm ftm; /* * 0123456789012345678901234567890123456789012345678901234567890123456789 04-27-99 10:32PM 270158 Game booklet.pdf 03-11-99 10:03PM <DIR> Get A3d Banner We also try to parse the format from CMD.EXE, which is similar: 03/22/2001 06:23p 62,325 cls.pdf * */ cp = line; if ( isdigit((int) cp[0]) && isdigit((int) cp[1]) && ispunct((int) cp[2]) && isdigit((int) cp[3]) && isdigit((int) cp[4]) && ispunct((int) cp[5]) && isdigit((int) cp[6]) && isdigit((int) cp[7]) ) { (void) memset(&ftm, 0, sizeof(struct tm)); ftm.tm_isdst = -1; cp[2] = '\0'; ftm.tm_mon = atoi(cp + 0); if (ftm.tm_mon > 0) ftm.tm_mon -= 1; cp[5] = '\0'; ftm.tm_mday = atoi(cp + 3); if ((isdigit((int) cp[8])) && (isdigit((int) cp[9]))) { /* Four-digit year */ cp[10] = '\0'; year = atoi(cp + 6); if (year > 1900) year -= 1900; ftm.tm_year = year; /* years since 1900 */ cp += 11; } else { /* Two-digit year */ cp[8] = '\0'; year = atoi(cp + 6); if (year < 98) year += 100; ftm.tm_year = year; /* years since 1900 */ cp += 9; } for (;;) { if (*cp == '\0') return (-1); if (isdigit((int) *cp)) break; cp++; } cp[2] = '\0'; hour = atoi(cp); if (((cp[5] == 'P') || (cp[5] == 'p')) && (hour < 12)) hour += 12; else if (((cp[5] == 'A') || (cp[5] == 'a')) && (hour == 12)) hour -= 12; ftm.tm_hour = hour; cp[5] = '\0'; ftm.tm_min = atoi(cp + 3); *ftime = mktime(&ftm); if (*ftype == (time_t) -1) return (-1); cp += 6; *ftype = '-'; for (;;) { if (*cp == '\0') return (-1); if ((*cp == '<') && (cp[1] == 'D')) { /* found <DIR> */ *ftype = 'd'; cp += 5; break; /* size field will end up being empty string */ } else if ((*cp == '<') && (cp[1] == 'J')) { /* found <JUNCTION> * * Will we ever really see this? * IIS from Win2000sp1 sends <DIR> * for FTP, but CMD.EXE prints * <JUNCTION>. */ *ftype = 'd'; cp += 10; break; } else if (isdigit((int) *cp)) { break; } else { cp++; } } sizestart = cp; for (;;) { if (*cp == '\0') return (-1); #ifdef HAVE_MEMMOVE if (*cp == ',') { /* Yuck -- US Locale dependency */ memmove(cp, cp + 1, strlen(cp + 1) + 1); } #endif if (!isdigit((int) *cp)) { *cp++ = '\0'; break; } cp++; } if (fsize != NULL) { #if defined(HAVE_LONG_LONG) && defined(SCANF_LONG_LONG) if (*ftype == 'd') *fsize = 0; else (void) sscanf(sizestart, SCANF_LONG_LONG, fsize); #elif defined(HAVE_LONG_LONG) && defined(HAVE_STRTOQ) if (*ftype == 'd') *fsize = 0; else *fsize = (longest_int) strtoq(sizestart, NULL, 0); #else *fsize = (longest_int) 0; if (*ftype != 'd') { long fsize2 = 0L; (void) sscanf(sizestart, "%ld", &fsize2); *fsize = (longest_int) fsize2; } #endif } for (;;) { if (*cp == '\0') return (-1); if (!isspace((int) *cp)) { break; } cp++; } filestart = cp; if (curdirlen == 0) { (void) Strncpy(fname, filestart, fnamesize); } else { (void) Strncpy(fname, curdir, fnamesize); (void) Strncat(fname, filestart, fnamesize); } return (0); } return (-1); } /* UnDosLine */
static int UnLslRLine( char *const line, const char *const curdir, size_t curdirlen, char *fname, size_t fnamesize, char *linkto, size_t linktosize, int *ftype, longest_int *fsize, time_t *ftime, time_t now, int thisyear, int *plugend) { char *cp; int mon = 0, day = 0, hr = 0, min = 0, year = 0, sec = 0; int haveIsoHHMMSS = -1; char *monstart, *daystart, *hrstart, *minstart, *yearstart, *secstart = NULL; char *linktostart, *filestart = NULL; char *sizestart; char *pe; struct tm ftm; *plugend = 0; *ftype = 0; if (ftime != NULL) *ftime = (time_t) -1; if (fsize != NULL) *fsize = (longest_int) -1; /* * Look for the digit just before the space * before the month name. * -rw-rw---- 1 gleason sysdev 33404 Mar 24 01:29 RCmd.o -rw-rw-r-- 1 gleason sysdevzz 1829 Jul 7 1996 README -rw-rw-r-- 1 gleason sysdevzz 1829 Jul 7 1996 README -rw-rw-r-- 1 gleason sysdevzz 1829 Jul 7 1996 README -rw-rw-r-- 1 gleason sysdevzz 1829 Jul 7 1996 README drwxrwxrwx 1 pvr pvr 45056 Jan 1 2000 DataFiles * *------------------------------^ * 0123456789012345 *------plugend--------^ * 9876543210 * */ for (cp = line; *cp != '\0'; cp++) { if ( (isdigit((int) *cp)) && (isspace((int) cp[1])) && (isupper((int) cp[2])) && (islower((int) cp[3])) /* && (islower((int) cp[4])) */ && (isspace((int) cp[5])) && ( ((isdigit((int) cp[6])) && (isdigit((int) cp[7]))) || ((isdigit((int) cp[6])) && (isspace((int) cp[7]))) || ((isspace((int) cp[6])) && (isdigit((int) cp[7]))) ) && (isspace((int) cp[8])) ) { monstart = cp + 2; daystart = cp + 6; if ( ((isspace((int) cp[9])) || (isdigit((int) cp[9]))) && (isdigit((int) cp[10])) && (isdigit((int) cp[11])) && (isdigit((int) cp[12])) && ((isdigit((int) cp[13])) || (isspace((int) cp[13]))) ) { /* "Mon DD YYYY" form */ yearstart = cp + 9; if (isspace((int) *yearstart)) yearstart++; hrstart = NULL; minstart = NULL; filestart = cp + 15; cp[1] = '\0'; /* end size */ cp[5] = '\0'; /* end mon */ cp[8] = '\0'; /* end day */ if (! isspace((int) filestart[-1])) { if (isspace((int) filestart[-2])) { filestart--; } } filestart[-1] = '\0'; /* end year */ mon = LsMonthNameToNum(monstart); day = atoi(daystart); hr = 23; min = 59; sec = 59; year = atoi(yearstart); pe = cp; while (isdigit((int) *pe)) pe--; while (isspace((int) *pe)) pe--; *plugend = (int) (pe - line) + 1; break; } else if ( /* * Windows NT does not 0 pad. (isdigit((int) cp[9])) && */ (isdigit((int) cp[10])) && (cp[11] == ':') && (isdigit((int) cp[12])) && (isdigit((int) cp[13])) ) { /* "Mon DD HH:MM" form */ yearstart = NULL; hrstart = cp + 9; minstart = cp + 12; filestart = cp + 15; cp[1] = '\0'; /* end size */ cp[5] = '\0'; /* end mon */ cp[8] = '\0'; /* end day */ cp[11] = '\0'; /* end hr */ cp[14] = '\0'; /* end min */ mon = LsMonthNameToNum(monstart); day = atoi(daystart); hr = atoi(hrstart); min = atoi(minstart); sec = 0; year = 0; pe = cp; while (isdigit((int) *pe)) pe--; while (isspace((int) *pe)) pe--; *plugend = (int) (pe - line) + 1; break; } } else if ( (isdigit((int) *cp)) && (isspace((int) cp[1])) && (isdigit((int) cp[2])) && (isdigit((int) cp[3])) && (isdigit((int) cp[4])) && (isdigit((int) cp[5])) && (cp[6] == '-') && (isdigit((int) cp[7])) && (isdigit((int) cp[8])) && (cp[9] == '-') && (isdigit((int) cp[10])) && (isdigit((int) cp[11])) && (isspace((int) cp[12])) && (isdigit((int) cp[13])) && (isdigit((int) cp[14])) && (cp[15] == ':') && (isdigit((int) cp[16])) && (isdigit((int) cp[17])) && ( ((haveIsoHHMMSS = isspace((int) cp[18]))) || ( (isdigit((int) cp[19])) && (isdigit((int) cp[20])) && (isspace((int) cp[21])) && ((haveIsoHHMMSS = (int) cp[18]) == ':') ) ) ) { /* "YYYY-mm-dd HH:MM" or "YYYY-mm-dd HH:MM:SS" form */ /* drwxr-xr-x 4 ftpuser ftpusers 136 2008-03-12 23:38 beta 0123456789012345678901234567890123456789 */ yearstart = cp + 2; cp[6] = '\0'; /* end year */ monstart = cp + 7; cp[9] = '\0'; /* end month */ daystart = cp + 10; cp[12] = '\0'; /* end day */ hrstart = cp + 13; cp[15] = '\0'; /* end hr */ minstart = cp + 16; cp[18] = '\0'; /* end min */ if (haveIsoHHMMSS == ':') { secstart = cp + 19; cp[21] = '\0'; /* end sec */ sec = atoi(secstart); filestart = cp + 22; } else { filestart = cp + 19; sec = 0; } mon = atoi(monstart) - 1; day = atoi(daystart); hr = atoi(hrstart); min = atoi(minstart); year = atoi(yearstart); pe = cp; while (isdigit((int) *pe)) pe--; while (isspace((int) *pe)) pe--; *plugend = (int) (pe - line) + 1; break; } } if (*cp == '\0') return (-1); linktostart = strstr(filestart, " -> "); if (linktostart != NULL) { *linktostart = '\0'; linktostart += 4; (void) Strncpy(linkto, linktostart, linktosize); } else { *linkto = '\0'; } if (curdirlen == 0) { (void) Strncpy(fname, filestart, fnamesize); } else { (void) Strncpy(fname, curdir, fnamesize); (void) Strncat(fname, filestart, fnamesize); } if (ftime != NULL) { (void) memset(&ftm, 0, sizeof(struct tm)); ftm.tm_mon = mon; ftm.tm_mday = day; ftm.tm_hour = hr; ftm.tm_min = min; ftm.tm_sec = sec; ftm.tm_isdst = -1; if (year == 0) { /* We guess the year, based on what the * current year is. * * UNIX ls would always print the year * if the file was older than 6 months, * but many non-UNIX based servers do * not honor that convention, so we * now assume that if the year was not * given it implies the current year, * unless the file is up to two days * into the future. */ ftm.tm_year = thisyear - 1900; *ftime = mktime(&ftm); if (*ftime == (time_t) -1) { /* panic */ } else if (*ftime > (now + (2 * 86400L))) { --ftm.tm_year; *ftime = mktime(&ftm); } } else { ftm.tm_year = year - 1900; *ftime = mktime(&ftm); } } if (fsize != NULL) { while ((cp > line) && (isdigit((int) *cp))) --cp; sizestart = cp + 1; #if defined(HAVE_LONG_LONG) && defined(SCANF_LONG_LONG) (void) sscanf(sizestart, SCANF_LONG_LONG, fsize); #elif defined(HAVE_LONG_LONG) && defined(HAVE_STRTOQ) *fsize = (longest_int) strtoq(sizestart, NULL, 0); #else { long fsize2 = 0L; (void) sscanf(sizestart, "%ld", &fsize2); *fsize = (longest_int) fsize2; } #endif } switch (line[0]) { case 'd': case 'l': *ftype = (int) line[0]; break; case 'b': case 'c': case 's': *ftype = (int) line[0]; return (-1); default: *ftype = '-'; } return (0); } /* UnLslRLine */
int main(int argc, char **argv) { char a[8]; char pad1[32]; char *b; char c[37]; char pad2[23]; int i; int len1, len2; b = Strncpy(a, "hello", sizeof(a)); b = Strncat(b, "world", sizeof(a)); printf("1: result=[%s] should be=[%s]\n", b, "hellowo" ); for (i=0; i<sizeof(c); i++) c[i] = 'X'; b = Strncpy(c, "testing", sizeof(c) - 2); #if (STRN_ZERO_PAD == 1) for (i=7; i<sizeof(c) - 2; i++) { if (c[i] != '\0') { printf("2: did not clear to end of buffer\n"); break; } } #endif for (i=sizeof(c) - 2; i<sizeof(c); i++) { if (c[i] != 'X') { printf("2: overwrote buffer\n"); break; } } for (i=0; i<sizeof(c); i++) c[i] = 'X'; b = Strncpy(c, "testing", sizeof(c) - 2); b = Strncat(b, " still", sizeof(c) - 2); #if (STRN_ZERO_PAD == 1) for (i=13; i<sizeof(c) - 2; i++) { if (c[i] != '\0') { printf("3: did not clear to end of buffer\n"); break; } } #endif for (i=sizeof(c) - 2; i<sizeof(c); i++) { if (c[i] != 'X') { printf("3: overwrote buffer\n"); break; } } /*--------------*/ b = Strnpcpy(a, "hello", sizeof(a)); len1 = (int) (b - a); b = Strnpcat(a, "world", sizeof(a)); len2 = (int) (b - a); printf("4: result=[%s] should be=[%s] len1=%d len2=%d\n", a, "hellowo", len1, len2 ); for (i=0; i<sizeof(c); i++) c[i] = 'X'; b = Strnpcpy(c, "testing", sizeof(c) - 2); #if (STRNP_ZERO_PAD == 1) for (i=7; i<sizeof(c) - 2; i++) { if (c[i] != '\0') { printf("5: did not clear to end of buffer\n"); break; } } #endif for (i=sizeof(c) - 2; i<sizeof(c); i++) { if (c[i] != 'X') { printf("5: overwrote buffer\n"); break; } } for (i=0; i<sizeof(c); i++) c[i] = 'X'; b = Strnpcpy(c, "testing", sizeof(c) - 2); b = Strnpcat(c, " still", sizeof(c) - 2); #if (STRNP_ZERO_PAD == 1) for (i=13; i<sizeof(c) - 2; i++) { if (c[i] != '\0') { printf("6: did not clear to end of buffer\n"); break; } } #endif for (i=sizeof(c) - 2; i<sizeof(c); i++) { if (c[i] != 'X') { printf("6: overwrote buffer\n"); break; } } /*--------------*/ { char *str; str = NULL; if (Dynscat(&str, "this is a test", 0) == NULL) { printf("7a: fail\n"); } else if (strcmp(str, "this is a test") != 0) { printf("7b: fail\n"); } free(str); str = NULL; if (Dynscat(&str, "this is a test", 0) == NULL) { printf("7c: fail\n"); } else if (strcmp(str, "this is a test") != 0) { printf("7d: fail\n"); } else if (Dynscat(&str, " ", "", "and", " ", "so is this", 0) == NULL) { printf("7e: fail\n"); } else if (strcmp(str, "this is a test and so is this") != 0) { printf("7f: fail\n"); } free(str); } exit(0); }
int thrash_rc(void) { struct stat st; string word, str; longstring cwd; char *cp, *dp, *rc; FILE *fp; int i; (void) get_cwd(cwd, sizeof(cwd)); if (cwd[strlen(cwd) - 1] != '/') (void) Strncat(cwd, "/"); /* Because some versions of regular ftp complain about ncftp's * #set commands, FTPRC takes precedence over NETRC. */ cp = getenv("DOTDIR"); for (i=0; i<2; i++) { rc = (i == 0) ? FTPRC : NETRC; (void) sprintf(rcname, "%s%s", cwd, rc); if (stat(rcname, &st) == 0) goto foundrc; (void) sprintf(rcname, "%s.%s", cwd, rc); if (stat(rcname, &st) == 0) goto foundrc; if (cp != NULL) { (void) sprintf(rcname, "%s/.%s", cp, rc); if (stat(rcname, &st) == 0) goto foundrc; } (void) sprintf(rcname, "%s/.%s", uinfo.homedir, rc); if (stat(rcname, &st) == 0) goto foundrc; } return (0); /* it's OK not to have an rc. */ foundrc: if ((st.st_mode & 077) != 0) /* rc must be unreadable by others. */ (void) chmod(rcname, 0600); if ((fp = fopen(rcname, "r")) == NULL) { PERROR("thrash_rc", rcname); return -1; } parsing_rc = 1; while ((cp = FGets(str, fp)) != 0) { while (isspace(*cp)) ++cp; /* skip leading space. */ if (*cp == '#') { if ((strncmp("set", ++cp, (size_t)3) == 0) || (strncmp("unset", cp, (size_t)5) == 0)) { (void) strcpy(line, cp); makeargv(); (void) set(margc, margv); /* setting or unsetting a variable. */ } /* else a comment. */ } else { if (strncmp(cp, "machine", (size_t) 7) == 0) { /* We have a new machine record. */ cp += 7; while (isspace(*cp)) ++cp; /* skip delimiting space. */ dp = word; while (*cp && !isspace(*cp)) *dp++ = *cp++; /* copy the name. */ *dp = 0; AddNewSitePtr(word); } } } (void) fclose(fp); parsing_rc = 0; return 1; } /* thrash_rc */
/* Converts a pre-loaded Bookmark structure into a RFC 1738 * Uniform Resource Locator. */ void BookmarkToURL(BookmarkPtr bmp, char *url, size_t urlsize) { char pbuf[32]; /* //<user>:<password>@<host>:<port>/<url-path> */ /* Note that if an absolute path is given, * you need to escape the first entry, i.e. /pub -> %2Fpub */ (void) Strncpy(url, "ftp://", urlsize); if (bmp->user[0] != '\0') { (void) Strncat(url, bmp->user, urlsize); if (bmp->pass[0] != '\0') { (void) Strncat(url, ":", urlsize); (void) Strncat(url, "PASSWORD", urlsize); } (void) Strncat(url, "@", urlsize); } (void) Strncat(url, bmp->name, urlsize); if (bmp->port != 21) { (void) sprintf(pbuf, ":%u", (unsigned int) bmp->port); (void) Strncat(url, pbuf, urlsize); } if (bmp->dir[0] == '/') { /* Absolute URL path, must escape first slash. */ (void) Strncat(url, "/%2F", urlsize); (void) Strncat(url, bmp->dir + 1, urlsize); (void) Strncat(url, "/", urlsize); } else if (bmp->dir[0] != '\0') { (void) Strncat(url, "/", urlsize); (void) Strncat(url, bmp->dir, urlsize); (void) Strncat(url, "/", urlsize); } } /* BookmarkToURL */
/* We need to make something we can give to popen. This is simple * if it is a plain file, but if they wanted to page a compressed * file we have to prepend the correct filter before the pager name. */ int MakePageCmdLine(char *cmd, size_t siz, char *remote_file) { int useZCat; int useGZCat; int binaryPage; int len; useZCat = 0; useGZCat = 0; binaryPage = 0; len = (int) strlen(remote_file); if (len > 2) { if (remote_file[len - 2] == '.') { /* Check for .Z files. */ if (remote_file[len-1] == 'Z') useZCat = 1; /* Check for .z (gzip) files. */ if (remote_file[len - 1] == 'z') useGZCat = 1; } } if (len > 3) { /* Check for ".gz" (gzip) files. */ if (STREQ(remote_file + len - 3, ".gz")) useGZCat = 1; } /* Run compressed remote files through zcat, then the pager. * If GZCAT was defined, we also try paging gzipped files. */ if (useGZCat) { #ifdef GZCAT (void) Strncpy(cmd, GZCAT, siz); (void) Strncat(cmd, " | ", siz); (void) Strncat(cmd, gPager, siz); #else PrintF("NcFTP wasn't configured to page gzipped files.\n"); #endif } else if (useZCat) { #ifdef ZCAT (void) Strncpy(cmd, ZCAT, siz); (void) Strncat(cmd, " | ", siz); (void) Strncat(cmd, gPager, siz); #else # ifdef GZCAT /* gzcat can do .Z's also. */ (void) Strncpy(cmd, GZCAT, siz); (void) Strncat(cmd, " | ", siz); (void) Strncat(cmd, gPager, siz); # else PrintF("NcFTP wasn't configured to page compressed files.\n"); # endif #endif } else { (void) Strncpy(cmd, gPager, siz); } binaryPage = (useZCat || useGZCat); return (binaryPage); } /* MakePageCmdLine */