diff options
Diffstat (limited to 'ports/darwin')
-rw-r--r-- | ports/darwin/guts/COPYRIGHT | 17 | ||||
-rw-r--r-- | ports/darwin/guts/fcntl.c | 46 | ||||
-rw-r--r-- | ports/darwin/guts/fgetgrent_r.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/fgetpwent_r.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/fgetxattr.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/flistxattr.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/fsetxattr.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/fstat.c | 27 | ||||
-rw-r--r-- | ports/darwin/guts/getgrent_r.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/getgrouplist.c | 42 | ||||
-rw-r--r-- | ports/darwin/guts/getgroups.c | 22 | ||||
-rw-r--r-- | ports/darwin/guts/getpwent_r.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/getxattr.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/listxattr.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/lstat.c | 27 | ||||
-rw-r--r-- | ports/darwin/guts/open.c | 49 | ||||
-rw-r--r-- | ports/darwin/guts/scandir.c | 14 | ||||
-rw-r--r-- | ports/darwin/guts/setxattr.c | 13 | ||||
-rw-r--r-- | ports/darwin/guts/stat.c | 31 | ||||
-rw-r--r-- | ports/darwin/portdefs.h | 10 | ||||
-rw-r--r-- | ports/darwin/preports | 2 | ||||
-rw-r--r-- | ports/darwin/pseudo_wrappers.c | 316 | ||||
-rw-r--r-- | ports/darwin/subports | 3 | ||||
-rw-r--r-- | ports/darwin/wrapfuncs.in | 25 |
24 files changed, 761 insertions, 0 deletions
diff --git a/ports/darwin/guts/COPYRIGHT b/ports/darwin/guts/COPYRIGHT new file mode 100644 index 0000000..c96e1b1 --- /dev/null +++ b/ports/darwin/guts/COPYRIGHT @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2008-2010 Wind River Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Lesser GNU General Public License for more details. + * + * You should have received a copy of the Lesser GNU General Public License + * version 2.1 along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ diff --git a/ports/darwin/guts/fcntl.c b/ports/darwin/guts/fcntl.c new file mode 100644 index 0000000..ef42b33 --- /dev/null +++ b/ports/darwin/guts/fcntl.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fcntl(int fd, int cmd, ... { struct flock *lock }) + * int rc = -1; + */ + int save_errno; + long long flag = 0; + void *ptr = 0; + off_t off = 0; + + va_start(ap, cmd); + flag = va_arg(ap, long long); + va_end(ap); + rc = real_fcntl(fd, cmd, flag); + + switch (cmd) { + case F_DUPFD: +#ifdef F_DUPFD_CLOEXEC + /* it doesn't exist now, but if I take this out they'll add it + * just to mess with me. + */ + case F_DUPFD_CLOEXEC: +#endif + /* actually do something */ + save_errno = errno; + if (rc != -1) { + pseudo_debug(2, "fcntl_dup: %d->%d\n", fd, rc); + pseudo_client_op(OP_DUP, 0, fd, rc, 0, 0); + } + errno = save_errno; + break; + default: + /* nothing to do, we hope */ + break; + } + + save_errno = errno; + pseudo_debug(3, "fcntl(fd %d, cmd %d, %llx) => %d (%s)\n", + fd, cmd, flag, rc, strerror(errno)); + errno = save_errno; + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/fgetgrent_r.c b/ports/darwin/guts/fgetgrent_r.c new file mode 100644 index 0000000..e760cdd --- /dev/null +++ b/ports/darwin/guts/fgetgrent_r.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fgetgrent_r(FILE *fp, struct group*gbuf, char *buf, size_t buflen, struct group **gbufp) + * int rc = -1; + */ + + rc = real_fgetgrent_r(fp, gbuf, buf, buflen, gbufp); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/fgetpwent_r.c b/ports/darwin/guts/fgetpwent_r.c new file mode 100644 index 0000000..cfea5b8 --- /dev/null +++ b/ports/darwin/guts/fgetpwent_r.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fgetpwent_r(FILE *fp, struct passwd *pbuf, char *buf, size_t buflen, struct passwd **pbufp) + * int rc = -1; + */ + + rc = real_fgetpwent_r(fp, pbuf, buf, buflen, pbufp); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/fgetxattr.c b/ports/darwin/guts/fgetxattr.c new file mode 100644 index 0000000..1cd8904 --- /dev/null +++ b/ports/darwin/guts/fgetxattr.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size, u_int32_t position, int options) + * ssize_t rc = -1; + */ + + rc = real_fgetxattr(filedes, name, value, size, position, options); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/flistxattr.c b/ports/darwin/guts/flistxattr.c new file mode 100644 index 0000000..7575f28 --- /dev/null +++ b/ports/darwin/guts/flistxattr.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t flistxattr(int filedes, char *list, size_t size, int options) + * ssize_t rc = -1; + */ + + rc = real_flistxattr(filedes, list, size, options); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/fsetxattr.c b/ports/darwin/guts/fsetxattr.c new file mode 100644 index 0000000..541569a --- /dev/null +++ b/ports/darwin/guts/fsetxattr.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fsetxattr(int filedes, const char *name, const void *value, size_t size, u_int32_t position, int options) + * int rc = -1; + */ + + rc = real_fsetxattr(filedes, name, value, size, position, options); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/fstat.c b/ports/darwin/guts/fstat.c new file mode 100644 index 0000000..7695147 --- /dev/null +++ b/ports/darwin/guts/fstat.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int fstat(int fd, struct stat *buf) + * int rc = -1; + */ + pseudo_msg_t *msg; + + rc = real_fstat(fd, buf); + + if (rc == -1) { + return rc; + } + + /* query database + * note that symlink canonicalizing is now automatic, so we + * don't need to check for a symlink on this end + */ + msg = pseudo_client_op(OP_FSTAT, 0, fd, -1, 0, buf); + if (msg && msg->result == RESULT_SUCCEED) { + pseudo_stat_msg(buf, msg); + } + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/getgrent_r.c b/ports/darwin/guts/getgrent_r.c new file mode 100644 index 0000000..9d5db5a --- /dev/null +++ b/ports/darwin/guts/getgrent_r.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) + * int rc = -1; + */ + + rc = real_getgrent_r(gbuf, buf, buflen, gbufp); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/getgrouplist.c b/ports/darwin/guts/getgrouplist.c new file mode 100644 index 0000000..85fccc9 --- /dev/null +++ b/ports/darwin/guts/getgrouplist.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_getgrouplist(const char *name, int basegid, int *groups, int *ngroups) { + * int rc = -1; + */ + + int found = 0; + int found_group = 0; + char buf[PSEUDO_PWD_MAX]; + struct group grp, *gbuf = &grp; + + setgrent(); + while ((rc = wrap_getgrent_r(gbuf, buf, PSEUDO_PWD_MAX, &gbuf)) == 0) { + int i = 0; + for (i = 0; gbuf->gr_mem[i]; ++i) { + if (!strcmp(gbuf->gr_mem[i], name)) { + if (found < *ngroups) + groups[found] = gbuf->gr_gid; + ++found; + if ((int) gbuf->gr_gid == basegid) + found_group = 1; + } + } + } + endgrent(); + if (!found_group) { + if (found < *ngroups) + groups[found] = basegid; + ++found; + } + if (found >= *ngroups) + rc = -1; + else + rc = found; + *ngroups = found; + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/getgroups.c b/ports/darwin/guts/getgroups.c new file mode 100644 index 0000000..3cbeb76 --- /dev/null +++ b/ports/darwin/guts/getgroups.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_getgroups(int size, gid_t *list) { + * int rc = -1; + */ + struct passwd *p = wrap_getpwuid(wrap_getuid()); + int oldsize = size; + + if (p) { + rc = wrap_getgrouplist(p->pw_name, wrap_getgid(), (int *) list, &size); + if (oldsize == 0 || size <= oldsize) + rc = size; + } else { + errno = ENOENT; + } + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/getpwent_r.c b/ports/darwin/guts/getpwent_r.c new file mode 100644 index 0000000..3de41b9 --- /dev/null +++ b/ports/darwin/guts/getpwent_r.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) + * int rc = -1; + */ + + rc = real_getpwent_r(pwbuf, buf, buflen, pwbufp); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/getxattr.c b/ports/darwin/guts/getxattr.c new file mode 100644 index 0000000..16f0993 --- /dev/null +++ b/ports/darwin/guts/getxattr.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size, u_int32_t position, int options) + * ssize_t rc = -1; + */ + + rc = real_getxattr(pathname, name, value, size, position, options); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/listxattr.c b/ports/darwin/guts/listxattr.c new file mode 100644 index 0000000..0bba451 --- /dev/null +++ b/ports/darwin/guts/listxattr.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * ssize_t listxattr(const char *pathname, char *list, size_t size, int options) + * ssize_t rc = -1; + */ + + rc = real_listxattr(pathname, list, size, options); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/lstat.c b/ports/darwin/guts/lstat.c new file mode 100644 index 0000000..01e0f30 --- /dev/null +++ b/ports/darwin/guts/lstat.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int lstat(const char *path, struct stat *buf) + * int rc = -1; + */ + + pseudo_msg_t *msg; + + rc = real_lstat(path, buf); + if (rc == -1) { + return rc; + } + + /* query database + * note that symlink canonicalizing is now automatic, so we + * don't need to check for a symlink on this end + */ + msg = pseudo_client_op(OP_STAT, 0, -1, -1, path, buf); + if (msg && msg->result == RESULT_SUCCEED) { + pseudo_stat_msg(buf, msg); + } + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/open.c b/ports/darwin/guts/open.c new file mode 100644 index 0000000..64cb6ad --- /dev/null +++ b/ports/darwin/guts/open.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int open(const char *path, int flags, ... { int mode }) + * int rc = -1; + */ + + struct stat buf; + int existed = 1; + int save_errno; + + /* if a creation has been requested, check whether file exists */ + if (flags & O_CREAT) { + save_errno = errno; + rc = real_stat(path, &buf); + existed = (rc != -1); + if (!existed) + pseudo_debug(2, "open_creat: %s -> 0%o\n", path, mode); + errno = save_errno; + } + + /* because we are not actually root, secretly mask in 0700 to the + * underlying mode + */ + rc = real_open(path, flags, PSEUDO_FS_MODE(mode)); + save_errno = errno; + + if (rc != -1) { + int stat_rc; + stat_rc = real_stat(path, &buf); + + if (stat_rc != -1) { + buf.st_mode = PSEUDO_DB_MODE(buf.st_mode, mode); + if (!existed) { + pseudo_client_op(OP_CREAT, 0, -1, -1, path, &buf); + } + pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, -1, path, &buf); + } else { + pseudo_debug(1, "open (fd %d, path %s, flags %d) succeeded, but stat failed (%s).\n", + rc, path, flags, strerror(errno)); + pseudo_client_op(OP_OPEN, PSEUDO_ACCESS(flags), rc, -1, path, 0); + } + errno = save_errno; + } + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/scandir.c b/ports/darwin/guts/scandir.c new file mode 100644 index 0000000..6492b1b --- /dev/null +++ b/ports/darwin/guts/scandir.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2010 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * static int + * wrap_scandir(const char *path, struct dirent ***namelist, int (*filter)(struct dirent *), int (*compar)(const void *, const void *)) { + * int rc = -1; + */ + + rc = real_scandir(path, namelist, filter, compar); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/setxattr.c b/ports/darwin/guts/setxattr.c new file mode 100644 index 0000000..3c8fd3d --- /dev/null +++ b/ports/darwin/guts/setxattr.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int setxattr(const char *pathname, const char *name, const void *value, size_t size, u_int32_t position, int options) + * int rc = -1; + */ + + rc = real_setxattr(pathname, name, value, size, position, options); + +/* return rc; + * } + */ diff --git a/ports/darwin/guts/stat.c b/ports/darwin/guts/stat.c new file mode 100644 index 0000000..1e1cf67 --- /dev/null +++ b/ports/darwin/guts/stat.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 Wind River Systems; see + * guts/COPYRIGHT for information. + * + * int stat(const char *path, struct stat *buf) + * int rc = -1; + */ + + pseudo_msg_t *msg; + int save_errno; + + rc = real_stat(path, buf); + if (rc == -1) { + return rc; + } + save_errno = errno; + + /* query database + * note that symlink canonicalizing is now automatic, so we + * don't need to check for a symlink on this end + */ + msg = pseudo_client_op(OP_STAT, 0, -1, AT_FDCWD, path, buf); + if (msg) { + pseudo_stat_msg(buf, msg); + } + + errno = save_errno; + +/* return rc; + * } + */ diff --git a/ports/darwin/portdefs.h b/ports/darwin/portdefs.h new file mode 100644 index 0000000..f27e28d --- /dev/null +++ b/ports/darwin/portdefs.h @@ -0,0 +1,10 @@ +#define PRELINK_LIBRARIES "DYLD_INSERT_LIBRARIES" +#define PRELINK_PATH "DYLD_LIBRARY_PATH" +#define PSEUDO_STATBUF_64 0 +#define PSEUDO_STATBUF struct stat +#define PSEUDO_LINKPATH_SEPARATOR ":" +/* hackery to allow sneaky things to be done with getgrent() */ +extern int pseudo_host_etc_passwd_fd; +extern int pseudo_host_etc_group_fd; +extern FILE *pseudo_host_etc_passwd_file; +extern FILE *pseudo_host_etc_group_file; diff --git a/ports/darwin/preports b/ports/darwin/preports new file mode 100644 index 0000000..a996c69 --- /dev/null +++ b/ports/darwin/preports @@ -0,0 +1,2 @@ +#!/bin/sh +echo "unix" "uids_generic" diff --git a/ports/darwin/pseudo_wrappers.c b/ports/darwin/pseudo_wrappers.c new file mode 100644 index 0000000..36d9172 --- /dev/null +++ b/ports/darwin/pseudo_wrappers.c @@ -0,0 +1,316 @@ +/* + * pseudo_wrappers.c, darwin pseudo wrappers + * + * Copyright (c) 2008-2011 Wind River Systems, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the Lesser GNU General Public License version 2.1 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the Lesser GNU General Public License for more details. + * + * You should have received a copy of the Lesser GNU General Public License + * version 2.1 along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +/* there's no fgetgrent_r or fgetpwent_r in Darwin */ +int +pseudo_getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp) { + /* note that we don't wrap fgetpwent_r, since there's no path + * references in it. + */ + if (!pseudo_pwd) { + errno = ENOENT; + return -1; + } + return fgetpwent_r(pseudo_pwd, pwbuf, buf, buflen, pwbufp); +} + +int +pseudo_getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) { + /* note that we don't wrap fgetgrent_r, since there's no path + * references in it. + */ + if (!pseudo_grp) { + errno = ENOENT; + return -1; + } + return fgetgrent_r(pseudo_grp, gbuf, buf, buflen, gbufp); +} + +#define PLENTY_LONG 2048 +/* the original uid/gid code for Linux was written in terms of the + * fget*ent_r() functions... which Darwin doesn't have. But wait! They're + * actually pretty easy to implement. + */ +int +pseudo_fgetgrent_r(FILE *fp, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp) { + char linebuf[PLENTY_LONG] = { 0 }; + char *s, *t, *u; + size_t max_members; + char **members; + size_t member = 0; + long started_at = -1; + gid_t gid; + int error = ENOENT; + size_t len; + + /* any early exit should set *gbufp to NULL */ + if (gbufp) + *gbufp = NULL; + + if (!gbuf || !fp || !buf) + goto error_out; + + if (fp == pseudo_host_etc_group_file) { + struct group *g; + pseudo_antimagic(); + g = getgrent(); + pseudo_magic(); + if (g) { + char *s = linebuf; + s += snprintf(linebuf, PLENTY_LONG, + "%s:%s:%ld:", + g->gr_name, + g->gr_passwd, + (long) g->gr_gid); + if (g->gr_mem) { + int i; + for (i = 0; g->gr_mem[i]; ++i) { + s += snprintf(s, + PLENTY_LONG - (s - linebuf), + "%s,", + g->gr_mem[i]); + } + if (s[-1] == ',') + --s; + } + strcpy(s, "\n"); + } else { + goto error_out; + } + } else { + started_at = ftell(fp); + if (started_at == -1) { + goto error_out; + } + s = fgets(linebuf, PLENTY_LONG, fp); + if (!s) { + goto error_out; + } + } + /* fgets will have stored a '\0' if there was no error; if there + * was an error, though, linebuf was initialized to all zeroes so + * the string is null-terminated anyway... + */ + len = strlen(linebuf); + if (len > buflen) { + error = ERANGE; + goto error_out; + } + memcpy(buf, linebuf, len); + /* round up to 8, hope for the best? */ + len = len + 8 + (((unsigned long long) (buf + len)) % 8); + members = (char **) (buf + len); + if (len >= buflen) { + error = ERANGE; + goto error_out; + } + /* this is how many pointers we have room for... */ + max_members = (buflen - len) / sizeof(*members); + + t = buf; + /* yes, I can assume that Darwin has strsep() */ + s = strsep(&t, ":"); + if (!s) { + goto error_out; + } + gbuf->gr_name = s; + s = strsep(&t, ":"); + if (!s) { + goto error_out; + } + gbuf->gr_passwd = s; + s = strsep(&t, ":"); + if (!s) { + goto error_out; + } + gid = (gid_t) strtol(s, &u, 10); + /* should be a null byte, otherwise we didn't get a valid number */ + if (*u) + goto error_out; + gbuf->gr_gid = gid; + + /* now, s points to a comma-separated list of members, which we + * want to stash pointers to in 'members'. + */ + s = strsep(&t, ":"); + t = s; + while ((s = strsep(&t, ",")) != NULL) { + if (*s) { + if (member + 1 > max_members) { + errno = ERANGE; + goto error_out; + } + members[member++] = s; + } + } + if (member + 1 > max_members) { + errno = ERANGE; + goto error_out; + } + members[member++] = NULL; + *gbufp = gbuf; + return 0; + +error_out: + if (started_at != -1) + fseek(fp, started_at, SEEK_SET); + return error; + return -1; +} + +int +pseudo_fgetpwent_r(FILE *fp, struct passwd *pbuf, char *buf, size_t buflen, struct passwd **pbufp) { + char linebuf[PLENTY_LONG] = { 0 }; + char *s, *t, *u; + long started_at = -1; + __darwin_time_t timestamp; + uid_t uid; + gid_t gid; + int error = ENOENT; + size_t len; + + /* any early exit should set *gbufp to NULL */ + if (pbufp) + *pbufp = NULL; + + if (!pbuf || !fp || !buf) + goto error_out; + + if (fp == pseudo_host_etc_passwd_file) { + struct passwd *p; + + pseudo_antimagic(); + p = getpwent(); + pseudo_magic(); + if (p) { + snprintf(linebuf, PLENTY_LONG, + "%s:%s:%ld:%ld:%s:%ld:%ld:%s:%s:%s\n", + p->pw_name, + p->pw_passwd, + (long) p->pw_uid, + (long) p->pw_gid, + p->pw_class, + (long) p->pw_change, + (long) p->pw_expire, + p->pw_gecos, + p->pw_dir, + p->pw_shell); + } else { + goto error_out; + } + } else { + started_at = ftell(fp); + if (started_at == -1) { + goto error_out; + } + s = fgets(linebuf, PLENTY_LONG, fp); + if (!s) { + goto error_out; + } + } + /* fgets will have stored a '\0' if there was no error; if there + * was an error, though, linebuf was initialized to all zeroes so + * the string is null-terminated anyway... + */ + len = strlen(linebuf); + if (len > buflen) { + error = ERANGE; + goto error_out; + } + if (linebuf[len - 1] == '\n') { + linebuf[len - 1] = '\0'; + --len; + } + memcpy(buf, linebuf, len); + + t = buf; + /* yes, I can assume that Darwin has strsep() */ + s = strsep(&t, ":"); + if (!s) { + goto error_out; + } + pbuf->pw_name = s; + + s = strsep(&t, ":"); + if (!s) + goto error_out; + pbuf->pw_passwd = s; + + s = strsep(&t, ":"); + if (!s) + goto error_out; + uid = (uid_t) strtol(s, &u, 10); + /* should be a null byte, otherwise we didn't get a valid number */ + if (*u) + goto error_out; + pbuf->pw_uid = uid; + + s = strsep(&t, ":"); + if (!s) + goto error_out; + gid = (gid_t) strtol(s, &u, 10); + /* should be a null byte, otherwise we didn't get a valid number */ + if (*u) + goto error_out; + pbuf->pw_gid = gid; + + s = strsep(&t, ":"); + if (!s) + goto error_out; + pbuf->pw_class = s; + + s = strsep(&t, ":"); + if (!s) + goto error_out; + timestamp = (__darwin_time_t) strtol(s, &u, 10); + /* should be a null byte, otherwise we didn't get a valid number */ + if (*u) + goto error_out; + pbuf->pw_change = timestamp; + + timestamp = (__darwin_time_t) strtol(s, &u, 10); + /* should be a null byte, otherwise we didn't get a valid number */ + if (*u) + goto error_out; + pbuf->pw_expire = timestamp; + + s = strsep(&t, ":"); + if (!s) + goto error_out; + pbuf->pw_gecos = s; + + s = strsep(&t, ":"); + if (!s) + goto error_out; + pbuf->pw_dir = s; + + s = strsep(&t, ":"); + if (!s) + goto error_out; + pbuf->pw_shell = s; + + *pbufp = pbuf; + return 0; + +error_out: + if (started_at != -1) + fseek(fp, started_at, SEEK_SET); + return error; + return -1; +} diff --git a/ports/darwin/subports b/ports/darwin/subports new file mode 100644 index 0000000..57bdd6d --- /dev/null +++ b/ports/darwin/subports @@ -0,0 +1,3 @@ +#!/bin/sh +# no subports at this time +exit 0 diff --git a/ports/darwin/wrapfuncs.in b/ports/darwin/wrapfuncs.in new file mode 100644 index 0000000..39d9893 --- /dev/null +++ b/ports/darwin/wrapfuncs.in @@ -0,0 +1,25 @@ +# On Darwin, mode_t promotes to int, so you have to use int for va_arg +int open(const char *path, int flags, ...{int mode}); /* flags=0 */ +int stat(const char *path, struct stat *buf); /* inode64=1 */ +int lstat(const char *path, struct stat *buf); /* flags=AT_SYMLINK_NOFOLLOW, inode64=1 */ +int fstat(int fd, struct stat *buf); /* inode64=1 */ +int fcntl(int fd, int cmd, ...{struct flock *lock}); +# just so we know the inums of symlinks +# for emulation of passwd utilities +int getgrouplist(const char *user, gid_t group, gid_t *groups, int *ngroups); +# we use "pathname" to avoid canonicalizing paths, because these functions are +# unimplemented +ssize_t getxattr(const char *pathname, const char *name, void *value, size_t size, u_int32_t position, int options); +ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size, u_int32_t position, int options); +ssize_t listxattr(const char *pathname, char *list, size_t size, int options); +ssize_t flistxattr(int filedes, char *list, size_t size, int options); +int setxattr(const char *pathname, const char *name, const void *value, size_t size, u_int32_t position, int options); +int fsetxattr(int filedes, const char *name, const void *value, size_t size, u_int32_t position, int options); +# local color UIDs +int getgrouplist(const char *name, int basegid, int *groups, int *ngroups); +int scandir(const char *path, struct dirent ***namelist, int (*filter)(struct dirent *), int (*compar)()); +int getgroups(int size, gid_t *list); +int fgetgrent_r(FILE *fp, struct group *gbuf, char *buf, size_t buflen, struct group **gbufp); /* real_func=pseudo_fgetgrent_r */ +int fgetpwent_r(FILE *fp, struct passwd *pbuf, char *buf, size_t buflen, struct passwd **pbufp); /* real_func=pseudo_fgetpwent_r */ +int getpwent_r(struct passwd *pwbuf, char *buf, size_t buflen, struct passwd **pwbufp); /* real_func=pseudo_getpwent_r */ +int getgrent_r(struct group *gbuf, char *buf, size_t buflen, struct group **gbufp); /* real_func=pseudo_getgrent_r */ |