1 /*- 2 * Copyright (c) 2006-2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #include <sys/param.h> 30 #include <sys/types.h> 31 #include <sys/stat.h> 32 #include <sys/socket.h> 33 #include <sys/un.h> 34 #ifndef makedev 35 #include <sys/mkdev.h> 36 #endif 37 38 #include <assert.h> 39 #include <ctype.h> 40 #include <errno.h> 41 #include <fcntl.h> 42 #include <grp.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include <unistd.h> 47 48 #ifndef HAS_TRUNCATE64 49 #define truncate64 truncate 50 #define ftruncate64 ftruncate 51 #endif 52 #ifndef HAS_STAT64 53 #define stat64 stat 54 #define fstat64 fstat 55 #define lstat64 lstat 56 #endif 57 #ifdef HAS_FREEBSD_ACL 58 #include <sys/acl.h> 59 #endif 60 61 #ifndef ALLPERMS 62 #define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) 63 #endif 64 65 enum action { 66 ACTION_OPEN, 67 ACTION_OPENAT, 68 ACTION_CREATE, 69 ACTION_UNLINK, 70 ACTION_UNLINKAT, 71 ACTION_MKDIR, 72 ACTION_MKDIRAT, 73 ACTION_RMDIR, 74 ACTION_LINK, 75 ACTION_LINKAT, 76 ACTION_SYMLINK, 77 ACTION_SYMLINKAT, 78 ACTION_RENAME, 79 ACTION_RENAMEAT, 80 ACTION_MKFIFO, 81 ACTION_MKFIFOAT, 82 ACTION_MKNOD, 83 ACTION_MKNODAT, 84 ACTION_BIND, 85 #ifdef HAS_BINDAT 86 ACTION_BINDAT, 87 #endif 88 ACTION_CONNECT, 89 #ifdef HAS_CONNECTAT 90 ACTION_CONNECTAT, 91 #endif 92 ACTION_CHMOD, 93 ACTION_FCHMOD, 94 #ifdef HAS_LCHMOD 95 ACTION_LCHMOD, 96 #endif 97 ACTION_FCHMODAT, 98 ACTION_CHOWN, 99 ACTION_FCHOWN, 100 ACTION_LCHOWN, 101 ACTION_FCHOWNAT, 102 #ifdef HAS_CHFLAGS 103 ACTION_CHFLAGS, 104 #endif 105 #ifdef HAS_FCHFLAGS 106 ACTION_FCHFLAGS, 107 #endif 108 #ifdef HAS_CHFLAGSAT 109 ACTION_CHFLAGSAT, 110 #endif 111 #ifdef HAS_LCHFLAGS 112 ACTION_LCHFLAGS, 113 #endif 114 ACTION_TRUNCATE, 115 ACTION_FTRUNCATE, 116 ACTION_STAT, 117 ACTION_FSTAT, 118 ACTION_LSTAT, 119 ACTION_FSTATAT, 120 ACTION_PATHCONF, 121 ACTION_FPATHCONF, 122 #ifdef HAS_LPATHCONF 123 ACTION_LPATHCONF, 124 #endif 125 #ifdef HAS_FREEBSD_ACL 126 ACTION_PREPENDACL, 127 ACTION_READACL, 128 #endif 129 ACTION_WRITE, 130 }; 131 132 #define TYPE_NONE 0x0000 133 #define TYPE_STRING 0x0001 134 #define TYPE_NUMBER 0x0002 135 #define TYPE_DESCRIPTOR 0x0003 136 #define TYPE_MASK 0x000f 137 138 #define TYPE_OPTIONAL 0x0100 139 140 #define MAX_ARGS 8 141 142 struct syscall_desc { 143 const char *sd_name; 144 enum action sd_action; 145 int sd_args[MAX_ARGS]; 146 }; 147 148 static struct syscall_desc syscalls[] = { 149 { "open", ACTION_OPEN, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } }, 150 { "openat", ACTION_OPENAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } }, 151 { "create", ACTION_CREATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, 152 { "unlink", ACTION_UNLINK, { TYPE_STRING, TYPE_NONE } }, 153 { "unlinkat", ACTION_UNLINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 154 { "mkdir", ACTION_MKDIR, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, 155 { "mkdirat", ACTION_MKDIRAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, 156 { "rmdir", ACTION_RMDIR, { TYPE_STRING, TYPE_NONE } }, 157 { "link", ACTION_LINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 158 { "linkat", ACTION_LINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 159 { "symlink", ACTION_SYMLINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 160 { "symlinkat", ACTION_SYMLINKAT, { TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, 161 { "rename", ACTION_RENAME, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 162 { "renameat", ACTION_RENAMEAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, 163 { "mkfifo", ACTION_MKFIFO, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, 164 { "mkfifoat", ACTION_MKFIFOAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, 165 { "mknod", ACTION_MKNOD, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} }, 166 { "mknodat", ACTION_MKNODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} }, 167 { "bind", ACTION_BIND, { TYPE_STRING, TYPE_NONE } }, 168 #ifdef HAS_BINDAT 169 { "bindat", ACTION_BINDAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, 170 #endif 171 { "connect", ACTION_CONNECT, { TYPE_STRING, TYPE_NONE } }, 172 #ifdef HAS_CONNECTAT 173 { "connectat", ACTION_CONNECTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, 174 #endif 175 { "chmod", ACTION_CHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, 176 { "fchmod", ACTION_FCHMOD, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } }, 177 #ifdef HAS_LCHMOD 178 { "lchmod", ACTION_LCHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, 179 #endif 180 { "fchmodat", ACTION_FCHMODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } }, 181 { "chown", ACTION_CHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, 182 { "fchown", ACTION_FCHOWN, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, 183 { "lchown", ACTION_LCHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } }, 184 { "fchownat", ACTION_FCHOWNAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } }, 185 #ifdef HAS_CHFLAGS 186 { "chflags", ACTION_CHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 187 #endif 188 #ifdef HAS_FCHFLAGS 189 { "fchflags", ACTION_FCHFLAGS, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, 190 #endif 191 #ifdef HAS_CHFLAGSAT 192 { "chflagsat", ACTION_CHFLAGSAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 193 #endif 194 #ifdef HAS_LCHFLAGS 195 { "lchflags", ACTION_LCHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 196 #endif 197 { "truncate", ACTION_TRUNCATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } }, 198 { "ftruncate", ACTION_FTRUNCATE, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } }, 199 { "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 200 { "fstat", ACTION_FSTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, 201 { "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 202 { "fstatat", ACTION_FSTATAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 203 { "pathconf", ACTION_PATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 204 { "fpathconf", ACTION_FPATHCONF, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, 205 #ifdef HAS_LPATHCONF 206 { "lpathconf", ACTION_LPATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 207 #endif 208 #ifdef HAS_FREEBSD_ACL 209 { "prependacl", ACTION_PREPENDACL, { TYPE_STRING, TYPE_STRING, TYPE_NONE } }, 210 { "readacl", ACTION_READACL, { TYPE_STRING, TYPE_NONE } }, 211 #endif 212 { "write", ACTION_WRITE, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } }, 213 { NULL, -1, { TYPE_NONE } } 214 }; 215 216 struct flag { 217 long long f_flag; 218 const char *f_str; 219 }; 220 221 static struct flag open_flags[] = { 222 #ifdef O_RDONLY 223 { O_RDONLY, "O_RDONLY" }, 224 #endif 225 #ifdef O_WRONLY 226 { O_WRONLY, "O_WRONLY" }, 227 #endif 228 #ifdef O_RDWR 229 { O_RDWR, "O_RDWR" }, 230 #endif 231 #ifdef O_NONBLOCK 232 { O_NONBLOCK, "O_NONBLOCK" }, 233 #endif 234 #ifdef O_APPEND 235 { O_APPEND, "O_APPEND" }, 236 #endif 237 #ifdef O_CREAT 238 { O_CREAT, "O_CREAT" }, 239 #endif 240 #ifdef O_TRUNC 241 { O_TRUNC, "O_TRUNC" }, 242 #endif 243 #ifdef O_EXCL 244 { O_EXCL, "O_EXCL" }, 245 #endif 246 #ifdef O_SHLOCK 247 { O_SHLOCK, "O_SHLOCK" }, 248 #endif 249 #ifdef O_EXLOCK 250 { O_EXLOCK, "O_EXLOCK" }, 251 #endif 252 #ifdef O_DIRECT 253 { O_DIRECT, "O_DIRECT" }, 254 #endif 255 #ifdef O_FSYNC 256 { O_FSYNC, "O_FSYNC" }, 257 #endif 258 #ifdef O_SYNC 259 { O_SYNC, "O_SYNC" }, 260 #endif 261 #ifdef O_NOFOLLOW 262 { O_NOFOLLOW, "O_NOFOLLOW" }, 263 #endif 264 #ifdef O_NOCTTY 265 { O_NOCTTY, "O_NOCTTY" }, 266 #endif 267 #ifdef O_DIRECTORY 268 { O_DIRECTORY, "O_DIRECTORY" }, 269 #endif 270 { 0, NULL } 271 }; 272 273 #ifdef HAS_CHFLAGS 274 static struct flag chflags_flags[] = { 275 #ifdef UF_NODUMP 276 { UF_NODUMP, "UF_NODUMP" }, 277 #endif 278 #ifdef UF_IMMUTABLE 279 { UF_IMMUTABLE, "UF_IMMUTABLE" }, 280 #endif 281 #ifdef UF_APPEND 282 { UF_APPEND, "UF_APPEND" }, 283 #endif 284 #ifdef UF_NOUNLINK 285 { UF_NOUNLINK, "UF_NOUNLINK" }, 286 #endif 287 #ifdef UF_OPAQUE 288 { UF_OPAQUE, "UF_OPAQUE" }, 289 #endif 290 #ifdef SF_ARCHIVED 291 { SF_ARCHIVED, "SF_ARCHIVED" }, 292 #endif 293 #ifdef SF_IMMUTABLE 294 { SF_IMMUTABLE, "SF_IMMUTABLE" }, 295 #endif 296 #ifdef SF_APPEND 297 { SF_APPEND, "SF_APPEND" }, 298 #endif 299 #ifdef SF_NOUNLINK 300 { SF_NOUNLINK, "SF_NOUNLINK" }, 301 #endif 302 #ifdef SF_SNAPSHOT 303 { SF_SNAPSHOT, "SF_SNAPSHOT" }, 304 #endif 305 { 0, NULL } 306 }; 307 #endif 308 309 static struct flag unlinkat_flags[] = { 310 { AT_REMOVEDIR, "AT_REMOVEDIR" }, 311 { 0, NULL } 312 }; 313 314 static struct flag linkat_flags[] = { 315 { AT_SYMLINK_FOLLOW, "AT_SYMLINK_FOLLOW" }, 316 { 0, NULL } 317 }; 318 319 static struct flag chflagsat_flags[] = { 320 { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" }, 321 { 0, NULL } 322 }; 323 324 static struct flag fchmodat_flags[] = { 325 { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" }, 326 { 0, NULL } 327 }; 328 329 static struct flag fchownat_flags[] = { 330 { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" }, 331 { 0, NULL } 332 }; 333 334 static struct flag fstatat_flags[] = { 335 { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" }, 336 { 0, NULL } 337 }; 338 339 struct name { 340 int n_name; 341 const char *n_str; 342 }; 343 344 static struct name pathconf_names[] = { 345 #ifdef _PC_LINK_MAX 346 { _PC_LINK_MAX, "_PC_LINK_MAX" }, 347 #endif 348 #ifdef _PC_NAME_MAX 349 { _PC_NAME_MAX, "_PC_NAME_MAX" }, 350 #endif 351 #ifdef _PC_PATH_MAX 352 { _PC_PATH_MAX, "_PC_PATH_MAX" }, 353 #endif 354 #ifdef _PC_SYMLINK_MAX 355 { _PC_SYMLINK_MAX, "_PC_SYMLINK_MAX" }, 356 #endif 357 { 0, NULL } 358 }; 359 360 static const char *err2str(int error); 361 362 static int *descriptors; 363 static int ndescriptors; 364 365 static void 366 usage(void) 367 { 368 369 fprintf(stderr, "usage: pjdfstest [-U umask] [-u uid] [-g gid1[,gid2[...]]] syscall args ...\n"); 370 exit(1); 371 } 372 373 static long long 374 str2flags(struct flag *tflags, char *sflags) 375 { 376 long long flags = 0; 377 unsigned int i; 378 char *f; 379 380 /* 'none' or '0' means no flags */ 381 if (strcmp(sflags, "none") == 0 || strcmp(sflags, "0") == 0) 382 return (0); 383 for (f = strtok(sflags, ",|"); f != NULL; f = strtok(NULL, ",|")) { 384 for (i = 0; tflags[i].f_str != NULL; i++) { 385 if (strcmp(tflags[i].f_str, f) == 0) 386 break; 387 } 388 if (tflags[i].f_str == NULL) { 389 fprintf(stderr, "unknown flag '%s'\n", f); 390 exit(1); 391 } 392 flags |= tflags[i].f_flag; 393 } 394 return (flags); 395 } 396 397 #ifdef HAS_CHFLAGS 398 static char * 399 flags2str(struct flag *tflags, long long flags) 400 { 401 static char sflags[1024]; 402 unsigned int i; 403 404 sflags[0] = '\0'; 405 for (i = 0; tflags[i].f_str != NULL; i++) { 406 if (flags & tflags[i].f_flag) { 407 if (sflags[0] != '\0') 408 strlcat(sflags, ",", sizeof(sflags)); 409 strlcat(sflags, tflags[i].f_str, sizeof(sflags)); 410 } 411 } 412 if (sflags[0] == '\0') 413 strlcpy(sflags, "none", sizeof(sflags)); 414 return (sflags); 415 } 416 #endif 417 418 static int 419 str2name(struct name *names, char *name) 420 { 421 unsigned int i; 422 423 for (i = 0; names[i].n_str != NULL; i++) { 424 if (strcmp(names[i].n_str, name) == 0) 425 return (names[i].n_name); 426 } 427 return (-1); 428 } 429 430 static struct syscall_desc * 431 find_syscall(const char *name) 432 { 433 int i; 434 435 for (i = 0; syscalls[i].sd_name != NULL; i++) { 436 if (strcmp(syscalls[i].sd_name, name) == 0) 437 return (&syscalls[i]); 438 } 439 return (NULL); 440 } 441 442 static void 443 show_stat(struct stat64 *sp, const char *what) 444 { 445 446 if (strcmp(what, "mode") == 0) 447 printf("0%o", (unsigned int)(sp->st_mode & ALLPERMS)); 448 else if (strcmp(what, "inode") == 0) 449 printf("%lld", (long long)sp->st_ino); 450 else if (strcmp(what, "nlink") == 0) 451 printf("%lld", (long long)sp->st_nlink); 452 else if (strcmp(what, "uid") == 0) 453 printf("%d", (int)sp->st_uid); 454 else if (strcmp(what, "gid") == 0) 455 printf("%d", (int)sp->st_gid); 456 else if (strcmp(what, "size") == 0) 457 printf("%lld", (long long)sp->st_size); 458 else if (strcmp(what, "blocks") == 0) 459 printf("%lld", (long long)sp->st_blocks); 460 else if (strcmp(what, "atime") == 0) 461 printf("%lld", (long long)sp->st_atime); 462 else if (strcmp(what, "mtime") == 0) 463 printf("%lld", (long long)sp->st_mtime); 464 else if (strcmp(what, "ctime") == 0) 465 printf("%lld", (long long)sp->st_ctime); 466 #ifdef HAS_CHFLAGS 467 else if (strcmp(what, "flags") == 0) 468 printf("%s", flags2str(chflags_flags, (long long)sp->st_flags)); 469 #endif 470 else if (strcmp(what, "major") == 0) 471 printf("%u", (unsigned int)major(sp->st_rdev)); 472 else if (strcmp(what, "minor") == 0) 473 printf("%u", (unsigned int)minor(sp->st_rdev)); 474 else if (strcmp(what, "type") == 0) { 475 switch (sp->st_mode & S_IFMT) { 476 case S_IFIFO: 477 printf("fifo"); 478 break; 479 case S_IFCHR: 480 printf("char"); 481 break; 482 case S_IFDIR: 483 printf("dir"); 484 break; 485 case S_IFBLK: 486 printf("block"); 487 break; 488 case S_IFREG: 489 printf("regular"); 490 break; 491 case S_IFLNK: 492 printf("symlink"); 493 break; 494 case S_IFSOCK: 495 printf("socket"); 496 break; 497 default: 498 printf("unknown"); 499 break; 500 } 501 } else { 502 printf("unknown"); 503 } 504 } 505 506 static void 507 show_stats(struct stat64 *sp, char *what) 508 { 509 const char *s = ""; 510 char *w; 511 512 for (w = strtok(what, ","); w != NULL; w = strtok(NULL, ",")) { 513 printf("%s", s); 514 show_stat(sp, w); 515 s = ","; 516 } 517 printf("\n"); 518 } 519 520 static void 521 descriptor_add(int fd) 522 { 523 524 ndescriptors++; 525 if (descriptors == NULL) { 526 descriptors = malloc(sizeof(descriptors[0]) * ndescriptors); 527 } else { 528 descriptors = realloc(descriptors, 529 sizeof(descriptors[0]) * ndescriptors); 530 } 531 assert(descriptors != NULL); 532 descriptors[ndescriptors - 1] = fd; 533 } 534 535 static int 536 descriptor_get(int pos) 537 { 538 539 if (pos < 0 || pos >= ndescriptors) { 540 fprintf(stderr, "invalid descriptor %d\n", pos); 541 exit(1); 542 } 543 544 return (descriptors[pos]); 545 } 546 547 static unsigned int 548 call_syscall(struct syscall_desc *scall, char *argv[]) 549 { 550 struct stat64 sb; 551 long long flags; 552 unsigned int i; 553 char *endp; 554 int name, rval; 555 union { 556 char *str; 557 long long num; 558 } args[MAX_ARGS]; 559 #ifdef HAS_FREEBSD_ACL 560 int entry_id = ACL_FIRST_ENTRY; 561 acl_t acl, newacl; 562 acl_entry_t entry, newentry; 563 #endif 564 565 /* 566 * Verify correctness of the arguments. 567 */ 568 for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) { 569 if (scall->sd_args[i] == TYPE_NONE) { 570 if (argv[i] == NULL || strcmp(argv[i], ":") == 0) 571 break; 572 fprintf(stderr, "too many arguments [%s]\n", argv[i]); 573 exit(1); 574 } else { 575 if (argv[i] == NULL || strcmp(argv[i], ":") == 0) { 576 if (scall->sd_args[i] & TYPE_OPTIONAL) 577 break; 578 fprintf(stderr, "too few arguments\n"); 579 exit(1); 580 } 581 if ((scall->sd_args[i] & TYPE_MASK) == TYPE_STRING) { 582 if (strcmp(argv[i], "NULL") == 0) 583 args[i].str = NULL; 584 else if (strcmp(argv[i], "DEADCODE") == 0) 585 args[i].str = (void *)0xdeadc0de; 586 else 587 args[i].str = argv[i]; 588 } else if ((scall->sd_args[i] & TYPE_MASK) == 589 TYPE_NUMBER) { 590 args[i].num = strtoll(argv[i], &endp, 0); 591 if (*endp != '\0' && 592 !isspace((unsigned char)*endp)) { 593 fprintf(stderr, 594 "invalid argument %u, number expected [%s]\n", 595 i, endp); 596 exit(1); 597 } 598 } else if ((scall->sd_args[i] & TYPE_MASK) == 599 TYPE_DESCRIPTOR) { 600 if (strcmp(argv[i], "AT_FDCWD") == 0) { 601 args[i].num = AT_FDCWD; 602 } else if (strcmp(argv[i], "BADFD") == 0) { 603 /* In case AT_FDCWD is -1 on some systems... */ 604 if (AT_FDCWD == -1) 605 args[i].num = -2; 606 else 607 args[i].num = -1; 608 } else { 609 int pos; 610 611 pos = strtoll(argv[i], &endp, 0); 612 if (*endp != '\0' && 613 !isspace((unsigned char)*endp)) { 614 fprintf(stderr, 615 "invalid argument %u, number expected [%s]\n", 616 i, endp); 617 exit(1); 618 } 619 args[i].num = descriptor_get(pos); 620 } 621 } 622 } 623 } 624 /* 625 * Call the given syscall. 626 */ 627 #define NUM(n) (args[(n)].num) 628 #define STR(n) (args[(n)].str) 629 switch (scall->sd_action) { 630 case ACTION_OPEN: 631 flags = str2flags(open_flags, STR(1)); 632 if (flags & O_CREAT) { 633 if (i == 2) { 634 fprintf(stderr, "too few arguments\n"); 635 exit(1); 636 } 637 rval = open(STR(0), (int)flags, (mode_t)NUM(2)); 638 } else { 639 if (i == 3) { 640 fprintf(stderr, "too many arguments\n"); 641 exit(1); 642 } 643 rval = open(STR(0), (int)flags); 644 } 645 if (rval >= 0) 646 descriptor_add(rval); 647 break; 648 case ACTION_OPENAT: 649 flags = str2flags(open_flags, STR(2)); 650 if (flags & O_CREAT) { 651 if (i == 3) { 652 fprintf(stderr, "too few arguments\n"); 653 exit(1); 654 } 655 rval = openat(NUM(0), STR(1), (int)flags, 656 (mode_t)NUM(3)); 657 } else { 658 if (i == 4) { 659 fprintf(stderr, "too many arguments\n"); 660 exit(1); 661 } 662 rval = openat(NUM(0), STR(1), (int)flags); 663 } 664 if (rval >= 0) 665 descriptor_add(rval); 666 break; 667 case ACTION_CREATE: 668 rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1)); 669 if (rval >= 0) 670 close(rval); 671 break; 672 case ACTION_UNLINK: 673 rval = unlink(STR(0)); 674 break; 675 case ACTION_UNLINKAT: 676 rval = unlinkat(NUM(0), STR(1), 677 (int)str2flags(unlinkat_flags, STR(2))); 678 break; 679 case ACTION_MKDIR: 680 rval = mkdir(STR(0), (mode_t)NUM(1)); 681 break; 682 case ACTION_MKDIRAT: 683 rval = mkdirat(NUM(0), STR(1), (mode_t)NUM(2)); 684 break; 685 case ACTION_RMDIR: 686 rval = rmdir(STR(0)); 687 break; 688 case ACTION_LINK: 689 rval = link(STR(0), STR(1)); 690 break; 691 case ACTION_LINKAT: 692 rval = linkat(NUM(0), STR(1), NUM(2), STR(3), 693 (int)str2flags(linkat_flags, STR(4))); 694 break; 695 case ACTION_SYMLINK: 696 rval = symlink(STR(0), STR(1)); 697 break; 698 case ACTION_SYMLINKAT: 699 rval = symlinkat(STR(0), NUM(1), STR(2)); 700 break; 701 case ACTION_RENAME: 702 rval = rename(STR(0), STR(1)); 703 break; 704 case ACTION_RENAMEAT: 705 rval = renameat(NUM(0), STR(1), NUM(2), STR(3)); 706 break; 707 case ACTION_MKFIFO: 708 rval = mkfifo(STR(0), (mode_t)NUM(1)); 709 break; 710 case ACTION_MKFIFOAT: 711 rval = mkfifoat(NUM(0), STR(1), (mode_t)NUM(2)); 712 break; 713 case ACTION_MKNOD: 714 case ACTION_MKNODAT: 715 { 716 mode_t ntype; 717 dev_t dev; 718 int fa; 719 720 switch (scall->sd_action) { 721 case ACTION_MKNOD: 722 fa = 0; 723 break; 724 case ACTION_MKNODAT: 725 fa = 1; 726 break; 727 default: 728 abort(); 729 } 730 731 dev = makedev(NUM(fa + 3), NUM(fa + 4)); 732 if (strcmp(STR(fa + 1), "c") == 0) /* character device */ 733 ntype = S_IFCHR; 734 else if (strcmp(STR(fa + 1), "b") == 0) /* block device */ 735 ntype = S_IFBLK; 736 else if (strcmp(STR(fa + 1), "f") == 0) /* fifo special */ 737 ntype = S_IFIFO; 738 else if (strcmp(STR(fa + 1), "d") == 0) /* directory */ 739 ntype = S_IFDIR; 740 else if (strcmp(STR(fa + 1), "o") == 0) /* regular file */ 741 ntype = S_IFREG; 742 else { 743 fprintf(stderr, "wrong argument 1\n"); 744 exit(1); 745 } 746 switch (scall->sd_action) { 747 case ACTION_MKNOD: 748 rval = mknod(STR(0), ntype | NUM(2), dev); 749 break; 750 case ACTION_MKNODAT: 751 rval = mknodat(NUM(0), STR(1), ntype | NUM(3), dev); 752 break; 753 default: 754 abort(); 755 } 756 break; 757 } 758 case ACTION_BIND: 759 { 760 struct sockaddr_un sunx; 761 762 sunx.sun_family = AF_UNIX; 763 strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1); 764 sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0'; 765 rval = socket(AF_UNIX, SOCK_STREAM, 0); 766 if (rval < 0) 767 break; 768 rval = bind(rval, (struct sockaddr *)&sunx, sizeof(sunx)); 769 break; 770 } 771 #ifdef HAS_BINDAT 772 case ACTION_BINDAT: 773 { 774 struct sockaddr_un sunx; 775 776 sunx.sun_family = AF_UNIX; 777 strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1); 778 sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0'; 779 rval = socket(AF_UNIX, SOCK_STREAM, 0); 780 if (rval < 0) 781 break; 782 rval = bindat(NUM(0), rval, (struct sockaddr *)&sunx, 783 sizeof(sunx)); 784 break; 785 } 786 #endif 787 case ACTION_CONNECT: 788 { 789 struct sockaddr_un sunx; 790 791 sunx.sun_family = AF_UNIX; 792 strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1); 793 sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0'; 794 rval = socket(AF_UNIX, SOCK_STREAM, 0); 795 if (rval < 0) 796 break; 797 rval = connect(rval, (struct sockaddr *)&sunx, sizeof(sunx)); 798 break; 799 } 800 #ifdef HAS_CONNECTAT 801 case ACTION_CONNECTAT: 802 { 803 struct sockaddr_un sunx; 804 805 sunx.sun_family = AF_UNIX; 806 strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1); 807 sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0'; 808 rval = socket(AF_UNIX, SOCK_STREAM, 0); 809 if (rval < 0) 810 break; 811 rval = connectat(NUM(0), rval, (struct sockaddr *)&sunx, 812 sizeof(sunx)); 813 break; 814 } 815 #endif 816 case ACTION_CHMOD: 817 rval = chmod(STR(0), (mode_t)NUM(1)); 818 break; 819 case ACTION_FCHMOD: 820 rval = fchmod(NUM(0), (mode_t)NUM(1)); 821 break; 822 #ifdef HAS_LCHMOD 823 case ACTION_LCHMOD: 824 rval = lchmod(STR(0), (mode_t)NUM(1)); 825 break; 826 #endif 827 case ACTION_FCHMODAT: 828 rval = fchmodat(NUM(0), STR(1), (mode_t)NUM(2), 829 str2flags(fchmodat_flags, STR(3))); 830 break; 831 case ACTION_CHOWN: 832 rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2)); 833 break; 834 case ACTION_FCHOWN: 835 rval = fchown(NUM(0), (uid_t)NUM(1), (gid_t)NUM(2)); 836 break; 837 case ACTION_LCHOWN: 838 rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2)); 839 break; 840 case ACTION_FCHOWNAT: 841 rval = fchownat(NUM(0), STR(1), (uid_t)NUM(2), (gid_t)NUM(3), 842 (int)str2flags(fchownat_flags, STR(4))); 843 break; 844 #ifdef HAS_CHFLAGS 845 case ACTION_CHFLAGS: 846 rval = chflags(STR(0), 847 (unsigned long)str2flags(chflags_flags, STR(1))); 848 break; 849 #endif 850 #ifdef HAS_FCHFLAGS 851 case ACTION_FCHFLAGS: 852 rval = fchflags(NUM(0), 853 (unsigned long)str2flags(chflags_flags, STR(1))); 854 break; 855 #endif 856 #ifdef HAS_CHFLAGSAT 857 case ACTION_CHFLAGSAT: 858 rval = chflagsat(NUM(0), STR(1), 859 (unsigned long)str2flags(chflags_flags, STR(2)), 860 (int)str2flags(chflagsat_flags, STR(3))); 861 break; 862 #endif 863 #ifdef HAS_LCHFLAGS 864 case ACTION_LCHFLAGS: 865 rval = lchflags(STR(0), 866 (unsigned long)str2flags(chflags_flags, STR(1))); 867 break; 868 #endif 869 case ACTION_TRUNCATE: 870 rval = truncate64(STR(0), NUM(1)); 871 break; 872 case ACTION_FTRUNCATE: 873 rval = ftruncate64(NUM(0), NUM(1)); 874 break; 875 case ACTION_STAT: 876 rval = stat64(STR(0), &sb); 877 if (rval == 0) { 878 show_stats(&sb, STR(1)); 879 return (i); 880 } 881 break; 882 case ACTION_FSTAT: 883 rval = fstat64(NUM(0), &sb); 884 if (rval == 0) { 885 show_stats(&sb, STR(1)); 886 return (i); 887 } 888 break; 889 case ACTION_LSTAT: 890 rval = lstat64(STR(0), &sb); 891 if (rval == 0) { 892 show_stats(&sb, STR(1)); 893 return (i); 894 } 895 break; 896 case ACTION_FSTATAT: 897 rval = fstatat(NUM(0), STR(1), &sb, 898 (int)str2flags(fstatat_flags, STR(2))); 899 if (rval == 0) { 900 show_stats(&sb, STR(3)); 901 return (i); 902 } 903 break; 904 case ACTION_PATHCONF: 905 case ACTION_FPATHCONF: 906 #ifdef HAS_LPATHCONF 907 case ACTION_LPATHCONF: 908 #endif 909 { 910 long lrval; 911 912 name = str2name(pathconf_names, STR(1)); 913 if (name == -1) { 914 fprintf(stderr, "unknown name %s", STR(1)); 915 exit(1); 916 } 917 errno = 0; 918 switch (scall->sd_action) { 919 case ACTION_PATHCONF: 920 lrval = pathconf(STR(0), name); 921 break; 922 case ACTION_FPATHCONF: 923 lrval = fpathconf(NUM(0), name); 924 break; 925 #ifdef HAS_LPATHCONF 926 case ACTION_LPATHCONF: 927 lrval = lpathconf(STR(0), name); 928 break; 929 #endif 930 default: 931 abort(); 932 } 933 if (lrval == -1 && errno == 0) { 934 printf("unlimited\n"); 935 return (i); 936 } else if (lrval >= 0) { 937 printf("%ld\n", lrval); 938 return (i); 939 } 940 rval = -1; 941 break; 942 } 943 #ifdef HAS_FREEBSD_ACL 944 case ACTION_PREPENDACL: 945 rval = -1; 946 947 acl = acl_get_file(STR(0), ACL_TYPE_NFS4); 948 if (acl == NULL) 949 break; 950 951 newacl = acl_from_text(STR(1)); 952 if (acl == NULL) 953 break; 954 955 while (acl_get_entry(newacl, entry_id, &newentry) == 1) { 956 entry_id = ACL_NEXT_ENTRY; 957 958 if (acl_create_entry_np(&acl, &entry, 0)) 959 break; 960 961 if (acl_copy_entry(entry, newentry)) 962 break; 963 } 964 965 rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl); 966 break; 967 case ACTION_READACL: 968 acl = acl_get_file(STR(0), ACL_TYPE_NFS4); 969 if (acl == NULL) 970 rval = -1; 971 else 972 rval = 0; 973 break; 974 #endif 975 case ACTION_WRITE: 976 rval = write(NUM(0), STR(1), strlen(STR(1))); 977 break; 978 default: 979 fprintf(stderr, "unsupported syscall\n"); 980 exit(1); 981 } 982 #undef STR 983 #undef NUM 984 if (rval < 0) { 985 const char *serrno; 986 987 serrno = err2str(errno); 988 fprintf(stderr, "%s returned %d\n", scall->sd_name, rval); 989 printf("%s\n", serrno); 990 exit(1); 991 } 992 printf("0\n"); 993 return (i); 994 } 995 996 static void 997 set_gids(char *gids) 998 { 999 gid_t *gidset; 1000 long ngroups; 1001 char *g, *endp; 1002 unsigned i; 1003 1004 ngroups = sysconf(_SC_NGROUPS_MAX); 1005 assert(ngroups > 0); 1006 gidset = malloc(sizeof(*gidset) * ngroups); 1007 assert(gidset != NULL); 1008 for (i = 0, g = strtok(gids, ","); g != NULL; 1009 g = strtok(NULL, ","), i++) { 1010 if (i >= ngroups) { 1011 fprintf(stderr, "too many gids\n"); 1012 exit(1); 1013 } 1014 gidset[i] = strtol(g, &endp, 0); 1015 if (*endp != '\0' && !isspace((unsigned char)*endp)) { 1016 fprintf(stderr, "invalid gid '%s' - number expected\n", 1017 g); 1018 exit(1); 1019 } 1020 } 1021 if (setgroups(i, gidset) < 0) { 1022 fprintf(stderr, "cannot change groups: %s\n", strerror(errno)); 1023 exit(1); 1024 } 1025 if (setegid(gidset[0]) < 0) { 1026 fprintf(stderr, "cannot change effective gid: %s\n", 1027 strerror(errno)); 1028 exit(1); 1029 } 1030 free(gidset); 1031 } 1032 1033 int 1034 main(int argc, char *argv[]) 1035 { 1036 struct syscall_desc *scall; 1037 unsigned int n; 1038 char *gids, *endp; 1039 int uid, umsk, ch; 1040 1041 uid = -1; 1042 gids = NULL; 1043 umsk = 0; 1044 1045 while ((ch = getopt(argc, argv, "g:u:U:")) != -1) { 1046 switch(ch) { 1047 case 'g': 1048 gids = optarg; 1049 break; 1050 case 'u': 1051 uid = (int)strtol(optarg, &endp, 0); 1052 if (*endp != '\0' && !isspace((unsigned char)*endp)) { 1053 fprintf(stderr, "invalid uid '%s' - number " 1054 "expected\n", optarg); 1055 exit(1); 1056 } 1057 break; 1058 case 'U': 1059 umsk = (int)strtol(optarg, &endp, 0); 1060 if (*endp != '\0' && !isspace((unsigned char)*endp)) { 1061 fprintf(stderr, "invalid umask '%s' - number " 1062 "expected\n", optarg); 1063 exit(1); 1064 } 1065 break; 1066 default: 1067 usage(); 1068 } 1069 } 1070 argc -= optind; 1071 argv += optind; 1072 1073 if (argc < 1) { 1074 fprintf(stderr, "too few arguments\n"); 1075 usage(); 1076 } 1077 1078 if (gids != NULL) { 1079 fprintf(stderr, "changing groups to %s\n", gids); 1080 set_gids(gids); 1081 } 1082 if (uid != -1) { 1083 fprintf(stderr, "changing uid to %d\n", uid); 1084 if (setuid(uid) < 0) { 1085 fprintf(stderr, "cannot change uid: %s\n", 1086 strerror(errno)); 1087 exit(1); 1088 } 1089 } 1090 1091 /* Change umask to requested value or to 0, if not requested. */ 1092 umask(umsk); 1093 1094 for (;;) { 1095 scall = find_syscall(argv[0]); 1096 if (scall == NULL) { 1097 fprintf(stderr, "syscall '%s' not supported\n", 1098 argv[0]); 1099 exit(1); 1100 } 1101 argc++; 1102 argv++; 1103 n = call_syscall(scall, argv); 1104 argc += n; 1105 argv += n; 1106 if (argv[0] == NULL) 1107 break; 1108 argc++; 1109 argv++; 1110 } 1111 1112 exit(0); 1113 } 1114 1115 static const char * 1116 err2str(int error) 1117 { 1118 static char errnum[8]; 1119 1120 switch (error) { 1121 #ifdef EPERM 1122 case EPERM: 1123 return ("EPERM"); 1124 #endif 1125 #ifdef ENOENT 1126 case ENOENT: 1127 return ("ENOENT"); 1128 #endif 1129 #ifdef ESRCH 1130 case ESRCH: 1131 return ("ESRCH"); 1132 #endif 1133 #ifdef EINTR 1134 case EINTR: 1135 return ("EINTR"); 1136 #endif 1137 #ifdef EIO 1138 case EIO: 1139 return ("EIO"); 1140 #endif 1141 #ifdef ENXIO 1142 case ENXIO: 1143 return ("ENXIO"); 1144 #endif 1145 #ifdef E2BIG 1146 case E2BIG: 1147 return ("E2BIG"); 1148 #endif 1149 #ifdef ENOEXEC 1150 case ENOEXEC: 1151 return ("ENOEXEC"); 1152 #endif 1153 #ifdef EBADF 1154 case EBADF: 1155 return ("EBADF"); 1156 #endif 1157 #ifdef ECHILD 1158 case ECHILD: 1159 return ("ECHILD"); 1160 #endif 1161 #ifdef EDEADLK 1162 case EDEADLK: 1163 return ("EDEADLK"); 1164 #endif 1165 #ifdef ENOMEM 1166 case ENOMEM: 1167 return ("ENOMEM"); 1168 #endif 1169 #ifdef EACCES 1170 case EACCES: 1171 return ("EACCES"); 1172 #endif 1173 #ifdef EFAULT 1174 case EFAULT: 1175 return ("EFAULT"); 1176 #endif 1177 #ifdef ENOTBLK 1178 case ENOTBLK: 1179 return ("ENOTBLK"); 1180 #endif 1181 #ifdef EBUSY 1182 case EBUSY: 1183 return ("EBUSY"); 1184 #endif 1185 #ifdef EEXIST 1186 case EEXIST: 1187 return ("EEXIST"); 1188 #endif 1189 #ifdef EXDEV 1190 case EXDEV: 1191 return ("EXDEV"); 1192 #endif 1193 #ifdef ENODEV 1194 case ENODEV: 1195 return ("ENODEV"); 1196 #endif 1197 #ifdef ENOTDIR 1198 case ENOTDIR: 1199 return ("ENOTDIR"); 1200 #endif 1201 #ifdef EISDIR 1202 case EISDIR: 1203 return ("EISDIR"); 1204 #endif 1205 #ifdef EINVAL 1206 case EINVAL: 1207 return ("EINVAL"); 1208 #endif 1209 #ifdef ENFILE 1210 case ENFILE: 1211 return ("ENFILE"); 1212 #endif 1213 #ifdef EMFILE 1214 case EMFILE: 1215 return ("EMFILE"); 1216 #endif 1217 #ifdef ENOTTY 1218 case ENOTTY: 1219 return ("ENOTTY"); 1220 #endif 1221 #ifdef ETXTBSY 1222 case ETXTBSY: 1223 return ("ETXTBSY"); 1224 #endif 1225 #ifdef EFBIG 1226 case EFBIG: 1227 return ("EFBIG"); 1228 #endif 1229 #ifdef ENOSPC 1230 case ENOSPC: 1231 return ("ENOSPC"); 1232 #endif 1233 #ifdef ESPIPE 1234 case ESPIPE: 1235 return ("ESPIPE"); 1236 #endif 1237 #ifdef EROFS 1238 case EROFS: 1239 return ("EROFS"); 1240 #endif 1241 #ifdef EMLINK 1242 case EMLINK: 1243 return ("EMLINK"); 1244 #endif 1245 #ifdef EPIPE 1246 case EPIPE: 1247 return ("EPIPE"); 1248 #endif 1249 #ifdef EDOM 1250 case EDOM: 1251 return ("EDOM"); 1252 #endif 1253 #ifdef ERANGE 1254 case ERANGE: 1255 return ("ERANGE"); 1256 #endif 1257 #ifdef EAGAIN 1258 case EAGAIN: 1259 return ("EAGAIN"); 1260 #endif 1261 #ifdef EINPROGRESS 1262 case EINPROGRESS: 1263 return ("EINPROGRESS"); 1264 #endif 1265 #ifdef EALREADY 1266 case EALREADY: 1267 return ("EALREADY"); 1268 #endif 1269 #ifdef ENOTSOCK 1270 case ENOTSOCK: 1271 return ("ENOTSOCK"); 1272 #endif 1273 #ifdef EDESTADDRREQ 1274 case EDESTADDRREQ: 1275 return ("EDESTADDRREQ"); 1276 #endif 1277 #ifdef EMSGSIZE 1278 case EMSGSIZE: 1279 return ("EMSGSIZE"); 1280 #endif 1281 #ifdef EPROTOTYPE 1282 case EPROTOTYPE: 1283 return ("EPROTOTYPE"); 1284 #endif 1285 #ifdef ENOPROTOOPT 1286 case ENOPROTOOPT: 1287 return ("ENOPROTOOPT"); 1288 #endif 1289 #ifdef EPROTONOSUPPORT 1290 case EPROTONOSUPPORT: 1291 return ("EPROTONOSUPPORT"); 1292 #endif 1293 #ifdef ESOCKTNOSUPPORT 1294 case ESOCKTNOSUPPORT: 1295 return ("ESOCKTNOSUPPORT"); 1296 #endif 1297 #ifdef EOPNOTSUPP 1298 case EOPNOTSUPP: 1299 return ("EOPNOTSUPP"); 1300 #endif 1301 #ifdef EPFNOSUPPORT 1302 case EPFNOSUPPORT: 1303 return ("EPFNOSUPPORT"); 1304 #endif 1305 #ifdef EAFNOSUPPORT 1306 case EAFNOSUPPORT: 1307 return ("EAFNOSUPPORT"); 1308 #endif 1309 #ifdef EADDRINUSE 1310 case EADDRINUSE: 1311 return ("EADDRINUSE"); 1312 #endif 1313 #ifdef EADDRNOTAVAIL 1314 case EADDRNOTAVAIL: 1315 return ("EADDRNOTAVAIL"); 1316 #endif 1317 #ifdef ENETDOWN 1318 case ENETDOWN: 1319 return ("ENETDOWN"); 1320 #endif 1321 #ifdef ENETUNREACH 1322 case ENETUNREACH: 1323 return ("ENETUNREACH"); 1324 #endif 1325 #ifdef ENETRESET 1326 case ENETRESET: 1327 return ("ENETRESET"); 1328 #endif 1329 #ifdef ECONNABORTED 1330 case ECONNABORTED: 1331 return ("ECONNABORTED"); 1332 #endif 1333 #ifdef ECONNRESET 1334 case ECONNRESET: 1335 return ("ECONNRESET"); 1336 #endif 1337 #ifdef ENOBUFS 1338 case ENOBUFS: 1339 return ("ENOBUFS"); 1340 #endif 1341 #ifdef EISCONN 1342 case EISCONN: 1343 return ("EISCONN"); 1344 #endif 1345 #ifdef ENOTCONN 1346 case ENOTCONN: 1347 return ("ENOTCONN"); 1348 #endif 1349 #ifdef ESHUTDOWN 1350 case ESHUTDOWN: 1351 return ("ESHUTDOWN"); 1352 #endif 1353 #ifdef ETOOMANYREFS 1354 case ETOOMANYREFS: 1355 return ("ETOOMANYREFS"); 1356 #endif 1357 #ifdef ETIMEDOUT 1358 case ETIMEDOUT: 1359 return ("ETIMEDOUT"); 1360 #endif 1361 #ifdef ECONNREFUSED 1362 case ECONNREFUSED: 1363 return ("ECONNREFUSED"); 1364 #endif 1365 #ifdef ELOOP 1366 case ELOOP: 1367 return ("ELOOP"); 1368 #endif 1369 #ifdef ENAMETOOLONG 1370 case ENAMETOOLONG: 1371 return ("ENAMETOOLONG"); 1372 #endif 1373 #ifdef EHOSTDOWN 1374 case EHOSTDOWN: 1375 return ("EHOSTDOWN"); 1376 #endif 1377 #ifdef EHOSTUNREACH 1378 case EHOSTUNREACH: 1379 return ("EHOSTUNREACH"); 1380 #endif 1381 #ifdef ENOTEMPTY 1382 case ENOTEMPTY: 1383 return ("ENOTEMPTY"); 1384 #endif 1385 #ifdef EPROCLIM 1386 case EPROCLIM: 1387 return ("EPROCLIM"); 1388 #endif 1389 #ifdef EUSERS 1390 case EUSERS: 1391 return ("EUSERS"); 1392 #endif 1393 #ifdef EDQUOT 1394 case EDQUOT: 1395 return ("EDQUOT"); 1396 #endif 1397 #ifdef ESTALE 1398 case ESTALE: 1399 return ("ESTALE"); 1400 #endif 1401 #ifdef EREMOTE 1402 case EREMOTE: 1403 return ("EREMOTE"); 1404 #endif 1405 #ifdef EBADRPC 1406 case EBADRPC: 1407 return ("EBADRPC"); 1408 #endif 1409 #ifdef ERPCMISMATCH 1410 case ERPCMISMATCH: 1411 return ("ERPCMISMATCH"); 1412 #endif 1413 #ifdef EPROGUNAVAIL 1414 case EPROGUNAVAIL: 1415 return ("EPROGUNAVAIL"); 1416 #endif 1417 #ifdef EPROGMISMATCH 1418 case EPROGMISMATCH: 1419 return ("EPROGMISMATCH"); 1420 #endif 1421 #ifdef EPROCUNAVAIL 1422 case EPROCUNAVAIL: 1423 return ("EPROCUNAVAIL"); 1424 #endif 1425 #ifdef ENOLCK 1426 case ENOLCK: 1427 return ("ENOLCK"); 1428 #endif 1429 #ifdef ENOSYS 1430 case ENOSYS: 1431 return ("ENOSYS"); 1432 #endif 1433 #ifdef EFTYPE 1434 case EFTYPE: 1435 return ("EFTYPE"); 1436 #endif 1437 #ifdef EAUTH 1438 case EAUTH: 1439 return ("EAUTH"); 1440 #endif 1441 #ifdef ENEEDAUTH 1442 case ENEEDAUTH: 1443 return ("ENEEDAUTH"); 1444 #endif 1445 #ifdef EIDRM 1446 case EIDRM: 1447 return ("EIDRM"); 1448 #endif 1449 #ifdef ENOMSG 1450 case ENOMSG: 1451 return ("ENOMSG"); 1452 #endif 1453 #ifdef EOVERFLOW 1454 case EOVERFLOW: 1455 return ("EOVERFLOW"); 1456 #endif 1457 #ifdef ECANCELED 1458 case ECANCELED: 1459 return ("ECANCELED"); 1460 #endif 1461 #ifdef EILSEQ 1462 case EILSEQ: 1463 return ("EILSEQ"); 1464 #endif 1465 #ifdef ENOATTR 1466 case ENOATTR: 1467 return ("ENOATTR"); 1468 #endif 1469 #ifdef EDOOFUS 1470 case EDOOFUS: 1471 return ("EDOOFUS"); 1472 #endif 1473 #ifdef EBADMSG 1474 case EBADMSG: 1475 return ("EBADMSG"); 1476 #endif 1477 #ifdef EMULTIHOP 1478 case EMULTIHOP: 1479 return ("EMULTIHOP"); 1480 #endif 1481 #ifdef ENOLINK 1482 case ENOLINK: 1483 return ("ENOLINK"); 1484 #endif 1485 #ifdef EPROTO 1486 case EPROTO: 1487 return ("EPROTO"); 1488 #endif 1489 default: 1490 snprintf(errnum, sizeof(errnum), "%d", error); 1491 return (errnum); 1492 } 1493 } 1494