static void h_mbtowc(const char *locale, const char *illegal, const char *legal) { char buf[64]; size_t stateful, ret; char *str; ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); #ifdef __NetBSD__ ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL); #else if (setlocale(LC_CTYPE, locale) == NULL) { fprintf(stderr, "Locale %s not found.\n", locale); return; } #endif ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); (void)printf("Using locale: %s\n", str); stateful = wctomb(NULL, L'\0'); (void)printf("Locale is state-%sdependent\n", stateful ? "in" : ""); /* initialize internal state */ ret = mbtowc(NULL, NULL, 0); ATF_REQUIRE(stateful ? ret : !ret); (void)strvis(buf, illegal, VIS_WHITE | VIS_OCTAL); (void)printf("Checking illegal sequence: \"%s\"\n", buf); ret = mbtowc(NULL, illegal, strlen(illegal)); (void)printf("mbtowc() returned: %zd\n", ret); ATF_REQUIRE_EQ(ret, (size_t)-1); (void)printf("errno: %s\n", strerror(errno)); ATF_REQUIRE_EQ(errno, EILSEQ); /* if this is stateless encoding, this re-initialization is not required. */ if (stateful) { /* re-initialize internal state */ ret = mbtowc(NULL, NULL, 0); ATF_REQUIRE(stateful ? ret : !ret); } /* valid multibyte sequence case */ (void)strvis(buf, legal, VIS_WHITE | VIS_OCTAL); (void)printf("Checking legal sequence: \"%s\"\n", buf); errno = 0; ret = mbtowc(NULL, legal, strlen(legal)); (void)printf("mbtowc() returned: %zd\n", ret); ATF_REQUIRE(ret != (size_t)-1); (void)printf("errno: %s\n", strerror(errno)); ATF_REQUIRE_EQ(errno, 0); (void)printf("Ok.\n"); }
void fmt_puts(char *s, int *leftp) { static char *v = 0; static int maxlen = 0; char *nv; int len, nlen; if (*leftp == 0) return; len = strlen(s) * 4 + 1; if (len > maxlen) { if (maxlen == 0) nlen = getpagesize(); else nlen = maxlen; while (len > nlen) nlen *= 2; nv = realloc(v, nlen); if (nv == 0) return; v = nv; maxlen = nlen; } len = strvis(v, s, VIS_TAB | VIS_NL | VIS_CSTYLE); if (*leftp != -1) { if (len > *leftp) { v[*leftp] = '\0'; *leftp = 0; } else *leftp -= len; } (void)printf("%s", v); }
int safe_print(const char *src) { size_t len; char *name; int flags; flags = VIS_NL | VIS_OCTAL | VIS_WHITE; if (f_octal_escape) flags |= VIS_CSTYLE; len = strlen(src); if (len != 0 && ~(size_t)0/len <= 4) { errx(EXIT_FAILURE, "%s: name too long", src); /* NOTREACHED */ return 0; } name = (char *)malloc(4*len+1); if (name != NULL) { len = strvis(name, src, flags); (void)printf("%s", name); free(name); return len; } else errx(EXIT_FAILURE, "out of memory!"); /* NOTREACHED */ return 0; }
/* * Build a block of characters containing the message. * It is sent blank filled and in a single block to * try to keep the message in one piece if the recipient * is in vi at the time */ static void print_mesg(FILE *tf, CTL_MSG *request, char *remote_machine) { time_t clocktime; struct tm *localclock; char line_buf[N_LINES][N_CHARS]; int sizes[N_LINES]; char big_buf[(N_LINES + 1) * N_CHARS]; char *bptr, *lptr, vis_user[sizeof(request->l_name) * 4]; int i, j, max_size; i = 0; max_size = 0; time(&clocktime); localclock = localtime(&clocktime); (void)snprintf(line_buf[i], N_CHARS, " "); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, "Message from Talk_Daemon@%s at %d:%02d ...", hostname, localclock->tm_hour , localclock->tm_min ); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; strvis(vis_user, request->l_name, VIS_CSTYLE); (void)snprintf(line_buf[i], N_CHARS, "talk: connection requested by %s@%s.", vis_user, remote_machine); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, "talk: respond with: talk %s@%s", vis_user, remote_machine); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, " "); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; bptr = big_buf; *bptr++ = '\007'; /* send something to wake them up */ *bptr++ = '\r'; /* add a \r in case of raw mode */ *bptr++ = '\n'; for (i = 0; i < N_LINES; i++) { /* copy the line into the big buffer */ lptr = line_buf[i]; while (*lptr != '\0') *(bptr++) = *(lptr++); /* pad out the rest of the lines with blanks */ for (j = sizes[i]; j < max_size + 2; j++) *(bptr++) = ' '; *(bptr++) = '\r'; /* add a \r in case of raw mode */ *(bptr++) = '\n'; } *bptr = '\0'; fprintf(tf, "%s", big_buf); fflush(tf); }
static void h_wctomb(const struct test *t, char tc) { wchar_t wcs[16 + 2]; char buf[128]; char cs[MB_LEN_MAX]; const char *pcs; char *str; mbstate_t st; mbstate_t *stp = NULL; size_t sz, ret, i; ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); (void)printf("Checking sequence: \"%s\"\n", buf); ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); (void)printf("Using locale: %s\n", str); if (tc == TC_WCRTOMB_ST) { (void)memset(&st, 0, sizeof(st)); stp = &st; } wcs[t->wclen] = L'X'; /* poison */ pcs = t->data; sz = mbsrtowcs(wcs, &pcs, t->wclen + 2, NULL); ATF_REQUIRE_EQ_MSG(sz, t->wclen, "mbsrtowcs() returned: " "%zu, expected: %zu", sz, t->wclen); ATF_REQUIRE_EQ(wcs[t->wclen], 0); for (i = 0; i < t->wclen + 1; i++) { if (tc == TC_WCTOMB) ret = wctomb(cs, wcs[i]); else ret = wcrtomb(cs, wcs[i], stp); if (ret == t->mblen[i]) continue; (void)printf("At position %zd:\n", i); (void)printf(" expected: %zd\n", t->mblen[i]); (void)printf(" got : %zd\n", ret); atf_tc_fail("Test failed"); /* NOTREACHED */ } (void)printf("Ok.\n"); }
END_TEST #endif /* HAVE_STRLCPY */ #ifndef HAVE_STRNVIS START_TEST(test_strnvis) { char dst[BUFSIZ]; const char *src = "0123456789ABCDEF\n\t\r\b\a\v\f1234\\"; mark_point(); strvis(dst, src, VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); fail_unless (strlen(dst) == 40, "length should be equal to 40"); mark_point(); strvisx(dst, src, strlen(src), VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); fail_unless (strlen(dst) == 40, "length should be equal to 40"); mark_point(); strnvis(dst, src, BUFSIZ, VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL|VIS_NOSLASH); fail_unless (strlen(dst) == 39, "length should be equal to 39"); }
/*ARGSUSED*/ void listvariables(int c) { value_t *p; char *buf; char charbuf[5]; /* for vis(3), 4 chars for encoding, plus nul */ puts("v\r"); for (p = vtable; p->v_name; p++) { fputs(p->v_name, stdout); switch (p->v_type&TMASK) { case STRING: if (p->v_value) { buf = malloc(4*strlen(p->v_value) + 1); if (buf == NULL) { fprintf(stderr, "Unable to malloc()\n"); abort(); } strvis(buf, p->v_value, VIS_WHITE); printf(" %s", buf); free(buf); } putchar('\r'); putchar('\n'); break; case NUMBER: printf(" %ld\r\n", number(p->v_value)); break; case BOOL: printf(" %s\r\n", !boolean(p->v_value) ? "false" : "true"); break; case CHAR: vis(charbuf, character(p->v_value), VIS_WHITE, 0); printf(" %s\r\n", charbuf); break; } } }
void fmt_puts(const char *s, int *leftp) { static char *v = NULL, *nv; static int maxlen = 0; int len; if (*leftp == 0) return; len = strlen(s) * 4 + 1; if (len > maxlen) { size_t newmaxlen = maxlen; if (newmaxlen == 0) newmaxlen = getpagesize(); while (len > newmaxlen) newmaxlen *= 2; nv = realloc(v, newmaxlen); if (nv == 0) { free(v); v = NULL; maxlen = 0; return; } maxlen = newmaxlen; v = nv; } strvis(v, s, VIS_TAB | VIS_NL | VIS_CSTYLE); if (*leftp != -1) { len = strlen(v); if (len > *leftp) { v[*leftp] = '\0'; *leftp = 0; } else *leftp -= len; } printf("%s", v); }
static void statf(int indent, FTSENT *p) { struct group *gr; struct passwd *pw; uint32_t val; off_t len; int fd, offset; char *fflags; char *escaped_name; escaped_name = calloc(1, p->fts_namelen * 4 + 1); if (escaped_name == NULL) errx(1, "statf(): calloc() failed"); strvis(escaped_name, p->fts_name, VIS_WHITE | VIS_OCTAL | VIS_GLOB); if (iflag || S_ISDIR(p->fts_statp->st_mode)) offset = printf("%*s%s", indent, "", escaped_name); else offset = printf("%*s %s", indent, "", escaped_name); free(escaped_name); if (offset > (INDENTNAMELEN + indent)) offset = MAXLINELEN; else offset += printf("%*s", (INDENTNAMELEN + indent) - offset, ""); if (!S_ISREG(p->fts_statp->st_mode) && !dflag) output(indent, &offset, "type=%s", inotype(p->fts_statp->st_mode)); if (p->fts_statp->st_uid != uid) { if (keys & F_UNAME) { pw = getpwuid(p->fts_statp->st_uid); if (pw != NULL) output(indent, &offset, "uname=%s", pw->pw_name); else if (wflag) warnx("Could not get uname for uid=%u", p->fts_statp->st_uid); else errx(1, "Could not get uname for uid=%u", p->fts_statp->st_uid); } if (keys & F_UID) output(indent, &offset, "uid=%u", p->fts_statp->st_uid); } if (p->fts_statp->st_gid != gid) { if (keys & F_GNAME) { gr = getgrgid(p->fts_statp->st_gid); if (gr != NULL) output(indent, &offset, "gname=%s", gr->gr_name); else if (wflag) warnx("Could not get gname for gid=%u", p->fts_statp->st_gid); else errx(1, "Could not get gname for gid=%u", p->fts_statp->st_gid); } if (keys & F_GID) output(indent, &offset, "gid=%u", p->fts_statp->st_gid); } if (keys & F_MODE && (p->fts_statp->st_mode & MBITS) != mode) output(indent, &offset, "mode=%#o", p->fts_statp->st_mode & MBITS); if (keys & F_NLINK && p->fts_statp->st_nlink != 1) output(indent, &offset, "nlink=%u", p->fts_statp->st_nlink); if (keys & F_SIZE) output(indent, &offset, "size=%jd", (intmax_t)p->fts_statp->st_size); if (keys & F_TIME) output(indent, &offset, "time=%ld.%ld", (long)p->fts_statp->st_mtimespec.tv_sec, p->fts_statp->st_mtimespec.tv_nsec); if (keys & F_CKSUM && S_ISREG(p->fts_statp->st_mode)) { if ((fd = open(p->fts_accpath, O_RDONLY, 0)) < 0 || crc(fd, &val, &len)) err(1, "%s", p->fts_accpath); (void)close(fd); output(indent, &offset, "cksum=%lu", (unsigned long)val); } #ifdef ENABLE_MD5 if (keys & F_MD5 && S_ISREG(p->fts_statp->st_mode)) { char *digest, buf[33]; digest = MD5File(p->fts_accpath, buf); if (!digest) err(1, "%s", p->fts_accpath); output(indent, &offset, "md5digest=%s", digest); } #endif /* ENABLE_MD5 */ #ifdef ENABLE_SHA1 if (keys & F_SHA1 && S_ISREG(p->fts_statp->st_mode)) { char *digest, buf[41]; digest = SHA1_File(p->fts_accpath, buf); if (!digest) err(1, "%s", p->fts_accpath); output(indent, &offset, "sha1digest=%s", digest); } #endif /* ENABLE_SHA1 */ #ifdef ENABLE_RMD160 if (keys & F_RMD160 && S_ISREG(p->fts_statp->st_mode)) { char *digest, buf[41]; digest = RIPEMD160_File(p->fts_accpath, buf); if (!digest) err(1, "%s", p->fts_accpath); output(indent, &offset, "ripemd160digest=%s", digest); } #endif /* ENABLE_RMD160 */ #ifdef ENABLE_SHA256 if (keys & F_SHA256 && S_ISREG(p->fts_statp->st_mode)) { char *digest, buf[65]; digest = SHA256_File(p->fts_accpath, buf); if (!digest) err(1, "%s", p->fts_accpath); output(indent, &offset, "sha256digest=%s", digest); } #endif /* ENABLE_SHA256 */ if (keys & F_SLINK && (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { char visbuf[MAXPATHLEN * 4]; char *s = rlink(p->fts_accpath); strvis(visbuf, s, VIS_WHITE | VIS_OCTAL); output(indent, &offset, "link=%s", visbuf); } if (keys & F_FLAGS && p->fts_statp->st_flags != flags) { fflags = flags_to_string(p->fts_statp->st_flags); output(indent, &offset, "flags=%s", fflags); free(fflags); } (void)putchar('\n'); }
/* * Send message described by the passed pointer to the * passed output buffer. Return -1 on error. * Adjust the status: field if need be. * If doign is given, suppress ignored header fields. * prefix is a string to prepend to each output line. */ int sendmessage(struct message *mp, FILE *obuf, struct ignoretab *doign, char *prefix) { int count; FILE *ibuf; char line[LINESIZE]; char visline[4 * LINESIZE - 3]; int ishead, infld, ignoring = 0, dostat, firstline; char *cp, *cp2; int c = 0; int length; int prefixlen = 0; int rval; int dovis; struct sigaction act, saveint; sigset_t oset; sendsignal = 0; rval = -1; dovis = isatty(fileno(obuf)); sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; act.sa_handler = sendint; (void)sigaction(SIGINT, &act, &saveint); (void)sigprocmask(SIG_UNBLOCK, &intset, &oset); /* * Compute the prefix string, without trailing whitespace */ if (prefix != NULL) { cp2 = 0; for (cp = prefix; *cp; cp++) if (*cp != ' ' && *cp != '\t') cp2 = cp; prefixlen = cp2 == 0 ? 0 : cp2 - prefix + 1; } ibuf = setinput(mp); count = mp->m_size; ishead = 1; dostat = doign == 0 || !isign("status", doign); infld = 0; firstline = 1; /* * Process headers first */ while (count > 0 && ishead) { if (fgets(line, sizeof(line), ibuf) == NULL) break; count -= length = strlen(line); if (firstline) { /* * First line is the From line, so no headers * there to worry about */ firstline = 0; ignoring = doign == ignoreall; } else if (line[0] == '\n') { /* * If line is blank, we've reached end of * headers, so force out status: field * and note that we are no longer in header * fields */ if (dostat) { if (statusput(mp, obuf, prefix) == -1) goto out; dostat = 0; } ishead = 0; ignoring = doign == ignoreall; } else if (infld && (line[0] == ' ' || line[0] == '\t')) { /* * If this line is a continuation (via space or tab) * of a previous header field, just echo it * (unless the field should be ignored). * In other words, nothing to do. */ } else { /* * Pick up the header field if we have one. */ for (cp = line; (c = *cp++) && c != ':' && !isspace(c);) ; cp2 = --cp; while (isspace(*cp++)) ; if (cp[-1] != ':') { /* * Not a header line, force out status: * This happens in uucp style mail where * there are no headers at all. */ if (dostat) { if (statusput(mp, obuf, prefix) == -1) goto out; dostat = 0; } if (doign != ignoreall) /* add blank line */ (void)putc('\n', obuf); ishead = 0; ignoring = 0; } else { /* * If it is an ignored field and * we care about such things, skip it. */ *cp2 = 0; /* temporarily null terminate */ if (doign && isign(line, doign)) ignoring = 1; else if (strcasecmp(line, "status") == 0) { /* * If the field is "status," go compute * and print the real Status: field */ if (dostat) { if (statusput(mp, obuf, prefix) == -1) goto out; dostat = 0; } ignoring = 1; } else { ignoring = 0; *cp2 = c; /* restore */ } infld = 1; } } if (!ignoring) { /* * Strip trailing whitespace from prefix * if line is blank. */ if (prefix != NULL) { if (length > 1) fputs(prefix, obuf); else (void)fwrite(prefix, sizeof(*prefix), prefixlen, obuf); } if (dovis) { length = strvis(visline, line, VIS_SAFE|VIS_NOSLASH); (void)fwrite(visline, sizeof(*visline), length, obuf); } else (void)fwrite(line, sizeof(*line), length, obuf); if (ferror(obuf)) goto out; } if (sendsignal == SIGINT) goto out; } /* * Copy out message body */ if (doign == ignoreall) count--; /* skip final blank line */ while (count > 0) { if (fgets(line, sizeof(line), ibuf) == NULL) { c = 0; break; } count -= c = strlen(line); if (prefix != NULL) { /* * Strip trailing whitespace from prefix * if line is blank. */ if (c > 1) fputs(prefix, obuf); else (void)fwrite(prefix, sizeof(*prefix), prefixlen, obuf); } /* * We can't read the record file (or inbox for recipient) * properly with 'From ' lines in the message body (from * forwarded messages or sentences starting with "From "), * so we will prepend those lines with a '>'. */ if (strncmp(line, "From ", 5) == 0) (void)fwrite(">", 1, 1, obuf); /* '>' before 'From ' */ if (dovis) { length = strvis(visline, line, VIS_SAFE|VIS_NOSLASH); (void)fwrite(visline, sizeof(*visline), length, obuf); } else (void)fwrite(line, sizeof(*line), c, obuf); if (ferror(obuf) || sendsignal == SIGINT) goto out; } if (doign == ignoreall && c > 0 && line[c - 1] != '\n') /* no final blank line */ if ((c = getc(ibuf)) != EOF && putc(c, obuf) == EOF) goto out; rval = 0; out: sendsignal = 0; (void)sigprocmask(SIG_SETMASK, &oset, NULL); (void)sigaction(SIGINT, &saveint, NULL); return(rval); }
/* * Build a block of characters containing the message. * It is sent blank filled and in a single block to * try to keep the message in one piece if the recipient * in vi at the time */ int print_mesg(const char *tty, CTL_MSG *request, const char *remote_machine) { struct timeval now; time_t clock_sec; struct tm *localclock; struct iovec iovec; char line_buf[N_LINES][N_CHARS]; int sizes[N_LINES]; char big_buf[N_LINES*N_CHARS]; char *bptr, *lptr, *vis_user; int i, j, max_size; i = 0; max_size = 0; gettimeofday(&now, NULL); clock_sec = now.tv_sec; localclock = localtime(&clock_sec); (void)snprintf(line_buf[i], N_CHARS, " "); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, "Message from Talk_Daemon@%s at %d:%02d on %d/%.2d/%.2d ...", hostname, localclock->tm_hour , localclock->tm_min, localclock->tm_year + 1900, localclock->tm_mon + 1, localclock->tm_mday); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; vis_user = malloc(strlen(request->l_name) * 4 + 1); strvis(vis_user, request->l_name, VIS_CSTYLE); (void)snprintf(line_buf[i], N_CHARS, "talk: connection requested by %s@%s", vis_user, remote_machine); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, "talk: respond with: talk %s@%s", vis_user, remote_machine); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); i++; (void)snprintf(line_buf[i], N_CHARS, " "); sizes[i] = strlen(line_buf[i]); max_size = max(max_size, sizes[i]); bptr = big_buf; *bptr++ = '\007'; /* send something to wake them up */ *bptr++ = '\r'; /* add a \r in case of raw mode */ *bptr++ = '\n'; for (i = 0; i < N_LINES; i++) { /* copy the line into the big buffer */ lptr = line_buf[i]; while (*lptr != '\0') *(bptr++) = *(lptr++); /* pad out the rest of the lines with blanks */ for (j = sizes[i]; j < max_size + 2; j++) *(bptr++) = ' '; *(bptr++) = '\r'; /* add a \r in case of raw mode */ *(bptr++) = '\n'; } *bptr = '\0'; iovec.iov_base = big_buf; iovec.iov_len = bptr - big_buf; /* * we choose a timeout of RING_WAIT-5 seconds so that we don't * stack up processes trying to write messages to a tty * that is permanently blocked. */ if (ttymsg(&iovec, 1, tty, RING_WAIT - 5) != NULL) return (FAILED); return (SUCCESS); }
ATF_TC_BODY(strvis_null, tc) { char dst[] = "fail"; strvis(dst, NULL, VIS_SAFE); ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); }
ATF_TC_BODY(strvis_empty, tc) { char dst[] = "fail"; strvis(dst, "", VIS_SAFE); ATF_REQUIRE(dst[0] == '\0' && dst[1] == 'a'); }
/* * expect "str" (a regular expression) on file descriptor "fd", storing * the FTP return code of the command in the integer "ftprc". The "str" * string is expected to match some FTP return codes after a '\n', e.g. * "\n(550|226).*\n" */ static int expect(int fd, const char *str, int *ftprc) { int rc; char *p, buf[90], progress_str[90]; char tmp[MAXLEN]; #if EXPECT_DEBUG char *vstr; #endif /* EXPECT_DEBUG */ regex_t rstr; int done; struct pollfd set[1]; int retval; regmatch_t match; int verbose_expect=0; static int next = 1; #if EXPECT_DEBUG vstr=malloc(2*sizeof(buf)); if (vstr == NULL) err(EXIT_FAILURE, "expect: malloc() failed"); strvis(vstr, str, VIS_NL|VIS_SAFE|VIS_CSTYLE); #endif /* EXPECT_DEBUG */ if (regcomp(&rstr, str, REG_EXTENDED) != 0) err(EXIT_FAILURE, "expect: regcomp() failed"); #if EXPECT_DEBUG if (expect_debug) printf("expecting \"%s\" on fd %d ...\n", vstr, fd); #endif /* EXPECT_DEBUG */ if(0) setbuf(stdout, NULL); memset(buf, '\n', sizeof(buf)); done=0; retval=0; set[0].fd = fd; set[0].events = POLLIN; while(!done) { rc = poll(set, 1, 10*60*1000); /* seconds until next message from tar */ switch (rc) { case -1: if (errno == EINTR) break; warn("expect: poll() failed (probably ftp died because of bad args)"); done = 1; retval = -1; break; case 0: warnx("expect: poll() timeout"); /* need to send ftp coprocess SIGINT to make it stop * downloading into dir that we'll blow away in a second */ kill(ftp_pid, SIGINT); /* Wait until ftp coprocess is responsive again * XXX Entering recursion here! */ rc = ftp_cmd("cd .\n", "\n(550|250).*\n"); if (rc != 250) { /* now we have a really good reason to bail out ;) */ } /* ftp is at command prompt again, and will wait for our * next command. If we were downloading, we can now safely * continue and remove the dir that the tar command was * expanding to */ done = 1; /* hope that's ok */ retval = -1; break; default: if (set[0].revents & POLLHUP) { done = 1; retval = -1; break; } rc = read(fd, &buf[sizeof(buf) - 1], 1); if (rc <= 0) { done = 1; retval = -1; break; } if (verbose_expect) putchar(buf[sizeof(buf)-1]); #if EXPECT_DEBUG { char *v=malloc(2*sizeof(buf)); strvis(v, buf, VIS_NL|VIS_SAFE|VIS_CSTYLE); if (expect_debug) printf("expect=<%s>, buf=<%*s>\n", vstr, strlen(v), v); free(v); } #endif /* EXPECT_DEBUG */ /****************** pkg_select mess ! ******************/ if (store_expect) { int len; memset(tmp, 0, MAXLEN); XSTRCPY(tmp, buf); len = strlen(tmp); /* returned result has 2 lines, separated by a \n * we need the 2d one, pointed by strchr * returned string does not finish with \n\0, e.g. : * '\n' <repeats 78 times>, "---> TYPE A\n\001" */ if ((tmp[len - 2] == '\n') && ((p = strchr(tmp, '\n')) != NULL)) { p++; /* cleanup leading \n */ trimcr(p); /* callback */ fill_store(p); } } /* was not a store request */ /* used for progress bars with tar(1) */ if (use_tar && strncmp(buf, "pkgsrc/", 7) == 0 && (p = strchr(buf, '/')) != NULL) { /* point after pkgsrc/ */ strcpy(progress_str, p); /* /category/blah */ p++; /* category/blah */ if ((p = strchr(p, '/')) != NULL) { if (conf.shell_output) printf("%s\n", progress_str); else if (next) { char msg[MAXLEN]; p++; *p = '\0'; snprintf(msg, MAXLEN, "extracting pkgsrc%s", progress_str); next = progress_bar(pkgsrc_progress, msg, INCREMENTAL); } } /* extract category from path */ } /* strcmp pkgsrc/ (tar progress) */ if (regexec(&rstr, buf, 1, &match, 0) == 0) { #if EXPECT_DEBUG if (expect_debug) printf("Gotcha -> %s!\n", buf+match.rm_so+1); fflush(stdout); #endif /* EXPECT_DEBUG */ if (ftprc && isdigit((unsigned char)buf[match.rm_so+1])) *ftprc = atoi(buf+match.rm_so+1); done=1; retval=0; } memmove(buf, buf+1, sizeof(buf)-1); /* yes, this is non-performant */ break; } /* switch rc */ } #if EXPECT_DEBUG printf("done.\n"); if (str) free(vstr); #endif /* EXPECT_DEBUG */ return retval; }
static void h_ctype2(const struct test *t, bool use_mbstate) { mbstate_t *stp; mbstate_t st; char buf[SIZE]; char *str; size_t n; ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); #if defined(__NetBSD__) ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL); #else if (setlocale(LC_CTYPE, t->locale) == NULL) { fprintf(stderr, "Locale %s not found.\n", t->locale); return; } #endif (void)strvis(buf, t->data, VIS_WHITE | VIS_OCTAL); (void)printf("Checking string: \"%s\"\n", buf); ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); (void)printf("Using locale: %s\n", str); (void)printf("Using mbstate: %s\n", use_mbstate ? "yes" : "no"); (void)memset(&st, 0, sizeof(st)); // mbrtowc(0, 0, 0, &st); /* XXX for ISO2022-JP */ stp = use_mbstate ? &st : 0; for (n = 9; n > 0; n--) { const char *src = t->data; wchar_t dst; size_t nchar = 0; int width = 0; ATF_REQUIRE(mbsinit(stp) != 0); for (;;) { size_t rv = mbrtowc(&dst, src, n, stp); if (rv == 0) break; if (rv == (size_t)-2) { src += n; width += n; continue; } if (rv == (size_t)-1) { ATF_REQUIRE_EQ(errno, EILSEQ); atf_tc_fail("Invalid sequence"); /* NOTREACHED */ } width += rv; src += rv; if (dst != t->wchars[nchar] || width != t->widths[nchar]) { (void)printf("At position %zd:\n", nchar); (void)printf(" expected: 0x%04X (%u)\n", t->wchars[nchar], t->widths[nchar]); (void)printf(" got : 0x%04X (%u)\n", dst, width); atf_tc_fail("Test failed"); } nchar++; width = 0; } ATF_REQUIRE_EQ_MSG(dst, 0, "Incorrect terminating character: " "0x%04X (expected: 0x00)", dst); ATF_REQUIRE_EQ_MSG(nchar, t->length, "Incorrect length: " "%zd (expected: %zd)", nchar, t->length); } { wchar_t wbuf[SIZE]; size_t rv; char const *src = t->data; int i; (void)memset(wbuf, 0xFF, sizeof(wbuf)); rv = mbsrtowcs(wbuf, &src, SIZE, stp); ATF_REQUIRE_EQ_MSG(rv, t->length, "Incorrect length: %zd " "(expected: %zd)", rv, t->length); ATF_REQUIRE_EQ(src, NULL); for (i = 0; wbuf[i] != 0; ++i) { if (wbuf[i] == t->wchars[i]) continue; (void)printf("At position %d:\n", i); (void)printf(" expected: 0x%04X\n", t->wchars[i]); (void)printf(" got : 0x%04X\n", wbuf[i]); atf_tc_fail("Test failed"); } ATF_REQUIRE_EQ_MSG((size_t)i, t->length, "Incorrect length: " "%d (expected: %zd)", i, t->length); } (void)printf("Ok.\n"); }