1 /* $NetBSD: fstat.c,v 1.114 2020/08/26 23:08:29 christos Exp $ */ 2 3 /*- 4 * Copyright (c) 1988, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 __COPYRIGHT("@(#) Copyright (c) 1988, 1993\ 35 The Regents of the University of California. All rights reserved."); 36 #endif /* not lint */ 37 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)fstat.c 8.3 (Berkeley) 5/2/95"; 41 #else 42 __RCSID("$NetBSD: fstat.c,v 1.114 2020/08/26 23:08:29 christos Exp $"); 43 #endif 44 #endif /* not lint */ 45 46 #include <sys/types.h> 47 #include <sys/param.h> 48 #include <sys/time.h> 49 #include <sys/proc.h> 50 #include <sys/stat.h> 51 #include <sys/vnode.h> 52 #include <sys/socket.h> 53 #include <sys/socketvar.h> 54 #include <sys/domain.h> 55 #include <sys/protosw.h> 56 #include <sys/unpcb.h> 57 #include <sys/sysctl.h> 58 #include <sys/filedesc.h> 59 #include <sys/pipe.h> 60 #define _KERNEL 61 #include <sys/mount.h> 62 #undef _KERNEL 63 #define _KERNEL 64 #include <sys/file.h> 65 #include <ufs/ufs/inode.h> 66 #include <ufs/ufs/ufsmount.h> 67 #undef _KERNEL 68 #define NFS 69 #include <nfs/nfsproto.h> 70 #include <nfs/rpcv2.h> 71 #include <nfs/nfs.h> 72 #include <nfs/nfsnode.h> 73 #undef NFS 74 #include <msdosfs/denode.h> 75 #include <msdosfs/bpb.h> 76 #define _KERNEL 77 #include <msdosfs/msdosfsmount.h> 78 #undef _KERNEL 79 #define _KERNEL 80 #include <miscfs/genfs/layer.h> 81 #undef _KERNEL 82 83 #include <net/route.h> 84 #include <netinet/in.h> 85 #include <netinet/in_systm.h> 86 #include <netinet/ip.h> 87 #include <netinet/in_pcb.h> 88 89 #ifdef INET6 90 #include <netinet/ip6.h> 91 #include <netinet6/in6.h> 92 #include <netinet6/ip6_var.h> 93 #include <netinet6/in6_pcb.h> 94 #endif 95 96 #include <netatalk/at.h> 97 #include <netatalk/ddp_var.h> 98 99 #include <netdb.h> 100 #include <arpa/inet.h> 101 102 #include <ctype.h> 103 #include <errno.h> 104 #include <kvm.h> 105 #include <limits.h> 106 #include <nlist.h> 107 #include <paths.h> 108 #include <pwd.h> 109 #include <stdio.h> 110 #include <stdlib.h> 111 #include <string.h> 112 #include <unistd.h> 113 #include <err.h> 114 #include <util.h> 115 116 #include "fstat.h" 117 118 #define TEXT -1 119 #define CDIR -2 120 #define RDIR -3 121 #define TRACE -4 122 123 typedef struct devs { 124 struct devs *next; 125 long fsid; 126 ino_t ino; 127 const char *name; 128 } DEVS; 129 static DEVS *devs; 130 131 static int fsflg, /* show files on same filesystem as file(s) argument */ 132 pflg, /* show files open by a particular pid */ 133 uflg; /* show files open by a particular (effective) user */ 134 static int checkfile; /* true if restricting to particular files or filesystems */ 135 static int nflg; /* (numerical) display f.s. and rdev as dev_t */ 136 static int Aflg; /* prefix with address of file structure */ 137 static int Oflg; /* print offset instead of size */ 138 int vflg; /* display errors in locating kernel data objects etc... */ 139 140 static fdfile_t **ofiles; /* buffer of pointers to file structures */ 141 static int fstat_maxfiles; 142 #define ALLOC_OFILES(d) \ 143 if ((d) > fstat_maxfiles) { \ 144 size_t len = (d) * sizeof(fdfile_t *); \ 145 free(ofiles); \ 146 ofiles = malloc(len); \ 147 if (ofiles == NULL) { \ 148 err(1, "malloc(%zu)", len); \ 149 } \ 150 fstat_maxfiles = (d); \ 151 } 152 153 kvm_t *kd; 154 155 static const char *const dtypes[] = { 156 DTYPE_NAMES 157 }; 158 159 static void dofiles(struct kinfo_proc2 *); 160 static int ext2fs_filestat(struct vnode *, struct filestat *); 161 static int getfname(const char *); 162 static void getinetproto(char *, size_t, int); 163 static void getatproto(char *, size_t, int); 164 static char *getmnton(struct mount *); 165 static const char *layer_filestat(struct vnode *, struct filestat *); 166 static int msdosfs_filestat(struct vnode *, struct filestat *); 167 static int nfs_filestat(struct vnode *, struct filestat *); 168 static const char *inet_addrstr(char *, size_t, const struct in_addr *, 169 uint16_t, bool); 170 #ifdef INET6 171 static const char *inet6_addrstr(char *, size_t, const struct in6_addr *, 172 uint16_t, bool); 173 #endif 174 static const char *at_addrstr(char *, size_t, const struct sockaddr_at *); 175 static void socktrans(struct file *, struct socket *, int); 176 static void misctrans(struct file *, int); 177 static int ufs_filestat(struct vnode *, struct filestat *); 178 static void usage(void) __dead; 179 static const char *vfilestat(struct vnode *, struct filestat *); 180 static void vtrans(struct file *, struct vnode *, int, int, long); 181 static void ftrans(fdfile_t *, int); 182 static void ptrans(struct file *, struct pipe *, int); 183 static void kdriver_init(void); 184 static void check_privs(void); 185 186 int 187 main(int argc, char **argv) 188 { 189 struct passwd *passwd; 190 struct kinfo_proc2 *p, *plast; 191 int arg, ch, what; 192 char *memf, *nlistf; 193 char buf[_POSIX2_LINE_MAX]; 194 int cnt; 195 gid_t egid = getegid(); 196 197 (void)setegid(getgid()); 198 arg = 0; 199 what = KERN_PROC_ALL; 200 nlistf = memf = NULL; 201 while ((ch = getopt(argc, argv, "fnAOp:u:vN:M:")) != -1) 202 switch((char)ch) { 203 case 'f': 204 fsflg = 1; 205 break; 206 case 'M': 207 memf = optarg; 208 break; 209 case 'N': 210 nlistf = optarg; 211 break; 212 case 'n': 213 nflg = 1; 214 break; 215 case 'A': 216 Aflg = 1; 217 break; 218 case 'O': 219 Oflg = 1; 220 break; 221 case 'p': 222 if (pflg++) 223 usage(); 224 if (!isdigit((unsigned char)*optarg)) { 225 warnx("-p requires a process id"); 226 usage(); 227 } 228 what = KERN_PROC_PID; 229 arg = atoi(optarg); 230 break; 231 case 'u': 232 if (uflg++) 233 usage(); 234 if (!(passwd = getpwnam(optarg))) { 235 errx(1, "%s: unknown uid", optarg); 236 } 237 what = KERN_PROC_UID; 238 arg = passwd->pw_uid; 239 break; 240 case 'v': 241 vflg = 1; 242 break; 243 case '?': 244 default: 245 usage(); 246 } 247 248 check_privs(); 249 250 kdriver_init(); 251 252 if (*(argv += optind)) { 253 for (; *argv; ++argv) { 254 if (getfname(*argv)) 255 checkfile = 1; 256 } 257 if (!checkfile) /* file(s) specified, but none accessible */ 258 exit(1); 259 } 260 261 ALLOC_OFILES(256); /* reserve space for file pointers */ 262 263 if (fsflg && !checkfile) { 264 /* -f with no files means use wd */ 265 if (getfname(".") == 0) 266 exit(1); 267 checkfile = 1; 268 } 269 270 /* 271 * Discard setgid privileges. If not the running kernel, we toss 272 * them away totally so that bad guys can't print interesting stuff 273 * from kernel memory, otherwise switch back to kmem for the 274 * duration of the kvm_openfiles() call. 275 */ 276 if (nlistf != NULL || memf != NULL) 277 (void)setgid(getgid()); 278 else 279 (void)setegid(egid); 280 281 if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == NULL) 282 errx(1, "%s", buf); 283 284 /* get rid of it now anyway */ 285 if (nlistf == NULL && memf == NULL) 286 (void)setgid(getgid()); 287 288 if ((p = kvm_getproc2(kd, what, arg, sizeof *p, &cnt)) == NULL) { 289 errx(1, "%s", kvm_geterr(kd)); 290 } 291 if (Aflg) 292 (void)printf("%-*s ", 2*(int)(sizeof(void*)), "ADDR"); 293 if (nflg) 294 (void)printf( 295 "USER CMD PID FD DEV INUM MODE %s R/W", 296 Oflg ? " OFFS" : "SZ|DV" ); 297 else 298 (void)printf( 299 "USER CMD PID FD MOUNT INUM MODE %s R/W", 300 Oflg ? " OFFS" : "SZ|DV" ); 301 302 if (checkfile && fsflg == 0) 303 (void)printf(" NAME\n"); 304 else 305 (void)putchar('\n'); 306 307 for (plast = &p[cnt]; p < plast; ++p) { 308 if (p->p_stat == SZOMB) 309 continue; 310 dofiles(p); 311 } 312 return 0; 313 } 314 315 static void 316 check_privs(void) 317 { 318 int expaddr; 319 size_t expsize = sizeof(expaddr); 320 const char *expname = "kern.expose_address"; 321 322 if (geteuid() == 0) 323 return; 324 325 if (sysctlbyname(expname, &expaddr, &expsize, NULL, 0) == -1) 326 err(EXIT_FAILURE, "Can't get sysctl `%s'", expname); 327 if (expaddr == 0) 328 errx(EXIT_FAILURE, "This program does not work without " 329 "sysctl `%s' being set", expname); 330 } 331 332 static const char *Uname, *Comm; 333 pid_t Pid; 334 335 #define PREFIX(i) (void)printf("%-8.8s %-10s %5d", Uname, Comm, Pid); \ 336 switch(i) { \ 337 case TEXT: \ 338 (void)printf(" text"); \ 339 break; \ 340 case CDIR: \ 341 (void)printf(" wd"); \ 342 break; \ 343 case RDIR: \ 344 (void)printf(" root"); \ 345 break; \ 346 case TRACE: \ 347 (void)printf(" tr"); \ 348 break; \ 349 default: \ 350 (void)printf(" %4d", i); \ 351 break; \ 352 } 353 354 static struct kinfo_drivers *kdriver; 355 static size_t kdriverlen; 356 357 static int 358 kdriver_comp(const void *a, const void *b) 359 { 360 const struct kinfo_drivers *ka = a; 361 const struct kinfo_drivers *kb = b; 362 int kac = ka->d_cmajor == -1 ? 0 : ka->d_cmajor; 363 int kbc = kb->d_cmajor == -1 ? 0 : kb->d_cmajor; 364 int kab = ka->d_bmajor == -1 ? 0 : ka->d_bmajor; 365 int kbb = kb->d_bmajor == -1 ? 0 : kb->d_bmajor; 366 int c = kac - kbc; 367 if (c == 0) 368 return kab - kbb; 369 else 370 return c; 371 } 372 373 static const char * 374 kdriver_search(int type, dev_t num) 375 { 376 struct kinfo_drivers k, *kp; 377 static char buf[64]; 378 379 if (nflg) 380 goto out; 381 382 if (type == VBLK) { 383 k.d_bmajor = num; 384 k.d_cmajor = -1; 385 } else { 386 k.d_bmajor = -1; 387 k.d_cmajor = num; 388 } 389 kp = bsearch(&k, kdriver, kdriverlen, sizeof(*kdriver), kdriver_comp); 390 if (kp) 391 return kp->d_name; 392 out: 393 snprintf(buf, sizeof(buf), "%llu", (unsigned long long)num); 394 return buf; 395 } 396 397 398 static void 399 kdriver_init(void) 400 { 401 size_t sz; 402 int error; 403 static const int name[2] = { CTL_KERN, KERN_DRIVERS }; 404 405 error = sysctl(name, __arraycount(name), NULL, &sz, NULL, 0); 406 if (error == -1) { 407 warn("sysctl kern.drivers"); 408 return; 409 } 410 411 if (sz % sizeof(*kdriver)) { 412 warnx("bad size %zu for kern.drivers", sz); 413 return; 414 } 415 416 kdriver = malloc(sz); 417 if (kdriver == NULL) { 418 warn("malloc"); 419 return; 420 } 421 422 error = sysctl(name, __arraycount(name), kdriver, &sz, NULL, 0); 423 if (error == -1) { 424 warn("sysctl kern.drivers"); 425 return; 426 } 427 428 kdriverlen = sz / sizeof(*kdriver); 429 qsort(kdriver, kdriverlen, sizeof(*kdriver), kdriver_comp); 430 #ifdef DEBUG 431 for (size_t i = 0; i < kdriverlen; i++) 432 printf("%d %d %s\n", kdriver[i].d_cmajor, kdriver[i].d_bmajor, 433 kdriver[i].d_name); 434 #endif 435 } 436 437 /* 438 * print open files attributed to this process 439 */ 440 static void 441 dofiles(struct kinfo_proc2 *p) 442 { 443 int i; 444 struct filedesc filed; 445 struct cwdinfo cwdi; 446 struct fdtab dt; 447 448 Uname = user_from_uid(p->p_uid, 0); 449 Pid = p->p_pid; 450 Comm = p->p_comm; 451 452 if (p->p_fd == 0 || p->p_cwdi == 0) 453 return; 454 if (!KVM_READ(p->p_fd, &filed, sizeof (filed))) { 455 warnx("can't read filedesc at %p for pid %d", 456 (void *)(uintptr_t)p->p_fd, Pid); 457 return; 458 } 459 if (filed.fd_lastfile == -1) 460 return; 461 if (!KVM_READ(p->p_cwdi, &cwdi, sizeof(cwdi))) { 462 warnx("can't read cwdinfo at %p for pid %d", 463 (void *)(uintptr_t)p->p_cwdi, Pid); 464 return; 465 } 466 if (!KVM_READ(filed.fd_dt, &dt, sizeof(dt))) { 467 warnx("can't read dtab at %p for pid %d", filed.fd_dt, Pid); 468 return; 469 } 470 if ((unsigned)filed.fd_lastfile >= dt.dt_nfiles || 471 filed.fd_freefile > filed.fd_lastfile + 1) { 472 dprintf("filedesc corrupted at %p for pid %d", 473 (void *)(uintptr_t)p->p_fd, Pid); 474 return; 475 } 476 /* 477 * root directory vnode, if one 478 */ 479 if (cwdi.cwdi_rdir) 480 vtrans(NULL, cwdi.cwdi_rdir, RDIR, FREAD, (long)cwdi.cwdi_rdir); 481 /* 482 * current working directory vnode 483 */ 484 vtrans(NULL, cwdi.cwdi_cdir, CDIR, FREAD, (long)cwdi.cwdi_cdir); 485 #if 0 486 /* 487 * Disable for now, since p->p_tracep appears to point to a ktr_desc * 488 * ktrace vnode, if one 489 */ 490 if (p->p_tracep) 491 ftrans(p->p_tracep, TRACE); 492 #endif 493 /* 494 * open files 495 */ 496 #define FPSIZE (sizeof (fdfile_t *)) 497 ALLOC_OFILES(filed.fd_lastfile+1); 498 if (!KVM_READ(&filed.fd_dt->dt_ff, ofiles, 499 (filed.fd_lastfile+1) * FPSIZE)) { 500 dprintf("can't read file structures at %p for pid %d", 501 &filed.fd_dt->dt_ff, Pid); 502 return; 503 } 504 for (i = 0; i <= filed.fd_lastfile; i++) { 505 if (ofiles[i] == NULL) 506 continue; 507 ftrans(ofiles[i], i); 508 } 509 } 510 511 static void 512 ftrans(fdfile_t *fp, int i) 513 { 514 struct file file; 515 fdfile_t fdfile; 516 517 if (!KVM_READ(fp, &fdfile, sizeof(fdfile))) { 518 dprintf("can't read file %d at %p for pid %d", 519 i, fp, Pid); 520 return; 521 } 522 if (fdfile.ff_file == NULL) { 523 dprintf("null ff_file for %d at %p for pid %d", 524 i, fp, Pid); 525 return; 526 } 527 if (!KVM_READ(fdfile.ff_file, &file, sizeof(file))) { 528 dprintf("can't read file %d at %p for pid %d", 529 i, fdfile.ff_file, Pid); 530 return; 531 } 532 if (Aflg && file.f_type != DTYPE_VNODE && checkfile == 0) 533 (void)printf("%*lx ", 534 2*(int)(sizeof(void*)), (long)fdfile.ff_file); 535 switch (file.f_type) { 536 case DTYPE_VNODE: 537 vtrans(&file, file.f_data, i, file.f_flag, (long)fdfile.ff_file); 538 break; 539 case DTYPE_SOCKET: 540 socktrans(&file, file.f_data, i); 541 break; 542 case DTYPE_PIPE: 543 if (checkfile == 0) 544 ptrans(&file, file.f_data, i); 545 break; 546 case DTYPE_MISC: 547 case DTYPE_KQUEUE: 548 case DTYPE_CRYPTO: 549 case DTYPE_MQUEUE: 550 case DTYPE_SEM: 551 if (checkfile == 0) 552 misctrans(&file, i); 553 break; 554 default: 555 dprintf("unknown file type %d for file %d of pid %d", 556 file.f_type, i, Pid); 557 break; 558 } 559 } 560 561 static const char dead[] = "dead"; 562 static const char *vnode_tag[] = { 563 VNODE_TAGS 564 }; 565 566 static const char * 567 vfilestat(struct vnode *vp, struct filestat *fsp) 568 { 569 const char *badtype = NULL; 570 571 if (vp->v_type == VNON) 572 badtype = "none"; 573 else if (vp->v_type == VBAD) 574 badtype = "bad"; 575 else 576 switch (vp->v_tag) { 577 case VT_NON: 578 badtype = dead; 579 break; 580 case VT_UFS: 581 case VT_LFS: 582 case VT_MFS: 583 if (!ufs_filestat(vp, fsp)) 584 badtype = "error"; 585 break; 586 case VT_MSDOSFS: 587 if (!msdosfs_filestat(vp, fsp)) 588 badtype = "error"; 589 break; 590 case VT_NFS: 591 if (!nfs_filestat(vp, fsp)) 592 badtype = "error"; 593 break; 594 case VT_EXT2FS: 595 if (!ext2fs_filestat(vp, fsp)) 596 badtype = "error"; 597 break; 598 case VT_ISOFS: 599 if (!isofs_filestat(vp, fsp)) 600 badtype = "error"; 601 break; 602 case VT_NTFS: 603 if (!ntfs_filestat(vp, fsp)) 604 badtype = "error"; 605 break; 606 case VT_PTYFS: 607 if (!ptyfs_filestat(vp, fsp)) 608 badtype = "error"; 609 break; 610 case VT_TMPFS: 611 if (!tmpfs_filestat(vp, fsp)) 612 badtype = "error"; 613 break; 614 case VT_NULL: 615 case VT_OVERLAY: 616 case VT_UMAP: 617 badtype = layer_filestat(vp, fsp); 618 break; 619 default: { 620 static char unknown[10]; 621 (void)snprintf(unknown, sizeof unknown, "%s(%#x)", 622 (size_t)vp->v_tag < __arraycount(vnode_tag) ? 623 vnode_tag[vp->v_tag] : "?", vp->v_tag); 624 badtype = unknown; 625 break; 626 } 627 } 628 return badtype; 629 } 630 631 static int 632 checkfs(struct vnode *vp, struct vnode *vn, struct filestat *fst, 633 const char **type, const char **fname) 634 { 635 *fname = NULL; 636 if (!KVM_READ(vp, vn, sizeof(*vn))) { 637 dprintf("can't read vnode at %p for pid %d", vp, Pid); 638 return 0; 639 } 640 *type = vfilestat(vn, fst); 641 if (checkfile) { 642 int fsmatch = 0; 643 DEVS *d; 644 #if 0 645 if (*type && *type != dead) 646 return 0; 647 #endif 648 for (d = devs; d != NULL; d = d->next) { 649 if (d->fsid == fst->fsid) { 650 fsmatch = 1; 651 if (d->ino == fst->fileid) { 652 *fname = d->name; 653 break; 654 } 655 } 656 } 657 if (fsmatch == 0 || (*fname == NULL && fsflg == 0)) 658 return 0; 659 } 660 return 1; 661 } 662 663 static void 664 vprint(struct vnode *vn, struct filestat *fst) 665 { 666 switch (vn->v_type) { 667 case VBLK: 668 case VCHR: { 669 const char *name; 670 671 if (nflg || ((name = devname(fst->rdev, vn->v_type == VCHR ? 672 S_IFCHR : S_IFBLK)) == NULL)) 673 (void)printf(" %s,%-2llu", 674 kdriver_search(vn->v_type, major(fst->rdev)), 675 (unsigned long long)minor(fst->rdev)); 676 else 677 (void)printf(" %6s", name); 678 break; 679 } 680 default: 681 (void)printf(" %6lld", (long long)fst->size); 682 } 683 } 684 685 void 686 oprint(struct file *fp, const char *str) 687 { 688 if (Oflg) 689 (void)printf(" %6lld", (long long)(fp ? fp->f_offset : 0)); 690 fputs(str, stdout); 691 } 692 693 static void 694 vtrans(struct file *fp, struct vnode *vp, int i, int flag, long addr) 695 { 696 struct vnode vn; 697 char mode[15], rw[3]; 698 const char *badtype, *filename; 699 struct filestat fst; 700 701 if (!checkfs(vp, &vn, &fst, &badtype, &filename)) 702 return; 703 704 if (Aflg) 705 (void)printf("%*lx ", 2*(int)(sizeof(void*)), addr); 706 PREFIX(i); 707 if (badtype == dead) { 708 char buf[1024]; 709 (void)snprintb(buf, sizeof(buf), VNODE_FLAGBITS, 710 vn.v_iflag | vn.v_vflag | vn.v_uflag); 711 (void)printf(" flags %s\n", buf); 712 return; 713 } else if (badtype) { 714 (void)printf(" - - %10s -\n", badtype); 715 return; 716 } 717 if (nflg) 718 (void)printf(" %3llu,%-2llu", 719 (unsigned long long)major(fst.fsid), 720 (unsigned long long)minor(fst.fsid)); 721 else 722 (void)printf(" %-8s", getmnton(vn.v_mount)); 723 if (nflg) 724 (void)snprintf(mode, sizeof mode, "%6o", fst.mode); 725 else 726 strmode(fst.mode, mode); 727 (void)printf(" %8"PRIu64" %*s", fst.fileid, nflg ? 5 : 10, mode); 728 if (Oflg) { 729 oprint(fp, ""); 730 } else { 731 vprint(&vn, &fst); 732 } 733 rw[0] = '\0'; 734 if (flag & FREAD) 735 (void)strlcat(rw, "r", sizeof(rw)); 736 if (flag & FWRITE) 737 (void)strlcat(rw, "w", sizeof(rw)); 738 (void)printf(" %-2s", rw); 739 if (filename && !fsflg) 740 (void)printf(" %s", filename); 741 (void)putchar('\n'); 742 } 743 744 static int 745 ufs_filestat(struct vnode *vp, struct filestat *fsp) 746 { 747 struct inode inode; 748 struct ufsmount ufsmount; 749 union dinode { 750 struct ufs1_dinode dp1; 751 struct ufs2_dinode dp2; 752 } dip; 753 754 if (!KVM_READ(VTOI(vp), &inode, sizeof (inode))) { 755 dprintf("can't read inode at %p for pid %d", VTOI(vp), Pid); 756 return 0; 757 } 758 759 if (!KVM_READ(inode.i_ump, &ufsmount, sizeof (struct ufsmount))) { 760 dprintf("can't read ufsmount at %p for pid %d", inode.i_ump, Pid); 761 return 0; 762 } 763 764 switch (ufsmount.um_fstype) { 765 case UFS1: 766 if (!KVM_READ(inode.i_din.ffs1_din, &dip, 767 sizeof(struct ufs1_dinode))) { 768 dprintf("can't read dinode at %p for pid %d", 769 inode.i_din.ffs1_din, Pid); 770 return 0; 771 } 772 fsp->rdev = dip.dp1.di_rdev; 773 break; 774 case UFS2: 775 if (!KVM_READ(inode.i_din.ffs2_din, &dip, 776 sizeof(struct ufs2_dinode))) { 777 dprintf("can't read dinode at %p for pid %d", 778 inode.i_din.ffs2_din, Pid); 779 return 0; 780 } 781 fsp->rdev = dip.dp2.di_rdev; 782 break; 783 default: 784 dprintf("unknown ufs type %ld for pid %d", 785 ufsmount.um_fstype, Pid); 786 break; 787 } 788 fsp->fsid = inode.i_dev & 0xffff; 789 fsp->fileid = inode.i_number; 790 fsp->mode = (mode_t)inode.i_mode; 791 fsp->size = inode.i_size; 792 793 return 1; 794 } 795 796 static int 797 ext2fs_filestat(struct vnode *vp, struct filestat *fsp) 798 { 799 struct inode inode; 800 struct ext2fs_dinode dinode; 801 802 if (!KVM_READ(VTOI(vp), &inode, sizeof (inode))) { 803 dprintf("can't read inode at %p for pid %d", VTOI(vp), Pid); 804 return 0; 805 } 806 fsp->fsid = inode.i_dev & 0xffff; 807 fsp->fileid = inode.i_number; 808 809 if (!KVM_READ(inode.i_din.e2fs_din, &dinode, sizeof dinode)) { 810 dprintf("can't read ext2fs_dinode at %p for pid %d", 811 inode.i_din.e2fs_din, Pid); 812 return 0; 813 } 814 fsp->mode = dinode.e2di_mode; 815 fsp->size = dinode.e2di_size; 816 fsp->rdev = dinode.e2di_rdev; 817 818 return 1; 819 } 820 821 static int 822 nfs_filestat(struct vnode *vp, struct filestat *fsp) 823 { 824 struct nfsnode nfsnode; 825 struct vattr va; 826 827 if (!KVM_READ(VTONFS(vp), &nfsnode, sizeof (nfsnode))) { 828 dprintf("can't read nfsnode at %p for pid %d", VTONFS(vp), 829 Pid); 830 return 0; 831 } 832 if (!KVM_READ(nfsnode.n_vattr, &va, sizeof(va))) { 833 dprintf("can't read vnode attributes at %p for pid %d", 834 nfsnode.n_vattr, Pid); 835 return 0; 836 } 837 fsp->fsid = va.va_fsid; 838 fsp->fileid = va.va_fileid; 839 fsp->size = nfsnode.n_size; 840 fsp->rdev = va.va_rdev; 841 fsp->mode = (mode_t)va.va_mode | getftype(vp->v_type); 842 843 return 1; 844 } 845 846 static int 847 msdosfs_filestat(struct vnode *vp, struct filestat *fsp) 848 { 849 struct denode de; 850 struct msdosfsmount mp; 851 852 if (!KVM_READ(VTONFS(vp), &de, sizeof(de))) { 853 dprintf("can't read denode at %p for pid %d", VTONFS(vp), 854 Pid); 855 return 0; 856 } 857 if (!KVM_READ(de.de_pmp, &mp, sizeof(mp))) { 858 dprintf("can't read mount struct at %p for pid %d", de.de_pmp, 859 Pid); 860 return 0; 861 } 862 863 fsp->fsid = de.de_dev & 0xffff; 864 fsp->fileid = 0; /* XXX see msdosfs_vptofh() for more info */ 865 fsp->size = de.de_FileSize; 866 fsp->rdev = 0; /* msdosfs doesn't support device files */ 867 fsp->mode = (0777 & mp.pm_mask) | getftype(vp->v_type); 868 return 1; 869 } 870 871 static const char * 872 layer_filestat(struct vnode *vp, struct filestat *fsp) 873 { 874 struct layer_node layer_node; 875 struct mount mount; 876 struct vnode vn; 877 const char *badtype; 878 879 if (!KVM_READ(VTOLAYER(vp), &layer_node, sizeof(layer_node))) { 880 dprintf("can't read layer_node at %p for pid %d", 881 VTOLAYER(vp), Pid); 882 return "error"; 883 } 884 if (!KVM_READ(vp->v_mount, &mount, sizeof(struct mount))) { 885 dprintf("can't read mount struct at %p for pid %d", 886 vp->v_mount, Pid); 887 return "error"; 888 } 889 vp = layer_node.layer_lowervp; 890 if (!KVM_READ(vp, &vn, sizeof(struct vnode))) { 891 dprintf("can't read vnode at %p for pid %d", vp, Pid); 892 return "error"; 893 } 894 if ((badtype = vfilestat(&vn, fsp)) == NULL) 895 fsp->fsid = mount.mnt_stat.f_fsidx.__fsid_val[0]; 896 return badtype; 897 } 898 899 static char * 900 getmnton(struct mount *m) 901 { 902 static struct mount mount; 903 static struct mtab { 904 struct mtab *next; 905 struct mount *m; 906 char mntonname[MNAMELEN]; 907 } *mhead = NULL; 908 struct mtab *mt; 909 910 for (mt = mhead; mt != NULL; mt = mt->next) 911 if (m == mt->m) 912 return mt->mntonname; 913 if (!KVM_READ(m, &mount, sizeof(struct mount))) { 914 warnx("can't read mount table at %p", m); 915 return NULL; 916 } 917 if ((mt = malloc(sizeof (struct mtab))) == NULL) { 918 err(1, "malloc(%u)", (unsigned int)sizeof(struct mtab)); 919 } 920 mt->m = m; 921 (void)memmove(&mt->mntonname[0], &mount.mnt_stat.f_mntonname[0], 922 MNAMELEN); 923 mt->next = mhead; 924 mhead = mt; 925 return mt->mntonname; 926 } 927 928 static const char * 929 inet_addrstr(char *buf, size_t len, const struct in_addr *a, uint16_t p, bool isdg) 930 { 931 char addr[256], serv[256]; 932 struct sockaddr_in sin; 933 const int niflags = 934 (nflg ? (NI_NUMERICHOST|NI_NUMERICSERV) : 0) | 935 (isdg ? NI_DGRAM : 0); 936 937 938 (void)memset(&sin, 0, sizeof(sin)); 939 sin.sin_family = AF_INET; 940 sin.sin_len = sizeof(sin); 941 sin.sin_addr = *a; 942 sin.sin_port = htons(p); 943 944 serv[0] = '\0'; 945 946 if (getnameinfo((struct sockaddr *)&sin, sin.sin_len, 947 addr, sizeof(addr), serv, sizeof(serv), niflags)) { 948 if (inet_ntop(AF_INET, a, addr, sizeof(addr)) == NULL) 949 strlcpy(addr, "invalid", sizeof(addr)); 950 } 951 952 if (serv[0] == '\0') 953 snprintf(serv, sizeof(serv), "%u", p); 954 955 if (a->s_addr == INADDR_ANY) { 956 if (p == 0) 957 buf[0] = '\0'; 958 else 959 snprintf(buf, len, "*:%s", serv); 960 return buf; 961 } 962 963 snprintf(buf, len, "%s:%s", addr, serv); 964 return buf; 965 } 966 967 #ifdef INET6 968 static const char * 969 inet6_addrstr(char *buf, size_t len, const struct in6_addr *a, uint16_t p, bool isdg) 970 { 971 char addr[256], serv[256]; 972 struct sockaddr_in6 sin6; 973 const int niflags = 974 (nflg ? (NI_NUMERICHOST|NI_NUMERICSERV) : 0) | 975 (isdg ? NI_DGRAM : 0); 976 977 (void)memset(&sin6, 0, sizeof(sin6)); 978 sin6.sin6_family = AF_INET6; 979 sin6.sin6_len = sizeof(sin6); 980 sin6.sin6_addr = *a; 981 sin6.sin6_port = htons(p); 982 983 inet6_getscopeid(&sin6, INET6_IS_ADDR_LINKLOCAL); 984 serv[0] = '\0'; 985 986 if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, 987 addr, sizeof(addr), serv, sizeof(serv), niflags)) { 988 if (inet_ntop(AF_INET6, a, addr, sizeof(addr)) == NULL) 989 strlcpy(addr, "invalid", sizeof(addr)); 990 } 991 992 if (serv[0] == '\0') 993 snprintf(serv, sizeof(serv), "%u", p); 994 995 if (IN6_IS_ADDR_UNSPECIFIED(a)) { 996 if (p == 0) 997 buf[0] = '\0'; 998 else 999 snprintf(buf, len, "*:%s", serv); 1000 return buf; 1001 } 1002 1003 if (strchr(addr, ':') == NULL) 1004 snprintf(buf, len, "%s:%s", addr, serv); 1005 else 1006 snprintf(buf, len, "[%s]:%s", addr, serv); 1007 1008 return buf; 1009 } 1010 #endif 1011 1012 static const char * 1013 at_addrstr(char *buf, size_t len, const struct sockaddr_at *sat) 1014 { 1015 const struct netrange *nr = &sat->sat_range.r_netrange; 1016 const struct at_addr *at = &sat->sat_addr; 1017 char addr[64], phase[64], range[64]; 1018 1019 if (sat->sat_port || at->s_net || at->s_node) { 1020 if (at->s_net || at->s_node) 1021 snprintf(addr, sizeof(addr), "%u.%u:%u", 1022 ntohs(at->s_net), at->s_node, sat->sat_port); 1023 else 1024 snprintf(addr, sizeof(addr), "*:%u", sat->sat_port); 1025 } else 1026 addr[0] = '\0'; 1027 1028 if (nr->nr_phase) 1029 snprintf(phase, sizeof(phase), " phase %u", nr->nr_phase); 1030 else 1031 phase[0] = '\0'; 1032 1033 if (nr->nr_firstnet || nr->nr_lastnet) 1034 snprintf(range, sizeof(range), " range [%u-%u]", 1035 ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet)); 1036 else 1037 range[0] = '\0'; 1038 1039 snprintf(buf, len, "%s%s%s", addr, phase, range); 1040 return buf; 1041 } 1042 1043 static void 1044 socktrans(struct file *f, struct socket *sock, int i) 1045 { 1046 static const char *stypename[] = { 1047 "unused", /* 0 */ 1048 "stream", /* 1 */ 1049 "dgram", /* 2 */ 1050 "raw", /* 3 */ 1051 "rdm", /* 4 */ 1052 "seqpak" /* 5 */ 1053 }; 1054 #define STYPEMAX 5 1055 struct socket so; 1056 struct protosw proto; 1057 struct domain dom; 1058 struct inpcb inpcb; 1059 #ifdef INET6 1060 struct in6pcb in6pcb; 1061 #endif 1062 struct unpcb unpcb; 1063 struct ddpcb ddpcb; 1064 int len; 1065 char dname[32]; 1066 char lbuf[512], fbuf[512], pbuf[24]; 1067 bool isdgram; 1068 1069 pbuf[0] = '\0'; 1070 /* fill in socket */ 1071 if (!KVM_READ(sock, &so, sizeof(struct socket))) { 1072 dprintf("can't read sock at %p", sock); 1073 goto bad; 1074 } 1075 1076 /* fill in protosw entry */ 1077 if (!KVM_READ(so.so_proto, &proto, sizeof(struct protosw))) { 1078 dprintf("can't read protosw at %p", so.so_proto); 1079 goto bad; 1080 } 1081 1082 /* fill in domain */ 1083 if (!KVM_READ(proto.pr_domain, &dom, sizeof(struct domain))) { 1084 dprintf("can't read domain at %p", proto.pr_domain); 1085 goto bad; 1086 } 1087 1088 if (checkfile && dom.dom_family != AF_LOCAL) 1089 return; 1090 1091 if ((len = kvm_read(kd, (u_long)dom.dom_name, dname, 1092 sizeof(dname) - 1)) != sizeof(dname) -1) { 1093 dprintf("can't read domain name at %p", dom.dom_name); 1094 dname[0] = '\0'; 1095 } 1096 else 1097 dname[len] = '\0'; 1098 1099 /* 1100 * protocol specific formatting 1101 * 1102 * Try to find interesting things to print. For TCP, the interesting 1103 * thing is the address of the tcpcb, for UDP and others, just the 1104 * inpcb (socket pcb). For UNIX domain, its the address of the socket 1105 * pcb and the address of the connected pcb (if connected). Otherwise 1106 * just print the protocol number and address of the socket itself. 1107 * The idea is not to duplicate netstat, but to make available enough 1108 * information for further analysis. 1109 */ 1110 fbuf[0] = '\0'; 1111 lbuf[0] = '\0'; 1112 isdgram = false; 1113 switch(dom.dom_family) { 1114 case AF_INET: 1115 getinetproto(pbuf, sizeof(pbuf), proto.pr_protocol); 1116 switch (proto.pr_protocol) { 1117 case IPPROTO_UDP: 1118 isdgram = true; 1119 /* FALLTHROUGH */ 1120 case IPPROTO_TCP: 1121 if (so.so_pcb == NULL) 1122 break; 1123 if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb, 1124 sizeof(inpcb)) != sizeof(inpcb)) { 1125 dprintf("can't read inpcb at %p", so.so_pcb); 1126 goto bad; 1127 } 1128 inet_addrstr(lbuf, sizeof(lbuf), &inpcb.inp_laddr, 1129 ntohs(inpcb.inp_lport), isdgram); 1130 inet_addrstr(fbuf, sizeof(fbuf), &inpcb.inp_faddr, 1131 ntohs(inpcb.inp_fport), isdgram); 1132 break; 1133 default: 1134 break; 1135 } 1136 break; 1137 #ifdef INET6 1138 case AF_INET6: 1139 getinetproto(pbuf, sizeof(pbuf), proto.pr_protocol); 1140 switch (proto.pr_protocol) { 1141 case IPPROTO_UDP: 1142 isdgram = true; 1143 /* FALLTHROUGH */ 1144 case IPPROTO_TCP: 1145 if (so.so_pcb == NULL) 1146 break; 1147 if (kvm_read(kd, (u_long)so.so_pcb, (char *)&in6pcb, 1148 sizeof(in6pcb)) != sizeof(in6pcb)) { 1149 dprintf("can't read in6pcb at %p", so.so_pcb); 1150 goto bad; 1151 } 1152 inet6_addrstr(lbuf, sizeof(lbuf), &in6pcb.in6p_laddr, 1153 ntohs(in6pcb.in6p_lport), isdgram); 1154 inet6_addrstr(fbuf, sizeof(fbuf), &in6pcb.in6p_faddr, 1155 ntohs(in6pcb.in6p_fport), isdgram); 1156 break; 1157 default: 1158 break; 1159 } 1160 break; 1161 #endif 1162 case AF_LOCAL: 1163 /* print address of pcb and connected pcb */ 1164 if (so.so_pcb) { 1165 char shoconn[4], *cp; 1166 void *pcb[2]; 1167 size_t p = 0; 1168 1169 pcb[0] = so.so_pcb; 1170 1171 cp = shoconn; 1172 if (!(so.so_state & SS_CANTRCVMORE)) 1173 *cp++ = '<'; 1174 *cp++ = '-'; 1175 if (!(so.so_state & SS_CANTSENDMORE)) 1176 *cp++ = '>'; 1177 *cp = '\0'; 1178 again: 1179 if (kvm_read(kd, (u_long)pcb[p], (char *)&unpcb, 1180 sizeof(struct unpcb)) != sizeof(struct unpcb)){ 1181 dprintf("can't read unpcb at %p", so.so_pcb); 1182 goto bad; 1183 } 1184 if (checkfile) { 1185 struct vnode vn; 1186 struct filestat fst; 1187 const char *badtype, *filename; 1188 if (unpcb.unp_vnode == NULL) 1189 return; 1190 if (!checkfs(unpcb.unp_vnode, &vn, &fst, 1191 &badtype, &filename)) 1192 return; 1193 } 1194 1195 if (unpcb.unp_addr) { 1196 struct sockaddr_un *sun = 1197 malloc(unpcb.unp_addrlen); 1198 if (sun == NULL) 1199 err(1, "malloc(%zu)", 1200 unpcb.unp_addrlen); 1201 if (kvm_read(kd, (u_long)unpcb.unp_addr, 1202 sun, unpcb.unp_addrlen) != 1203 (ssize_t)unpcb.unp_addrlen) { 1204 dprintf("can't read sun at %p", 1205 unpcb.unp_addr); 1206 free(sun); 1207 } else { 1208 snprintf(fbuf, sizeof(fbuf), " %s %s %s", 1209 shoconn, sun->sun_path, 1210 p == 0 ? "[creat]" : "[using]"); 1211 free(sun); 1212 break; 1213 } 1214 } 1215 if (unpcb.unp_conn) { 1216 if (p == 0) { 1217 pcb[++p] = unpcb.unp_conn; 1218 goto again; 1219 } else 1220 snprintf(fbuf, sizeof(fbuf), 1221 " %p %s %p", pcb[0], shoconn, 1222 pcb[1]); 1223 } 1224 } 1225 break; 1226 case AF_APPLETALK: 1227 getatproto(pbuf, sizeof(pbuf), proto.pr_protocol); 1228 if (so.so_pcb) { 1229 if (kvm_read(kd, (u_long)so.so_pcb, (char *)&ddpcb, 1230 sizeof(ddpcb)) != sizeof(ddpcb)){ 1231 dprintf("can't read ddpcb at %p", so.so_pcb); 1232 goto bad; 1233 } 1234 at_addrstr(fbuf, sizeof(fbuf), &ddpcb.ddp_fsat); 1235 at_addrstr(lbuf, sizeof(lbuf), &ddpcb.ddp_lsat); 1236 } 1237 break; 1238 default: 1239 /* print protocol number and socket address */ 1240 snprintf(fbuf, sizeof(fbuf), " %d %jx", proto.pr_protocol, 1241 (uintmax_t)(uintptr_t)sock); 1242 break; 1243 } 1244 PREFIX(i); 1245 if ((u_short)so.so_type > STYPEMAX) 1246 (void)printf("* %s ?%d", dname, so.so_type); 1247 else 1248 (void)printf("* %s %s", dname, stypename[so.so_type]); 1249 1250 if (pbuf[0]) 1251 printf("%s", pbuf); 1252 if (fbuf[0] || lbuf[0]) 1253 printf(" %s%s%s", fbuf, (fbuf[0] && lbuf[0]) ? " <-> " : "", 1254 lbuf); 1255 else if (so.so_pcb) 1256 printf(" %jx", (uintmax_t)(uintptr_t)so.so_pcb); 1257 oprint(f, "\n"); 1258 return; 1259 bad: 1260 (void)printf("* error\n"); 1261 } 1262 1263 static void 1264 ptrans(struct file *fp, struct pipe *cpipe, int i) 1265 { 1266 struct pipe cp; 1267 1268 PREFIX(i); 1269 1270 /* fill in pipe */ 1271 if (!KVM_READ(cpipe, &cp, sizeof(struct pipe))) { 1272 dprintf("can't read pipe at %p", cpipe); 1273 goto bad; 1274 } 1275 1276 /* pipe descriptor is either read or write, never both */ 1277 (void)printf("* pipe %p %s %p %s%s%s", cpipe, 1278 (fp->f_flag & FWRITE) ? "->" : "<-", 1279 cp.pipe_peer, 1280 (fp->f_flag & FWRITE) ? "w" : "r", 1281 (fp->f_flag & FNONBLOCK) ? "n" : "", 1282 (cp.pipe_state & PIPE_ASYNC) ? "a" : ""); 1283 oprint(fp, "\n"); 1284 return; 1285 bad: 1286 (void)printf("* error\n"); 1287 } 1288 1289 static void 1290 misctrans(struct file *file, int i) 1291 { 1292 1293 PREFIX(i); 1294 pmisc(file, dtypes[file->f_type]); 1295 } 1296 1297 /* 1298 * getinetproto -- 1299 * print name of protocol number 1300 */ 1301 static void 1302 getinetproto(char *buf, size_t len, int number) 1303 { 1304 const char *cp; 1305 1306 switch (number) { 1307 case IPPROTO_IP: 1308 cp = "ip"; break; 1309 case IPPROTO_ICMP: 1310 cp ="icmp"; break; 1311 case IPPROTO_GGP: 1312 cp ="ggp"; break; 1313 case IPPROTO_TCP: 1314 cp ="tcp"; break; 1315 case IPPROTO_EGP: 1316 cp ="egp"; break; 1317 case IPPROTO_PUP: 1318 cp ="pup"; break; 1319 case IPPROTO_UDP: 1320 cp ="udp"; break; 1321 case IPPROTO_IDP: 1322 cp ="idp"; break; 1323 case IPPROTO_RAW: 1324 cp ="raw"; break; 1325 case IPPROTO_ICMPV6: 1326 cp ="icmp6"; break; 1327 default: 1328 (void)snprintf(buf, len, " %d", number); 1329 return; 1330 } 1331 (void)snprintf(buf, len, " %s", cp); 1332 } 1333 1334 /* 1335 * getatproto -- 1336 * print name of protocol number 1337 */ 1338 static void 1339 getatproto(char *buf, size_t len, int number) 1340 { 1341 const char *cp; 1342 1343 switch (number) { 1344 case ATPROTO_DDP: 1345 cp = "ddp"; break; 1346 case ATPROTO_AARP: 1347 cp ="aarp"; break; 1348 default: 1349 (void)snprintf(buf, len, " %d", number); 1350 return; 1351 } 1352 (void)snprintf(buf, len, " %s", cp); 1353 } 1354 1355 static int 1356 getfname(const char *filename) 1357 { 1358 struct stat statbuf; 1359 DEVS *cur; 1360 1361 if (stat(filename, &statbuf)) { 1362 warn("stat(%s)", filename); 1363 return 0; 1364 } 1365 if ((cur = malloc(sizeof(*cur))) == NULL) { 1366 err(1, "malloc(%zu)", sizeof(*cur)); 1367 } 1368 cur->next = devs; 1369 devs = cur; 1370 1371 cur->ino = statbuf.st_ino; 1372 cur->fsid = statbuf.st_dev & 0xffff; 1373 cur->name = filename; 1374 return 1; 1375 } 1376 1377 mode_t 1378 getftype(enum vtype v_type) 1379 { 1380 mode_t ftype; 1381 1382 switch (v_type) { 1383 case VREG: 1384 ftype = S_IFREG; 1385 break; 1386 case VDIR: 1387 ftype = S_IFDIR; 1388 break; 1389 case VBLK: 1390 ftype = S_IFBLK; 1391 break; 1392 case VCHR: 1393 ftype = S_IFCHR; 1394 break; 1395 case VLNK: 1396 ftype = S_IFLNK; 1397 break; 1398 case VSOCK: 1399 ftype = S_IFSOCK; 1400 break; 1401 case VFIFO: 1402 ftype = S_IFIFO; 1403 break; 1404 default: 1405 ftype = 0; 1406 break; 1407 }; 1408 1409 return ftype; 1410 } 1411 1412 static void 1413 usage(void) 1414 { 1415 (void)fprintf(stderr, "Usage: %s [-Afnv] [-M core] [-N system] " 1416 "[-p pid] [-u user] [file ...]\n", getprogname()); 1417 exit(1); 1418 } 1419