version 1.54, 2015/11/13 08:30:18 |
version 1.55, 2015/11/13 08:32:10 |
|
|
|
|
__dead void usage(void); |
__dead void usage(void); |
|
|
|
static int prepare_message(struct input_msg *, int, const char *); |
static void send_message(struct imsgbuf *, void *, size_t, int); |
static void send_message(struct imsgbuf *, void *, size_t, int); |
static int read_message(struct imsgbuf *, struct imsg *, pid_t); |
static int read_message(struct imsgbuf *, struct imsg *, pid_t); |
|
|
|
|
int |
int |
main(int argc, char **argv) |
main(int argc, char **argv) |
{ |
{ |
int opt, pair[2], fd, idx, mode, error; |
int opt, pair[2], fd, idx; |
char *home; |
char *home; |
struct passwd *pw; |
struct passwd *pw; |
struct imsgbuf ibuf; |
struct imsgbuf ibuf; |
|
|
|
|
imsg_init(&ibuf, pair[0]); |
imsg_init(&ibuf, pair[0]); |
for (idx = 0; idx < argc; idx++) { |
for (idx = 0; idx < argc; idx++) { |
memset(&msg, 0, sizeof msg); |
fd = prepare_message(&msg, idx, argv[idx]); |
msg.idx = idx; |
|
|
|
if (strcmp(argv[idx], "-") == 0) { |
|
if (fstat(STDIN_FILENO, &msg.sb) == -1) { |
|
fd = -1; |
|
msg.error = errno; |
|
} else |
|
fd = STDIN_FILENO; |
|
} else { |
|
if (Lflag) |
|
error = stat(argv[idx], &msg.sb); |
|
else |
|
error = lstat(argv[idx], &msg.sb); |
|
if (error == -1) { |
|
fd = -1; |
|
msg.error = errno; |
|
} else { |
|
/* |
|
* pledge(2) doesn't let us pass directory file |
|
* descriptors around - but in fact we don't |
|
* need them, so just don't open directories or |
|
* symlinks (which could be to directories). |
|
*/ |
|
mode = msg.sb.st_mode; |
|
if (!S_ISDIR(mode) && !S_ISLNK(mode)) { |
|
fd = open(argv[idx], |
|
O_RDONLY|O_NONBLOCK); |
|
if (fd == -1 && (errno == ENFILE || |
|
errno == EMFILE)) |
|
err(1, "open"); |
|
} else |
|
fd = -1; |
|
if (S_ISLNK(mode)) |
|
read_link(&msg, argv[idx]); |
|
} |
|
} |
|
send_message(&ibuf, &msg, sizeof msg, fd); |
send_message(&ibuf, &msg, sizeof msg, fd); |
|
|
if (read_message(&ibuf, &imsg, pid) == 0) |
if (read_message(&ibuf, &imsg, pid) == 0) |
|
|
err(1, "wait"); |
err(1, "wait"); |
} |
} |
_exit(0); /* let the child flush */ |
_exit(0); /* let the child flush */ |
|
} |
|
|
|
static int |
|
prepare_message(struct input_msg *msg, int idx, const char *path) |
|
{ |
|
int fd, mode, error; |
|
|
|
memset(msg, 0, sizeof *msg); |
|
msg->idx = idx; |
|
|
|
if (strcmp(path, "-") == 0) { |
|
if (fstat(STDIN_FILENO, &msg->sb) == -1) { |
|
msg->error = errno; |
|
return (-1); |
|
} |
|
return (STDIN_FILENO); |
|
} |
|
|
|
if (Lflag) |
|
error = stat(path, &msg->sb); |
|
else |
|
error = lstat(path, &msg->sb); |
|
if (error == -1) { |
|
msg->error = errno; |
|
return (-1); |
|
} |
|
|
|
/* |
|
* pledge(2) doesn't let us pass directory file descriptors around - |
|
* but in fact we don't need them, so just don't open directories or |
|
* symlinks (which could be to directories). |
|
*/ |
|
mode = msg->sb.st_mode; |
|
if (!S_ISDIR(mode) && !S_ISLNK(mode)) { |
|
fd = open(path, O_RDONLY|O_NONBLOCK); |
|
if (fd == -1 && (errno == ENFILE || errno == EMFILE)) |
|
err(1, "open"); |
|
} else |
|
fd = -1; |
|
if (S_ISLNK(mode)) |
|
read_link(msg, path); |
|
return (fd); |
|
|
} |
} |
|
|
static void |
static void |