krb5_error_code KRB5_LIB_FUNCTION krb5_get_server_rcache(krb5_context context, const krb5_data *piece, krb5_rcache *id) { krb5_rcache rcache; krb5_error_code ret; char *tmp = malloc(4 * piece->length + 1); char *name; if(tmp == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } strvisx(tmp, piece->data, piece->length, VIS_WHITE | VIS_OCTAL); #ifdef HAVE_GETEUID asprintf(&name, "FILE:rc_%s_%u", tmp, (unsigned)geteuid()); #else asprintf(&name, "FILE:rc_%s", tmp); #endif free(tmp); if(name == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } ret = krb5_rc_resolve_full(context, &rcache, name); free(name); if(ret) return ret; *id = rcache; return ret; }
void logmsg(int pri, const char *message, ...) { va_list ap; if (pri > loglevel) return; va_start(ap, message); if (daemonize) /* syslog does its own vissing. */ vsyslog(pri, message, ap); else { char buf[MAX_LOGLINE]; char visbuf[2 * MAX_LOGLINE]; /* We don't care about truncation. */ vsnprintf(buf, sizeof buf, message, ap); #ifdef __NetBSD__ size_t len = strlen(buf); if (len > sizeof visbuf) { len = sizeof visbuf; } strvisx(visbuf, buf, len, VIS_CSTYLE | VIS_NL); #else strnvis(visbuf, buf, sizeof visbuf, VIS_CSTYLE | VIS_NL); #endif /* !__NetBSD__ */ fprintf(stderr, "%s\n", visbuf); } va_end(ap); }
static struct utmpx * utmp_update(const struct utmpx *utx) { char buf[sizeof(*utx) * 4 + 1]; pid_t pid; int status; _DIAGASSERT(utx != NULL); (void)strvisx(buf, (const char *)(const void *)utx, sizeof(*utx), VIS_WHITE); switch (pid = fork()) { case 0: (void)execl(_PATH_UTMP_UPDATE, strrchr(_PATH_UTMP_UPDATE, '/') + 1, buf, NULL); _exit(1); /*NOTREACHED*/ case -1: return NULL; default: if (waitpid(pid, &status, 0) == -1) return NULL; if (WIFEXITED(status) && WEXITSTATUS(status) == 0) return memcpy(&ut, utx, sizeof(ut)); return NULL; } }
static void KRB5_CALLCONV log_file(const char *timestr, const char *msg, void *data) { struct file_data *f = data; char *msgclean; size_t len = strlen(msg); if(f->keep_open == 0) f->fd = fopen(f->filename, f->mode); if(f->fd == NULL) return; /* make sure the log doesn't contain special chars */ msgclean = malloc((len + 1) * 4); if (msgclean == NULL) goto out; strvisx(msgclean, rk_UNCONST(msg), len, VIS_OCTAL); fprintf(f->fd, "%s %s\n", timestr, msgclean); free(msgclean); out: if(f->keep_open == 0) { fclose(f->fd); f->fd = NULL; } }
/* * XXX * This is a stub until marc does the real one. */ static char * shquote(char **argv) { static long arg_max = -1; size_t len; char **p, *dst, *src; static char *buf = NULL; if (buf == NULL) { if ((arg_max = sysconf(_SC_ARG_MAX)) == -1) { // errx(1, "sysconf _SC_ARG_MAX failed"); fprintf(stderr, "w: sysconf _SC_ARG_MAX failed\n"); pthread_exit(NULL); } if ((buf = malloc((u_int)(4 * arg_max) + 1)) == NULL) { // errx(1, "malloc failed"); fprintf(stderr, "w: malloc failed\n"); pthread_exit(NULL); } } if (*argv == 0) { buf[0] = 0; return (buf); } dst = buf; for (p = argv; (src = *p++) != 0; ) { if (*src == 0) continue; len = (size_t)(4 * arg_max - (dst - buf)) / 4; strvisx(dst, src, strlen(src) < len ? strlen(src) : len, VIS_NL | VIS_CSTYLE); while (*dst) dst++; if ((4 * arg_max - (dst - buf)) / 4 > 0) *dst++ = ' '; } /* Chop off trailing space */ if (dst != buf && dst[-1] == ' ') dst--; *dst = '\0'; return (buf); }
/* Convert a buffer into a visible string. */ char * paste_print(struct paste_buffer *pb, size_t width) { char *buf; size_t len, used; if (width < 3) width = 3; buf = xmalloc(width * 4 + 1); len = pb->size; if (len > width) len = width; used = strvisx(buf, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL); if (pb->size > width || used > width) strlcpy(buf + width - 3, "...", 4); return (buf); }
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"); }
static char * shquote(char **argv) { long arg_max; static size_t buf_size; size_t len; char **p, *dst, *src; static char *buf = NULL; if (buf == NULL) { if ((arg_max = sysconf(_SC_ARG_MAX)) == -1) errx(1, "sysconf _SC_ARG_MAX failed"); if (arg_max >= LONG_MAX / 4 || arg_max >= (long)(SIZE_MAX / 4)) errx(1, "sysconf _SC_ARG_MAX preposterously large"); buf_size = 4 * arg_max + 1; if ((buf = malloc(buf_size)) == NULL) errx(1, "malloc failed"); } if (*argv == NULL) { buf[0] = '\0'; return (buf); } dst = buf; for (p = argv; (src = *p++) != NULL; ) { if (*src == '\0') continue; len = (buf_size - 1 - (dst - buf)) / 4; strvisx(dst, src, strlen(src) < len ? strlen(src) : len, VIS_NL | VIS_CSTYLE); while (*dst != '\0') dst++; if ((buf_size - 1 - (dst - buf)) / 4 > 0) *dst++ = ' '; } /* Chop off trailing space */ if (dst != buf && dst[-1] == ' ') dst--; *dst = '\0'; return (buf); }
int cmd_list_buffers_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_target_data *data = self->data; struct session *s; struct paste_buffer *pb; u_int idx; char tmp[51 * 4 + 1]; size_t size, len; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); idx = 0; while ((pb = paste_walk_stack(&s->buffers, &idx)) != NULL) { size = pb->size; /* Translate the first 50 characters. */ len = size; if (len > 50) len = 50; strvisx(tmp, pb->data, len, VIS_OCTAL|VIS_TAB|VIS_NL); /* * If the first 50 characters were encoded as a longer string, * or there is definitely more data, add "...". */ if (size > 50 || strlen(tmp) > 50) { tmp[50 - 3] = '\0'; strlcat(tmp, "...", sizeof tmp); } ctx->print(ctx, "%u: %zu bytes: \"%s\"", idx - 1, size, tmp); } return (0); }
static enum cmd_retval cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; struct client *c = item->client; struct session *s; struct paste_buffer *pb; const char *path, *bufname, *bufdata, *start, *end, *cwd; const char *flags; char *msg, *file, resolved[PATH_MAX]; size_t size, used, msglen, bufsize; FILE *f; if (!args_has(args, 'b')) { if ((pb = paste_get_top(NULL)) == NULL) { cmdq_error(item, "no buffers"); return (CMD_RETURN_ERROR); } } else { bufname = args_get(args, 'b'); pb = paste_get_name(bufname); if (pb == NULL) { cmdq_error(item, "no buffer %s", bufname); return (CMD_RETURN_ERROR); } } bufdata = paste_buffer_data(pb, &bufsize); if (self->entry == &cmd_show_buffer_entry) path = "-"; else path = args->argv[0]; if (strcmp(path, "-") == 0) { if (c == NULL) { cmdq_error(item, "can't write to stdout"); return (CMD_RETURN_ERROR); } if (c->session == NULL || (c->flags & CLIENT_CONTROL)) goto do_stdout; goto do_print; } if (c != NULL && c->session == NULL && c->cwd != NULL) cwd = c->cwd; else if ((s = c->session) != NULL && s->cwd != NULL) cwd = s->cwd; else cwd = "."; flags = "wb"; if (args_has(self->args, 'a')) flags = "ab"; if (*path == '/') file = xstrdup(path); else xasprintf(&file, "%s/%s", cwd, path); if (realpath(file, resolved) == NULL && strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) { cmdq_error(item, "%s: %s", file, strerror(ENAMETOOLONG)); return (CMD_RETURN_ERROR); } f = fopen(resolved, flags); free(file); if (f == NULL) { cmdq_error(item, "%s: %s", resolved, strerror(errno)); return (CMD_RETURN_ERROR); } if (fwrite(bufdata, 1, bufsize, f) != bufsize) { cmdq_error(item, "%s: write error", resolved); fclose(f); return (CMD_RETURN_ERROR); } fclose(f); return (CMD_RETURN_NORMAL); do_stdout: evbuffer_add(c->stdout_data, bufdata, bufsize); server_client_push_stdout(c); return (CMD_RETURN_NORMAL); do_print: if (bufsize > (INT_MAX / 4) - 1) { cmdq_error(item, "buffer too big"); return (CMD_RETURN_ERROR); } msg = NULL; used = 0; while (used != bufsize) { start = bufdata + used; end = memchr(start, '\n', bufsize - used); if (end != NULL) size = end - start; else size = bufsize - used; msglen = size * 4 + 1; msg = xrealloc(msg, msglen); strvisx(msg, start, size, VIS_OCTAL|VIS_TAB); cmdq_print(item, "%s", msg); used += size + (end != NULL); } free(msg); return (CMD_RETURN_NORMAL); }
int cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; struct paste_buffer *pb; char *in, *buf, *ptr; size_t size, len; u_int width; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); if (data->buffer == -1) { if ((pb = paste_get_top(&s->buffers)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) { ctx->error(ctx, "no buffer %d", data->buffer); return (-1); } if (pb == NULL) return (0); size = pb->size; if (size > SIZE_MAX / 4 - 1) size = SIZE_MAX / 4 - 1; in = xmalloc(size * 4 + 1); strvisx(in, pb->data, size, VIS_OCTAL|VIS_TAB); width = s->sx; if (ctx->cmdclient != NULL) width = ctx->cmdclient->tty.sx; buf = xmalloc(width + 1); len = 0; ptr = in; do { buf[len++] = *ptr++; if (len == width || buf[len - 1] == '\n') { if (buf[len - 1] == '\n') len--; buf[len] = '\0'; ctx->print(ctx, "%s", buf); len = 0; } } while (*ptr != '\0'); if (len != 0) { buf[len] = '\0'; ctx->print(ctx, "%s", buf); } xfree(buf); xfree(in); return (0); }
void start_login(char *host, int autologin, char *name) { char **argv; #define TABBUFSIZ 512 char defent[TABBUFSIZ]; char defstrs[TABBUFSIZ]; #undef TABBUFSIZ const char *loginprog = NULL; extern struct sockaddr_storage from; char buf[sizeof(from) * 4 + 1]; scrub_env(); /* * -a : pass on the address of the host. * -h : pass on name of host. * WARNING: -h and -a are accepted by login * if and only if getuid() == 0. * -p : don't clobber the environment (so terminal type stays set). * * -f : force this login, he has already been authenticated */ argv = addarg(0, "login"); argv = addarg(argv, "-a"); (void)strvisx(buf, (const char *)(const void *)&from, sizeof(from), VIS_WHITE); argv = addarg(argv, buf); argv = addarg(argv, "-h"); argv = addarg(argv, host); argv = addarg(argv, "-p"); #ifdef LINEMODE /* * Set the environment variable "LINEMODE" to either * "real" or "kludge" if we are operating in either * real or kludge linemode. */ if (lmodetype == REAL_LINEMODE) setenv("LINEMODE", "real", 1); # ifdef KLUDGELINEMODE else if (lmodetype == KLUDGE_LINEMODE || lmodetype == KLUDGE_OK) setenv("LINEMODE", "kludge", 1); # endif #endif #ifdef SECURELOGIN /* * don't worry about the -f that might get sent. * A -s is supposed to override it anyhow. */ if (require_secure_login) argv = addarg(argv, "-s"); #endif #ifdef AUTHENTICATION if (auth_level >= 0 && autologin == AUTH_VALID) { argv = addarg(argv, "-f"); argv = addarg(argv, "--"); argv = addarg(argv, name); } else #endif if (getenv("USER")) { argv = addarg(argv, "--"); argv = addarg(argv, getenv("USER")); /* * Assume that login will set the USER variable * correctly. For SysV systems, this means that * USER will no longer be set, just LOGNAME by * login. (The problem is that if the auto-login * fails, and the user then specifies a different * account name, he can get logged in with both * LOGNAME and USER in his environment, but the * USER value will be wrong. */ unsetenv("USER"); } if (getent(defent, gettyname) == 1) { char *cp = defstrs; loginprog = getstr("lo", &cp); } if (loginprog == NULL) loginprog = _PATH_LOGIN; closelog(); /* * This sleep(1) is in here so that telnetd can * finish up with the tty. There's a race condition * the login banner message gets lost... */ sleep(1); execv(loginprog, argv); syslog(LOG_ERR, "%s: %m", loginprog); fatalperror(net, loginprog); /*NOTREACHED*/ }
int main(int argc, char *argv[]) { char *buf, *visbuf, *p; const char *options, *attrname; size_t len; ssize_t ret; int buflen, visbuflen, ch, error, i, arg_counter, attrnamespace, minargc; int flag_force = 0; int flag_nofollow = 0; int flag_null = 0; int flag_quiet = 0; int flag_string = 0; int flag_hex = 0; visbuflen = buflen = 0; visbuf = buf = NULL; p = basename(argv[0]); if (p == NULL) p = argv[0]; if (!strcmp(p, "getextattr")) { what = EAGET; options = "fhqsx"; minargc = 3; } else if (!strcmp(p, "setextattr")) { what = EASET; options = "fhnq"; minargc = 4; } else if (!strcmp(p, "rmextattr")) { what = EARM; options = "fhq"; minargc = 3; } else if (!strcmp(p, "lsextattr")) { what = EALS; options = "fhq"; minargc = 2; } else { usage(); } while ((ch = getopt(argc, argv, options)) != -1) { switch (ch) { case 'f': flag_force = 1; break; case 'h': flag_nofollow = 1; break; case 'n': flag_null = 1; break; case 'q': flag_quiet = 1; break; case 's': flag_string = 1; break; case 'x': flag_hex = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc < minargc) usage(); error = extattr_string_to_namespace(argv[0], &attrnamespace); if (error) err(-1, "%s", argv[0]); argc--; argv++; if (what != EALS) { attrname = argv[0]; argc--; argv++; } else attrname = NULL; if (what == EASET) { mkbuf(&buf, &buflen, strlen(argv[0]) + 1); strcpy(buf, argv[0]); argc--; argv++; } for (arg_counter = 0; arg_counter < argc; arg_counter++) { switch (what) { case EARM: if (flag_nofollow) error = extattr_delete_link(argv[arg_counter], attrnamespace, attrname); else error = extattr_delete_file(argv[arg_counter], attrnamespace, attrname); if (error >= 0) continue; break; case EASET: len = strlen(buf) + flag_null; if (flag_nofollow) ret = extattr_set_link(argv[arg_counter], attrnamespace, attrname, buf, len); else ret = extattr_set_file(argv[arg_counter], attrnamespace, attrname, buf, len); if (ret >= 0) { if ((size_t)ret != len && !flag_quiet) { warnx("Set %zd bytes of %zu for %s", ret, len, attrname); } continue; } break; case EALS: if (flag_nofollow) ret = extattr_list_link(argv[arg_counter], attrnamespace, NULL, 0); else ret = extattr_list_file(argv[arg_counter], attrnamespace, NULL, 0); if (ret < 0) break; mkbuf(&buf, &buflen, ret); if (flag_nofollow) ret = extattr_list_link(argv[arg_counter], attrnamespace, buf, buflen); else ret = extattr_list_file(argv[arg_counter], attrnamespace, buf, buflen); if (ret < 0) break; if (!flag_quiet) printf("%s\t", argv[arg_counter]); for (i = 0; i < ret; i += ch + 1) { /* The attribute name length is unsigned. */ ch = (unsigned char)buf[i]; printf("%s%*.*s", i ? "\t" : "", ch, ch, buf + i + 1); } if (!flag_quiet || ret > 0) printf("\n"); continue; case EAGET: if (flag_nofollow) ret = extattr_get_link(argv[arg_counter], attrnamespace, attrname, NULL, 0); else ret = extattr_get_file(argv[arg_counter], attrnamespace, attrname, NULL, 0); if (ret < 0) break; mkbuf(&buf, &buflen, ret); if (flag_nofollow) ret = extattr_get_link(argv[arg_counter], attrnamespace, attrname, buf, buflen); else ret = extattr_get_file(argv[arg_counter], attrnamespace, attrname, buf, buflen); if (ret < 0) break; if (!flag_quiet) printf("%s\t", argv[arg_counter]); if (flag_string) { mkbuf(&visbuf, &visbuflen, ret * 4 + 1); strvisx(visbuf, buf, ret, VIS_SAFE | VIS_WHITE); printf("\"%s\"\n", visbuf); continue; } else if (flag_hex) { for (i = 0; i < ret; i++) printf("%s%02x", i ? " " : "", buf[i]); printf("\n"); continue; } else { fwrite(buf, ret, 1, stdout); printf("\n"); continue; } default: break; } if (!flag_quiet) warn("%s: failed", argv[arg_counter]); if (flag_force) continue; return(1); } return (0); }
void source(int argc, char **argv) { struct stat stb; static BUF buffer; BUF *bp; off_t i, statbytes; size_t amt; int fd = -1, haderr, indx; char *last, *name, buf[16384], encname[MAXPATHLEN]; int len; for (indx = 0; indx < argc; ++indx) { fd = -1; name = argv[indx]; statbytes = 0; len = strlen(name); while (len > 1 && name[len-1] == '/') name[--len] = '\0'; if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0) goto syserr; if (strchr(name, '\n') != NULL) { strvisx(encname, name, len, VIS_NL); name = encname; } if (fstat(fd, &stb) < 0) { syserr: run_err("%s: %s", name, strerror(errno)); goto next; } if (stb.st_size < 0) { run_err("%s: %s", name, "Negative file size"); goto next; } unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: break; case S_IFDIR: if (iamrecursive) { rsource(name, &stb); goto next; } /* FALLTHROUGH */ default: run_err("%s: not a regular file", name); goto next; } if ((last = strrchr(name, '/')) == NULL) last = name; else ++last; curfile = last; if (pflag) { /* * Make it compatible with possible future * versions expecting microseconds. */ (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime), (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime)); if (verbose_mode) { fprintf(stderr, "File mtime %ld atime %ld\n", (long)stb.st_mtime, (long)stb.st_atime); fprintf(stderr, "Sending file timestamps: %s", buf); } (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) snprintf(buf, sizeof buf, "C%04o %lld %s\n", (u_int) (stb.st_mode & FILEMODEMASK), (long long)stb.st_size, last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); } (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { next: if (fd != -1) { (void) close(fd); fd = -1; } continue; } if (showprogress) start_progress_meter(curfile, stb.st_size, &statbytes); set_nonblock(remout); for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { amt = bp->cnt; if (i + (off_t)amt > stb.st_size) amt = stb.st_size - i; if (!haderr) { if (atomicio(read, fd, bp->buf, amt) != amt) haderr = errno; } /* Keep writing after error to retain sync */ if (haderr) { (void)atomicio(vwrite, remout, bp->buf, amt); continue; } if (atomicio6(vwrite, remout, bp->buf, amt, scpio, &statbytes) != amt) haderr = errno; } unset_nonblock(remout); if (showprogress) stop_progress_meter(); if (fd != -1) { if (close(fd) < 0 && !haderr) haderr = errno; fd = -1; } if (!haderr) (void) atomicio(vwrite, remout, empty, 1); else run_err("%s: %s", name, strerror(haderr)); (void) response(); } }
int main(int argc, char *argv[]) { char inp[UCHAR_MAX + 1]; char out[4 * UCHAR_MAX + 1]; int i, j, fail = 0; ssize_t owant, o, r; for (i = 0; i <= UCHAR_MAX; i++) { inp[i] = i; } strvisx(out, inp, UCHAR_MAX + 1, 0); printf("%s\n", out); for (i = 0; i < NTESTS; i++) { arc4random_buf(ibuf, sizeof(ibuf) - 1); ibuf[sizeof(ibuf) - 1] = '\0'; title = 0; for (j = 0; j < sizeof(flags)/sizeof(flags[0]); j++) { owant = sizeof(ibuf); o = strnvis(obuf, ibuf, owant, flags[j]); if (o >= owant) { owant = o + 1; o = strnvis(obuf, ibuf, owant, flags[j]); if (o > owant) { dotitle(i, j); printf("HUGE overflow\n"); } if (o < owant - 1) { dotitle(i, j); printf("over-estimate of overflow\n"); } } else if (o > strlen(ibuf) * 4) { dotitle(i, j); printf("wants too much %d %d\n", o, strlen(ibuf) * 4); continue; } r = strnunvis(rbuf, obuf, sizeof rbuf); if (r == -1) { dotitle(i, j); printf("cannot decode\n"); printf("%s\n", obuf); fail = 1; } else if (r != strlen(ibuf)) { dotitle(i, j); printf("rlen %d != inlen %d\n", r, strlen(ibuf)); printf("%s\n", obuf); printf("%s\n", rbuf); fail = 1; } else if (bcmp(ibuf, rbuf, r)) { dotitle(i, j); printf("strings are different\n"); printf("%s\n", ibuf); printf("%s\n", rbuf); fail = 1; } } } exit(fail); }
static int pstatus(char *arg) { struct ioc_vol v; struct ioc_read_subchannel ss; struct cd_sub_channel_info data; int rc, trk, m, s, f; int what = 0; char *p, vmcn[(4 * 15) + 1]; while ((p = strtok(arg, " \t"))) { arg = 0; if (!strncasecmp(p, "audio", strlen(p))) what |= STATUS_AUDIO; else if (!strncasecmp(p, "media", strlen(p))) what |= STATUS_MEDIA; else if (!strncasecmp(p, "volume", strlen(p))) what |= STATUS_VOLUME; else { warnx("invalid command arguments"); return 0; } } if (!what) what = STATUS_AUDIO|STATUS_MEDIA|STATUS_VOLUME; if (what & STATUS_AUDIO) { rc = status (&trk, &m, &s, &f); if (rc >= 0) if (verbose) printf ("Audio status = %d<%s>, current track = %d, current position = %d:%02d.%02d\n", rc, strstatus (rc), trk, m, s, f); else printf ("%d %d %d:%02d.%02d\n", rc, trk, m, s, f); else printf ("No current status info available\n"); } if (what & STATUS_MEDIA) { bzero (&ss, sizeof (ss)); ss.data = &data; ss.data_len = sizeof (data); ss.address_format = msf ? CD_MSF_FORMAT : CD_LBA_FORMAT; ss.data_format = CD_MEDIA_CATALOG; rc = ioctl (fd, CDIOCREADSUBCHANNEL, (char *) &ss); if (rc >= 0) { printf("Media catalog is %sactive", ss.data->what.media_catalog.mc_valid ? "": "in"); if (ss.data->what.media_catalog.mc_valid && ss.data->what.media_catalog.mc_number[0]) { strvisx (vmcn, ss.data->what.media_catalog.mc_number, (sizeof (vmcn) - 1) / 4, VIS_OCTAL | VIS_NL); printf(", number \"%.*s\"", (int)sizeof (vmcn), vmcn); } putchar('\n'); } else printf("No media catalog info available\n"); } if (what & STATUS_VOLUME) { rc = ioctl (fd, CDIOCGETVOL, &v); if (rc >= 0) if (verbose) printf ("Left volume = %d, right volume = %d\n", v.vol[0], v.vol[1]); else printf ("%d %d\n", v.vol[0], v.vol[1]); else printf ("No volume level info available\n"); } return(0); }
char * print_arg(struct syscall_args *sc, unsigned long *args, long retval, struct trussinfo *trussinfo) { char *tmp; pid_t pid; tmp = NULL; pid = trussinfo->pid; switch (sc->type & ARG_MASK) { case Hex: asprintf(&tmp, "0x%x", (int)args[sc->offset]); break; case Octal: asprintf(&tmp, "0%o", (int)args[sc->offset]); break; case Int: asprintf(&tmp, "%d", (int)args[sc->offset]); break; case Name: { /* NULL-terminated string. */ char *tmp2; tmp2 = get_string(pid, (void*)args[sc->offset], 0); asprintf(&tmp, "\"%s\"", tmp2); free(tmp2); break; } case BinString: { /* Binary block of data that might have printable characters. XXX If type|OUT, assume that the length is the syscall's return value. Otherwise, assume that the length of the block is in the next syscall argument. */ int max_string = trussinfo->strsize; char tmp2[max_string+1], *tmp3; int len; int truncated = 0; if (sc->type & OUT) len = retval; else len = args[sc->offset + 1]; /* Don't print more than max_string characters, to avoid word wrap. If we have to truncate put some ... after the string. */ if (len > max_string) { len = max_string; truncated = 1; } if (len && get_struct(pid, (void*)args[sc->offset], &tmp2, len) != -1) { tmp3 = malloc(len * 4 + 1); while (len) { if (strvisx(tmp3, tmp2, len, VIS_CSTYLE|VIS_TAB|VIS_NL) <= max_string) break; len--; truncated = 1; }; asprintf(&tmp, "\"%s\"%s", tmp3, truncated ? "..." : ""); free(tmp3); } else { asprintf(&tmp, "0x%lx", args[sc->offset]); } break; } case StringArray: { int num, size, i; char *tmp2; char *string; char *strarray[100]; /* XXX This is ugly. */ if (get_struct(pid, (void *)args[sc->offset], (void *)&strarray, sizeof(strarray)) == -1) err(1, "get_struct %p", (void *)args[sc->offset]); num = 0; size = 0; /* Find out how large of a buffer we'll need. */ while (strarray[num] != NULL) { string = get_string(pid, (void*)strarray[num], 0); size += strlen(string); free(string); num++; } size += 4 + (num * 4); tmp = (char *)malloc(size); tmp2 = tmp; tmp2 += sprintf(tmp2, " ["); for (i = 0; i < num; i++) { string = get_string(pid, (void*)strarray[i], 0); tmp2 += sprintf(tmp2, " \"%s\"%c", string, (i + 1 == num) ? ' ' : ','); free(string); } tmp2 += sprintf(tmp2, "]"); break; } #ifdef __LP64__ case Quad: asprintf(&tmp, "0x%lx", args[sc->offset]); break; #else case Quad: { unsigned long long ll; ll = *(unsigned long long *)(args + sc->offset); asprintf(&tmp, "0x%llx", ll); break; } #endif case Ptr: asprintf(&tmp, "0x%lx", args[sc->offset]); break; case Readlinkres: { char *tmp2; if (retval == -1) { tmp = strdup(""); break; } tmp2 = get_string(pid, (void*)args[sc->offset], retval); asprintf(&tmp, "\"%s\"", tmp2); free(tmp2); break; } case Ioctl: { const char *temp = ioctlname(args[sc->offset]); if (temp) tmp = strdup(temp); else { unsigned long arg = args[sc->offset]; asprintf(&tmp, "0x%lx { IO%s%s 0x%lx('%c'), %lu, %lu }", arg, arg & IOC_OUT ? "R" : "", arg & IOC_IN ? "W" : "", IOCGROUP(arg), isprint(IOCGROUP(arg)) ? (char)IOCGROUP(arg) : '?', arg & 0xFF, IOCPARM_LEN(arg)); } break; } case Umtx: { struct umtx umtx; if (get_struct(pid, (void *)args[sc->offset], &umtx, sizeof(umtx)) != -1) asprintf(&tmp, "{ 0x%lx }", (long)umtx.u_owner); else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Timespec: { struct timespec ts; if (get_struct(pid, (void *)args[sc->offset], &ts, sizeof(ts)) != -1) asprintf(&tmp, "{%ld.%09ld }", (long)ts.tv_sec, ts.tv_nsec); else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Timeval: { struct timeval tv; if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) asprintf(&tmp, "{%ld.%06ld }", (long)tv.tv_sec, tv.tv_usec); else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Timeval2: { struct timeval tv[2]; if (get_struct(pid, (void *)args[sc->offset], &tv, sizeof(tv)) != -1) asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }", (long)tv[0].tv_sec, tv[0].tv_usec, (long)tv[1].tv_sec, tv[1].tv_usec); else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Itimerval: { struct itimerval itv; if (get_struct(pid, (void *)args[sc->offset], &itv, sizeof(itv)) != -1) asprintf(&tmp, "{%ld.%06ld, %ld.%06ld }", (long)itv.it_interval.tv_sec, itv.it_interval.tv_usec, (long)itv.it_value.tv_sec, itv.it_value.tv_usec); else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case LinuxSockArgs: { struct linux_socketcall_args largs; if (get_struct(pid, (void *)args[sc->offset], (void *)&largs, sizeof(largs)) == -1) { err(1, "get_struct %p", (void *)args[sc->offset]); } const char *what; char buf[30]; switch (largs.what) { case LINUX_SOCKET: what = "LINUX_SOCKET"; break; case LINUX_BIND: what = "LINUX_BIND"; break; case LINUX_CONNECT: what = "LINUX_CONNECT"; break; case LINUX_LISTEN: what = "LINUX_LISTEN"; break; case LINUX_ACCEPT: what = "LINUX_ACCEPT"; break; case LINUX_GETSOCKNAME: what = "LINUX_GETSOCKNAME"; break; case LINUX_GETPEERNAME: what = "LINUX_GETPEERNAME"; break; case LINUX_SOCKETPAIR: what = "LINUX_SOCKETPAIR"; break; case LINUX_SEND: what = "LINUX_SEND"; break; case LINUX_RECV: what = "LINUX_RECV"; break; case LINUX_SENDTO: what = "LINUX_SENDTO"; break; case LINUX_RECVFROM: what = "LINUX_RECVFROM"; break; case LINUX_SHUTDOWN: what = "LINUX_SHUTDOWN"; break; case LINUX_SETSOCKOPT: what = "LINUX_SETSOCKOPT"; break; case LINUX_GETSOCKOPT: what = "LINUX_GETSOCKOPT"; break; case LINUX_SENDMSG: what = "LINUX_SENDMSG"; break; case LINUX_RECVMSG: what = "LINUX_RECVMSG"; break; default: sprintf(buf, "%d", largs.what); what = buf; break; } asprintf(&tmp, "(0x%lx)%s, 0x%lx", args[sc->offset], what, (long unsigned int)largs.args); break; } case Pollfd: { /* * XXX: A Pollfd argument expects the /next/ syscall argument * to be the number of fds in the array. This matches the poll * syscall. */ struct pollfd *pfd; int numfds = args[sc->offset+1]; int bytes = sizeof(struct pollfd) * numfds; int i, tmpsize, u, used; const int per_fd = 100; if ((pfd = malloc(bytes)) == NULL) err(1, "Cannot malloc %d bytes for pollfd array", bytes); if (get_struct(pid, (void *)args[sc->offset], pfd, bytes) != -1) { used = 0; tmpsize = 1 + per_fd * numfds + 2; if ((tmp = malloc(tmpsize)) == NULL) err(1, "Cannot alloc %d bytes for poll output", tmpsize); tmp[used++] = '{'; for (i = 0; i < numfds; i++) { u = snprintf(tmp + used, per_fd, "%s%d/%s", i > 0 ? " " : "", pfd[i].fd, xlookup_bits(poll_flags, pfd[i].events)); if (u > 0) used += u < per_fd ? u : per_fd; } tmp[used++] = '}'; tmp[used++] = '\0'; } else { asprintf(&tmp, "0x%lx", args[sc->offset]); } free(pfd); break; } case Fd_set: { /* * XXX: A Fd_set argument expects the /first/ syscall argument * to be the number of fds in the array. This matches the * select syscall. */ fd_set *fds; int numfds = args[0]; int bytes = _howmany(numfds, _NFDBITS) * _NFDBITS; int i, tmpsize, u, used; const int per_fd = 20; if ((fds = malloc(bytes)) == NULL) err(1, "Cannot malloc %d bytes for fd_set array", bytes); if (get_struct(pid, (void *)args[sc->offset], fds, bytes) != -1) { used = 0; tmpsize = 1 + numfds * per_fd + 2; if ((tmp = malloc(tmpsize)) == NULL) err(1, "Cannot alloc %d bytes for fd_set " "output", tmpsize); tmp[used++] = '{'; for (i = 0; i < numfds; i++) { if (FD_ISSET(i, fds)) { u = snprintf(tmp + used, per_fd, "%d ", i); if (u > 0) used += u < per_fd ? u : per_fd; } } if (tmp[used-1] == ' ') used--; tmp[used++] = '}'; tmp[used++] = '\0'; } else asprintf(&tmp, "0x%lx", args[sc->offset]); free(fds); break; } case Signal: tmp = strsig2(args[sc->offset]); break; case Sigset: { long sig; sigset_t ss; int i, used; char *signame; sig = args[sc->offset]; if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, sizeof(ss)) == -1) { asprintf(&tmp, "0x%lx", args[sc->offset]); break; } tmp = malloc(sys_nsig * 8); /* 7 bytes avg per signal name */ used = 0; for (i = 1; i < sys_nsig; i++) { if (sigismember(&ss, i)) { signame = strsig(i); used += sprintf(tmp + used, "%s|", signame); free(signame); } } if (used) tmp[used-1] = 0; else strcpy(tmp, "0x0"); break; } case Sigprocmask: { switch (args[sc->offset]) { #define S(a) case a: tmp = strdup(#a); break; S(SIG_BLOCK); S(SIG_UNBLOCK); S(SIG_SETMASK); #undef S } if (tmp == NULL) asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Fcntlflag: { /* XXX output depends on the value of the previous argument */ switch (args[sc->offset-1]) { case F_SETFD: tmp = strdup(xlookup_bits(fcntlfd_arg, args[sc->offset])); break; case F_SETFL: tmp = strdup(xlookup_bits(fcntlfl_arg, args[sc->offset])); break; case F_GETFD: case F_GETFL: case F_GETOWN: tmp = strdup(""); break; default: asprintf(&tmp, "0x%lx", args[sc->offset]); break; } break; } case Open: tmp = strdup(xlookup_bits(open_flags, args[sc->offset])); break; case Fcntl: tmp = strdup(xlookup(fcntl_arg, args[sc->offset])); break; case Mprot: tmp = strdup(xlookup_bits(mprot_flags, args[sc->offset])); break; case Mmapflags: { char *base, *alignstr; int align, flags; /* * MAP_ALIGNED can't be handled by xlookup_bits(), so * generate that string manually and prepend it to the * string from xlookup_bits(). Have to be careful to * avoid outputting MAP_ALIGNED|0 if MAP_ALIGNED is * the only flag. */ flags = args[sc->offset] & ~MAP_ALIGNMENT_MASK; align = args[sc->offset] & MAP_ALIGNMENT_MASK; if (align != 0) { if (align == MAP_ALIGNED_SUPER) alignstr = strdup("MAP_ALIGNED_SUPER"); else asprintf(&alignstr, "MAP_ALIGNED(%d)", align >> MAP_ALIGNMENT_SHIFT); if (flags == 0) { tmp = alignstr; break; } } else alignstr = NULL; base = strdup(xlookup_bits(mmap_flags, flags)); if (alignstr == NULL) { tmp = base; break; } asprintf(&tmp, "%s|%s", alignstr, base); free(alignstr); free(base); break; } case Whence: tmp = strdup(xlookup(whence_arg, args[sc->offset])); break; case Sockdomain: tmp = strdup(xlookup(sockdomain_arg, args[sc->offset])); break; case Socktype: tmp = strdup(xlookup(socktype_arg, args[sc->offset])); break; case Shutdown: tmp = strdup(xlookup(shutdown_arg, args[sc->offset])); break; case Resource: tmp = strdup(xlookup(resource_arg, args[sc->offset])); break; case Pathconf: tmp = strdup(xlookup(pathconf_arg, args[sc->offset])); break; case Rforkflags: tmp = strdup(xlookup_bits(rfork_flags, args[sc->offset])); break; case Sockaddr: { struct sockaddr_storage ss; char addr[64]; struct sockaddr_in *lsin; struct sockaddr_in6 *lsin6; struct sockaddr_un *sun; struct sockaddr *sa; char *p; u_char *q; int i; if (args[sc->offset] == 0) { asprintf(&tmp, "NULL"); break; } /* yuck: get ss_len */ if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, sizeof(ss.ss_len) + sizeof(ss.ss_family)) == -1) err(1, "get_struct %p", (void *)args[sc->offset]); /* * If ss_len is 0, then try to guess from the sockaddr type. * AF_UNIX may be initialized incorrectly, so always frob * it by using the "right" size. */ if (ss.ss_len == 0 || ss.ss_family == AF_UNIX) { switch (ss.ss_family) { case AF_INET: ss.ss_len = sizeof(*lsin); break; case AF_UNIX: ss.ss_len = sizeof(*sun); break; default: /* hurrrr */ break; } } if (get_struct(pid, (void *)args[sc->offset], (void *)&ss, ss.ss_len) == -1) { err(2, "get_struct %p", (void *)args[sc->offset]); } switch (ss.ss_family) { case AF_INET: lsin = (struct sockaddr_in *)&ss; inet_ntop(AF_INET, &lsin->sin_addr, addr, sizeof addr); asprintf(&tmp, "{ AF_INET %s:%d }", addr, htons(lsin->sin_port)); break; case AF_INET6: lsin6 = (struct sockaddr_in6 *)&ss; inet_ntop(AF_INET6, &lsin6->sin6_addr, addr, sizeof addr); asprintf(&tmp, "{ AF_INET6 [%s]:%d }", addr, htons(lsin6->sin6_port)); break; case AF_UNIX: sun = (struct sockaddr_un *)&ss; asprintf(&tmp, "{ AF_UNIX \"%s\" }", sun->sun_path); break; default: sa = (struct sockaddr *)&ss; asprintf(&tmp, "{ sa_len = %d, sa_family = %d, sa_data " "= {%n%*s } }", (int)sa->sa_len, (int)sa->sa_family, &i, 6 * (int)(sa->sa_len - ((char *)&sa->sa_data - (char *)sa)), ""); if (tmp != NULL) { p = tmp + i; for (q = (u_char *)&sa->sa_data; q < (u_char *)sa + sa->sa_len; q++) p += sprintf(p, " %#02x,", *q); } } break; } case Sigaction: { struct sigaction sa; char *hand; const char *h; if (get_struct(pid, (void *)args[sc->offset], &sa, sizeof(sa)) != -1) { asprintf(&hand, "%p", sa.sa_handler); if (sa.sa_handler == SIG_DFL) h = "SIG_DFL"; else if (sa.sa_handler == SIG_IGN) h = "SIG_IGN"; else h = hand; asprintf(&tmp, "{ %s %s ss_t }", h, xlookup_bits(sigaction_flags, sa.sa_flags)); free(hand); } else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Kevent: { /* * XXX XXX: the size of the array is determined by either the * next syscall argument, or by the syscall returnvalue, * depending on which argument number we are. This matches the * kevent syscall, but luckily that's the only syscall that uses * them. */ struct kevent *ke; int numevents = -1; int bytes = 0; int i, tmpsize, u, used; const int per_ke = 100; if (sc->offset == 1) numevents = args[sc->offset+1]; else if (sc->offset == 3 && retval != -1) numevents = retval; if (numevents >= 0) bytes = sizeof(struct kevent) * numevents; if ((ke = malloc(bytes)) == NULL) err(1, "Cannot malloc %d bytes for kevent array", bytes); if (numevents >= 0 && get_struct(pid, (void *)args[sc->offset], ke, bytes) != -1) { used = 0; tmpsize = 1 + per_ke * numevents + 2; if ((tmp = malloc(tmpsize)) == NULL) err(1, "Cannot alloc %d bytes for kevent " "output", tmpsize); tmp[used++] = '{'; for (i = 0; i < numevents; i++) { u = snprintf(tmp + used, per_ke, "%s%p,%s,%s,%d,%p,%p", i > 0 ? " " : "", (void *)ke[i].ident, xlookup(kevent_filters, ke[i].filter), xlookup_bits(kevent_flags, ke[i].flags), ke[i].fflags, (void *)ke[i].data, (void *)ke[i].udata); if (u > 0) used += u < per_ke ? u : per_ke; } tmp[used++] = '}'; tmp[used++] = '\0'; } else { asprintf(&tmp, "0x%lx", args[sc->offset]); } free(ke); break; } case Stat: { struct stat st; if (get_struct(pid, (void *)args[sc->offset], &st, sizeof(st)) != -1) { char mode[12]; strmode(st.st_mode, mode); asprintf(&tmp, "{ mode=%s,inode=%jd,size=%jd,blksize=%ld }", mode, (intmax_t)st.st_ino, (intmax_t)st.st_size, (long)st.st_blksize); } else { asprintf(&tmp, "0x%lx", args[sc->offset]); } break; } case Rusage: { struct rusage ru; if (get_struct(pid, (void *)args[sc->offset], &ru, sizeof(ru)) != -1) { asprintf(&tmp, "{ u=%ld.%06ld,s=%ld.%06ld,in=%ld,out=%ld }", (long)ru.ru_utime.tv_sec, ru.ru_utime.tv_usec, (long)ru.ru_stime.tv_sec, ru.ru_stime.tv_usec, ru.ru_inblock, ru.ru_oublock); } else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case Rlimit: { struct rlimit rl; if (get_struct(pid, (void *)args[sc->offset], &rl, sizeof(rl)) != -1) { asprintf(&tmp, "{ cur=%ju,max=%ju }", rl.rlim_cur, rl.rlim_max); } else asprintf(&tmp, "0x%lx", args[sc->offset]); break; } case ExitStatus: { char *signame; int status; signame = NULL; if (get_struct(pid, (void *)args[sc->offset], &status, sizeof(status)) != -1) { if (WIFCONTINUED(status)) tmp = strdup("{ CONTINUED }"); else if (WIFEXITED(status)) asprintf(&tmp, "{ EXITED,val=%d }", WEXITSTATUS(status)); else if (WIFSIGNALED(status)) asprintf(&tmp, "{ SIGNALED,sig=%s%s }", signame = strsig2(WTERMSIG(status)), WCOREDUMP(status) ? ",cored" : ""); else asprintf(&tmp, "{ STOPPED,sig=%s }", signame = strsig2(WTERMSIG(status))); } else asprintf(&tmp, "0x%lx", args[sc->offset]); free(signame); break; } case Waitoptions: tmp = strdup(xlookup_bits(wait_options, args[sc->offset])); break; case Idtype: tmp = strdup(xlookup(idtype_arg, args[sc->offset])); break; case Procctl: tmp = strdup(xlookup(procctl_arg, args[sc->offset])); break; default: errx(1, "Invalid argument type %d\n", sc->type & ARG_MASK); }
enum cmd_retval cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c = cmdq->client; struct session *s; struct paste_buffer *pb; const char *path; char *cause, *start, *end, *msg; size_t size, used, msglen; int cwd, fd, buffer; FILE *f; if (!args_has(args, 'b')) { if ((pb = paste_get_top(&global_buffers)) == NULL) { cmdq_error(cmdq, "no buffers"); return (CMD_RETURN_ERROR); } } else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { cmdq_error(cmdq, "buffer %s", cause); free(cause); return (CMD_RETURN_ERROR); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { cmdq_error(cmdq, "no buffer %d", buffer); return (CMD_RETURN_ERROR); } } if (self->entry == &cmd_show_buffer_entry) path = "-"; else path = args->argv[0]; if (strcmp(path, "-") == 0) { if (c == NULL) { cmdq_error(cmdq, "can't write to stdout"); return (CMD_RETURN_ERROR); } if (c->session == NULL || (c->flags & CLIENT_CONTROL)) goto do_stdout; goto do_print; } if (c != NULL && c->session == NULL) cwd = c->cwd; else if ((s = cmd_current_session(cmdq, 0)) != NULL) cwd = s->cwd; else cwd = AT_FDCWD; f = NULL; if (args_has(self->args, 'a')) { fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600); if (fd != -1) f = fdopen(fd, "ab"); } else { fd = openat(cwd, path, O_CREAT|O_RDWR, 0600); if (fd != -1) f = fdopen(fd, "wb"); } if (f == NULL) { if (fd != -1) close(fd); cmdq_error(cmdq, "%s: %s", path, strerror(errno)); return (CMD_RETURN_ERROR); } if (fwrite(pb->data, 1, pb->size, f) != pb->size) { cmdq_error(cmdq, "%s: fwrite error", path); fclose(f); return (CMD_RETURN_ERROR); } fclose(f); return (CMD_RETURN_NORMAL); do_stdout: evbuffer_add(c->stdout_data, pb->data, pb->size); server_push_stdout(c); return (CMD_RETURN_NORMAL); do_print: if (pb->size > (INT_MAX / 4) - 1) { cmdq_error(cmdq, "buffer too big"); return (CMD_RETURN_ERROR); } msg = NULL; msglen = 0; used = 0; while (used != pb->size) { start = pb->data + used; end = memchr(start, '\n', pb->size - used); if (end != NULL) size = end - start; else size = pb->size - used; msglen = size * 4 + 1; msg = xrealloc(msg, 1, msglen); strvisx(msg, start, size, VIS_OCTAL|VIS_TAB); cmdq_print(cmdq, "%s", msg); used += size + (end != NULL); } free(msg); return (CMD_RETURN_NORMAL); }
enum cmd_retval cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; struct session *s; struct paste_buffer *pb; const char *path, *newpath, *wd; char *cause, *start, *end; size_t size, used; int buffer; mode_t mask; FILE *f; char *msg; size_t msglen; if (!args_has(args, 'b')) { if ((pb = paste_get_top(&global_buffers)) == NULL) { cmdq_error(cmdq, "no buffers"); return (CMD_RETURN_ERROR); } } else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { cmdq_error(cmdq, "buffer %s", cause); free(cause); return (CMD_RETURN_ERROR); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { cmdq_error(cmdq, "no buffer %d", buffer); return (CMD_RETURN_ERROR); } } if (self->entry == &cmd_show_buffer_entry) path = "-"; else path = args->argv[0]; if (strcmp(path, "-") == 0) { c = cmdq->client; if (c == NULL) { cmdq_error(cmdq, "can't write to stdout"); return (CMD_RETURN_ERROR); } if (c->session == NULL || (c->flags & CLIENT_CONTROL)) goto do_stdout; goto do_print; } c = cmdq->client; if (c != NULL) wd = c->cwd; else if ((s = cmd_current_session(cmdq, 0)) != NULL) { wd = options_get_string(&s->options, "default-path"); if (*wd == '\0') wd = s->cwd; } else wd = NULL; if (wd != NULL && *wd != '\0') { newpath = get_full_path(wd, path); if (newpath != NULL) path = newpath; } mask = umask(S_IRWXG | S_IRWXO); if (args_has(self->args, 'a')) f = fopen(path, "ab"); else f = fopen(path, "wb"); umask(mask); if (f == NULL) { cmdq_error(cmdq, "%s: %s", path, strerror(errno)); return (CMD_RETURN_ERROR); } if (fwrite(pb->data, 1, pb->size, f) != pb->size) { cmdq_error(cmdq, "%s: fwrite error", path); fclose(f); return (CMD_RETURN_ERROR); } fclose(f); return (CMD_RETURN_NORMAL); do_stdout: evbuffer_add(c->stdout_data, pb->data, pb->size); server_push_stdout(c); return (CMD_RETURN_NORMAL); do_print: if (pb->size > (INT_MAX / 4) - 1) { cmdq_error(cmdq, "buffer too big"); return (CMD_RETURN_ERROR); } msg = NULL; msglen = 0; used = 0; while (used != pb->size) { start = pb->data + used; end = memchr(start, '\n', pb->size - used); if (end != NULL) size = end - start; else size = pb->size - used; msglen = size * 4 + 1; msg = xrealloc(msg, 1, msglen); strvisx(msg, start, size, VIS_OCTAL|VIS_TAB); cmdq_print(cmdq, "%s", msg); used += size + (end != NULL); } free(msg); return (CMD_RETURN_NORMAL); }
int main(int argc, char *argv[]) { char ptyname[2][16], buf[2][BUFSIZE], str[4 * BUFSIZE + 1]; size_t n[2] = {0, 0}, readlen[2] = {0, 0}, writelen[2] = {0, 0}, i, j; struct pollfd fds[3]; struct termios term; int ch, fd[2], mfd[2]; if (setvbuf(stdout, NULL, _IOLBF, 0) != 0) err(1, "setvbuf"); while ((ch = getopt(argc, argv, "qv")) != -1) { switch (ch) { case 'q': qflag = 1; break; case 'v': vflag = 1; break; default: usage(); } } argc -= optind; argv += optind; if (argc != 0) usage(); ch = 1; memset(&term, 0, sizeof(term)); cfmakeraw(&term); for (i = 0; i < nitems(mfd); i++) { if (openpty(&mfd[i], &fd[i], ptyname[i], &term, NULL) == -1) err(1, "openpty"); if (ioctl(mfd[i], TIOCEXT, &ch) == -1) err(1, "ioctl TIOCEXT"); if (ioctl(mfd[i], TIOCREMOTE, &ch) == -1) err(1, "ioctl TIOCREMOTE"); if (!qflag) printf("%d PTY: %s\n", mfd[i], ptyname[i]); } fds[0].fd = mfd[0]; fds[0].events = POLLIN; fds[1].fd = mfd[1]; fds[1].events = POLLIN; fds[2].fd = STDIN_FILENO; fds[2].events = POLLIN; /* finish if both ends have finished or stdin has been closed */ while ((fds[0].fd != -1 || fds[1].fd != -1) && fds[2].fd != -1) { ssize_t rv; if (poll(fds, nitems(fds), INFTIM) == -1) err(1, "poll"); /* exit on error, detect hangup */ for (i = 0; i < nitems(fds); i++) { if (fds[i].revents & POLLNVAL) errx(1, "POLLNVAL %d", fds[i].fd); if (fds[i].revents & POLLERR) errx(1, "POLLERR %d", fds[i].fd); if (fds[i].revents & POLLHUP) fds[i].fd = -1; } /* anything from stdin terminates the program */ if (fds[2].revents & POLLIN) fds[2].fd = -1; /* copy bidirectional between master pseudo terminals */ for (i = 0, j = 1; i < nitems(mfd); i++, j--) { if (fds[i].revents & POLLIN) { if ((rv = read(fds[i].fd, buf[i], BUFSIZE)) == -1) err(1, "read %d", fds[i].fd); if (rv > 0) { if (vflag) { strvisx(str, buf[i], rv, VIS_NL); printf("%d >>> %s\n", fds[i].fd, str); } readlen[i] += rv; n[i] = rv; fds[i].events &= ~POLLIN; fds[j].events |= POLLOUT; } else if (vflag) printf("%d >>> EOF", fds[i].fd); } if (fds[j].revents & POLLOUT) { if ((rv = write(fds[j].fd, buf[i], n[i])) == -1) err(1, "write"); if (rv > 0) { if (vflag) { strvisx(str, buf[i], rv, VIS_NL); printf("%d <<< %s\n", fds[j].fd, str); } writelen[j] += rv; n[i] -= rv; if (n[i] > 0) { memmove(buf[i], buf[i] + rv, n[i]); } else { fds[i].events |= POLLIN; fds[j].events &= ~POLLOUT; } } else if (vflag) printf("%d <<< EOF", fds[j].fd); } } } /* log statistics */ if (!qflag) { for (i = 0, j = 1; i < nitems(mfd); i++, j--) { printf("%d READLEN: %zu\n", mfd[i], readlen[i]); printf("%d WRITELEN: %zu\n", mfd[i], writelen[i]); } } return (0); }
int main(int argc, char *argv[]) { struct msgbuf *bufp, cur; char *bp, *ep, *memf, *nextp, *nlistf, *p, *q, *visbp; kvm_t *kd; size_t buflen, bufpos; long pri; int ch, clear; bool all; all = false; clear = false; (void) setlocale(LC_CTYPE, ""); memf = nlistf = NULL; while ((ch = getopt(argc, argv, "acM:N:")) != -1) switch(ch) { case 'a': all = true; break; case 'c': clear = true; break; case 'M': memf = optarg; break; case 'N': nlistf = optarg; break; case '?': default: usage(); } argc -= optind; if (argc != 0) usage(); if (memf == NULL) { /* * Running kernel. Use sysctl. This gives an unwrapped * buffer as a side effect. */ if (sysctlbyname("kern.msgbuf", NULL, &buflen, NULL, 0) == -1) err(1, "sysctl kern.msgbuf"); if ((bp = malloc(buflen + 2)) == NULL) errx(1, "malloc failed"); if (sysctlbyname("kern.msgbuf", bp, &buflen, NULL, 0) == -1) err(1, "sysctl kern.msgbuf"); if (clear) if (sysctlbyname("kern.msgbuf_clear", NULL, NULL, &clear, sizeof(int))) err(1, "sysctl kern.msgbuf_clear"); } else { /* Read in kernel message buffer and do sanity checks. */ kd = kvm_open(nlistf, memf, NULL, O_RDONLY, "dmesg"); if (kd == NULL) exit (1); if (kvm_nlist(kd, nl) == -1) errx(1, "kvm_nlist: %s", kvm_geterr(kd)); if (nl[X_MSGBUF].n_type == 0) errx(1, "%s: msgbufp not found", nlistf ? nlistf : "namelist"); if (KREAD(nl[X_MSGBUF].n_value, bufp) || KREAD((long)bufp, cur)) errx(1, "kvm_read: %s", kvm_geterr(kd)); if (cur.msg_magic != MSG_MAGIC) errx(1, "kernel message buffer has different magic " "number"); if ((bp = malloc(cur.msg_size + 2)) == NULL) errx(1, "malloc failed"); /* Unwrap the circular buffer to start from the oldest data. */ bufpos = MSGBUF_SEQ_TO_POS(&cur, cur.msg_wseq); if (kvm_read(kd, (long)&cur.msg_ptr[bufpos], bp, cur.msg_size - bufpos) != (ssize_t)(cur.msg_size - bufpos)) errx(1, "kvm_read: %s", kvm_geterr(kd)); if (bufpos != 0 && kvm_read(kd, (long)cur.msg_ptr, &bp[cur.msg_size - bufpos], bufpos) != (ssize_t)bufpos) errx(1, "kvm_read: %s", kvm_geterr(kd)); kvm_close(kd); buflen = cur.msg_size; } /* * Ensure that the buffer ends with a newline and a \0 to avoid * complications below. We left space above. */ if (buflen == 0 || bp[buflen - 1] != '\n') bp[buflen++] = '\n'; bp[buflen] = '\0'; if ((visbp = malloc(4 * buflen + 1)) == NULL) errx(1, "malloc failed"); /* * The message buffer is circular, but has been unwrapped so that * the oldest data comes first. The data will be preceded by \0's * if the message buffer was not full. */ p = bp; ep = &bp[buflen]; if (*p == '\0') { /* Strip leading \0's */ while (*p == '\0') p++; } else if (!all) { /* Skip the first line, since it is probably incomplete. */ p = memchr(p, '\n', ep - p); p++; } for (; p < ep; p = nextp) { nextp = memchr(p, '\n', ep - p); nextp++; /* Skip ^<[0-9]+> syslog sequences. */ if (*p == '<' && isdigit(*(p+1))) { errno = 0; pri = strtol(p + 1, &q, 10); if (*q == '>' && pri >= 0 && pri < INT_MAX && errno == 0) { if (LOG_FAC(pri) != LOG_KERN && !all) continue; p = q + 1; } } (void)strvisx(visbp, p, nextp - p, 0); (void)printf("%s", visbp); } exit(0); }
/* * Display a list of ber elements. * */ void ldap_debug_elements(struct ber_element *root, int context, const char *fmt, ...) { va_list ap; static int indent = 0; long long v; int d; char *buf, *visbuf; size_t len; u_int i; int constructed; struct ber_oid o; if (verbose < 2 || !debug) return; if (fmt != NULL) { va_start(ap, fmt); vlog(LOG_DEBUG, fmt, ap); va_end(ap); } /* calculate lengths */ ber_calc_len(root); switch (root->be_encoding) { case BER_TYPE_SEQUENCE: case BER_TYPE_SET: constructed = root->be_encoding; break; default: constructed = 0; break; } fprintf(stderr, "%*slen %lu ", indent, "", root->be_len); switch (root->be_class) { case BER_CLASS_UNIVERSAL: fprintf(stderr, "class: universal(%u) type: ", root->be_class); switch (root->be_type) { case BER_TYPE_EOC: fprintf(stderr, "end-of-content"); break; case BER_TYPE_BOOLEAN: fprintf(stderr, "boolean"); break; case BER_TYPE_INTEGER: fprintf(stderr, "integer"); break; case BER_TYPE_BITSTRING: fprintf(stderr, "bit-string"); break; case BER_TYPE_OCTETSTRING: fprintf(stderr, "octet-string"); break; case BER_TYPE_NULL: fprintf(stderr, "null"); break; case BER_TYPE_OBJECT: fprintf(stderr, "object"); break; case BER_TYPE_ENUMERATED: fprintf(stderr, "enumerated"); break; case BER_TYPE_SEQUENCE: fprintf(stderr, "sequence"); break; case BER_TYPE_SET: fprintf(stderr, "set"); break; } break; case BER_CLASS_APPLICATION: fprintf(stderr, "class: application(%u) type: ", root->be_class); switch (root->be_type) { case LDAP_REQ_BIND: case LDAP_RES_BIND: fprintf(stderr, "bind"); break; case LDAP_REQ_UNBIND_30: fprintf(stderr, "unbind"); break; case LDAP_REQ_SEARCH: fprintf(stderr, "search"); break; case LDAP_RES_SEARCH_ENTRY: fprintf(stderr, "search entry"); break; case LDAP_RES_SEARCH_RESULT: fprintf(stderr, "search result"); break; case LDAP_REQ_MODIFY: case LDAP_RES_MODIFY: fprintf(stderr, "modify"); break; case LDAP_REQ_ADD: case LDAP_RES_ADD: fprintf(stderr, "add"); break; case LDAP_REQ_DELETE_30: case LDAP_RES_DELETE: fprintf(stderr, "delete"); break; case LDAP_REQ_MODRDN: case LDAP_RES_MODRDN: fprintf(stderr, "modrdn"); break; case LDAP_REQ_COMPARE: case LDAP_RES_COMPARE: fprintf(stderr, "compare"); break; case LDAP_REQ_ABANDON_30: fprintf(stderr, "abandon"); break; case LDAP_REQ_EXTENDED: case LDAP_RES_EXTENDED: fprintf(stderr, "extended"); break; } break; case BER_CLASS_PRIVATE: fprintf(stderr, "class: private(%u) type: ", root->be_class); fprintf(stderr, "encoding (%lu) type: ", root->be_encoding); break; case BER_CLASS_CONTEXT: fprintf(stderr, "class: context(%u) type: ", root->be_class); switch (context) { case LDAP_REQ_BIND: switch(root->be_type) { case LDAP_AUTH_SIMPLE: fprintf(stderr, "auth simple"); break; } break; case LDAP_REQ_SEARCH: switch(root->be_type) { case LDAP_FILT_AND: fprintf(stderr, "and"); break; case LDAP_FILT_OR: fprintf(stderr, "or"); break; case LDAP_FILT_NOT: fprintf(stderr, "not"); break; case LDAP_FILT_EQ: fprintf(stderr, "equal"); break; case LDAP_FILT_SUBS: fprintf(stderr, "substring"); break; case LDAP_FILT_GE: fprintf(stderr, "greater-or-equal"); break; case LDAP_FILT_LE: fprintf(stderr, "less-or-equal"); break; case LDAP_FILT_PRES: fprintf(stderr, "presence"); break; case LDAP_FILT_APPR: fprintf(stderr, "approximate"); break; } break; } break; default: fprintf(stderr, "class: <INVALID>(%u) type: ", root->be_class); break; } fprintf(stderr, "(%lu) encoding %lu ", root->be_type, root->be_encoding); if (constructed) root->be_encoding = constructed; switch (root->be_encoding) { case BER_TYPE_BOOLEAN: if (ber_get_boolean(root, &d) == -1) { fprintf(stderr, "<INVALID>\n"); break; } fprintf(stderr, "%s(%d)\n", d ? "true" : "false", d); break; case BER_TYPE_INTEGER: if (ber_get_integer(root, &v) == -1) { fprintf(stderr, "<INVALID>\n"); break; } fprintf(stderr, "value %lld\n", v); break; case BER_TYPE_ENUMERATED: if (ber_get_enumerated(root, &v) == -1) { fprintf(stderr, "<INVALID>\n"); break; } fprintf(stderr, "value %lld\n", v); break; case BER_TYPE_BITSTRING: if (ber_get_bitstring(root, (void *)&buf, &len) == -1) { fprintf(stderr, "<INVALID>\n"); break; } fprintf(stderr, "hexdump "); for (i = 0; i < len; i++) fprintf(stderr, "%02x", buf[i]); fprintf(stderr, "\n"); break; case BER_TYPE_OBJECT: if (ber_get_oid(root, &o) == -1) { fprintf(stderr, "<INVALID>\n"); break; } fprintf(stderr, "\n"); break; case BER_TYPE_OCTETSTRING: if (ber_get_nstring(root, (void *)&buf, &len) == -1) { fprintf(stderr, "<INVALID>\n"); break; } if ((visbuf = malloc(len * 4 + 1)) != NULL) { strvisx(visbuf, buf, len, 0); fprintf(stderr, "string \"%s\"\n", visbuf); free(visbuf); } break; case BER_TYPE_NULL: /* no payload */ case BER_TYPE_EOC: case BER_TYPE_SEQUENCE: case BER_TYPE_SET: default: fprintf(stderr, "\n"); break; } if (constructed && root->be_sub) { indent += 2; ldap_debug_elements(root->be_sub, context, NULL); indent -= 2; } if (root->be_next) ldap_debug_elements(root->be_next, context, NULL); }
int cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct session *s; struct paste_buffer *pb; int buffer; char *in, *buf, *ptr, *cause; size_t size, len; u_int width; if ((s = cmd_find_session(ctx, NULL, 0)) == NULL) return (-1); if (!args_has(args, 'b')) { if ((pb = paste_get_top(&global_buffers)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { ctx->error(ctx, "buffer %s", cause); xfree(cause); return (-1); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { ctx->error(ctx, "no buffer %d", buffer); return (-1); } } size = pb->size; if (size > SIZE_MAX / 4 - 1) size = SIZE_MAX / 4 - 1; in = xmalloc(size * 4 + 1); strvisx(in, pb->data, size, VIS_OCTAL|VIS_TAB); width = s->sx; if (ctx->cmdclient != NULL) width = ctx->cmdclient->tty.sx; buf = xmalloc(width + 1); len = 0; ptr = in; do { buf[len++] = *ptr++; if (len == width || buf[len - 1] == '\n') { if (buf[len - 1] == '\n') len--; buf[len] = '\0'; ctx->print(ctx, "%s", buf); len = 0; } } while (*ptr != '\0'); if (len != 0) { buf[len] = '\0'; ctx->print(ctx, "%s", buf); } xfree(buf); xfree(in); return (0); }
/* * Display the current state of the queue. Format = 1 if long format. */ void displayq(int format) { struct queue *q; int i, rank, nitems, fd, ret, len; char *cp, *ecp, *p; struct queue **queue; struct winsize win; struct stat statb; FILE *fp; termwidth = 80; if (isatty(STDOUT_FILENO)) { if ((p = getenv("COLUMNS")) != NULL) termwidth = atoi(p); else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == 0 && win.ws_col > 0) termwidth = win.ws_col; } if (termwidth < 60) termwidth = 60; lflag = format; totsize = 0; if ((i = cgetent(&bp, printcapdb, printer)) == -2) fatal("can't open printer description file"); else if (i == -1) fatal("unknown printer"); else if (i == -3) fatal("potential reference loop detected in printcap file"); if (cgetstr(bp, DEFLP, &LP) < 0) LP = _PATH_DEFDEVLP; if (cgetstr(bp, "rp", &RP) < 0) RP = DEFLP; if (cgetstr(bp, "sd", &SD) < 0) SD = _PATH_DEFSPOOL; if (cgetstr(bp,"lo", &LO) < 0) LO = DEFLOCK; if (cgetstr(bp, "st", &ST) < 0) ST = DEFSTAT; cgetstr(bp, "rm", &RM); if ((cp = checkremote()) != NULL) printf("Warning: %s\n", cp); /* * Print out local queue * Find all the control files in the spooling directory */ PRIV_START; if (chdir(SD) < 0) fatal("cannot chdir to spooling directory"); PRIV_END; if ((nitems = getq(&queue)) < 0) fatal("cannot examine spooling area"); PRIV_START; ret = stat(LO, &statb); PRIV_END; if (ret >= 0) { if (statb.st_mode & S_IXUSR) { if (remote) printf("%s: ", host); printf("Warning: %s is down: ", printer); PRIV_START; fd = safe_open(ST, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd >= 0 && flock(fd, LOCK_SH) == 0) { while ((i = read(fd, line, sizeof(line))) > 0) (void)fwrite(line, 1, i, stdout); (void)close(fd); /* unlocks as well */ } else putchar('\n'); } if (statb.st_mode & S_IXGRP) { if (remote) printf("%s: ", host); printf("Warning: %s queue is turned off\n", printer); } } if (nitems) { PRIV_START; fd = safe_open(LO, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd < 0 || (fp = fdopen(fd, "r")) == NULL) { if (fd >= 0) close(fd); nodaemon(); } else { /* get daemon pid */ cp = current; ecp = cp + sizeof(current) - 1; while ((i = getc(fp)) != EOF && i != '\n') { if (cp < ecp) *cp++ = i; } *cp = '\0'; i = atoi(current); if (i <= 0) { ret = -1; } else { PRIV_START; ret = kill(i, 0); PRIV_END; } if (ret < 0 && errno != EPERM) { nodaemon(); } else { /* read current file name */ cp = current; ecp = cp + sizeof(current) - 1; while ((i = getc(fp)) != EOF && i != '\n') { if (cp < ecp) *cp++ = i; } *cp = '\0'; /* * Print the status file. */ if (remote) printf("%s: ", host); PRIV_START; fd = safe_open(ST, O_RDONLY|O_NOFOLLOW, 0); PRIV_END; if (fd >= 0 && flock(fd, LOCK_SH) == 0) { while ((i = read(fd, line, sizeof(line))) > 0) (void)fwrite(line, 1, i, stdout); (void)close(fd); /* unlocks as well */ } else putchar('\n'); } (void)fclose(fp); } /* * Now, examine the control files and print out the jobs to * be done for each user. */ if (!lflag) header(); /* The currently printed job is treated specially. */ if (!remote && current[0] != '\0') inform(current, 0); for (i = 0, rank = 1; i < nitems; i++) { q = queue[i]; if (remote || strcmp(current, q->q_name) != 0) inform(q->q_name, rank++); free(q); } } free(queue); if (!remote) { if (nitems == 0) puts("no entries"); return; } /* * Print foreign queue * Note that a file in transit may show up in either queue. */ if (nitems) putchar('\n'); (void)snprintf(line, sizeof(line), "%c%s", format + '\3', RP); cp = line; cp += strlen(cp); for (i = 0; i < requests && cp - line < sizeof(line) - 1; i++) { len = line + sizeof(line) - cp; if (snprintf(cp, len, " %d", requ[i]) >= len) { cp += strlen(cp); break; } cp += strlen(cp); } for (i = 0; i < users && cp - line < sizeof(line) - 1; i++) { len = line + sizeof(line) - cp; if (snprintf(cp, len, " %s", user[i]) >= len) { cp += strlen(cp); break; } } if (cp-line < sizeof(line) - 1) strlcat(line, "\n", sizeof(line)); else line[sizeof(line) - 2] = '\n'; fd = getport(RM, 0); if (fd < 0) { if (from != host) printf("%s: ", host); (void)printf("connection to %s is down\n", RM); } else { struct sigaction osa, nsa; char *visline; int n = 0; i = strlen(line); if (write(fd, line, i) != i) fatal("Lost connection"); memset(&nsa, 0, sizeof(nsa)); nsa.sa_handler = alarmer; sigemptyset(&nsa.sa_mask); nsa.sa_flags = 0; (void)sigaction(SIGALRM, &nsa, &osa); alarm(wait_time); if ((visline = (char *)malloc(4 * sizeof(line) + 1)) == NULL) fatal("Out of memory"); while ((i = read(fd, line, sizeof(line))) > 0) { n = strvisx(visline, line, i, VIS_SAFE|VIS_NOSLASH); (void)fwrite(visline, 1, n, stdout); alarm(wait_time); } /* XXX some LPR implementations may not end stream with '\n' */ if (n > 0 && visline[n-1] != '\n') putchar('\n'); alarm(0); (void)sigaction(SIGALRM, &osa, NULL); free(visline); (void)close(fd); } }