aboutsummaryrefslogtreecommitdiffstats
path: root/pseudo_client.c
diff options
context:
space:
mode:
Diffstat (limited to 'pseudo_client.c')
-rw-r--r--pseudo_client.c115
1 files changed, 75 insertions, 40 deletions
diff --git a/pseudo_client.c b/pseudo_client.c
index 319fa05..b53ee25 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -32,13 +32,19 @@
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
#include "pseudo.h"
#include "pseudo_ipc.h"
#include "pseudo_client.h"
/* GNU extension */
+#if PSEUDO_PORT_LINUX
extern char *program_invocation_name;
+#else
+static char *program_invocation_name = "unknown";
+#endif
static char *base_path(int dirfd, const char *path, int leave_last);
@@ -60,6 +66,7 @@ size_t pseudo_chroot_len = 0;
char *pseudo_cwd_rel = NULL;
/* used for PSEUDO_DISABLED */
int pseudo_disabled = 0;
+static int pseudo_local_only = 0;
static char **fd_paths = NULL;
static int nfds = 0;
@@ -117,7 +124,9 @@ pseudo_init_client(void) {
* pseudo (and cause it to reinit the defaults).
*/
env = getenv("PSEUDO_DISABLED");
- if (!env) pseudo_get_value("PSEUDO_DISABLED");
+ if (!env) {
+ env = pseudo_get_value("PSEUDO_DISABLED");
+ }
if (env) {
int actually_disabled = 1;
switch (*env) {
@@ -128,6 +137,11 @@ pseudo_init_client(void) {
case 'N':
actually_disabled = 0;
break;
+ case 's':
+ case 'S':
+ actually_disabled = 0;
+ pseudo_local_only = 1;
+ break;
}
if (actually_disabled) {
if (!pseudo_disabled) {
@@ -287,10 +301,26 @@ pseudo_file_close(int *fd, FILE **fp) {
}
pseudo_antimagic();
if (*fp) {
+#if PSEUDO_PORT_DARWIN
+ if (*fp == pseudo_host_etc_passwd_file) {
+ endpwent();
+ } else if (*fp != pseudo_host_etc_group_file) {
+ endgrent();
+ } else {
+ fclose(*fp);
+ }
+#else
fclose(*fp);
+#endif
*fd = -1;
*fp = 0;
}
+#if PSEUDO_PORT_DARWIN
+ if (*fd == pseudo_host_etc_passwd_fd ||
+ *fd == pseudo_host_etc_group_fd) {
+ *fd = -1;
+ }
+#endif
/* this should be impossible */
if (*fd >= 0) {
close(*fd);
@@ -308,6 +338,15 @@ pseudo_file_open(char *name, int *fd, FILE **fp) {
pseudo_file_close(fd, fp);
pseudo_antimagic();
*fd = PSEUDO_ETC_FILE(name, NULL, O_RDONLY);
+#if PSEUDO_PORT_DARWIN
+ if (*fd == pseudo_host_etc_passwd_fd) {
+ *fp = pseudo_host_etc_passwd_file;
+ setpwent();
+ } else if (*fd == pseudo_host_etc_group_fd) {
+ *fp = pseudo_host_etc_group_file;
+ setgrent();
+ }
+#endif
if (*fd >= 0) {
*fd = pseudo_fd(*fd, MOVE_FD);
*fp = fdopen(*fd, "r");
@@ -601,7 +640,7 @@ client_spawn_server(void) {
pseudo_set_value("PSEUDO_RELOADED", "YES");
pseudo_setupenv();
- pseudo_dropenv(); /* drop LD_PRELOAD */
+ pseudo_dropenv(); /* drop PRELINK_LIBRARIES */
pseudo_debug(4, "calling execv on %s\n", argv[0]);
@@ -679,9 +718,13 @@ pseudo_fd(int fd, int how) {
static int
client_connect(void) {
/* we have a server pid, is it responsive? */
- struct sockaddr_un sun = { AF_UNIX, PSEUDO_SOCKET };
+ struct sockaddr_un sun = { .sun_family = AF_UNIX, .sun_path = PSEUDO_SOCKET };
int cwd_fd;
+#if PSEUDO_PORT_DARWIN
+ sun.sun_len = strlen(PSEUDO_SOCKET) + 1;
+#endif
+
connect_fd = socket(PF_UNIX, SOCK_STREAM, 0);
connect_fd = pseudo_fd(connect_fd, MOVE_FD);
if (connect_fd == -1) {
@@ -959,8 +1002,29 @@ base_path(int dirfd, const char *path, int leave_last) {
return newpath;
}
+#if PSEUDO_STATBUF_64
+pseudo_msg_t *
+pseudo_client_op_plain(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const struct stat *buf, ...) {
+ char *oldpath = NULL;
+ PSEUDO_STATBUF buf64;
+
+ if (op == OP_RENAME) {
+ va_list ap;
+ va_start(ap, buf);
+ oldpath = va_arg(ap, char *);
+ va_end(ap);
+ }
+ if (buf) {
+ pseudo_stat64_from32(&buf64, buf);
+ return pseudo_client_op(op, access, fd, dirfd, path, &buf64, oldpath);
+ } else {
+ return pseudo_client_op(op, access, fd, dirfd, path, NULL, oldpath);
+ }
+}
+#endif
+
pseudo_msg_t *
-pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const struct stat64 *buf, ...) {
+pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path, const PSEUDO_STATBUF *buf, ...) {
pseudo_msg_t *result = 0;
pseudo_msg_t msg = { .type = PSEUDO_MSG_OP };
size_t pathlen = -1;
@@ -1156,7 +1220,12 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
struct timeval tv1, tv2;
pseudo_debug(4, "sending request [ino %llu]\n", (unsigned long long) msg.ino);
gettimeofday(&tv1, NULL);
- result = pseudo_client_request(&msg, pathlen, path);
+ if (pseudo_local_only) {
+ /* disable server */
+ result = NULL;
+ } else {
+ result = pseudo_client_request(&msg, pathlen, path);
+ }
gettimeofday(&tv2, NULL);
++messages;
message_time.tv_sec += (tv2.tv_sec - tv1.tv_sec);
@@ -1208,40 +1277,6 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path
return result;
}
-void
-pseudo_stat32_from64(struct stat *buf32, struct stat64 *buf) {
- buf32->st_dev = buf->st_dev;
- buf32->st_ino = buf->st_ino;
- buf32->st_mode = buf->st_mode;
- buf32->st_nlink = buf->st_nlink;
- buf32->st_uid = buf->st_uid;
- buf32->st_gid = buf->st_gid;
- buf32->st_rdev = buf->st_rdev;
- buf32->st_size = buf->st_size;
- buf32->st_blksize = buf->st_blksize;
- buf32->st_blocks = buf->st_blocks;
- buf32->st_atime = buf->st_atime;
- buf32->st_mtime = buf->st_mtime;
- buf32->st_ctime = buf->st_ctime;
-}
-
-void
-pseudo_stat64_from32(struct stat64 *buf64, struct stat *buf) {
- buf64->st_dev = buf->st_dev;
- buf64->st_ino = buf->st_ino;
- buf64->st_mode = buf->st_mode;
- buf64->st_nlink = buf->st_nlink;
- buf64->st_uid = buf->st_uid;
- buf64->st_gid = buf->st_gid;
- buf64->st_rdev = buf->st_rdev;
- buf64->st_size = buf->st_size;
- buf64->st_blksize = buf->st_blksize;
- buf64->st_blocks = buf->st_blocks;
- buf64->st_atime = buf->st_atime;
- buf64->st_mtime = buf->st_mtime;
- buf64->st_ctime = buf->st_ctime;
-}
-
/* stuff for handling paths and execs */
static char *previous_path;
static char *previous_path_segs;
@@ -1257,7 +1292,7 @@ static void
populate_path_segs(void) {
size_t len = 0;
char *s;
- int c;
+ int c = 0;
free(path_segs);
free(previous_path_segs);