140a8ac8fSEnji Cooper /*-
240a8ac8fSEnji Cooper * Copyright (c) 2006-2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
340a8ac8fSEnji Cooper * All rights reserved.
440a8ac8fSEnji Cooper *
540a8ac8fSEnji Cooper * Redistribution and use in source and binary forms, with or without
640a8ac8fSEnji Cooper * modification, are permitted provided that the following conditions
740a8ac8fSEnji Cooper * are met:
840a8ac8fSEnji Cooper * 1. Redistributions of source code must retain the above copyright
940a8ac8fSEnji Cooper * notice, this list of conditions and the following disclaimer.
1040a8ac8fSEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
1140a8ac8fSEnji Cooper * notice, this list of conditions and the following disclaimer in the
1240a8ac8fSEnji Cooper * documentation and/or other materials provided with the distribution.
1340a8ac8fSEnji Cooper *
1440a8ac8fSEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
1540a8ac8fSEnji Cooper * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1640a8ac8fSEnji Cooper * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1740a8ac8fSEnji Cooper * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
1840a8ac8fSEnji Cooper * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1940a8ac8fSEnji Cooper * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2040a8ac8fSEnji Cooper * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2140a8ac8fSEnji Cooper * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2240a8ac8fSEnji Cooper * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2340a8ac8fSEnji Cooper * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2440a8ac8fSEnji Cooper * SUCH DAMAGE.
2540a8ac8fSEnji Cooper *
2640a8ac8fSEnji Cooper * $FreeBSD$
2740a8ac8fSEnji Cooper */
2840a8ac8fSEnji Cooper
29*3416500aSEnji Cooper /* Needs to be first to twiddle appropriate system configuration/HAVE_* flags */
30*3416500aSEnji Cooper #include "config.h"
31*3416500aSEnji Cooper
3240a8ac8fSEnji Cooper #include <sys/param.h>
33*3416500aSEnji Cooper #ifdef HAVE_SYS_ACL_H
34*3416500aSEnji Cooper #include <sys/acl.h>
35*3416500aSEnji Cooper #endif
36*3416500aSEnji Cooper #ifdef HAVE_SYS_MKDEV_H
37*3416500aSEnji Cooper #include <sys/mkdev.h>
38*3416500aSEnji Cooper #endif
3940a8ac8fSEnji Cooper #include <sys/stat.h>
4040a8ac8fSEnji Cooper #include <sys/socket.h>
4140a8ac8fSEnji Cooper #include <sys/un.h>
4240a8ac8fSEnji Cooper
4340a8ac8fSEnji Cooper #include <assert.h>
4440a8ac8fSEnji Cooper #include <ctype.h>
4540a8ac8fSEnji Cooper #include <errno.h>
4640a8ac8fSEnji Cooper #include <fcntl.h>
4740a8ac8fSEnji Cooper #include <grp.h>
4840a8ac8fSEnji Cooper #include <stdio.h>
4940a8ac8fSEnji Cooper #include <stdlib.h>
5040a8ac8fSEnji Cooper #include <string.h>
5140a8ac8fSEnji Cooper #include <unistd.h>
5240a8ac8fSEnji Cooper
53*3416500aSEnji Cooper #ifdef __sun__
54*3416500aSEnji Cooper #define _USE_STAT64
5540a8ac8fSEnji Cooper #endif
56*3416500aSEnji Cooper
57*3416500aSEnji Cooper #ifdef _USE_STAT64
58*3416500aSEnji Cooper typedef struct stat64 stat_t;
59*3416500aSEnji Cooper #else
60*3416500aSEnji Cooper typedef struct stat stat_t;
6140a8ac8fSEnji Cooper #endif
6240a8ac8fSEnji Cooper
6340a8ac8fSEnji Cooper #ifndef ALLPERMS
6440a8ac8fSEnji Cooper #define ALLPERMS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
6540a8ac8fSEnji Cooper #endif
6640a8ac8fSEnji Cooper
6740a8ac8fSEnji Cooper enum action {
6840a8ac8fSEnji Cooper ACTION_OPEN,
69*3416500aSEnji Cooper #ifdef HAVE_OPENAT
7040a8ac8fSEnji Cooper ACTION_OPENAT,
71*3416500aSEnji Cooper #endif
7240a8ac8fSEnji Cooper ACTION_CREATE,
7340a8ac8fSEnji Cooper ACTION_UNLINK,
74*3416500aSEnji Cooper #ifdef HAVE_UNLINKAT
7540a8ac8fSEnji Cooper ACTION_UNLINKAT,
76*3416500aSEnji Cooper #endif
7740a8ac8fSEnji Cooper ACTION_MKDIR,
78*3416500aSEnji Cooper #ifdef HAVE_MKDIRAT
7940a8ac8fSEnji Cooper ACTION_MKDIRAT,
80*3416500aSEnji Cooper #endif
8140a8ac8fSEnji Cooper ACTION_RMDIR,
8240a8ac8fSEnji Cooper ACTION_LINK,
83*3416500aSEnji Cooper #ifdef HAVE_LINKAT
8440a8ac8fSEnji Cooper ACTION_LINKAT,
85*3416500aSEnji Cooper #endif
8640a8ac8fSEnji Cooper ACTION_SYMLINK,
87*3416500aSEnji Cooper #ifdef HAVE_SYMLINKAT
8840a8ac8fSEnji Cooper ACTION_SYMLINKAT,
89*3416500aSEnji Cooper #endif
9040a8ac8fSEnji Cooper ACTION_RENAME,
91*3416500aSEnji Cooper #ifdef HAVE_RENAMEAT
9240a8ac8fSEnji Cooper ACTION_RENAMEAT,
93*3416500aSEnji Cooper #endif
9440a8ac8fSEnji Cooper ACTION_MKFIFO,
95*3416500aSEnji Cooper #ifdef HAVE_MKFIFOAT
9640a8ac8fSEnji Cooper ACTION_MKFIFOAT,
97*3416500aSEnji Cooper #endif
9840a8ac8fSEnji Cooper ACTION_MKNOD,
9940a8ac8fSEnji Cooper ACTION_MKNODAT,
10040a8ac8fSEnji Cooper ACTION_BIND,
101*3416500aSEnji Cooper #ifdef HAVE_BINDAT
10240a8ac8fSEnji Cooper ACTION_BINDAT,
10340a8ac8fSEnji Cooper #endif
10440a8ac8fSEnji Cooper ACTION_CONNECT,
105*3416500aSEnji Cooper #ifdef HAVE_CONNECTAT
10640a8ac8fSEnji Cooper ACTION_CONNECTAT,
10740a8ac8fSEnji Cooper #endif
10840a8ac8fSEnji Cooper ACTION_CHMOD,
10940a8ac8fSEnji Cooper ACTION_FCHMOD,
110*3416500aSEnji Cooper #ifdef HAVE_LCHMOD
11140a8ac8fSEnji Cooper ACTION_LCHMOD,
11240a8ac8fSEnji Cooper #endif
11340a8ac8fSEnji Cooper ACTION_FCHMODAT,
11440a8ac8fSEnji Cooper ACTION_CHOWN,
11540a8ac8fSEnji Cooper ACTION_FCHOWN,
11640a8ac8fSEnji Cooper ACTION_LCHOWN,
117*3416500aSEnji Cooper #ifdef HAVE_FCHOWNAT
11840a8ac8fSEnji Cooper ACTION_FCHOWNAT,
119*3416500aSEnji Cooper #endif
120*3416500aSEnji Cooper #ifdef HAVE_CHFLAGS
12140a8ac8fSEnji Cooper ACTION_CHFLAGS,
12240a8ac8fSEnji Cooper #endif
123*3416500aSEnji Cooper #ifdef HAVE_FCHFLAGS
12440a8ac8fSEnji Cooper ACTION_FCHFLAGS,
12540a8ac8fSEnji Cooper #endif
126*3416500aSEnji Cooper #ifdef HAVE_CHFLAGSAT
12740a8ac8fSEnji Cooper ACTION_CHFLAGSAT,
12840a8ac8fSEnji Cooper #endif
129*3416500aSEnji Cooper #ifdef HAVE_LCHFLAGS
13040a8ac8fSEnji Cooper ACTION_LCHFLAGS,
13140a8ac8fSEnji Cooper #endif
13240a8ac8fSEnji Cooper ACTION_TRUNCATE,
13340a8ac8fSEnji Cooper ACTION_FTRUNCATE,
134*3416500aSEnji Cooper #ifdef HAVE_POSIX_FALLOCATE
135*3416500aSEnji Cooper ACTION_POSIX_FALLOCATE,
136*3416500aSEnji Cooper #endif
13740a8ac8fSEnji Cooper ACTION_STAT,
13840a8ac8fSEnji Cooper ACTION_FSTAT,
13940a8ac8fSEnji Cooper ACTION_LSTAT,
14040a8ac8fSEnji Cooper ACTION_FSTATAT,
14140a8ac8fSEnji Cooper ACTION_PATHCONF,
14240a8ac8fSEnji Cooper ACTION_FPATHCONF,
143*3416500aSEnji Cooper #ifdef HAVE_LPATHCONF
14440a8ac8fSEnji Cooper ACTION_LPATHCONF,
14540a8ac8fSEnji Cooper #endif
146*3416500aSEnji Cooper #ifdef HAS_NFSV4_ACL_SUPPORT
14740a8ac8fSEnji Cooper ACTION_PREPENDACL,
14840a8ac8fSEnji Cooper ACTION_READACL,
14940a8ac8fSEnji Cooper #endif
15040a8ac8fSEnji Cooper ACTION_WRITE,
151*3416500aSEnji Cooper #ifdef HAVE_UTIMENSAT
152*3416500aSEnji Cooper ACTION_UTIMENSAT,
153*3416500aSEnji Cooper #endif
15440a8ac8fSEnji Cooper };
15540a8ac8fSEnji Cooper
15640a8ac8fSEnji Cooper #define TYPE_NONE 0x0000
15740a8ac8fSEnji Cooper #define TYPE_STRING 0x0001
15840a8ac8fSEnji Cooper #define TYPE_NUMBER 0x0002
15940a8ac8fSEnji Cooper #define TYPE_DESCRIPTOR 0x0003
16040a8ac8fSEnji Cooper #define TYPE_MASK 0x000f
16140a8ac8fSEnji Cooper
16240a8ac8fSEnji Cooper #define TYPE_OPTIONAL 0x0100
16340a8ac8fSEnji Cooper
16440a8ac8fSEnji Cooper #define MAX_ARGS 8
16540a8ac8fSEnji Cooper
16640a8ac8fSEnji Cooper struct syscall_desc {
16740a8ac8fSEnji Cooper const char *sd_name;
16840a8ac8fSEnji Cooper enum action sd_action;
16940a8ac8fSEnji Cooper int sd_args[MAX_ARGS];
17040a8ac8fSEnji Cooper };
17140a8ac8fSEnji Cooper
17240a8ac8fSEnji Cooper static struct syscall_desc syscalls[] = {
17340a8ac8fSEnji Cooper { "open", ACTION_OPEN, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } },
174*3416500aSEnji Cooper #ifdef HAVE_OPENAT
17540a8ac8fSEnji Cooper { "openat", ACTION_OPENAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER | TYPE_OPTIONAL, TYPE_NONE } },
176*3416500aSEnji Cooper #endif
17740a8ac8fSEnji Cooper { "create", ACTION_CREATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
17840a8ac8fSEnji Cooper { "unlink", ACTION_UNLINK, { TYPE_STRING, TYPE_NONE } },
179*3416500aSEnji Cooper #ifdef HAVE_UNLINKAT
18040a8ac8fSEnji Cooper { "unlinkat", ACTION_UNLINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
181*3416500aSEnji Cooper #endif
18240a8ac8fSEnji Cooper { "mkdir", ACTION_MKDIR, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
183*3416500aSEnji Cooper #ifdef HAVE_MKDIRAT
18440a8ac8fSEnji Cooper { "mkdirat", ACTION_MKDIRAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
185*3416500aSEnji Cooper #endif
18640a8ac8fSEnji Cooper { "rmdir", ACTION_RMDIR, { TYPE_STRING, TYPE_NONE } },
18740a8ac8fSEnji Cooper { "link", ACTION_LINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
188*3416500aSEnji Cooper #ifdef HAVE_LINKAT
18940a8ac8fSEnji Cooper { "linkat", ACTION_LINKAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
190*3416500aSEnji Cooper #endif
19140a8ac8fSEnji Cooper { "symlink", ACTION_SYMLINK, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
192*3416500aSEnji Cooper #ifdef HAVE_SYMLINKAT
19340a8ac8fSEnji Cooper { "symlinkat", ACTION_SYMLINKAT, { TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
194*3416500aSEnji Cooper #endif
19540a8ac8fSEnji Cooper { "rename", ACTION_RENAME, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
196*3416500aSEnji Cooper #ifdef HAVE_RENAMEAT
19740a8ac8fSEnji Cooper { "renameat", ACTION_RENAMEAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
198*3416500aSEnji Cooper #endif
19940a8ac8fSEnji Cooper { "mkfifo", ACTION_MKFIFO, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
200*3416500aSEnji Cooper #ifdef HAVE_MKFIFOAT
20140a8ac8fSEnji Cooper { "mkfifoat", ACTION_MKFIFOAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
202*3416500aSEnji Cooper #endif
20340a8ac8fSEnji Cooper { "mknod", ACTION_MKNOD, { TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} },
204*3416500aSEnji Cooper #ifdef HAVE_MKNODAT
20540a8ac8fSEnji Cooper { "mknodat", ACTION_MKNODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE} },
206*3416500aSEnji Cooper #endif
20740a8ac8fSEnji Cooper { "bind", ACTION_BIND, { TYPE_STRING, TYPE_NONE } },
208*3416500aSEnji Cooper #ifdef HAVE_BINDAT
20940a8ac8fSEnji Cooper { "bindat", ACTION_BINDAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
21040a8ac8fSEnji Cooper #endif
21140a8ac8fSEnji Cooper { "connect", ACTION_CONNECT, { TYPE_STRING, TYPE_NONE } },
212*3416500aSEnji Cooper #ifdef HAVE_CONNECTAT
21340a8ac8fSEnji Cooper { "connectat", ACTION_CONNECTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
21440a8ac8fSEnji Cooper #endif
21540a8ac8fSEnji Cooper { "chmod", ACTION_CHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
21640a8ac8fSEnji Cooper { "fchmod", ACTION_FCHMOD, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } },
217*3416500aSEnji Cooper #ifdef HAVE_LCHMOD
21840a8ac8fSEnji Cooper { "lchmod", ACTION_LCHMOD, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
21940a8ac8fSEnji Cooper #endif
220*3416500aSEnji Cooper #ifdef HAVE_FCHMODAT
22140a8ac8fSEnji Cooper { "fchmodat", ACTION_FCHMODAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
222*3416500aSEnji Cooper #endif
22340a8ac8fSEnji Cooper { "chown", ACTION_CHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
22440a8ac8fSEnji Cooper { "fchown", ACTION_FCHOWN, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
22540a8ac8fSEnji Cooper { "lchown", ACTION_LCHOWN, { TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
226*3416500aSEnji Cooper #ifdef HAVE_FCHOWNAT
22740a8ac8fSEnji Cooper { "fchownat", ACTION_FCHOWNAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NUMBER, TYPE_NUMBER, TYPE_STRING, TYPE_NONE } },
228*3416500aSEnji Cooper #endif
229*3416500aSEnji Cooper #ifdef HAVE_CHFLAGS
23040a8ac8fSEnji Cooper { "chflags", ACTION_CHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
23140a8ac8fSEnji Cooper #endif
232*3416500aSEnji Cooper #ifdef HAVE_FCHFLAGS
23340a8ac8fSEnji Cooper { "fchflags", ACTION_FCHFLAGS, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
23440a8ac8fSEnji Cooper #endif
235*3416500aSEnji Cooper #ifdef HAVE_CHFLAGSAT
23640a8ac8fSEnji Cooper { "chflagsat", ACTION_CHFLAGSAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
23740a8ac8fSEnji Cooper #endif
238*3416500aSEnji Cooper #ifdef HAVE_LCHFLAGS
23940a8ac8fSEnji Cooper { "lchflags", ACTION_LCHFLAGS, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
24040a8ac8fSEnji Cooper #endif
24140a8ac8fSEnji Cooper { "truncate", ACTION_TRUNCATE, { TYPE_STRING, TYPE_NUMBER, TYPE_NONE } },
24240a8ac8fSEnji Cooper { "ftruncate", ACTION_FTRUNCATE, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NONE } },
243*3416500aSEnji Cooper #ifdef HAVE_POSIX_FALLOCATE
244*3416500aSEnji Cooper { "posix_fallocate", ACTION_POSIX_FALLOCATE, { TYPE_DESCRIPTOR, TYPE_NUMBER, TYPE_NUMBER, TYPE_NONE } },
245*3416500aSEnji Cooper #endif
24640a8ac8fSEnji Cooper { "stat", ACTION_STAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
24740a8ac8fSEnji Cooper { "fstat", ACTION_FSTAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
24840a8ac8fSEnji Cooper { "lstat", ACTION_LSTAT, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
249*3416500aSEnji Cooper #ifdef HAVE_FSTATAT
25040a8ac8fSEnji Cooper { "fstatat", ACTION_FSTATAT, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_STRING, TYPE_STRING, TYPE_NONE } },
251*3416500aSEnji Cooper #endif
25240a8ac8fSEnji Cooper { "pathconf", ACTION_PATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
25340a8ac8fSEnji Cooper { "fpathconf", ACTION_FPATHCONF, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
254*3416500aSEnji Cooper #ifdef HAVE_LPATHCONF
25540a8ac8fSEnji Cooper { "lpathconf", ACTION_LPATHCONF, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
25640a8ac8fSEnji Cooper #endif
257*3416500aSEnji Cooper #ifdef HAS_NFSV4_ACL_SUPPORT
25840a8ac8fSEnji Cooper { "prependacl", ACTION_PREPENDACL, { TYPE_STRING, TYPE_STRING, TYPE_NONE } },
25940a8ac8fSEnji Cooper { "readacl", ACTION_READACL, { TYPE_STRING, TYPE_NONE } },
26040a8ac8fSEnji Cooper #endif
26140a8ac8fSEnji Cooper { "write", ACTION_WRITE, { TYPE_DESCRIPTOR, TYPE_STRING, TYPE_NONE } },
262*3416500aSEnji Cooper #ifdef HAVE_UTIMENSAT
263*3416500aSEnji Cooper { "utimensat", ACTION_UTIMENSAT, {
264*3416500aSEnji Cooper TYPE_DESCRIPTOR, /* Directory */
265*3416500aSEnji Cooper TYPE_STRING, /* Relative path */
266*3416500aSEnji Cooper TYPE_NUMBER, /* atime seconds */
267*3416500aSEnji Cooper TYPE_STRING, /* atime nanoseconds */
268*3416500aSEnji Cooper TYPE_NUMBER, /* mtime seconds */
269*3416500aSEnji Cooper TYPE_STRING, /* mtime nanoseconds */
270*3416500aSEnji Cooper TYPE_STRING, /* flags */}},
271*3416500aSEnji Cooper #endif
27240a8ac8fSEnji Cooper { NULL, -1, { TYPE_NONE } }
27340a8ac8fSEnji Cooper };
27440a8ac8fSEnji Cooper
27540a8ac8fSEnji Cooper struct flag {
27640a8ac8fSEnji Cooper long long f_flag;
27740a8ac8fSEnji Cooper const char *f_str;
27840a8ac8fSEnji Cooper };
27940a8ac8fSEnji Cooper
28040a8ac8fSEnji Cooper static struct flag open_flags[] = {
28140a8ac8fSEnji Cooper #ifdef O_RDONLY
28240a8ac8fSEnji Cooper { O_RDONLY, "O_RDONLY" },
28340a8ac8fSEnji Cooper #endif
28440a8ac8fSEnji Cooper #ifdef O_WRONLY
28540a8ac8fSEnji Cooper { O_WRONLY, "O_WRONLY" },
28640a8ac8fSEnji Cooper #endif
28740a8ac8fSEnji Cooper #ifdef O_RDWR
28840a8ac8fSEnji Cooper { O_RDWR, "O_RDWR" },
28940a8ac8fSEnji Cooper #endif
29040a8ac8fSEnji Cooper #ifdef O_NONBLOCK
29140a8ac8fSEnji Cooper { O_NONBLOCK, "O_NONBLOCK" },
29240a8ac8fSEnji Cooper #endif
29340a8ac8fSEnji Cooper #ifdef O_APPEND
29440a8ac8fSEnji Cooper { O_APPEND, "O_APPEND" },
29540a8ac8fSEnji Cooper #endif
29640a8ac8fSEnji Cooper #ifdef O_CREAT
29740a8ac8fSEnji Cooper { O_CREAT, "O_CREAT" },
29840a8ac8fSEnji Cooper #endif
29940a8ac8fSEnji Cooper #ifdef O_TRUNC
30040a8ac8fSEnji Cooper { O_TRUNC, "O_TRUNC" },
30140a8ac8fSEnji Cooper #endif
30240a8ac8fSEnji Cooper #ifdef O_EXCL
30340a8ac8fSEnji Cooper { O_EXCL, "O_EXCL" },
30440a8ac8fSEnji Cooper #endif
30540a8ac8fSEnji Cooper #ifdef O_SHLOCK
30640a8ac8fSEnji Cooper { O_SHLOCK, "O_SHLOCK" },
30740a8ac8fSEnji Cooper #endif
30840a8ac8fSEnji Cooper #ifdef O_EXLOCK
30940a8ac8fSEnji Cooper { O_EXLOCK, "O_EXLOCK" },
31040a8ac8fSEnji Cooper #endif
31140a8ac8fSEnji Cooper #ifdef O_DIRECT
31240a8ac8fSEnji Cooper { O_DIRECT, "O_DIRECT" },
31340a8ac8fSEnji Cooper #endif
31440a8ac8fSEnji Cooper #ifdef O_FSYNC
31540a8ac8fSEnji Cooper { O_FSYNC, "O_FSYNC" },
31640a8ac8fSEnji Cooper #endif
31740a8ac8fSEnji Cooper #ifdef O_SYNC
31840a8ac8fSEnji Cooper { O_SYNC, "O_SYNC" },
31940a8ac8fSEnji Cooper #endif
32040a8ac8fSEnji Cooper #ifdef O_NOFOLLOW
32140a8ac8fSEnji Cooper { O_NOFOLLOW, "O_NOFOLLOW" },
32240a8ac8fSEnji Cooper #endif
32340a8ac8fSEnji Cooper #ifdef O_NOCTTY
32440a8ac8fSEnji Cooper { O_NOCTTY, "O_NOCTTY" },
32540a8ac8fSEnji Cooper #endif
32640a8ac8fSEnji Cooper #ifdef O_DIRECTORY
32740a8ac8fSEnji Cooper { O_DIRECTORY, "O_DIRECTORY" },
32840a8ac8fSEnji Cooper #endif
32940a8ac8fSEnji Cooper { 0, NULL }
33040a8ac8fSEnji Cooper };
33140a8ac8fSEnji Cooper
332*3416500aSEnji Cooper #ifdef HAVE_CHFLAGS
33340a8ac8fSEnji Cooper static struct flag chflags_flags[] = {
33440a8ac8fSEnji Cooper #ifdef UF_NODUMP
33540a8ac8fSEnji Cooper { UF_NODUMP, "UF_NODUMP" },
33640a8ac8fSEnji Cooper #endif
33740a8ac8fSEnji Cooper #ifdef UF_IMMUTABLE
33840a8ac8fSEnji Cooper { UF_IMMUTABLE, "UF_IMMUTABLE" },
33940a8ac8fSEnji Cooper #endif
34040a8ac8fSEnji Cooper #ifdef UF_APPEND
34140a8ac8fSEnji Cooper { UF_APPEND, "UF_APPEND" },
34240a8ac8fSEnji Cooper #endif
34340a8ac8fSEnji Cooper #ifdef UF_NOUNLINK
34440a8ac8fSEnji Cooper { UF_NOUNLINK, "UF_NOUNLINK" },
34540a8ac8fSEnji Cooper #endif
34640a8ac8fSEnji Cooper #ifdef UF_OPAQUE
34740a8ac8fSEnji Cooper { UF_OPAQUE, "UF_OPAQUE" },
34840a8ac8fSEnji Cooper #endif
34940a8ac8fSEnji Cooper #ifdef SF_ARCHIVED
35040a8ac8fSEnji Cooper { SF_ARCHIVED, "SF_ARCHIVED" },
35140a8ac8fSEnji Cooper #endif
35240a8ac8fSEnji Cooper #ifdef SF_IMMUTABLE
35340a8ac8fSEnji Cooper { SF_IMMUTABLE, "SF_IMMUTABLE" },
35440a8ac8fSEnji Cooper #endif
35540a8ac8fSEnji Cooper #ifdef SF_APPEND
35640a8ac8fSEnji Cooper { SF_APPEND, "SF_APPEND" },
35740a8ac8fSEnji Cooper #endif
35840a8ac8fSEnji Cooper #ifdef SF_NOUNLINK
35940a8ac8fSEnji Cooper { SF_NOUNLINK, "SF_NOUNLINK" },
36040a8ac8fSEnji Cooper #endif
36140a8ac8fSEnji Cooper #ifdef SF_SNAPSHOT
36240a8ac8fSEnji Cooper { SF_SNAPSHOT, "SF_SNAPSHOT" },
36340a8ac8fSEnji Cooper #endif
36440a8ac8fSEnji Cooper { 0, NULL }
36540a8ac8fSEnji Cooper };
36640a8ac8fSEnji Cooper #endif
36740a8ac8fSEnji Cooper
368*3416500aSEnji Cooper #ifdef HAVE_UNLINKAT
36940a8ac8fSEnji Cooper static struct flag unlinkat_flags[] = {
37040a8ac8fSEnji Cooper { AT_REMOVEDIR, "AT_REMOVEDIR" },
37140a8ac8fSEnji Cooper { 0, NULL }
37240a8ac8fSEnji Cooper };
373*3416500aSEnji Cooper #endif
37440a8ac8fSEnji Cooper
375*3416500aSEnji Cooper #ifdef HAVE_LINKAT
37640a8ac8fSEnji Cooper static struct flag linkat_flags[] = {
377*3416500aSEnji Cooper #ifdef AT_SYMLINK_FOLLOW
37840a8ac8fSEnji Cooper { AT_SYMLINK_FOLLOW, "AT_SYMLINK_FOLLOW" },
379*3416500aSEnji Cooper #endif
38040a8ac8fSEnji Cooper { 0, NULL }
38140a8ac8fSEnji Cooper };
382*3416500aSEnji Cooper #endif
38340a8ac8fSEnji Cooper
384*3416500aSEnji Cooper #ifdef HAVE_CHFLAGSAT
38540a8ac8fSEnji Cooper static struct flag chflagsat_flags[] = {
38640a8ac8fSEnji Cooper { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
38740a8ac8fSEnji Cooper { 0, NULL }
38840a8ac8fSEnji Cooper };
389*3416500aSEnji Cooper #endif
39040a8ac8fSEnji Cooper
391*3416500aSEnji Cooper #ifdef HAVE_FCHMODAT
39240a8ac8fSEnji Cooper static struct flag fchmodat_flags[] = {
39340a8ac8fSEnji Cooper { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
39440a8ac8fSEnji Cooper { 0, NULL }
39540a8ac8fSEnji Cooper };
396*3416500aSEnji Cooper #endif
39740a8ac8fSEnji Cooper
398*3416500aSEnji Cooper #ifdef HAVE_FCHOWNAT
39940a8ac8fSEnji Cooper static struct flag fchownat_flags[] = {
40040a8ac8fSEnji Cooper { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
40140a8ac8fSEnji Cooper { 0, NULL }
40240a8ac8fSEnji Cooper };
403*3416500aSEnji Cooper #endif
40440a8ac8fSEnji Cooper
405*3416500aSEnji Cooper #ifdef HAVE_FSTATAT
40640a8ac8fSEnji Cooper static struct flag fstatat_flags[] = {
40740a8ac8fSEnji Cooper { AT_SYMLINK_NOFOLLOW, "AT_SYMLINK_NOFOLLOW" },
40840a8ac8fSEnji Cooper { 0, NULL }
40940a8ac8fSEnji Cooper };
410*3416500aSEnji Cooper #endif
41140a8ac8fSEnji Cooper
41240a8ac8fSEnji Cooper struct name {
41340a8ac8fSEnji Cooper int n_name;
41440a8ac8fSEnji Cooper const char *n_str;
41540a8ac8fSEnji Cooper };
41640a8ac8fSEnji Cooper
41740a8ac8fSEnji Cooper static struct name pathconf_names[] = {
41840a8ac8fSEnji Cooper #ifdef _PC_LINK_MAX
41940a8ac8fSEnji Cooper { _PC_LINK_MAX, "_PC_LINK_MAX" },
42040a8ac8fSEnji Cooper #endif
42140a8ac8fSEnji Cooper #ifdef _PC_NAME_MAX
42240a8ac8fSEnji Cooper { _PC_NAME_MAX, "_PC_NAME_MAX" },
42340a8ac8fSEnji Cooper #endif
42440a8ac8fSEnji Cooper #ifdef _PC_PATH_MAX
42540a8ac8fSEnji Cooper { _PC_PATH_MAX, "_PC_PATH_MAX" },
42640a8ac8fSEnji Cooper #endif
42740a8ac8fSEnji Cooper #ifdef _PC_SYMLINK_MAX
42840a8ac8fSEnji Cooper { _PC_SYMLINK_MAX, "_PC_SYMLINK_MAX" },
42940a8ac8fSEnji Cooper #endif
43040a8ac8fSEnji Cooper { 0, NULL }
43140a8ac8fSEnji Cooper };
43240a8ac8fSEnji Cooper
43340a8ac8fSEnji Cooper static const char *err2str(int error);
43440a8ac8fSEnji Cooper
43540a8ac8fSEnji Cooper static int *descriptors;
43640a8ac8fSEnji Cooper static int ndescriptors;
43740a8ac8fSEnji Cooper
43840a8ac8fSEnji Cooper static void
usage(void)43940a8ac8fSEnji Cooper usage(void)
44040a8ac8fSEnji Cooper {
44140a8ac8fSEnji Cooper
44240a8ac8fSEnji Cooper fprintf(stderr, "usage: pjdfstest [-U umask] [-u uid] [-g gid1[,gid2[...]]] syscall args ...\n");
44340a8ac8fSEnji Cooper exit(1);
44440a8ac8fSEnji Cooper }
44540a8ac8fSEnji Cooper
44640a8ac8fSEnji Cooper static long long
str2flags(struct flag * tflags,char * sflags)44740a8ac8fSEnji Cooper str2flags(struct flag *tflags, char *sflags)
44840a8ac8fSEnji Cooper {
44940a8ac8fSEnji Cooper long long flags = 0;
45040a8ac8fSEnji Cooper unsigned int i;
45140a8ac8fSEnji Cooper char *f;
45240a8ac8fSEnji Cooper
45340a8ac8fSEnji Cooper /* 'none' or '0' means no flags */
45440a8ac8fSEnji Cooper if (strcmp(sflags, "none") == 0 || strcmp(sflags, "0") == 0)
45540a8ac8fSEnji Cooper return (0);
45640a8ac8fSEnji Cooper for (f = strtok(sflags, ",|"); f != NULL; f = strtok(NULL, ",|")) {
45740a8ac8fSEnji Cooper for (i = 0; tflags[i].f_str != NULL; i++) {
45840a8ac8fSEnji Cooper if (strcmp(tflags[i].f_str, f) == 0)
45940a8ac8fSEnji Cooper break;
46040a8ac8fSEnji Cooper }
46140a8ac8fSEnji Cooper if (tflags[i].f_str == NULL) {
46240a8ac8fSEnji Cooper fprintf(stderr, "unknown flag '%s'\n", f);
46340a8ac8fSEnji Cooper exit(1);
46440a8ac8fSEnji Cooper }
46540a8ac8fSEnji Cooper flags |= tflags[i].f_flag;
46640a8ac8fSEnji Cooper }
46740a8ac8fSEnji Cooper return (flags);
46840a8ac8fSEnji Cooper }
46940a8ac8fSEnji Cooper
470*3416500aSEnji Cooper #ifdef HAVE_CHFLAGS
47140a8ac8fSEnji Cooper static char *
flags2str(struct flag * tflags,long long flags)47240a8ac8fSEnji Cooper flags2str(struct flag *tflags, long long flags)
47340a8ac8fSEnji Cooper {
47440a8ac8fSEnji Cooper static char sflags[1024];
47540a8ac8fSEnji Cooper unsigned int i;
47640a8ac8fSEnji Cooper
47740a8ac8fSEnji Cooper sflags[0] = '\0';
47840a8ac8fSEnji Cooper for (i = 0; tflags[i].f_str != NULL; i++) {
47940a8ac8fSEnji Cooper if (flags & tflags[i].f_flag) {
48040a8ac8fSEnji Cooper if (sflags[0] != '\0')
48140a8ac8fSEnji Cooper strlcat(sflags, ",", sizeof(sflags));
48240a8ac8fSEnji Cooper strlcat(sflags, tflags[i].f_str, sizeof(sflags));
48340a8ac8fSEnji Cooper }
48440a8ac8fSEnji Cooper }
48540a8ac8fSEnji Cooper if (sflags[0] == '\0')
48640a8ac8fSEnji Cooper strlcpy(sflags, "none", sizeof(sflags));
48740a8ac8fSEnji Cooper return (sflags);
48840a8ac8fSEnji Cooper }
48940a8ac8fSEnji Cooper #endif
49040a8ac8fSEnji Cooper
49140a8ac8fSEnji Cooper static int
str2name(struct name * names,char * name)49240a8ac8fSEnji Cooper str2name(struct name *names, char *name)
49340a8ac8fSEnji Cooper {
49440a8ac8fSEnji Cooper unsigned int i;
49540a8ac8fSEnji Cooper
49640a8ac8fSEnji Cooper for (i = 0; names[i].n_str != NULL; i++) {
49740a8ac8fSEnji Cooper if (strcmp(names[i].n_str, name) == 0)
49840a8ac8fSEnji Cooper return (names[i].n_name);
49940a8ac8fSEnji Cooper }
50040a8ac8fSEnji Cooper return (-1);
50140a8ac8fSEnji Cooper }
50240a8ac8fSEnji Cooper
50340a8ac8fSEnji Cooper static struct syscall_desc *
find_syscall(const char * name)50440a8ac8fSEnji Cooper find_syscall(const char *name)
50540a8ac8fSEnji Cooper {
50640a8ac8fSEnji Cooper int i;
50740a8ac8fSEnji Cooper
50840a8ac8fSEnji Cooper for (i = 0; syscalls[i].sd_name != NULL; i++) {
50940a8ac8fSEnji Cooper if (strcmp(syscalls[i].sd_name, name) == 0)
51040a8ac8fSEnji Cooper return (&syscalls[i]);
51140a8ac8fSEnji Cooper }
51240a8ac8fSEnji Cooper return (NULL);
51340a8ac8fSEnji Cooper }
51440a8ac8fSEnji Cooper
51540a8ac8fSEnji Cooper static void
show_stat(stat_t * sp,const char * what)516*3416500aSEnji Cooper show_stat(stat_t *sp, const char *what)
51740a8ac8fSEnji Cooper {
51840a8ac8fSEnji Cooper
51940a8ac8fSEnji Cooper if (strcmp(what, "mode") == 0)
52040a8ac8fSEnji Cooper printf("0%o", (unsigned int)(sp->st_mode & ALLPERMS));
52140a8ac8fSEnji Cooper else if (strcmp(what, "inode") == 0)
52240a8ac8fSEnji Cooper printf("%lld", (long long)sp->st_ino);
52340a8ac8fSEnji Cooper else if (strcmp(what, "nlink") == 0)
52440a8ac8fSEnji Cooper printf("%lld", (long long)sp->st_nlink);
52540a8ac8fSEnji Cooper else if (strcmp(what, "uid") == 0)
52640a8ac8fSEnji Cooper printf("%d", (int)sp->st_uid);
52740a8ac8fSEnji Cooper else if (strcmp(what, "gid") == 0)
52840a8ac8fSEnji Cooper printf("%d", (int)sp->st_gid);
52940a8ac8fSEnji Cooper else if (strcmp(what, "size") == 0)
53040a8ac8fSEnji Cooper printf("%lld", (long long)sp->st_size);
53140a8ac8fSEnji Cooper else if (strcmp(what, "blocks") == 0)
53240a8ac8fSEnji Cooper printf("%lld", (long long)sp->st_blocks);
53340a8ac8fSEnji Cooper else if (strcmp(what, "atime") == 0)
53440a8ac8fSEnji Cooper printf("%lld", (long long)sp->st_atime);
535*3416500aSEnji Cooper #if defined(HAVE_STRUCT_STAT_ST_ATIM) || \
536*3416500aSEnji Cooper defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
537*3416500aSEnji Cooper else if (strcmp(what, "atime_ns") == 0)
538*3416500aSEnji Cooper #ifdef HAVE_STRUCT_STAT_ST_ATIMESPEC
539*3416500aSEnji Cooper printf("%lld", (long long)sp->st_atimespec.tv_nsec);
540*3416500aSEnji Cooper #else
541*3416500aSEnji Cooper printf("%lld", (long long)sp->st_atim.tv_nsec);
542*3416500aSEnji Cooper #endif
543*3416500aSEnji Cooper #endif /* st_atim* */
54440a8ac8fSEnji Cooper else if (strcmp(what, "ctime") == 0)
54540a8ac8fSEnji Cooper printf("%lld", (long long)sp->st_ctime);
546*3416500aSEnji Cooper #if defined(HAVE_STRUCT_STAT_ST_CTIM) || \
547*3416500aSEnji Cooper defined(HAVE_STRUCT_STAT_ST_CTIMESPEC)
548*3416500aSEnji Cooper else if (strcmp(what, "ctime_ns") == 0)
549*3416500aSEnji Cooper #ifdef HAVE_STRUCT_STAT_ST_CTIMESPEC
550*3416500aSEnji Cooper printf("%lld", (long long)sp->st_ctimespec.tv_nsec);
551*3416500aSEnji Cooper #else
552*3416500aSEnji Cooper printf("%lld", (long long)sp->st_ctim.tv_nsec);
553*3416500aSEnji Cooper #endif
554*3416500aSEnji Cooper #endif /* st_ctim* */
555*3416500aSEnji Cooper else if (strcmp(what, "mtime") == 0)
556*3416500aSEnji Cooper printf("%lld", (long long)sp->st_mtime);
557*3416500aSEnji Cooper else if (strcmp(what, "mtime_ns") == 0)
558*3416500aSEnji Cooper #if defined(HAVE_STRUCT_STAT_ST_MTIM) || \
559*3416500aSEnji Cooper defined(HAVE_STRUCT_STAT_ST_MTIMESPEC)
560*3416500aSEnji Cooper #ifdef HAVE_STRUCT_STAT_ST_MTIMESPEC
561*3416500aSEnji Cooper printf("%lld", (long long)sp->st_mtimespec.tv_nsec);
562*3416500aSEnji Cooper #else
563*3416500aSEnji Cooper printf("%lld", (long long)sp->st_mtim.tv_nsec);
564*3416500aSEnji Cooper #endif
565*3416500aSEnji Cooper #endif /* st_mtim* */
566*3416500aSEnji Cooper #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
567*3416500aSEnji Cooper else if (strcmp(what, "birthtime") == 0)
568*3416500aSEnji Cooper printf("%lld", (long long)sp->st_birthtime);
569*3416500aSEnji Cooper #endif /* st_birthtime */
570*3416500aSEnji Cooper #if defined(HAVE_STRUCT_STAT_ST_BIRTHTIM) || \
571*3416500aSEnji Cooper defined(HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC)
572*3416500aSEnji Cooper else if (strcmp(what, "birthtime_ns") == 0)
573*3416500aSEnji Cooper #ifdef HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC
574*3416500aSEnji Cooper printf("%lld", (long long)sp->st_birthtimespec.tv_nsec);
575*3416500aSEnji Cooper #else
576*3416500aSEnji Cooper printf("%lld", (long long)sp->st_birthtim.tv_nsec);
577*3416500aSEnji Cooper #endif
578*3416500aSEnji Cooper #endif /* st_birthtim{,espec} */
579*3416500aSEnji Cooper #ifdef HAVE_CHFLAGS
58040a8ac8fSEnji Cooper else if (strcmp(what, "flags") == 0)
58140a8ac8fSEnji Cooper printf("%s", flags2str(chflags_flags, (long long)sp->st_flags));
58240a8ac8fSEnji Cooper #endif
58340a8ac8fSEnji Cooper else if (strcmp(what, "major") == 0)
58440a8ac8fSEnji Cooper printf("%u", (unsigned int)major(sp->st_rdev));
58540a8ac8fSEnji Cooper else if (strcmp(what, "minor") == 0)
58640a8ac8fSEnji Cooper printf("%u", (unsigned int)minor(sp->st_rdev));
58740a8ac8fSEnji Cooper else if (strcmp(what, "type") == 0) {
58840a8ac8fSEnji Cooper switch (sp->st_mode & S_IFMT) {
58940a8ac8fSEnji Cooper case S_IFIFO:
59040a8ac8fSEnji Cooper printf("fifo");
59140a8ac8fSEnji Cooper break;
59240a8ac8fSEnji Cooper case S_IFCHR:
59340a8ac8fSEnji Cooper printf("char");
59440a8ac8fSEnji Cooper break;
59540a8ac8fSEnji Cooper case S_IFDIR:
59640a8ac8fSEnji Cooper printf("dir");
59740a8ac8fSEnji Cooper break;
59840a8ac8fSEnji Cooper case S_IFBLK:
59940a8ac8fSEnji Cooper printf("block");
60040a8ac8fSEnji Cooper break;
60140a8ac8fSEnji Cooper case S_IFREG:
60240a8ac8fSEnji Cooper printf("regular");
60340a8ac8fSEnji Cooper break;
60440a8ac8fSEnji Cooper case S_IFLNK:
60540a8ac8fSEnji Cooper printf("symlink");
60640a8ac8fSEnji Cooper break;
60740a8ac8fSEnji Cooper case S_IFSOCK:
60840a8ac8fSEnji Cooper printf("socket");
60940a8ac8fSEnji Cooper break;
61040a8ac8fSEnji Cooper default:
61140a8ac8fSEnji Cooper printf("unknown");
61240a8ac8fSEnji Cooper break;
61340a8ac8fSEnji Cooper }
61440a8ac8fSEnji Cooper } else {
61540a8ac8fSEnji Cooper printf("unknown");
61640a8ac8fSEnji Cooper }
61740a8ac8fSEnji Cooper }
61840a8ac8fSEnji Cooper
61940a8ac8fSEnji Cooper static void
show_stats(stat_t * sp,char * what)620*3416500aSEnji Cooper show_stats(stat_t *sp, char *what)
62140a8ac8fSEnji Cooper {
62240a8ac8fSEnji Cooper const char *s = "";
62340a8ac8fSEnji Cooper char *w;
62440a8ac8fSEnji Cooper
62540a8ac8fSEnji Cooper for (w = strtok(what, ","); w != NULL; w = strtok(NULL, ",")) {
62640a8ac8fSEnji Cooper printf("%s", s);
62740a8ac8fSEnji Cooper show_stat(sp, w);
62840a8ac8fSEnji Cooper s = ",";
62940a8ac8fSEnji Cooper }
63040a8ac8fSEnji Cooper printf("\n");
63140a8ac8fSEnji Cooper }
63240a8ac8fSEnji Cooper
63340a8ac8fSEnji Cooper static void
descriptor_add(int fd)63440a8ac8fSEnji Cooper descriptor_add(int fd)
63540a8ac8fSEnji Cooper {
63640a8ac8fSEnji Cooper
63740a8ac8fSEnji Cooper ndescriptors++;
63840a8ac8fSEnji Cooper if (descriptors == NULL) {
63940a8ac8fSEnji Cooper descriptors = malloc(sizeof(descriptors[0]) * ndescriptors);
64040a8ac8fSEnji Cooper } else {
64140a8ac8fSEnji Cooper descriptors = realloc(descriptors,
64240a8ac8fSEnji Cooper sizeof(descriptors[0]) * ndescriptors);
64340a8ac8fSEnji Cooper }
64440a8ac8fSEnji Cooper assert(descriptors != NULL);
64540a8ac8fSEnji Cooper descriptors[ndescriptors - 1] = fd;
64640a8ac8fSEnji Cooper }
64740a8ac8fSEnji Cooper
64840a8ac8fSEnji Cooper static int
descriptor_get(int pos)64940a8ac8fSEnji Cooper descriptor_get(int pos)
65040a8ac8fSEnji Cooper {
65140a8ac8fSEnji Cooper
65240a8ac8fSEnji Cooper if (pos < 0 || pos >= ndescriptors) {
65340a8ac8fSEnji Cooper fprintf(stderr, "invalid descriptor %d\n", pos);
65440a8ac8fSEnji Cooper exit(1);
65540a8ac8fSEnji Cooper }
65640a8ac8fSEnji Cooper
65740a8ac8fSEnji Cooper return (descriptors[pos]);
65840a8ac8fSEnji Cooper }
65940a8ac8fSEnji Cooper
66040a8ac8fSEnji Cooper static unsigned int
call_syscall(struct syscall_desc * scall,char * argv[])66140a8ac8fSEnji Cooper call_syscall(struct syscall_desc *scall, char *argv[])
66240a8ac8fSEnji Cooper {
663*3416500aSEnji Cooper stat_t sb;
664*3416500aSEnji Cooper #ifdef HAVE_UTIMENSAT
665*3416500aSEnji Cooper struct timespec times[2];
666*3416500aSEnji Cooper int flag;
667*3416500aSEnji Cooper #endif
66840a8ac8fSEnji Cooper long long flags;
66940a8ac8fSEnji Cooper unsigned int i;
67040a8ac8fSEnji Cooper char *endp;
67140a8ac8fSEnji Cooper int name, rval;
67240a8ac8fSEnji Cooper union {
67340a8ac8fSEnji Cooper char *str;
67440a8ac8fSEnji Cooper long long num;
67540a8ac8fSEnji Cooper } args[MAX_ARGS];
676*3416500aSEnji Cooper #ifdef HAS_NFSV4_ACL_SUPPORT
67740a8ac8fSEnji Cooper int entry_id = ACL_FIRST_ENTRY;
67840a8ac8fSEnji Cooper acl_t acl, newacl;
67940a8ac8fSEnji Cooper acl_entry_t entry, newentry;
68040a8ac8fSEnji Cooper #endif
68140a8ac8fSEnji Cooper
68240a8ac8fSEnji Cooper /*
68340a8ac8fSEnji Cooper * Verify correctness of the arguments.
68440a8ac8fSEnji Cooper */
68540a8ac8fSEnji Cooper for (i = 0; i < sizeof(args)/sizeof(args[0]); i++) {
68640a8ac8fSEnji Cooper if (scall->sd_args[i] == TYPE_NONE) {
68740a8ac8fSEnji Cooper if (argv[i] == NULL || strcmp(argv[i], ":") == 0)
68840a8ac8fSEnji Cooper break;
68940a8ac8fSEnji Cooper fprintf(stderr, "too many arguments [%s]\n", argv[i]);
69040a8ac8fSEnji Cooper exit(1);
69140a8ac8fSEnji Cooper } else {
69240a8ac8fSEnji Cooper if (argv[i] == NULL || strcmp(argv[i], ":") == 0) {
69340a8ac8fSEnji Cooper if (scall->sd_args[i] & TYPE_OPTIONAL)
69440a8ac8fSEnji Cooper break;
69540a8ac8fSEnji Cooper fprintf(stderr, "too few arguments\n");
69640a8ac8fSEnji Cooper exit(1);
69740a8ac8fSEnji Cooper }
69840a8ac8fSEnji Cooper if ((scall->sd_args[i] & TYPE_MASK) == TYPE_STRING) {
69940a8ac8fSEnji Cooper if (strcmp(argv[i], "NULL") == 0)
70040a8ac8fSEnji Cooper args[i].str = NULL;
70140a8ac8fSEnji Cooper else if (strcmp(argv[i], "DEADCODE") == 0)
70240a8ac8fSEnji Cooper args[i].str = (void *)0xdeadc0de;
70340a8ac8fSEnji Cooper else
70440a8ac8fSEnji Cooper args[i].str = argv[i];
70540a8ac8fSEnji Cooper } else if ((scall->sd_args[i] & TYPE_MASK) ==
70640a8ac8fSEnji Cooper TYPE_NUMBER) {
70740a8ac8fSEnji Cooper args[i].num = strtoll(argv[i], &endp, 0);
70840a8ac8fSEnji Cooper if (*endp != '\0' &&
70940a8ac8fSEnji Cooper !isspace((unsigned char)*endp)) {
71040a8ac8fSEnji Cooper fprintf(stderr,
71140a8ac8fSEnji Cooper "invalid argument %u, number expected [%s]\n",
71240a8ac8fSEnji Cooper i, endp);
71340a8ac8fSEnji Cooper exit(1);
71440a8ac8fSEnji Cooper }
71540a8ac8fSEnji Cooper } else if ((scall->sd_args[i] & TYPE_MASK) ==
71640a8ac8fSEnji Cooper TYPE_DESCRIPTOR) {
71740a8ac8fSEnji Cooper if (strcmp(argv[i], "AT_FDCWD") == 0) {
71840a8ac8fSEnji Cooper args[i].num = AT_FDCWD;
71940a8ac8fSEnji Cooper } else if (strcmp(argv[i], "BADFD") == 0) {
72040a8ac8fSEnji Cooper /* In case AT_FDCWD is -1 on some systems... */
72140a8ac8fSEnji Cooper if (AT_FDCWD == -1)
72240a8ac8fSEnji Cooper args[i].num = -2;
72340a8ac8fSEnji Cooper else
72440a8ac8fSEnji Cooper args[i].num = -1;
72540a8ac8fSEnji Cooper } else {
72640a8ac8fSEnji Cooper int pos;
72740a8ac8fSEnji Cooper
72840a8ac8fSEnji Cooper pos = strtoll(argv[i], &endp, 0);
72940a8ac8fSEnji Cooper if (*endp != '\0' &&
73040a8ac8fSEnji Cooper !isspace((unsigned char)*endp)) {
73140a8ac8fSEnji Cooper fprintf(stderr,
73240a8ac8fSEnji Cooper "invalid argument %u, number expected [%s]\n",
73340a8ac8fSEnji Cooper i, endp);
73440a8ac8fSEnji Cooper exit(1);
73540a8ac8fSEnji Cooper }
73640a8ac8fSEnji Cooper args[i].num = descriptor_get(pos);
73740a8ac8fSEnji Cooper }
73840a8ac8fSEnji Cooper }
73940a8ac8fSEnji Cooper }
74040a8ac8fSEnji Cooper }
74140a8ac8fSEnji Cooper /*
74240a8ac8fSEnji Cooper * Call the given syscall.
74340a8ac8fSEnji Cooper */
74440a8ac8fSEnji Cooper #define NUM(n) (args[(n)].num)
74540a8ac8fSEnji Cooper #define STR(n) (args[(n)].str)
74640a8ac8fSEnji Cooper switch (scall->sd_action) {
74740a8ac8fSEnji Cooper case ACTION_OPEN:
74840a8ac8fSEnji Cooper flags = str2flags(open_flags, STR(1));
74940a8ac8fSEnji Cooper if (flags & O_CREAT) {
75040a8ac8fSEnji Cooper if (i == 2) {
75140a8ac8fSEnji Cooper fprintf(stderr, "too few arguments\n");
75240a8ac8fSEnji Cooper exit(1);
75340a8ac8fSEnji Cooper }
75440a8ac8fSEnji Cooper rval = open(STR(0), (int)flags, (mode_t)NUM(2));
75540a8ac8fSEnji Cooper } else {
75640a8ac8fSEnji Cooper if (i == 3) {
75740a8ac8fSEnji Cooper fprintf(stderr, "too many arguments\n");
75840a8ac8fSEnji Cooper exit(1);
75940a8ac8fSEnji Cooper }
76040a8ac8fSEnji Cooper rval = open(STR(0), (int)flags);
76140a8ac8fSEnji Cooper }
76240a8ac8fSEnji Cooper if (rval >= 0)
76340a8ac8fSEnji Cooper descriptor_add(rval);
76440a8ac8fSEnji Cooper break;
765*3416500aSEnji Cooper #ifdef HAVE_OPENAT
76640a8ac8fSEnji Cooper case ACTION_OPENAT:
76740a8ac8fSEnji Cooper flags = str2flags(open_flags, STR(2));
76840a8ac8fSEnji Cooper if (flags & O_CREAT) {
76940a8ac8fSEnji Cooper if (i == 3) {
77040a8ac8fSEnji Cooper fprintf(stderr, "too few arguments\n");
77140a8ac8fSEnji Cooper exit(1);
77240a8ac8fSEnji Cooper }
77340a8ac8fSEnji Cooper rval = openat(NUM(0), STR(1), (int)flags,
77440a8ac8fSEnji Cooper (mode_t)NUM(3));
77540a8ac8fSEnji Cooper } else {
77640a8ac8fSEnji Cooper if (i == 4) {
77740a8ac8fSEnji Cooper fprintf(stderr, "too many arguments\n");
77840a8ac8fSEnji Cooper exit(1);
77940a8ac8fSEnji Cooper }
78040a8ac8fSEnji Cooper rval = openat(NUM(0), STR(1), (int)flags);
78140a8ac8fSEnji Cooper }
78240a8ac8fSEnji Cooper if (rval >= 0)
78340a8ac8fSEnji Cooper descriptor_add(rval);
78440a8ac8fSEnji Cooper break;
785*3416500aSEnji Cooper #endif
78640a8ac8fSEnji Cooper case ACTION_CREATE:
78740a8ac8fSEnji Cooper rval = open(STR(0), O_CREAT | O_EXCL, (mode_t)NUM(1));
78840a8ac8fSEnji Cooper if (rval >= 0)
78940a8ac8fSEnji Cooper close(rval);
79040a8ac8fSEnji Cooper break;
79140a8ac8fSEnji Cooper case ACTION_UNLINK:
79240a8ac8fSEnji Cooper rval = unlink(STR(0));
79340a8ac8fSEnji Cooper break;
794*3416500aSEnji Cooper #ifdef HAVE_UNLINKAT
79540a8ac8fSEnji Cooper case ACTION_UNLINKAT:
79640a8ac8fSEnji Cooper rval = unlinkat(NUM(0), STR(1),
79740a8ac8fSEnji Cooper (int)str2flags(unlinkat_flags, STR(2)));
79840a8ac8fSEnji Cooper break;
799*3416500aSEnji Cooper #endif
80040a8ac8fSEnji Cooper case ACTION_MKDIR:
80140a8ac8fSEnji Cooper rval = mkdir(STR(0), (mode_t)NUM(1));
80240a8ac8fSEnji Cooper break;
803*3416500aSEnji Cooper #ifdef HAVE_MKDIRAT
80440a8ac8fSEnji Cooper case ACTION_MKDIRAT:
80540a8ac8fSEnji Cooper rval = mkdirat(NUM(0), STR(1), (mode_t)NUM(2));
80640a8ac8fSEnji Cooper break;
807*3416500aSEnji Cooper #endif
80840a8ac8fSEnji Cooper case ACTION_RMDIR:
80940a8ac8fSEnji Cooper rval = rmdir(STR(0));
81040a8ac8fSEnji Cooper break;
81140a8ac8fSEnji Cooper case ACTION_LINK:
81240a8ac8fSEnji Cooper rval = link(STR(0), STR(1));
81340a8ac8fSEnji Cooper break;
814*3416500aSEnji Cooper #ifdef HAVE_LINKAT
81540a8ac8fSEnji Cooper case ACTION_LINKAT:
81640a8ac8fSEnji Cooper rval = linkat(NUM(0), STR(1), NUM(2), STR(3),
81740a8ac8fSEnji Cooper (int)str2flags(linkat_flags, STR(4)));
81840a8ac8fSEnji Cooper break;
819*3416500aSEnji Cooper #endif
82040a8ac8fSEnji Cooper case ACTION_SYMLINK:
82140a8ac8fSEnji Cooper rval = symlink(STR(0), STR(1));
82240a8ac8fSEnji Cooper break;
823*3416500aSEnji Cooper #ifdef HAVE_SYMLINKAT
82440a8ac8fSEnji Cooper case ACTION_SYMLINKAT:
82540a8ac8fSEnji Cooper rval = symlinkat(STR(0), NUM(1), STR(2));
82640a8ac8fSEnji Cooper break;
827*3416500aSEnji Cooper #endif
82840a8ac8fSEnji Cooper case ACTION_RENAME:
82940a8ac8fSEnji Cooper rval = rename(STR(0), STR(1));
83040a8ac8fSEnji Cooper break;
831*3416500aSEnji Cooper #ifdef HAVE_RENAMEAT
83240a8ac8fSEnji Cooper case ACTION_RENAMEAT:
83340a8ac8fSEnji Cooper rval = renameat(NUM(0), STR(1), NUM(2), STR(3));
83440a8ac8fSEnji Cooper break;
835*3416500aSEnji Cooper #endif
83640a8ac8fSEnji Cooper case ACTION_MKFIFO:
83740a8ac8fSEnji Cooper rval = mkfifo(STR(0), (mode_t)NUM(1));
83840a8ac8fSEnji Cooper break;
839*3416500aSEnji Cooper #ifdef HAVE_MKFIFOAT
84040a8ac8fSEnji Cooper case ACTION_MKFIFOAT:
84140a8ac8fSEnji Cooper rval = mkfifoat(NUM(0), STR(1), (mode_t)NUM(2));
84240a8ac8fSEnji Cooper break;
843*3416500aSEnji Cooper #endif
84440a8ac8fSEnji Cooper case ACTION_MKNOD:
845*3416500aSEnji Cooper #ifdef HAVE_MKNODAT
84640a8ac8fSEnji Cooper case ACTION_MKNODAT:
847*3416500aSEnji Cooper #endif
84840a8ac8fSEnji Cooper {
84940a8ac8fSEnji Cooper mode_t ntype;
85040a8ac8fSEnji Cooper dev_t dev;
85140a8ac8fSEnji Cooper int fa;
85240a8ac8fSEnji Cooper
85340a8ac8fSEnji Cooper switch (scall->sd_action) {
85440a8ac8fSEnji Cooper case ACTION_MKNOD:
85540a8ac8fSEnji Cooper fa = 0;
85640a8ac8fSEnji Cooper break;
857*3416500aSEnji Cooper #ifdef HAVE_MKNODAT
85840a8ac8fSEnji Cooper case ACTION_MKNODAT:
85940a8ac8fSEnji Cooper fa = 1;
86040a8ac8fSEnji Cooper break;
861*3416500aSEnji Cooper #endif
86240a8ac8fSEnji Cooper default:
86340a8ac8fSEnji Cooper abort();
86440a8ac8fSEnji Cooper }
86540a8ac8fSEnji Cooper
86640a8ac8fSEnji Cooper dev = makedev(NUM(fa + 3), NUM(fa + 4));
86740a8ac8fSEnji Cooper if (strcmp(STR(fa + 1), "c") == 0) /* character device */
86840a8ac8fSEnji Cooper ntype = S_IFCHR;
86940a8ac8fSEnji Cooper else if (strcmp(STR(fa + 1), "b") == 0) /* block device */
87040a8ac8fSEnji Cooper ntype = S_IFBLK;
87140a8ac8fSEnji Cooper else if (strcmp(STR(fa + 1), "f") == 0) /* fifo special */
87240a8ac8fSEnji Cooper ntype = S_IFIFO;
87340a8ac8fSEnji Cooper else if (strcmp(STR(fa + 1), "d") == 0) /* directory */
87440a8ac8fSEnji Cooper ntype = S_IFDIR;
87540a8ac8fSEnji Cooper else if (strcmp(STR(fa + 1), "o") == 0) /* regular file */
87640a8ac8fSEnji Cooper ntype = S_IFREG;
87740a8ac8fSEnji Cooper else {
87840a8ac8fSEnji Cooper fprintf(stderr, "wrong argument 1\n");
87940a8ac8fSEnji Cooper exit(1);
88040a8ac8fSEnji Cooper }
88140a8ac8fSEnji Cooper switch (scall->sd_action) {
88240a8ac8fSEnji Cooper case ACTION_MKNOD:
88340a8ac8fSEnji Cooper rval = mknod(STR(0), ntype | NUM(2), dev);
88440a8ac8fSEnji Cooper break;
885*3416500aSEnji Cooper #ifdef HAVE_MKNODAT
88640a8ac8fSEnji Cooper case ACTION_MKNODAT:
88740a8ac8fSEnji Cooper rval = mknodat(NUM(0), STR(1), ntype | NUM(3), dev);
88840a8ac8fSEnji Cooper break;
889*3416500aSEnji Cooper #endif
89040a8ac8fSEnji Cooper default:
89140a8ac8fSEnji Cooper abort();
89240a8ac8fSEnji Cooper }
89340a8ac8fSEnji Cooper break;
89440a8ac8fSEnji Cooper }
89540a8ac8fSEnji Cooper case ACTION_BIND:
89640a8ac8fSEnji Cooper {
89740a8ac8fSEnji Cooper struct sockaddr_un sunx;
89840a8ac8fSEnji Cooper
89940a8ac8fSEnji Cooper sunx.sun_family = AF_UNIX;
90040a8ac8fSEnji Cooper strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
90140a8ac8fSEnji Cooper sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
90240a8ac8fSEnji Cooper rval = socket(AF_UNIX, SOCK_STREAM, 0);
90340a8ac8fSEnji Cooper if (rval < 0)
90440a8ac8fSEnji Cooper break;
90540a8ac8fSEnji Cooper rval = bind(rval, (struct sockaddr *)&sunx, sizeof(sunx));
90640a8ac8fSEnji Cooper break;
90740a8ac8fSEnji Cooper }
908*3416500aSEnji Cooper #ifdef HAVE_BINDAT
90940a8ac8fSEnji Cooper case ACTION_BINDAT:
91040a8ac8fSEnji Cooper {
91140a8ac8fSEnji Cooper struct sockaddr_un sunx;
91240a8ac8fSEnji Cooper
91340a8ac8fSEnji Cooper sunx.sun_family = AF_UNIX;
91440a8ac8fSEnji Cooper strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
91540a8ac8fSEnji Cooper sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
91640a8ac8fSEnji Cooper rval = socket(AF_UNIX, SOCK_STREAM, 0);
91740a8ac8fSEnji Cooper if (rval < 0)
91840a8ac8fSEnji Cooper break;
91940a8ac8fSEnji Cooper rval = bindat(NUM(0), rval, (struct sockaddr *)&sunx,
92040a8ac8fSEnji Cooper sizeof(sunx));
92140a8ac8fSEnji Cooper break;
92240a8ac8fSEnji Cooper }
92340a8ac8fSEnji Cooper #endif
92440a8ac8fSEnji Cooper case ACTION_CONNECT:
92540a8ac8fSEnji Cooper {
92640a8ac8fSEnji Cooper struct sockaddr_un sunx;
92740a8ac8fSEnji Cooper
92840a8ac8fSEnji Cooper sunx.sun_family = AF_UNIX;
92940a8ac8fSEnji Cooper strncpy(sunx.sun_path, STR(0), sizeof(sunx.sun_path) - 1);
93040a8ac8fSEnji Cooper sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
93140a8ac8fSEnji Cooper rval = socket(AF_UNIX, SOCK_STREAM, 0);
93240a8ac8fSEnji Cooper if (rval < 0)
93340a8ac8fSEnji Cooper break;
93440a8ac8fSEnji Cooper rval = connect(rval, (struct sockaddr *)&sunx, sizeof(sunx));
93540a8ac8fSEnji Cooper break;
93640a8ac8fSEnji Cooper }
937*3416500aSEnji Cooper #ifdef HAVE_CONNECTAT
93840a8ac8fSEnji Cooper case ACTION_CONNECTAT:
93940a8ac8fSEnji Cooper {
94040a8ac8fSEnji Cooper struct sockaddr_un sunx;
94140a8ac8fSEnji Cooper
94240a8ac8fSEnji Cooper sunx.sun_family = AF_UNIX;
94340a8ac8fSEnji Cooper strncpy(sunx.sun_path, STR(1), sizeof(sunx.sun_path) - 1);
94440a8ac8fSEnji Cooper sunx.sun_path[sizeof(sunx.sun_path) - 1] = '\0';
94540a8ac8fSEnji Cooper rval = socket(AF_UNIX, SOCK_STREAM, 0);
94640a8ac8fSEnji Cooper if (rval < 0)
94740a8ac8fSEnji Cooper break;
94840a8ac8fSEnji Cooper rval = connectat(NUM(0), rval, (struct sockaddr *)&sunx,
94940a8ac8fSEnji Cooper sizeof(sunx));
95040a8ac8fSEnji Cooper break;
95140a8ac8fSEnji Cooper }
95240a8ac8fSEnji Cooper #endif
95340a8ac8fSEnji Cooper case ACTION_CHMOD:
95440a8ac8fSEnji Cooper rval = chmod(STR(0), (mode_t)NUM(1));
95540a8ac8fSEnji Cooper break;
95640a8ac8fSEnji Cooper case ACTION_FCHMOD:
95740a8ac8fSEnji Cooper rval = fchmod(NUM(0), (mode_t)NUM(1));
95840a8ac8fSEnji Cooper break;
959*3416500aSEnji Cooper #ifdef HAVE_LCHMOD
96040a8ac8fSEnji Cooper case ACTION_LCHMOD:
96140a8ac8fSEnji Cooper rval = lchmod(STR(0), (mode_t)NUM(1));
96240a8ac8fSEnji Cooper break;
96340a8ac8fSEnji Cooper #endif
964*3416500aSEnji Cooper #ifdef HAVE_FCHMODAT
96540a8ac8fSEnji Cooper case ACTION_FCHMODAT:
96640a8ac8fSEnji Cooper rval = fchmodat(NUM(0), STR(1), (mode_t)NUM(2),
96740a8ac8fSEnji Cooper str2flags(fchmodat_flags, STR(3)));
96840a8ac8fSEnji Cooper break;
969*3416500aSEnji Cooper #endif
97040a8ac8fSEnji Cooper case ACTION_CHOWN:
97140a8ac8fSEnji Cooper rval = chown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
97240a8ac8fSEnji Cooper break;
97340a8ac8fSEnji Cooper case ACTION_FCHOWN:
97440a8ac8fSEnji Cooper rval = fchown(NUM(0), (uid_t)NUM(1), (gid_t)NUM(2));
97540a8ac8fSEnji Cooper break;
97640a8ac8fSEnji Cooper case ACTION_LCHOWN:
97740a8ac8fSEnji Cooper rval = lchown(STR(0), (uid_t)NUM(1), (gid_t)NUM(2));
97840a8ac8fSEnji Cooper break;
979*3416500aSEnji Cooper #ifdef HAVE_FCHOWNAT
98040a8ac8fSEnji Cooper case ACTION_FCHOWNAT:
98140a8ac8fSEnji Cooper rval = fchownat(NUM(0), STR(1), (uid_t)NUM(2), (gid_t)NUM(3),
98240a8ac8fSEnji Cooper (int)str2flags(fchownat_flags, STR(4)));
98340a8ac8fSEnji Cooper break;
984*3416500aSEnji Cooper #endif
985*3416500aSEnji Cooper #ifdef HAVE_CHFLAGS
98640a8ac8fSEnji Cooper case ACTION_CHFLAGS:
98740a8ac8fSEnji Cooper rval = chflags(STR(0),
98840a8ac8fSEnji Cooper (unsigned long)str2flags(chflags_flags, STR(1)));
98940a8ac8fSEnji Cooper break;
99040a8ac8fSEnji Cooper #endif
991*3416500aSEnji Cooper #ifdef HAVE_FCHFLAGS
99240a8ac8fSEnji Cooper case ACTION_FCHFLAGS:
99340a8ac8fSEnji Cooper rval = fchflags(NUM(0),
99440a8ac8fSEnji Cooper (unsigned long)str2flags(chflags_flags, STR(1)));
99540a8ac8fSEnji Cooper break;
99640a8ac8fSEnji Cooper #endif
997*3416500aSEnji Cooper #ifdef HAVE_CHFLAGSAT
99840a8ac8fSEnji Cooper case ACTION_CHFLAGSAT:
99940a8ac8fSEnji Cooper rval = chflagsat(NUM(0), STR(1),
100040a8ac8fSEnji Cooper (unsigned long)str2flags(chflags_flags, STR(2)),
100140a8ac8fSEnji Cooper (int)str2flags(chflagsat_flags, STR(3)));
100240a8ac8fSEnji Cooper break;
100340a8ac8fSEnji Cooper #endif
1004*3416500aSEnji Cooper #ifdef HAVE_LCHFLAGS
100540a8ac8fSEnji Cooper case ACTION_LCHFLAGS:
100640a8ac8fSEnji Cooper rval = lchflags(STR(0),
100740a8ac8fSEnji Cooper (unsigned long)str2flags(chflags_flags, STR(1)));
100840a8ac8fSEnji Cooper break;
100940a8ac8fSEnji Cooper #endif
101040a8ac8fSEnji Cooper case ACTION_TRUNCATE:
1011*3416500aSEnji Cooper #ifdef _USE_STAT64
101240a8ac8fSEnji Cooper rval = truncate64(STR(0), NUM(1));
1013*3416500aSEnji Cooper #else
1014*3416500aSEnji Cooper rval = truncate(STR(0), NUM(1));
1015*3416500aSEnji Cooper #endif
101640a8ac8fSEnji Cooper break;
101740a8ac8fSEnji Cooper case ACTION_FTRUNCATE:
1018*3416500aSEnji Cooper #ifdef _USE_STAT64
101940a8ac8fSEnji Cooper rval = ftruncate64(NUM(0), NUM(1));
1020*3416500aSEnji Cooper #else
1021*3416500aSEnji Cooper rval = ftruncate(NUM(0), NUM(1));
1022*3416500aSEnji Cooper #endif
102340a8ac8fSEnji Cooper break;
1024*3416500aSEnji Cooper #ifdef HAVE_POSIX_FALLOCATE
1025*3416500aSEnji Cooper case ACTION_POSIX_FALLOCATE:
1026*3416500aSEnji Cooper rval = posix_fallocate(NUM(0), NUM(1), NUM(2));
1027*3416500aSEnji Cooper if (rval != 0) {
1028*3416500aSEnji Cooper errno = rval;
1029*3416500aSEnji Cooper rval = -1;
1030*3416500aSEnji Cooper }
1031*3416500aSEnji Cooper break;
1032*3416500aSEnji Cooper #endif
103340a8ac8fSEnji Cooper case ACTION_STAT:
1034*3416500aSEnji Cooper #ifdef _USE_STAT64
103540a8ac8fSEnji Cooper rval = stat64(STR(0), &sb);
1036*3416500aSEnji Cooper #else
1037*3416500aSEnji Cooper rval = stat(STR(0), &sb);
1038*3416500aSEnji Cooper #endif
103940a8ac8fSEnji Cooper if (rval == 0) {
104040a8ac8fSEnji Cooper show_stats(&sb, STR(1));
104140a8ac8fSEnji Cooper return (i);
104240a8ac8fSEnji Cooper }
104340a8ac8fSEnji Cooper break;
104440a8ac8fSEnji Cooper case ACTION_FSTAT:
1045*3416500aSEnji Cooper #ifdef _USE_STAT64
104640a8ac8fSEnji Cooper rval = fstat64(NUM(0), &sb);
1047*3416500aSEnji Cooper #else
1048*3416500aSEnji Cooper rval = fstat(NUM(0), &sb);
1049*3416500aSEnji Cooper #endif
105040a8ac8fSEnji Cooper if (rval == 0) {
105140a8ac8fSEnji Cooper show_stats(&sb, STR(1));
105240a8ac8fSEnji Cooper return (i);
105340a8ac8fSEnji Cooper }
105440a8ac8fSEnji Cooper break;
105540a8ac8fSEnji Cooper case ACTION_LSTAT:
1056*3416500aSEnji Cooper #ifdef _USE_STAT64
105740a8ac8fSEnji Cooper rval = lstat64(STR(0), &sb);
1058*3416500aSEnji Cooper #else
1059*3416500aSEnji Cooper rval = lstat(STR(0), &sb);
1060*3416500aSEnji Cooper #endif
106140a8ac8fSEnji Cooper if (rval == 0) {
106240a8ac8fSEnji Cooper show_stats(&sb, STR(1));
106340a8ac8fSEnji Cooper return (i);
106440a8ac8fSEnji Cooper }
106540a8ac8fSEnji Cooper break;
1066*3416500aSEnji Cooper #ifdef HAVE_FSTATAT
106740a8ac8fSEnji Cooper case ACTION_FSTATAT:
106840a8ac8fSEnji Cooper rval = fstatat(NUM(0), STR(1), &sb,
106940a8ac8fSEnji Cooper (int)str2flags(fstatat_flags, STR(2)));
107040a8ac8fSEnji Cooper if (rval == 0) {
107140a8ac8fSEnji Cooper show_stats(&sb, STR(3));
107240a8ac8fSEnji Cooper return (i);
107340a8ac8fSEnji Cooper }
107440a8ac8fSEnji Cooper break;
1075*3416500aSEnji Cooper #endif
107640a8ac8fSEnji Cooper case ACTION_PATHCONF:
107740a8ac8fSEnji Cooper case ACTION_FPATHCONF:
1078*3416500aSEnji Cooper #ifdef HAVE_LPATHCONF
107940a8ac8fSEnji Cooper case ACTION_LPATHCONF:
108040a8ac8fSEnji Cooper #endif
108140a8ac8fSEnji Cooper {
108240a8ac8fSEnji Cooper long lrval;
108340a8ac8fSEnji Cooper
108440a8ac8fSEnji Cooper name = str2name(pathconf_names, STR(1));
108540a8ac8fSEnji Cooper if (name == -1) {
108640a8ac8fSEnji Cooper fprintf(stderr, "unknown name %s", STR(1));
108740a8ac8fSEnji Cooper exit(1);
108840a8ac8fSEnji Cooper }
108940a8ac8fSEnji Cooper errno = 0;
109040a8ac8fSEnji Cooper switch (scall->sd_action) {
109140a8ac8fSEnji Cooper case ACTION_PATHCONF:
109240a8ac8fSEnji Cooper lrval = pathconf(STR(0), name);
109340a8ac8fSEnji Cooper break;
109440a8ac8fSEnji Cooper case ACTION_FPATHCONF:
109540a8ac8fSEnji Cooper lrval = fpathconf(NUM(0), name);
109640a8ac8fSEnji Cooper break;
1097*3416500aSEnji Cooper #ifdef HAVE_LPATHCONF
109840a8ac8fSEnji Cooper case ACTION_LPATHCONF:
109940a8ac8fSEnji Cooper lrval = lpathconf(STR(0), name);
110040a8ac8fSEnji Cooper break;
110140a8ac8fSEnji Cooper #endif
110240a8ac8fSEnji Cooper default:
110340a8ac8fSEnji Cooper abort();
110440a8ac8fSEnji Cooper }
110540a8ac8fSEnji Cooper if (lrval == -1 && errno == 0) {
110640a8ac8fSEnji Cooper printf("unlimited\n");
110740a8ac8fSEnji Cooper return (i);
110840a8ac8fSEnji Cooper } else if (lrval >= 0) {
110940a8ac8fSEnji Cooper printf("%ld\n", lrval);
111040a8ac8fSEnji Cooper return (i);
111140a8ac8fSEnji Cooper }
111240a8ac8fSEnji Cooper rval = -1;
111340a8ac8fSEnji Cooper break;
111440a8ac8fSEnji Cooper }
1115*3416500aSEnji Cooper #ifdef HAS_NFSV4_ACL_SUPPORT
111640a8ac8fSEnji Cooper case ACTION_PREPENDACL:
111740a8ac8fSEnji Cooper rval = -1;
111840a8ac8fSEnji Cooper
111940a8ac8fSEnji Cooper acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
112040a8ac8fSEnji Cooper if (acl == NULL)
112140a8ac8fSEnji Cooper break;
112240a8ac8fSEnji Cooper
112340a8ac8fSEnji Cooper newacl = acl_from_text(STR(1));
112440a8ac8fSEnji Cooper if (acl == NULL)
112540a8ac8fSEnji Cooper break;
112640a8ac8fSEnji Cooper
112740a8ac8fSEnji Cooper while (acl_get_entry(newacl, entry_id, &newentry) == 1) {
112840a8ac8fSEnji Cooper entry_id = ACL_NEXT_ENTRY;
112940a8ac8fSEnji Cooper
113040a8ac8fSEnji Cooper if (acl_create_entry_np(&acl, &entry, 0))
113140a8ac8fSEnji Cooper break;
113240a8ac8fSEnji Cooper
113340a8ac8fSEnji Cooper if (acl_copy_entry(entry, newentry))
113440a8ac8fSEnji Cooper break;
113540a8ac8fSEnji Cooper }
113640a8ac8fSEnji Cooper
113740a8ac8fSEnji Cooper rval = acl_set_file(STR(0), ACL_TYPE_NFS4, acl);
113840a8ac8fSEnji Cooper break;
113940a8ac8fSEnji Cooper case ACTION_READACL:
114040a8ac8fSEnji Cooper acl = acl_get_file(STR(0), ACL_TYPE_NFS4);
114140a8ac8fSEnji Cooper if (acl == NULL)
114240a8ac8fSEnji Cooper rval = -1;
114340a8ac8fSEnji Cooper else
114440a8ac8fSEnji Cooper rval = 0;
114540a8ac8fSEnji Cooper break;
114640a8ac8fSEnji Cooper #endif
114740a8ac8fSEnji Cooper case ACTION_WRITE:
114840a8ac8fSEnji Cooper rval = write(NUM(0), STR(1), strlen(STR(1)));
114940a8ac8fSEnji Cooper break;
1150*3416500aSEnji Cooper #ifdef HAVE_UTIMENSAT
1151*3416500aSEnji Cooper case ACTION_UTIMENSAT:
1152*3416500aSEnji Cooper times[0].tv_sec = NUM(2);
1153*3416500aSEnji Cooper if (strcmp(STR(3), "UTIME_NOW") == 0)
1154*3416500aSEnji Cooper times[0].tv_nsec = UTIME_NOW;
1155*3416500aSEnji Cooper else if (strcmp(STR(3), "UTIME_OMIT") == 0)
1156*3416500aSEnji Cooper times[0].tv_nsec = UTIME_OMIT;
1157*3416500aSEnji Cooper else
1158*3416500aSEnji Cooper times[0].tv_nsec = strtol(STR(3), NULL, 10);
1159*3416500aSEnji Cooper times[1].tv_sec = NUM(4);
1160*3416500aSEnji Cooper if (strcmp(STR(5), "UTIME_NOW") == 0)
1161*3416500aSEnji Cooper times[1].tv_nsec = UTIME_NOW;
1162*3416500aSEnji Cooper else if (strcmp(STR(5), "UTIME_OMIT") == 0)
1163*3416500aSEnji Cooper times[1].tv_nsec = UTIME_OMIT;
1164*3416500aSEnji Cooper else
1165*3416500aSEnji Cooper times[1].tv_nsec = strtol(STR(5), NULL, 10);
1166*3416500aSEnji Cooper if (strcmp(STR(6), "AT_SYMLINK_NOFOLLOW") == 0)
1167*3416500aSEnji Cooper flag = AT_SYMLINK_NOFOLLOW;
1168*3416500aSEnji Cooper else
1169*3416500aSEnji Cooper flag = strtol(STR(6), NULL, 10);
1170*3416500aSEnji Cooper rval = utimensat(NUM(0), STR(1), times, flag);
1171*3416500aSEnji Cooper break;
1172*3416500aSEnji Cooper #endif
117340a8ac8fSEnji Cooper default:
117440a8ac8fSEnji Cooper fprintf(stderr, "unsupported syscall\n");
117540a8ac8fSEnji Cooper exit(1);
117640a8ac8fSEnji Cooper }
117740a8ac8fSEnji Cooper #undef STR
117840a8ac8fSEnji Cooper #undef NUM
117940a8ac8fSEnji Cooper if (rval < 0) {
118040a8ac8fSEnji Cooper const char *serrno;
118140a8ac8fSEnji Cooper
118240a8ac8fSEnji Cooper serrno = err2str(errno);
118340a8ac8fSEnji Cooper fprintf(stderr, "%s returned %d\n", scall->sd_name, rval);
118440a8ac8fSEnji Cooper printf("%s\n", serrno);
118540a8ac8fSEnji Cooper exit(1);
118640a8ac8fSEnji Cooper }
118740a8ac8fSEnji Cooper printf("0\n");
118840a8ac8fSEnji Cooper return (i);
118940a8ac8fSEnji Cooper }
119040a8ac8fSEnji Cooper
119140a8ac8fSEnji Cooper static void
set_gids(char * gids)119240a8ac8fSEnji Cooper set_gids(char *gids)
119340a8ac8fSEnji Cooper {
119440a8ac8fSEnji Cooper gid_t *gidset;
119540a8ac8fSEnji Cooper long ngroups;
119640a8ac8fSEnji Cooper char *g, *endp;
119740a8ac8fSEnji Cooper unsigned i;
119840a8ac8fSEnji Cooper
119940a8ac8fSEnji Cooper ngroups = sysconf(_SC_NGROUPS_MAX);
120040a8ac8fSEnji Cooper assert(ngroups > 0);
120140a8ac8fSEnji Cooper gidset = malloc(sizeof(*gidset) * ngroups);
120240a8ac8fSEnji Cooper assert(gidset != NULL);
120340a8ac8fSEnji Cooper for (i = 0, g = strtok(gids, ","); g != NULL;
120440a8ac8fSEnji Cooper g = strtok(NULL, ","), i++) {
1205*3416500aSEnji Cooper if ((long)i >= ngroups) {
120640a8ac8fSEnji Cooper fprintf(stderr, "too many gids\n");
120740a8ac8fSEnji Cooper exit(1);
120840a8ac8fSEnji Cooper }
120940a8ac8fSEnji Cooper gidset[i] = strtol(g, &endp, 0);
121040a8ac8fSEnji Cooper if (*endp != '\0' && !isspace((unsigned char)*endp)) {
121140a8ac8fSEnji Cooper fprintf(stderr, "invalid gid '%s' - number expected\n",
121240a8ac8fSEnji Cooper g);
121340a8ac8fSEnji Cooper exit(1);
121440a8ac8fSEnji Cooper }
121540a8ac8fSEnji Cooper }
121640a8ac8fSEnji Cooper if (setgroups(i, gidset) < 0) {
121740a8ac8fSEnji Cooper fprintf(stderr, "cannot change groups: %s\n", strerror(errno));
121840a8ac8fSEnji Cooper exit(1);
121940a8ac8fSEnji Cooper }
122040a8ac8fSEnji Cooper if (setegid(gidset[0]) < 0) {
122140a8ac8fSEnji Cooper fprintf(stderr, "cannot change effective gid: %s\n",
122240a8ac8fSEnji Cooper strerror(errno));
122340a8ac8fSEnji Cooper exit(1);
122440a8ac8fSEnji Cooper }
122540a8ac8fSEnji Cooper free(gidset);
122640a8ac8fSEnji Cooper }
122740a8ac8fSEnji Cooper
122840a8ac8fSEnji Cooper int
main(int argc,char * argv[])122940a8ac8fSEnji Cooper main(int argc, char *argv[])
123040a8ac8fSEnji Cooper {
123140a8ac8fSEnji Cooper struct syscall_desc *scall;
123240a8ac8fSEnji Cooper unsigned int n;
123340a8ac8fSEnji Cooper char *gids, *endp;
123440a8ac8fSEnji Cooper int uid, umsk, ch;
123540a8ac8fSEnji Cooper
123640a8ac8fSEnji Cooper uid = -1;
123740a8ac8fSEnji Cooper gids = NULL;
123840a8ac8fSEnji Cooper umsk = 0;
123940a8ac8fSEnji Cooper
124040a8ac8fSEnji Cooper while ((ch = getopt(argc, argv, "g:u:U:")) != -1) {
124140a8ac8fSEnji Cooper switch(ch) {
124240a8ac8fSEnji Cooper case 'g':
124340a8ac8fSEnji Cooper gids = optarg;
124440a8ac8fSEnji Cooper break;
124540a8ac8fSEnji Cooper case 'u':
124640a8ac8fSEnji Cooper uid = (int)strtol(optarg, &endp, 0);
124740a8ac8fSEnji Cooper if (*endp != '\0' && !isspace((unsigned char)*endp)) {
124840a8ac8fSEnji Cooper fprintf(stderr, "invalid uid '%s' - number "
124940a8ac8fSEnji Cooper "expected\n", optarg);
125040a8ac8fSEnji Cooper exit(1);
125140a8ac8fSEnji Cooper }
125240a8ac8fSEnji Cooper break;
125340a8ac8fSEnji Cooper case 'U':
125440a8ac8fSEnji Cooper umsk = (int)strtol(optarg, &endp, 0);
125540a8ac8fSEnji Cooper if (*endp != '\0' && !isspace((unsigned char)*endp)) {
125640a8ac8fSEnji Cooper fprintf(stderr, "invalid umask '%s' - number "
125740a8ac8fSEnji Cooper "expected\n", optarg);
125840a8ac8fSEnji Cooper exit(1);
125940a8ac8fSEnji Cooper }
126040a8ac8fSEnji Cooper break;
126140a8ac8fSEnji Cooper default:
126240a8ac8fSEnji Cooper usage();
126340a8ac8fSEnji Cooper }
126440a8ac8fSEnji Cooper }
126540a8ac8fSEnji Cooper argc -= optind;
126640a8ac8fSEnji Cooper argv += optind;
126740a8ac8fSEnji Cooper
126840a8ac8fSEnji Cooper if (argc < 1) {
126940a8ac8fSEnji Cooper fprintf(stderr, "too few arguments\n");
127040a8ac8fSEnji Cooper usage();
127140a8ac8fSEnji Cooper }
127240a8ac8fSEnji Cooper
127340a8ac8fSEnji Cooper if (gids != NULL) {
127440a8ac8fSEnji Cooper fprintf(stderr, "changing groups to %s\n", gids);
127540a8ac8fSEnji Cooper set_gids(gids);
127640a8ac8fSEnji Cooper }
127740a8ac8fSEnji Cooper if (uid != -1) {
127840a8ac8fSEnji Cooper fprintf(stderr, "changing uid to %d\n", uid);
127940a8ac8fSEnji Cooper if (setuid(uid) < 0) {
128040a8ac8fSEnji Cooper fprintf(stderr, "cannot change uid: %s\n",
128140a8ac8fSEnji Cooper strerror(errno));
128240a8ac8fSEnji Cooper exit(1);
128340a8ac8fSEnji Cooper }
128440a8ac8fSEnji Cooper }
128540a8ac8fSEnji Cooper
128640a8ac8fSEnji Cooper /* Change umask to requested value or to 0, if not requested. */
128740a8ac8fSEnji Cooper umask(umsk);
128840a8ac8fSEnji Cooper
128940a8ac8fSEnji Cooper for (;;) {
129040a8ac8fSEnji Cooper scall = find_syscall(argv[0]);
129140a8ac8fSEnji Cooper if (scall == NULL) {
129240a8ac8fSEnji Cooper fprintf(stderr, "syscall '%s' not supported\n",
129340a8ac8fSEnji Cooper argv[0]);
129440a8ac8fSEnji Cooper exit(1);
129540a8ac8fSEnji Cooper }
129640a8ac8fSEnji Cooper argc++;
129740a8ac8fSEnji Cooper argv++;
129840a8ac8fSEnji Cooper n = call_syscall(scall, argv);
129940a8ac8fSEnji Cooper argc += n;
130040a8ac8fSEnji Cooper argv += n;
130140a8ac8fSEnji Cooper if (argv[0] == NULL)
130240a8ac8fSEnji Cooper break;
130340a8ac8fSEnji Cooper argc++;
130440a8ac8fSEnji Cooper argv++;
130540a8ac8fSEnji Cooper }
130640a8ac8fSEnji Cooper
130740a8ac8fSEnji Cooper exit(0);
130840a8ac8fSEnji Cooper }
130940a8ac8fSEnji Cooper
131040a8ac8fSEnji Cooper static const char *
err2str(int error)131140a8ac8fSEnji Cooper err2str(int error)
131240a8ac8fSEnji Cooper {
131340a8ac8fSEnji Cooper static char errnum[8];
131440a8ac8fSEnji Cooper
131540a8ac8fSEnji Cooper switch (error) {
131640a8ac8fSEnji Cooper #ifdef EPERM
131740a8ac8fSEnji Cooper case EPERM:
131840a8ac8fSEnji Cooper return ("EPERM");
131940a8ac8fSEnji Cooper #endif
132040a8ac8fSEnji Cooper #ifdef ENOENT
132140a8ac8fSEnji Cooper case ENOENT:
132240a8ac8fSEnji Cooper return ("ENOENT");
132340a8ac8fSEnji Cooper #endif
132440a8ac8fSEnji Cooper #ifdef ESRCH
132540a8ac8fSEnji Cooper case ESRCH:
132640a8ac8fSEnji Cooper return ("ESRCH");
132740a8ac8fSEnji Cooper #endif
132840a8ac8fSEnji Cooper #ifdef EINTR
132940a8ac8fSEnji Cooper case EINTR:
133040a8ac8fSEnji Cooper return ("EINTR");
133140a8ac8fSEnji Cooper #endif
133240a8ac8fSEnji Cooper #ifdef EIO
133340a8ac8fSEnji Cooper case EIO:
133440a8ac8fSEnji Cooper return ("EIO");
133540a8ac8fSEnji Cooper #endif
133640a8ac8fSEnji Cooper #ifdef ENXIO
133740a8ac8fSEnji Cooper case ENXIO:
133840a8ac8fSEnji Cooper return ("ENXIO");
133940a8ac8fSEnji Cooper #endif
134040a8ac8fSEnji Cooper #ifdef E2BIG
134140a8ac8fSEnji Cooper case E2BIG:
134240a8ac8fSEnji Cooper return ("E2BIG");
134340a8ac8fSEnji Cooper #endif
134440a8ac8fSEnji Cooper #ifdef ENOEXEC
134540a8ac8fSEnji Cooper case ENOEXEC:
134640a8ac8fSEnji Cooper return ("ENOEXEC");
134740a8ac8fSEnji Cooper #endif
134840a8ac8fSEnji Cooper #ifdef EBADF
134940a8ac8fSEnji Cooper case EBADF:
135040a8ac8fSEnji Cooper return ("EBADF");
135140a8ac8fSEnji Cooper #endif
135240a8ac8fSEnji Cooper #ifdef ECHILD
135340a8ac8fSEnji Cooper case ECHILD:
135440a8ac8fSEnji Cooper return ("ECHILD");
135540a8ac8fSEnji Cooper #endif
135640a8ac8fSEnji Cooper #ifdef EDEADLK
135740a8ac8fSEnji Cooper case EDEADLK:
135840a8ac8fSEnji Cooper return ("EDEADLK");
135940a8ac8fSEnji Cooper #endif
136040a8ac8fSEnji Cooper #ifdef ENOMEM
136140a8ac8fSEnji Cooper case ENOMEM:
136240a8ac8fSEnji Cooper return ("ENOMEM");
136340a8ac8fSEnji Cooper #endif
136440a8ac8fSEnji Cooper #ifdef EACCES
136540a8ac8fSEnji Cooper case EACCES:
136640a8ac8fSEnji Cooper return ("EACCES");
136740a8ac8fSEnji Cooper #endif
136840a8ac8fSEnji Cooper #ifdef EFAULT
136940a8ac8fSEnji Cooper case EFAULT:
137040a8ac8fSEnji Cooper return ("EFAULT");
137140a8ac8fSEnji Cooper #endif
137240a8ac8fSEnji Cooper #ifdef ENOTBLK
137340a8ac8fSEnji Cooper case ENOTBLK:
137440a8ac8fSEnji Cooper return ("ENOTBLK");
137540a8ac8fSEnji Cooper #endif
137640a8ac8fSEnji Cooper #ifdef EBUSY
137740a8ac8fSEnji Cooper case EBUSY:
137840a8ac8fSEnji Cooper return ("EBUSY");
137940a8ac8fSEnji Cooper #endif
138040a8ac8fSEnji Cooper #ifdef EEXIST
138140a8ac8fSEnji Cooper case EEXIST:
138240a8ac8fSEnji Cooper return ("EEXIST");
138340a8ac8fSEnji Cooper #endif
138440a8ac8fSEnji Cooper #ifdef EXDEV
138540a8ac8fSEnji Cooper case EXDEV:
138640a8ac8fSEnji Cooper return ("EXDEV");
138740a8ac8fSEnji Cooper #endif
138840a8ac8fSEnji Cooper #ifdef ENODEV
138940a8ac8fSEnji Cooper case ENODEV:
139040a8ac8fSEnji Cooper return ("ENODEV");
139140a8ac8fSEnji Cooper #endif
139240a8ac8fSEnji Cooper #ifdef ENOTDIR
139340a8ac8fSEnji Cooper case ENOTDIR:
139440a8ac8fSEnji Cooper return ("ENOTDIR");
139540a8ac8fSEnji Cooper #endif
139640a8ac8fSEnji Cooper #ifdef EISDIR
139740a8ac8fSEnji Cooper case EISDIR:
139840a8ac8fSEnji Cooper return ("EISDIR");
139940a8ac8fSEnji Cooper #endif
140040a8ac8fSEnji Cooper #ifdef EINVAL
140140a8ac8fSEnji Cooper case EINVAL:
140240a8ac8fSEnji Cooper return ("EINVAL");
140340a8ac8fSEnji Cooper #endif
140440a8ac8fSEnji Cooper #ifdef ENFILE
140540a8ac8fSEnji Cooper case ENFILE:
140640a8ac8fSEnji Cooper return ("ENFILE");
140740a8ac8fSEnji Cooper #endif
140840a8ac8fSEnji Cooper #ifdef EMFILE
140940a8ac8fSEnji Cooper case EMFILE:
141040a8ac8fSEnji Cooper return ("EMFILE");
141140a8ac8fSEnji Cooper #endif
141240a8ac8fSEnji Cooper #ifdef ENOTTY
141340a8ac8fSEnji Cooper case ENOTTY:
141440a8ac8fSEnji Cooper return ("ENOTTY");
141540a8ac8fSEnji Cooper #endif
141640a8ac8fSEnji Cooper #ifdef ETXTBSY
141740a8ac8fSEnji Cooper case ETXTBSY:
141840a8ac8fSEnji Cooper return ("ETXTBSY");
141940a8ac8fSEnji Cooper #endif
142040a8ac8fSEnji Cooper #ifdef EFBIG
142140a8ac8fSEnji Cooper case EFBIG:
142240a8ac8fSEnji Cooper return ("EFBIG");
142340a8ac8fSEnji Cooper #endif
142440a8ac8fSEnji Cooper #ifdef ENOSPC
142540a8ac8fSEnji Cooper case ENOSPC:
142640a8ac8fSEnji Cooper return ("ENOSPC");
142740a8ac8fSEnji Cooper #endif
142840a8ac8fSEnji Cooper #ifdef ESPIPE
142940a8ac8fSEnji Cooper case ESPIPE:
143040a8ac8fSEnji Cooper return ("ESPIPE");
143140a8ac8fSEnji Cooper #endif
143240a8ac8fSEnji Cooper #ifdef EROFS
143340a8ac8fSEnji Cooper case EROFS:
143440a8ac8fSEnji Cooper return ("EROFS");
143540a8ac8fSEnji Cooper #endif
143640a8ac8fSEnji Cooper #ifdef EMLINK
143740a8ac8fSEnji Cooper case EMLINK:
143840a8ac8fSEnji Cooper return ("EMLINK");
143940a8ac8fSEnji Cooper #endif
144040a8ac8fSEnji Cooper #ifdef EPIPE
144140a8ac8fSEnji Cooper case EPIPE:
144240a8ac8fSEnji Cooper return ("EPIPE");
144340a8ac8fSEnji Cooper #endif
144440a8ac8fSEnji Cooper #ifdef EDOM
144540a8ac8fSEnji Cooper case EDOM:
144640a8ac8fSEnji Cooper return ("EDOM");
144740a8ac8fSEnji Cooper #endif
144840a8ac8fSEnji Cooper #ifdef ERANGE
144940a8ac8fSEnji Cooper case ERANGE:
145040a8ac8fSEnji Cooper return ("ERANGE");
145140a8ac8fSEnji Cooper #endif
145240a8ac8fSEnji Cooper #ifdef EAGAIN
145340a8ac8fSEnji Cooper case EAGAIN:
145440a8ac8fSEnji Cooper return ("EAGAIN");
145540a8ac8fSEnji Cooper #endif
145640a8ac8fSEnji Cooper #ifdef EINPROGRESS
145740a8ac8fSEnji Cooper case EINPROGRESS:
145840a8ac8fSEnji Cooper return ("EINPROGRESS");
145940a8ac8fSEnji Cooper #endif
146040a8ac8fSEnji Cooper #ifdef EALREADY
146140a8ac8fSEnji Cooper case EALREADY:
146240a8ac8fSEnji Cooper return ("EALREADY");
146340a8ac8fSEnji Cooper #endif
146440a8ac8fSEnji Cooper #ifdef ENOTSOCK
146540a8ac8fSEnji Cooper case ENOTSOCK:
146640a8ac8fSEnji Cooper return ("ENOTSOCK");
146740a8ac8fSEnji Cooper #endif
146840a8ac8fSEnji Cooper #ifdef EDESTADDRREQ
146940a8ac8fSEnji Cooper case EDESTADDRREQ:
147040a8ac8fSEnji Cooper return ("EDESTADDRREQ");
147140a8ac8fSEnji Cooper #endif
147240a8ac8fSEnji Cooper #ifdef EMSGSIZE
147340a8ac8fSEnji Cooper case EMSGSIZE:
147440a8ac8fSEnji Cooper return ("EMSGSIZE");
147540a8ac8fSEnji Cooper #endif
147640a8ac8fSEnji Cooper #ifdef EPROTOTYPE
147740a8ac8fSEnji Cooper case EPROTOTYPE:
147840a8ac8fSEnji Cooper return ("EPROTOTYPE");
147940a8ac8fSEnji Cooper #endif
148040a8ac8fSEnji Cooper #ifdef ENOPROTOOPT
148140a8ac8fSEnji Cooper case ENOPROTOOPT:
148240a8ac8fSEnji Cooper return ("ENOPROTOOPT");
148340a8ac8fSEnji Cooper #endif
148440a8ac8fSEnji Cooper #ifdef EPROTONOSUPPORT
148540a8ac8fSEnji Cooper case EPROTONOSUPPORT:
148640a8ac8fSEnji Cooper return ("EPROTONOSUPPORT");
148740a8ac8fSEnji Cooper #endif
148840a8ac8fSEnji Cooper #ifdef ESOCKTNOSUPPORT
148940a8ac8fSEnji Cooper case ESOCKTNOSUPPORT:
149040a8ac8fSEnji Cooper return ("ESOCKTNOSUPPORT");
149140a8ac8fSEnji Cooper #endif
149240a8ac8fSEnji Cooper #ifdef EOPNOTSUPP
149340a8ac8fSEnji Cooper case EOPNOTSUPP:
149440a8ac8fSEnji Cooper return ("EOPNOTSUPP");
149540a8ac8fSEnji Cooper #endif
149640a8ac8fSEnji Cooper #ifdef EPFNOSUPPORT
149740a8ac8fSEnji Cooper case EPFNOSUPPORT:
149840a8ac8fSEnji Cooper return ("EPFNOSUPPORT");
149940a8ac8fSEnji Cooper #endif
150040a8ac8fSEnji Cooper #ifdef EAFNOSUPPORT
150140a8ac8fSEnji Cooper case EAFNOSUPPORT:
150240a8ac8fSEnji Cooper return ("EAFNOSUPPORT");
150340a8ac8fSEnji Cooper #endif
150440a8ac8fSEnji Cooper #ifdef EADDRINUSE
150540a8ac8fSEnji Cooper case EADDRINUSE:
150640a8ac8fSEnji Cooper return ("EADDRINUSE");
150740a8ac8fSEnji Cooper #endif
150840a8ac8fSEnji Cooper #ifdef EADDRNOTAVAIL
150940a8ac8fSEnji Cooper case EADDRNOTAVAIL:
151040a8ac8fSEnji Cooper return ("EADDRNOTAVAIL");
151140a8ac8fSEnji Cooper #endif
151240a8ac8fSEnji Cooper #ifdef ENETDOWN
151340a8ac8fSEnji Cooper case ENETDOWN:
151440a8ac8fSEnji Cooper return ("ENETDOWN");
151540a8ac8fSEnji Cooper #endif
151640a8ac8fSEnji Cooper #ifdef ENETUNREACH
151740a8ac8fSEnji Cooper case ENETUNREACH:
151840a8ac8fSEnji Cooper return ("ENETUNREACH");
151940a8ac8fSEnji Cooper #endif
152040a8ac8fSEnji Cooper #ifdef ENETRESET
152140a8ac8fSEnji Cooper case ENETRESET:
152240a8ac8fSEnji Cooper return ("ENETRESET");
152340a8ac8fSEnji Cooper #endif
152440a8ac8fSEnji Cooper #ifdef ECONNABORTED
152540a8ac8fSEnji Cooper case ECONNABORTED:
152640a8ac8fSEnji Cooper return ("ECONNABORTED");
152740a8ac8fSEnji Cooper #endif
152840a8ac8fSEnji Cooper #ifdef ECONNRESET
152940a8ac8fSEnji Cooper case ECONNRESET:
153040a8ac8fSEnji Cooper return ("ECONNRESET");
153140a8ac8fSEnji Cooper #endif
153240a8ac8fSEnji Cooper #ifdef ENOBUFS
153340a8ac8fSEnji Cooper case ENOBUFS:
153440a8ac8fSEnji Cooper return ("ENOBUFS");
153540a8ac8fSEnji Cooper #endif
153640a8ac8fSEnji Cooper #ifdef EISCONN
153740a8ac8fSEnji Cooper case EISCONN:
153840a8ac8fSEnji Cooper return ("EISCONN");
153940a8ac8fSEnji Cooper #endif
154040a8ac8fSEnji Cooper #ifdef ENOTCONN
154140a8ac8fSEnji Cooper case ENOTCONN:
154240a8ac8fSEnji Cooper return ("ENOTCONN");
154340a8ac8fSEnji Cooper #endif
154440a8ac8fSEnji Cooper #ifdef ESHUTDOWN
154540a8ac8fSEnji Cooper case ESHUTDOWN:
154640a8ac8fSEnji Cooper return ("ESHUTDOWN");
154740a8ac8fSEnji Cooper #endif
154840a8ac8fSEnji Cooper #ifdef ETOOMANYREFS
154940a8ac8fSEnji Cooper case ETOOMANYREFS:
155040a8ac8fSEnji Cooper return ("ETOOMANYREFS");
155140a8ac8fSEnji Cooper #endif
155240a8ac8fSEnji Cooper #ifdef ETIMEDOUT
155340a8ac8fSEnji Cooper case ETIMEDOUT:
155440a8ac8fSEnji Cooper return ("ETIMEDOUT");
155540a8ac8fSEnji Cooper #endif
155640a8ac8fSEnji Cooper #ifdef ECONNREFUSED
155740a8ac8fSEnji Cooper case ECONNREFUSED:
155840a8ac8fSEnji Cooper return ("ECONNREFUSED");
155940a8ac8fSEnji Cooper #endif
156040a8ac8fSEnji Cooper #ifdef ELOOP
156140a8ac8fSEnji Cooper case ELOOP:
156240a8ac8fSEnji Cooper return ("ELOOP");
156340a8ac8fSEnji Cooper #endif
156440a8ac8fSEnji Cooper #ifdef ENAMETOOLONG
156540a8ac8fSEnji Cooper case ENAMETOOLONG:
156640a8ac8fSEnji Cooper return ("ENAMETOOLONG");
156740a8ac8fSEnji Cooper #endif
156840a8ac8fSEnji Cooper #ifdef EHOSTDOWN
156940a8ac8fSEnji Cooper case EHOSTDOWN:
157040a8ac8fSEnji Cooper return ("EHOSTDOWN");
157140a8ac8fSEnji Cooper #endif
157240a8ac8fSEnji Cooper #ifdef EHOSTUNREACH
157340a8ac8fSEnji Cooper case EHOSTUNREACH:
157440a8ac8fSEnji Cooper return ("EHOSTUNREACH");
157540a8ac8fSEnji Cooper #endif
157640a8ac8fSEnji Cooper #ifdef ENOTEMPTY
157740a8ac8fSEnji Cooper case ENOTEMPTY:
157840a8ac8fSEnji Cooper return ("ENOTEMPTY");
157940a8ac8fSEnji Cooper #endif
158040a8ac8fSEnji Cooper #ifdef EPROCLIM
158140a8ac8fSEnji Cooper case EPROCLIM:
158240a8ac8fSEnji Cooper return ("EPROCLIM");
158340a8ac8fSEnji Cooper #endif
158440a8ac8fSEnji Cooper #ifdef EUSERS
158540a8ac8fSEnji Cooper case EUSERS:
158640a8ac8fSEnji Cooper return ("EUSERS");
158740a8ac8fSEnji Cooper #endif
158840a8ac8fSEnji Cooper #ifdef EDQUOT
158940a8ac8fSEnji Cooper case EDQUOT:
159040a8ac8fSEnji Cooper return ("EDQUOT");
159140a8ac8fSEnji Cooper #endif
159240a8ac8fSEnji Cooper #ifdef ESTALE
159340a8ac8fSEnji Cooper case ESTALE:
159440a8ac8fSEnji Cooper return ("ESTALE");
159540a8ac8fSEnji Cooper #endif
159640a8ac8fSEnji Cooper #ifdef EREMOTE
159740a8ac8fSEnji Cooper case EREMOTE:
159840a8ac8fSEnji Cooper return ("EREMOTE");
159940a8ac8fSEnji Cooper #endif
160040a8ac8fSEnji Cooper #ifdef EBADRPC
160140a8ac8fSEnji Cooper case EBADRPC:
160240a8ac8fSEnji Cooper return ("EBADRPC");
160340a8ac8fSEnji Cooper #endif
160440a8ac8fSEnji Cooper #ifdef ERPCMISMATCH
160540a8ac8fSEnji Cooper case ERPCMISMATCH:
160640a8ac8fSEnji Cooper return ("ERPCMISMATCH");
160740a8ac8fSEnji Cooper #endif
160840a8ac8fSEnji Cooper #ifdef EPROGUNAVAIL
160940a8ac8fSEnji Cooper case EPROGUNAVAIL:
161040a8ac8fSEnji Cooper return ("EPROGUNAVAIL");
161140a8ac8fSEnji Cooper #endif
161240a8ac8fSEnji Cooper #ifdef EPROGMISMATCH
161340a8ac8fSEnji Cooper case EPROGMISMATCH:
161440a8ac8fSEnji Cooper return ("EPROGMISMATCH");
161540a8ac8fSEnji Cooper #endif
161640a8ac8fSEnji Cooper #ifdef EPROCUNAVAIL
161740a8ac8fSEnji Cooper case EPROCUNAVAIL:
161840a8ac8fSEnji Cooper return ("EPROCUNAVAIL");
161940a8ac8fSEnji Cooper #endif
162040a8ac8fSEnji Cooper #ifdef ENOLCK
162140a8ac8fSEnji Cooper case ENOLCK:
162240a8ac8fSEnji Cooper return ("ENOLCK");
162340a8ac8fSEnji Cooper #endif
162440a8ac8fSEnji Cooper #ifdef ENOSYS
162540a8ac8fSEnji Cooper case ENOSYS:
162640a8ac8fSEnji Cooper return ("ENOSYS");
162740a8ac8fSEnji Cooper #endif
162840a8ac8fSEnji Cooper #ifdef EFTYPE
162940a8ac8fSEnji Cooper case EFTYPE:
163040a8ac8fSEnji Cooper return ("EFTYPE");
163140a8ac8fSEnji Cooper #endif
163240a8ac8fSEnji Cooper #ifdef EAUTH
163340a8ac8fSEnji Cooper case EAUTH:
163440a8ac8fSEnji Cooper return ("EAUTH");
163540a8ac8fSEnji Cooper #endif
163640a8ac8fSEnji Cooper #ifdef ENEEDAUTH
163740a8ac8fSEnji Cooper case ENEEDAUTH:
163840a8ac8fSEnji Cooper return ("ENEEDAUTH");
163940a8ac8fSEnji Cooper #endif
164040a8ac8fSEnji Cooper #ifdef EIDRM
164140a8ac8fSEnji Cooper case EIDRM:
164240a8ac8fSEnji Cooper return ("EIDRM");
164340a8ac8fSEnji Cooper #endif
164440a8ac8fSEnji Cooper #ifdef ENOMSG
164540a8ac8fSEnji Cooper case ENOMSG:
164640a8ac8fSEnji Cooper return ("ENOMSG");
164740a8ac8fSEnji Cooper #endif
164840a8ac8fSEnji Cooper #ifdef EOVERFLOW
164940a8ac8fSEnji Cooper case EOVERFLOW:
165040a8ac8fSEnji Cooper return ("EOVERFLOW");
165140a8ac8fSEnji Cooper #endif
165240a8ac8fSEnji Cooper #ifdef ECANCELED
165340a8ac8fSEnji Cooper case ECANCELED:
165440a8ac8fSEnji Cooper return ("ECANCELED");
165540a8ac8fSEnji Cooper #endif
165640a8ac8fSEnji Cooper #ifdef EILSEQ
165740a8ac8fSEnji Cooper case EILSEQ:
165840a8ac8fSEnji Cooper return ("EILSEQ");
165940a8ac8fSEnji Cooper #endif
166040a8ac8fSEnji Cooper #ifdef ENOATTR
166140a8ac8fSEnji Cooper case ENOATTR:
166240a8ac8fSEnji Cooper return ("ENOATTR");
166340a8ac8fSEnji Cooper #endif
166440a8ac8fSEnji Cooper #ifdef EDOOFUS
166540a8ac8fSEnji Cooper case EDOOFUS:
166640a8ac8fSEnji Cooper return ("EDOOFUS");
166740a8ac8fSEnji Cooper #endif
166840a8ac8fSEnji Cooper #ifdef EBADMSG
166940a8ac8fSEnji Cooper case EBADMSG:
167040a8ac8fSEnji Cooper return ("EBADMSG");
167140a8ac8fSEnji Cooper #endif
167240a8ac8fSEnji Cooper #ifdef EMULTIHOP
167340a8ac8fSEnji Cooper case EMULTIHOP:
167440a8ac8fSEnji Cooper return ("EMULTIHOP");
167540a8ac8fSEnji Cooper #endif
167640a8ac8fSEnji Cooper #ifdef ENOLINK
167740a8ac8fSEnji Cooper case ENOLINK:
167840a8ac8fSEnji Cooper return ("ENOLINK");
167940a8ac8fSEnji Cooper #endif
168040a8ac8fSEnji Cooper #ifdef EPROTO
168140a8ac8fSEnji Cooper case EPROTO:
168240a8ac8fSEnji Cooper return ("EPROTO");
168340a8ac8fSEnji Cooper #endif
168440a8ac8fSEnji Cooper default:
168540a8ac8fSEnji Cooper snprintf(errnum, sizeof(errnum), "%d", error);
168640a8ac8fSEnji Cooper return (errnum);
168740a8ac8fSEnji Cooper }
168840a8ac8fSEnji Cooper }
1689