diff options
author | obrien <obrien@FreeBSD.org> | 2007-12-05 15:48:03 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2007-12-05 15:48:03 +0000 |
commit | ea691ecd980d2860f0b39e9e504de4da404806fd (patch) | |
tree | fa83b3bb0660890a21b550fa1f334b151bf098f9 /contrib/amd/libamu | |
parent | c06a2e613662fc6ce10145b41762be8f8ab22ba4 (diff) | |
download | FreeBSD-src-ea691ecd980d2860f0b39e9e504de4da404806fd.zip FreeBSD-src-ea691ecd980d2860f0b39e9e504de4da404806fd.tar.gz |
Virgin import of AMD (am-utils) v6.1.5
Sponsored by: Juniper Networks
Diffstat (limited to 'contrib/amd/libamu')
-rw-r--r-- | contrib/amd/libamu/amu.h | 7 | ||||
-rw-r--r-- | contrib/amd/libamu/hasmntopt.c | 15 | ||||
-rw-r--r-- | contrib/amd/libamu/misc_rpc.c | 7 | ||||
-rw-r--r-- | contrib/amd/libamu/mount_fs.c | 450 | ||||
-rw-r--r-- | contrib/amd/libamu/mtab.c | 131 | ||||
-rw-r--r-- | contrib/amd/libamu/nfs_prot_xdr.c | 5 | ||||
-rw-r--r-- | contrib/amd/libamu/strerror.c | 8 | ||||
-rw-r--r-- | contrib/amd/libamu/strutil.c | 270 | ||||
-rw-r--r-- | contrib/amd/libamu/wire.c | 107 | ||||
-rw-r--r-- | contrib/amd/libamu/xdr_func.c | 466 | ||||
-rw-r--r-- | contrib/amd/libamu/xutil.c | 308 |
11 files changed, 1191 insertions, 583 deletions
diff --git a/contrib/amd/libamu/amu.h b/contrib/amd/libamu/amu.h index 833d8c3..1e7834a 100644 --- a/contrib/amd/libamu/amu.h +++ b/contrib/amd/libamu/amu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: amu.h,v 1.3.2.4 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/amu.h * */ @@ -75,4 +74,6 @@ extern amq_mount_info_list *amqproc_getmntfs_1(voidp argp, CLIENT *rqstp); extern int *amqproc_mount_1(voidp argp, CLIENT *rqstp); extern amq_string *amqproc_getvers_1(voidp argp, CLIENT *rqstp); +extern long get_server_pid(void); + #endif /* not _AMU_H */ diff --git a/contrib/amd/libamu/hasmntopt.c b/contrib/amd/libamu/hasmntopt.c index e6696ed..14cceb5 100644 --- a/contrib/amd/libamu/hasmntopt.c +++ b/contrib/amd/libamu/hasmntopt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,9 +36,8 @@ n * modification, are permitted provided that the following conditions * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: hasmntopt.c,v 1.3.2.4 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/hasmntopt.c * */ @@ -49,7 +48,7 @@ n * modification, are permitted provided that the following conditions #include <amu.h> #ifndef MNTMAXSTR -# define MNTMAXSTR 128 +# define MNTMAXSTR 256 #endif /* not MNTMAXSTR */ @@ -59,7 +58,6 @@ n * modification, are permitted provided that the following conditions * * From: Piete Brooks <pb@cl.cam.ac.uk> */ - static char * nextmntopt(char **p) { @@ -69,7 +67,7 @@ nextmntopt(char **p) /* * Skip past white space */ - while (*cp && isspace(*cp)) + while (*cp && isspace((int) *cp)) cp++; /* @@ -98,18 +96,19 @@ nextmntopt(char **p) return rp; } + /* * replacement for hasmntopt if the system does not have it. */ char * -hasmntopt(mntent_t *mnt, char *opt) +amu_hasmntopt(mntent_t *mnt, char *opt) { char t[MNTMAXSTR]; char *f; char *o = t; int l = strlen(opt); - strcpy(t, mnt->mnt_opts); + xstrlcpy(t, mnt->mnt_opts, sizeof(t)); while (*(f = nextmntopt(&o))) if (NSTREQ(opt, f, l)) diff --git a/contrib/amd/libamu/misc_rpc.c b/contrib/amd/libamu/misc_rpc.c index 47b11ad..de0a920 100644 --- a/contrib/amd/libamu/misc_rpc.c +++ b/contrib/amd/libamu/misc_rpc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: misc_rpc.c,v 1.4.2.6 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/misc_rpc.c * */ @@ -93,7 +92,7 @@ pickup_rpc_reply(voidp pkt, int len, voidp where, XDRPROC_T_TYPE where_xdr) memset((voidp) &reply_msg, 0, sizeof(reply_msg)); memset((voidp) &reply_xdr, 0, sizeof(reply_xdr)); - reply_msg.acpted_rply.ar_results.where = (caddr_t) where; + reply_msg.acpted_rply.ar_results.where = where; reply_msg.acpted_rply.ar_results.proc = where_xdr; xdrmem_create(&reply_xdr, pkt, len, XDR_DECODE); diff --git a/contrib/amd/libamu/mount_fs.c b/contrib/amd/libamu/mount_fs.c index 3fecabe..74f064e 100644 --- a/contrib/amd/libamu/mount_fs.c +++ b/contrib/amd/libamu/mount_fs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: mount_fs.c,v 1.11.2.12 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/mount_fs.c * */ @@ -50,9 +49,10 @@ /* ensure that mount table options are delimited by a comma */ -#define append_opts(old, new) { \ - if (*(old) != '\0') strcat(old, ","); \ - strcat(old, new); } +#define append_opts(old, l, new) { \ + if (*(old) != '\0') \ + xstrlcat(old, ",", l); \ + xstrlcat(old, new, l); } /* * Standard mount flags @@ -107,7 +107,9 @@ struct opt_tab mnt_flags[] = /* * Do not define MNT2_NFS_OPT_* entries here! This is for generic - * mount(2) options only, not for NFS mount options. + * mount(2) options only, not for NFS mount options. If you need to put + * something here, it's probably not the right place: see + * include/am_compat.h. */ {0, 0} @@ -122,7 +124,7 @@ compute_mount_flags(mntent_t *mntp) int flags = 0; #ifdef MNT2_GEN_OPT_NEWTYPE - flags = MNT2_GEN_OPT_NEWTYPE; + flags |= MNT2_GEN_OPT_NEWTYPE; #endif /* MNT2_GEN_OPT_NEWTYPE */ #ifdef MNT2_GEN_OPT_AUTOMOUNTED flags |= MNT2_GEN_OPT_AUTOMOUNTED; @@ -132,7 +134,7 @@ compute_mount_flags(mntent_t *mntp) * Crack basic mount options */ for (opt = mnt_flags; opt->opt; opt++) { - flags |= hasmntopt(mntp, opt->opt) ? opt->flag : 0; + flags |= amu_hasmntopt(mntp, opt->opt) ? opt->flag : 0; } return flags; @@ -157,31 +159,33 @@ compute_automounter_mount_flags(mntent_t *mntp) int -mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, u_long nfs_version, const char *nfs_proto, const char *mnttabname) +mount_fs(mntent_t *mnt, int flags, caddr_t mnt_data, int retry, MTYPE_TYPE type, u_long nfs_version, const char *nfs_proto, const char *mnttabname, int on_autofs) { int error = 0; #ifdef MOUNT_TABLE_ON_FILE -# ifdef MNTTAB_OPT_DEV - struct stat stb; -# endif /* MNTTAB_OPT_DEV */ char *zopts = NULL, *xopts = NULL; -# if defined(MNTTAB_OPT_DEV) || (defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)) || defined(MNTTAB_OPT_PROTO) - char optsbuf[48]; -# endif /* defined(MNTTAB_OPT_DEV) || (defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS)) || defined(MNTTAB_OPT_PROTO) */ + size_t l; #endif /* MOUNT_TABLE_ON_FILE */ + char *mnt_dir = 0; + +#ifdef NEED_AUTOFS_SPACE_HACK + char *old_mnt_dir = 0; + /* perform space hack */ + if (on_autofs) { + old_mnt_dir = mnt->mnt_dir; + mnt->mnt_dir = mnt_dir = autofs_strdup_space_hack(old_mnt_dir); + } else +#endif /* NEED_AUTOFS_SPACE_HACK */ + mnt_dir = strdup(mnt->mnt_dir); -#ifdef DEBUG - dlog("%s fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)", - mnt->mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); -#endif /* DEBUG */ + dlog("'%s' fstype " MTYPE_PRINTF_TYPE " (%s) flags %#x (%s)", + mnt_dir, type, mnt->mnt_type, flags, mnt->mnt_opts); again: - clock_valid = 0; - error = MOUNT_TRAP(type, mnt, flags, mnt_data); if (error < 0) { - plog(XLOG_ERROR, "%s: mount: %m", mnt->mnt_dir); + plog(XLOG_ERROR, "'%s': mount: %m", mnt_dir); /* * The following code handles conditions which shouldn't * occur. They are possible either because amd screws up @@ -189,33 +193,18 @@ again: * messed with the mount point. Both have been known to * happen. -- stolcke 2/22/95 */ - if (errno == ENOENT) { - /* - * Occasionally the mount point vanishes, probably - * due to some race condition. Just recreate it - * as necessary. - */ - errno = mkdirs(mnt->mnt_dir, 0555); - if (errno != 0 && errno != EEXIST) - plog(XLOG_ERROR, "%s: mkdirs: %m", mnt->mnt_dir); - else { - plog(XLOG_WARNING, "extra mkdirs required for %s", - mnt->mnt_dir); - error = MOUNT_TRAP(type, mnt, flags, mnt_data); - } - } else if (errno == EBUSY) { + if (errno == EBUSY) { /* * Also, sometimes unmount isn't called, e.g., because * our mountlist is garbled. This leaves old mount * points around which need to be removed before we * can mount something new in their place. */ - errno = umount_fs(mnt->mnt_dir, mnttabname); + errno = umount_fs(mnt_dir, mnttabname, on_autofs); if (errno != 0) - plog(XLOG_ERROR, "%s: umount: %m", mnt->mnt_dir); + plog(XLOG_ERROR, "'%s': umount: %m", mnt_dir); else { - plog(XLOG_WARNING, "extra umount required for %s", - mnt->mnt_dir); + plog(XLOG_WARNING, "extra umount required for '%s'", mnt_dir); error = MOUNT_TRAP(type, mnt, flags, mnt_data); } } @@ -225,8 +214,16 @@ again: sleep(1); goto again; } + +#ifdef NEED_AUTOFS_SPACE_HACK + /* Undo space hack */ + if (on_autofs) + mnt->mnt_dir = old_mnt_dir; +#endif /* NEED_AUTOFS_SPACE_HACK */ + if (error < 0) { - return errno; + error = errno; + goto out; } #ifdef MOUNT_TABLE_ON_FILE @@ -234,23 +231,28 @@ again: * Allocate memory for options: * dev=..., vers={2,3}, proto={tcp,udp} */ - zopts = (char *) xmalloc(strlen(mnt->mnt_opts) + 48); + l = strlen(mnt->mnt_opts) + 48; + zopts = (char *) xmalloc(l); /* copy standard options */ xopts = mnt->mnt_opts; - strcpy(zopts, xopts); + xstrlcpy(zopts, xopts, l); # ifdef MNTTAB_OPT_DEV - /* add the extra dev= field to the mount table */ - if (lstat(mnt->mnt_dir, &stb) == 0) { - if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */ - sprintf(optsbuf, "%s=%04lx", - MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff); - else /* e.g. System Vr4 */ - sprintf(optsbuf, "%s=%08lx", - MNTTAB_OPT_DEV, (u_long) stb.st_dev); - append_opts(zopts, optsbuf); + { + /* add the extra dev= field to the mount table */ + struct stat stb; + if (lstat(mnt_dir, &stb) == 0) { + char optsbuf[48]; + if (sizeof(stb.st_dev) == 2) /* e.g. SunOS 4.1 */ + xsnprintf(optsbuf, sizeof(optsbuf), "%s=%04lx", + MNTTAB_OPT_DEV, (u_long) stb.st_dev & 0xffff); + else /* e.g. System Vr4 */ + xsnprintf(optsbuf, sizeof(optsbuf), "%s=%08lx", + MNTTAB_OPT_DEV, (u_long) stb.st_dev); + append_opts(zopts, l, optsbuf); + } } # endif /* MNTTAB_OPT_DEV */ @@ -261,8 +263,10 @@ again: */ if (nfs_version == NFS_VERSION3 && hasmntval(mnt, MNTTAB_OPT_VERS) != NFS_VERSION3) { - sprintf(optsbuf, "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3); - append_opts(zopts, optsbuf); + char optsbuf[48]; + xsnprintf(optsbuf, sizeof(optsbuf), + "%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3); + append_opts(zopts, l, optsbuf); } # endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */ @@ -271,9 +275,10 @@ again: * add the extra proto={tcp,udp} field to the mount table, * unless already specified by user. */ - if (nfs_proto && !hasmntopt(mnt, MNTTAB_OPT_PROTO)) { - sprintf(optsbuf, "%s=%s", MNTTAB_OPT_PROTO, nfs_proto); - append_opts(zopts, optsbuf); + if (nfs_proto && !amu_hasmntopt(mnt, MNTTAB_OPT_PROTO)) { + char optsbuf[48]; + xsnprintf(optsbuf, sizeof(optsbuf), "%s=%s", MNTTAB_OPT_PROTO, nfs_proto); + append_opts(zopts, l, optsbuf); } # endif /* MNTTAB_OPT_PROTO */ @@ -289,14 +294,15 @@ again: # endif /* HAVE_MNTENT_T_MNT_CNODE */ # ifdef HAVE_MNTENT_T_MNT_RO - mnt->mnt_ro = (hasmntopt(mnt, MNTTAB_OPT_RO) != NULL); + mnt->mnt_ro = (amu_hasmntopt(mnt, MNTTAB_OPT_RO) != NULL); # endif /* HAVE_MNTENT_T_MNT_RO */ # ifdef HAVE_MNTENT_T_MNT_TIME # ifdef HAVE_MNTENT_T_MNT_TIME_STRING { /* allocate enough space for a long */ - char *str = (char *) xmalloc(13 * sizeof(char)); - sprintf(str, "%ld", time((time_t *) NULL)); + size_t l = 13 * sizeof(char); + char *str = (char *) xmalloc(l); + xsnprintf(str, l, "%ld", time((time_t *) NULL)); mnt->mnt_time = str; } # else /* not HAVE_MNTENT_T_MNT_TIME_STRING */ @@ -314,7 +320,126 @@ again: # endif /* MNTTAB_OPT_DEV */ #endif /* MOUNT_TABLE_ON_FILE */ - return 0; + out: + XFREE(mnt_dir); + return error; +} + + +/* + * Compute all NFS attribute cache related flags separately. Note that this + * function now computes attribute-cache flags for both Amd's automount + * points (NFS) as well as any normal NFS mount that Amd performs. Edit + * with caution. + */ +static void +compute_nfs_attrcache_flags(nfs_args_t *nap, mntent_t *mntp) +{ + int acval = 0; + int err_acval = 1; /* 1 means we found no 'actimeo' value */ +#if defined(HAVE_NFS_ARGS_T_ACREGMIN) || defined(HAVE_NFS_ARGS_T_ACREGMAX) || defined(HAVE_NFS_ARGS_T_ACDIRMIN) || defined(HAVE_NFS_ARGS_T_ACDIRMAX) + int err_acrdmm; /* for ac{reg,dir}{min,max} */ +#endif /* HAVE_NFS_ARGS_T_AC{REG,DIR}{MIN,MAX} */ + + /************************************************************************/ + /*** ATTRIBUTE CACHES ***/ + /************************************************************************/ + /* + * acval is set to 0 at the top of the function. If actimeo mount option + * exists and defined in mntopts, then its acval is set to it. + * If the value is non-zero, then we set all attribute cache fields to it. + * If acval is zero, it means it was never defined in mntopts or the + * actimeo mount option does not exist, in which case we check for + * individual mount options per attribute cache. + * Regardless of the value of acval, mount flags are set based directly + * on the values of the attribute caches. + */ +#ifdef MNTTAB_OPT_ACTIMEO + err_acval = hasmntvalerr(mntp, MNTTAB_OPT_ACTIMEO, &acval); /* attr cache timeout (sec) */ +#endif /* MNTTAB_OPT_ACTIMEO */ + + /*** acregmin ***/ +#ifdef HAVE_NFS_ARGS_T_ACREGMIN + err_acrdmm = 1; /* 1 means we found no acregmin value */ + if (!err_acval) { + nap->acregmin = acval; /* min ac timeout for reg files (sec) */ + } else { +# ifdef MNTTAB_OPT_ACREGMIN + err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMIN, (int *) &nap->acregmin); +# else /* not MNTTAB_OPT_ACREGMIN */ + nap->acregmin = 0; +# endif /* not MNTTAB_OPT_ACREGMIN */ + } + /* set this flag iff we changed acregmin (possibly to zero) */ +# ifdef MNT2_NFS_OPT_ACREGMIN + if (!err_acval || !err_acrdmm) + nap->flags |= MNT2_NFS_OPT_ACREGMIN; +# endif /* MNT2_NFS_OPT_ACREGMIN */ +#endif /* HAVE_NFS_ARGS_T_ACREGMIN */ + + /*** acregmax ***/ +#ifdef HAVE_NFS_ARGS_T_ACREGMAX + err_acrdmm = 1; /* 1 means we found no acregmax value */ + if (!err_acval) { + nap->acregmax = acval; /* max ac timeout for reg files (sec) */ + } else { +# ifdef MNTTAB_OPT_ACREGMAX + err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACREGMAX, (int *) &nap->acregmax); +# else /* not MNTTAB_OPT_ACREGMAX */ + nap->acregmax = 0; +# endif /* not MNTTAB_OPT_ACREGMAX */ + } + /* set this flag iff we changed acregmax (possibly to zero) */ +# ifdef MNT2_NFS_OPT_ACREGMAX + if (!err_acval || !err_acrdmm) + nap->flags |= MNT2_NFS_OPT_ACREGMAX; +# endif /* MNT2_NFS_OPT_ACREGMAX */ +#endif /* HAVE_NFS_ARGS_T_ACREGMAX */ + + /*** acdirmin ***/ +#ifdef HAVE_NFS_ARGS_T_ACDIRMIN + err_acrdmm = 1; /* 1 means we found no acdirmin value */ + if (!err_acval) { + nap->acdirmin = acval; /* min ac timeout for dirs (sec) */ + } else { +# ifdef MNTTAB_OPT_ACDIRMIN + err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMIN, (int *) &nap->acdirmin); +# else /* not MNTTAB_OPT_ACDIRMIN */ + nap->acdirmin = 0; +# endif /* not MNTTAB_OPT_ACDIRMIN */ + } + /* set this flag iff we changed acdirmin (possibly to zero) */ +# ifdef MNT2_NFS_OPT_ACDIRMIN + if (!err_acval || !err_acrdmm) + nap->flags |= MNT2_NFS_OPT_ACDIRMIN; +# endif /* MNT2_NFS_OPT_ACDIRMIN */ +#endif /* HAVE_NFS_ARGS_T_ACDIRMIN */ + + /*** acdirmax ***/ +#ifdef HAVE_NFS_ARGS_T_ACDIRMAX + err_acrdmm = 1; /* 1 means we found no acdirmax value */ + if (!err_acval) { + nap->acdirmax = acval; /* max ac timeout for dirs (sec) */ + } else { +# ifdef MNTTAB_OPT_ACDIRMAX + err_acrdmm = hasmntvalerr(mntp, MNTTAB_OPT_ACDIRMAX, (int *) &nap->acdirmax); +# else /* not MNTTAB_OPT_ACDIRMAX */ + nap->acdirmax = 0; +# endif /* not MNTTAB_OPT_ACDIRMAX */ + } + /* set this flag iff we changed acdirmax (possibly to zero) */ +# ifdef MNT2_NFS_OPT_ACDIRMAX + if (!err_acval || !err_acrdmm) + nap->flags |= MNT2_NFS_OPT_ACDIRMAX; +# endif /* MNT2_NFS_OPT_ACDIRMAX */ +#endif /* HAVE_NFS_ARGS_T_ACDIRMAX */ + + + /* don't cache attributes */ +#if defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC) + if (amu_hasmntopt(mntp, MNTTAB_OPT_NOAC) != NULL) + nap->flags |= MNT2_NFS_OPT_NOAC; +#endif /* defined(MNTTAB_OPT_NOAC) && defined(MNT2_NFS_OPT_NOAC) */ } @@ -333,31 +458,28 @@ again: * fs_name: remote file system name to mount */ void -#ifdef HAVE_TRANSPORT_TYPE_TLI -compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct netconfig *nfsncp, struct sockaddr_in *ip_addr, u_long nfs_version, char *nfs_proto, am_nfs_handle_t *fhp, char *host_name, char *fs_name) -#else /* not HAVE_TRANSPORT_TYPE_TLI */ -compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_in *ip_addr, u_long nfs_version, char *nfs_proto, am_nfs_handle_t *fhp, char *host_name, char *fs_name) -#endif /* not HAVE_TRANSPORT_TYPE_TLI */ +compute_nfs_args(nfs_args_t *nap, + mntent_t *mntp, + int genflags, + struct netconfig *nfsncp, + struct sockaddr_in *ip_addr, + u_long nfs_version, + char *nfs_proto, + am_nfs_handle_t *fhp, + char *host_name, + char *fs_name) { - int acval = 0; -#ifdef HAVE_FS_NFS3 - static am_nfs_fh3 fh3; /* static, b/c gcc on aix corrupts stack */ -#endif /* HAVE_FS_NFS3 */ - /* initialize just in case */ memset((voidp) nap, 0, sizeof(nfs_args_t)); + /* compute all of the NFS attribute-cache flags */ + compute_nfs_attrcache_flags(nap, mntp); + /************************************************************************/ /*** FILEHANDLE DATA AND LENGTH ***/ /************************************************************************/ #ifdef HAVE_FS_NFS3 if (nfs_version == NFS_VERSION3) { - memset((voidp) &fh3, 0, sizeof(am_nfs_fh3)); - fh3.fh3_length = fhp->v3.mountres3_u.mountinfo.fhandle.fhandle3_len; - memmove(fh3.fh3_u.data, - fhp->v3.mountres3_u.mountinfo.fhandle.fhandle3_val, - fh3.fh3_length); - # if defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) /* * Some systems (Irix/bsdi3) have a separate field in nfs_args for @@ -365,9 +487,9 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ * the file handle set in nfs_args be plain bytes, and not * include the length field. */ - NFS_FH_DREF(nap->NFS_FH_FIELD, &(fh3.fh3_u.data)); + NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3.am_fh3_data); # else /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */ - NFS_FH_DREF(nap->NFS_FH_FIELD, &fh3); + NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v3); # endif /* not defined(HAVE_NFS_ARGS_T_FHSIZE) || defined(HAVE_NFS_ARGS_T_FH_LEN) */ # ifdef MNT2_NFS_OPT_NFSV3 nap->flags |= MNT2_NFS_OPT_NFSV3; @@ -377,12 +499,12 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ # endif /* MNT2_NFS_OPT_VER3 */ } else #endif /* HAVE_FS_NFS3 */ - NFS_FH_DREF(nap->NFS_FH_FIELD, &(fhp->v2.fhs_fh)); + NFS_FH_DREF(nap->NFS_FH_FIELD, &fhp->v2); #ifdef HAVE_NFS_ARGS_T_FHSIZE # ifdef HAVE_FS_NFS3 if (nfs_version == NFS_VERSION3) - nap->fhsize = fh3.fh3_length; + nap->fhsize = fhp->v3.am_fh3_length; else # endif /* HAVE_FS_NFS3 */ nap->fhsize = FHSIZE; @@ -392,7 +514,7 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #ifdef HAVE_NFS_ARGS_T_FH_LEN # ifdef HAVE_FS_NFS3 if (nfs_version == NFS_VERSION3) - nap->fh_len = fh3.fh3_length; + nap->fh_len = fhp->v3.am_fh3_length; else # endif /* HAVE_FS_NFS3 */ nap->fh_len = FHSIZE; @@ -401,75 +523,17 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ /************************************************************************/ /*** HOST NAME ***/ /************************************************************************/ + /* + * XXX: warning, using xstrlcpy in NFS_HN_DREF, which may corrupt a + * struct nfs_args, or truncate our concocted "hostname:/path" + * string prematurely. + */ NFS_HN_DREF(nap->hostname, host_name); #ifdef MNT2_NFS_OPT_HOSTNAME nap->flags |= MNT2_NFS_OPT_HOSTNAME; #endif /* MNT2_NFS_OPT_HOSTNAME */ /************************************************************************/ - /*** ATTRIBUTE CACHES ***/ - /************************************************************************/ - /* - * acval is set to 0 at the top of the function. If actimeo mount option - * exists and defined in mntopts, then it acval is set to it. - * If the value is non-zero, then we set all attribute cache fields to it. - * If acval is zero, it means it was never defined in mntopts or the - * actimeo mount option does not exist, in which case we check for - * individual mount options per attribute cache. - * Regardless of the value of acval, mount flags are set based directly - * on the values of the attribute caches. - */ -#ifdef MNTTAB_OPT_ACTIMEO - acval = hasmntval(mntp, MNTTAB_OPT_ACTIMEO); /* attr cache timeout (sec) */ -#endif /* MNTTAB_OPT_ACTIMEO */ - - if (acval) { -#ifdef HAVE_NFS_ARGS_T_ACREGMIN - nap->acregmin = acval; /* min ac timeout for reg files (sec) */ - nap->acregmax = acval; /* max ac timeout for reg files (sec) */ -#endif /* HAVE_NFS_ARGS_T_ACREGMIN */ -#ifdef HAVE_NFS_ARGS_T_ACDIRMIN - nap->acdirmin = acval; /* min ac timeout for dirs (sec) */ - nap->acdirmax = acval; /* max ac timeout for dirs (sec) */ -#endif /* HAVE_NFS_ARGS_T_ACDIRMIN */ - } else { -#ifdef MNTTAB_OPT_ACREGMIN - nap->acregmin = hasmntval(mntp, MNTTAB_OPT_ACREGMIN); -#endif /* MNTTAB_OPT_ACREGMIN */ -#ifdef MNTTAB_OPT_ACREGMAX - nap->acregmax = hasmntval(mntp, MNTTAB_OPT_ACREGMAX); -#endif /* MNTTAB_OPT_ACREGMAX */ -#ifdef MNTTAB_OPT_ACDIRMIN - nap->acdirmin = hasmntval(mntp, MNTTAB_OPT_ACDIRMIN); -#endif /* MNTTAB_OPT_ACDIRMIN */ -#ifdef MNTTAB_OPT_ACDIRMAX - nap->acdirmax = hasmntval(mntp, MNTTAB_OPT_ACDIRMAX); -#endif /* MNTTAB_OPT_ACDIRMAX */ - } /* end of "if (acval)" statement */ - -#ifdef MNT2_NFS_OPT_ACREGMIN - if (nap->acregmin) - nap->flags |= MNT2_NFS_OPT_ACREGMIN; -#endif /* MNT2_NFS_OPT_ACREGMIN */ -#ifdef MNT2_NFS_OPT_ACREGMAX - if (nap->acregmax) - nap->flags |= MNT2_NFS_OPT_ACREGMAX; -#endif /* MNT2_NFS_OPT_ACREGMAX */ -#ifdef MNT2_NFS_OPT_ACDIRMIN - if (nap->acdirmin) - nap->flags |= MNT2_NFS_OPT_ACDIRMIN; -#endif /* MNT2_NFS_OPT_ACDIRMIN */ -#ifdef MNT2_NFS_OPT_ACDIRMAX - if (nap->acdirmax) - nap->flags |= MNT2_NFS_OPT_ACDIRMAX; -#endif /* MNT2_NFS_OPT_ACDIRMAX */ - -#ifdef MNTTAB_OPT_NOAC /* don't cache attributes */ - if (hasmntopt(mntp, MNTTAB_OPT_NOAC) != NULL) - nap->flags |= MNT2_NFS_OPT_NOAC; -#endif /* MNTTAB_OPT_NOAC */ - - /************************************************************************/ /*** IP ADDRESS OF REMOTE HOST ***/ /************************************************************************/ if (ip_addr) { @@ -523,9 +587,9 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ /************************************************************************/ #ifdef MNT2_NFS_OPT_NOCONN /* check if user specified to use unconnected or connected sockets */ - if (hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCONN) != NULL) nap->flags |= MNT2_NFS_OPT_NOCONN; - else if (hasmntopt(mntp, MNTTAB_OPT_CONN) != NULL) + else if (amu_hasmntopt(mntp, MNTTAB_OPT_CONN) != NULL) nap->flags &= ~MNT2_NFS_OPT_NOCONN; else { /* @@ -553,7 +617,7 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #ifdef MNT2_NFS_OPT_RESVPORT # ifdef MNTTAB_OPT_RESVPORT - if (hasmntopt(mntp, MNTTAB_OPT_RESVPORT) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_RESVPORT) != NULL) nap->flags |= MNT2_NFS_OPT_RESVPORT; # else /* not MNTTAB_OPT_RESVPORT */ nap->flags |= MNT2_NFS_OPT_RESVPORT; @@ -587,12 +651,16 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ if (nap->rsize) nap->flags |= MNT2_NFS_OPT_RSIZE; #endif /* MNT2_NFS_OPT_RSIZE */ + if (nfs_version == NFS_VERSION && nap->rsize > 8192) + nap->rsize = 8192; nap->wsize = hasmntval(mntp, MNTTAB_OPT_WSIZE); #ifdef MNT2_NFS_OPT_WSIZE if (nap->wsize) nap->flags |= MNT2_NFS_OPT_WSIZE; #endif /* MNT2_NFS_OPT_WSIZE */ + if (nfs_version == NFS_VERSION && nap->wsize > 8192) + nap->wsize = 8192; nap->timeo = hasmntval(mntp, MNTTAB_OPT_TIMEO); #ifdef MNT2_NFS_OPT_TIMEO @@ -611,11 +679,13 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ nap->flags |= MNT2_NFS_OPT_BIODS; #endif /* MNT2_NFS_OPT_BIODS */ - if (hasmntopt(mntp, MNTTAB_OPT_SOFT) != NULL) +#ifdef MNT2_NFS_OPT_SOFT + if (amu_hasmntopt(mntp, MNTTAB_OPT_SOFT) != NULL) nap->flags |= MNT2_NFS_OPT_SOFT; +#endif /* MNT2_NFS_OPT_SOFT */ #ifdef MNT2_NFS_OPT_SPONGY - if (hasmntopt(mntp, MNTTAB_OPT_SPONGY) != NULL) { + if (amu_hasmntopt(mntp, MNTTAB_OPT_SPONGY) != NULL) { nap->flags |= MNT2_NFS_OPT_SPONGY; if (nap->flags & MNT2_NFS_OPT_SOFT) { plog(XLOG_USER, "Mount opts soft and spongy are incompatible - soft ignored"); @@ -631,7 +701,7 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #endif /* defined(MNT2_GEN_OPT_RONLY) && defined(MNT2_NFS_OPT_RONLY) */ #ifdef MNTTAB_OPT_INTR - if (hasmntopt(mntp, MNTTAB_OPT_INTR) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_INTR) != NULL) /* * Either turn on the "allow interrupts" option, or * turn off the "disallow interrupts" option" @@ -651,17 +721,17 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #endif /* MNTTAB_OPT_INTR */ #ifdef MNTTAB_OPT_NODEVS - if (hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_NODEVS) != NULL) nap->flags |= MNT2_NFS_OPT_NODEVS; #endif /* MNTTAB_OPT_NODEVS */ #ifdef MNTTAB_OPT_COMPRESS - if (hasmntopt(mntp, MNTTAB_OPT_COMPRESS) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_COMPRESS) != NULL) nap->flags |= MNT2_NFS_OPT_COMPRESS; #endif /* MNTTAB_OPT_COMPRESS */ #ifdef MNTTAB_OPT_PRIVATE /* mount private, single-client tree */ - if (hasmntopt(mntp, MNTTAB_OPT_PRIVATE) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_PRIVATE) != NULL) nap->flags |= MNT2_NFS_OPT_PRIVATE; #endif /* MNTTAB_OPT_PRIVATE */ @@ -676,33 +746,38 @@ compute_nfs_args(nfs_args_t *nap, mntent_t *mntp, int genflags, struct sockaddr_ #endif /* MNT2_NFS_OPT_PGTHRESH */ #if defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) - if (hasmntopt(mntp, MNTTAB_OPT_NOCTO) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_NOCTO) != NULL) nap->flags |= MNT2_NFS_OPT_NOCTO; #endif /* defined(MNT2_NFS_OPT_NOCTO) && defined(MNTTAB_OPT_NOCTO) */ #if defined(MNT2_NFS_OPT_POSIX) && defined(MNTTAB_OPT_POSIX) - if (hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) { + if (amu_hasmntopt(mntp, MNTTAB_OPT_POSIX) != NULL) { nap->flags |= MNT2_NFS_OPT_POSIX; nap->pathconf = NULL; } #endif /* MNT2_NFS_OPT_POSIX && MNTTAB_OPT_POSIX */ #if defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) - if (hasmntopt(mntp, MNTTAB_OPT_PROPLIST) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_PROPLIST) != NULL) nap->flags |= MNT2_NFS_OPT_PROPLIST; #endif /* defined(MNT2_NFS_OPT_PROPLIST) && defined(MNTTAB_OPT_PROPLIST) */ #if defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) nap->maxgrouplist = hasmntval(mntp, MNTTAB_OPT_MAXGROUPS); - if (nap->maxgrouplist != NULL) + if (nap->maxgrouplist != 0) nap->flags |= MNT2_NFS_OPT_MAXGRPS; #endif /* defined(MNT2_NFS_OPT_MAXGRPS) && defined(MNTTAB_OPT_MAXGROUPS) */ #if defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK) - if (hasmntopt(mntp, MNTTAB_OPT_NOLOCK) != NULL) + if (amu_hasmntopt(mntp, MNTTAB_OPT_NOLOCK) != NULL) nap->flags |= MNT2_NFS_OPT_NONLM; #endif /* defined(MNT2_NFS_OPT_NONLM) && defined(MNTTAB_OPT_NOLOCK) */ +#if defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) + if (amu_hasmntopt(mntp, MNTTAB_OPT_XLATECOOKIE) != NULL) + nap->flags |= MNT2_NFS_OPT_XLATECOOKIE; +#endif /* defined(MNT2_NFS_OPT_XLATECOOKIE) && defined(MNTTAB_OPT_XLATECOOKIE) */ + #ifdef HAVE_NFS_ARGS_T_OPTSTR nap->optstr = mntp->mnt_opts; #endif /* HAVE_NFS_ARGS_T_OPTSTR */ @@ -761,28 +836,9 @@ compute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp) nap->flags |= MNT2_NFS_OPT_DUMBTIMR; #endif /* MNT2_NFS_OPT_DUMBTIMR */ -#ifdef MNT2_NFS_OPT_NOAC - /* - * Don't cache attributes - they are changing under the kernel's feet. - * For example, IRIX5.2 will dispense with nfs lookup calls and hand stale - * filehandles to getattr unless we disable attribute caching on the - * automount points. - */ - nap->flags |= MNT2_NFS_OPT_NOAC; -#else /* not MNT2_NFS_OPT_NOAC */ - /* - * Setting these to 0 results in an error on some systems, which is why - * it's better to use "noac" if possible. - */ -# if defined(MNT2_NFS_OPT_ACREGMIN) && defined(MNT2_NFS_OPT_ACREGMAX) - nap->acregmin = nap->acregmax = 0; /* XXX: was 1, but why? */ - nap->flags |= MNT2_NFS_OPT_ACREGMIN | MNT2_NFS_OPT_ACREGMAX; -# endif /* defined(MNT2_NFS_OPT_ACREGMIN) && defined(MNT2_NFS_OPT_ACREGMAX) */ -# if defined(MNT2_NFS_OPT_ACDIRMIN) && defined(MNT2_NFS_OPT_ACDIRMAX) - nap->acdirmin = nap->acdirmax = 0; /* XXX: was 1, but why? */ - nap->flags |= MNT2_NFS_OPT_ACDIRMIN | MNT2_NFS_OPT_ACDIRMAX; -# endif /* defined(MNT2_NFS_OPT_ACDIRMIN) && defined(MNT2_NFS_OPT_ACDIRMAX) */ -#endif /* not MNT2_NFS_OPT_NOAC */ + /* compute all of the NFS attribute-cache flags */ + compute_nfs_attrcache_flags(nap, mntp); + /* * Provide a slight bit more security by requiring the kernel to use * reserved ports. @@ -798,7 +854,7 @@ compute_automounter_nfs_args(nfs_args_t *nap, mntent_t *mntp) static char * get_hex_string(u_int len, const char *fhdata) { - int i; + u_int i; static char buf[128]; /* better not go over it! */ char str[16]; short int arr[64]; @@ -808,9 +864,9 @@ get_hex_string(u_int len, const char *fhdata) buf[0] = '\0'; memset(&arr[0], 0, (64 * sizeof(short int))); memcpy(&arr[0], &fhdata[0], len); - for (i=0; i<len/sizeof(short int); i++) { - sprintf(str, "%04x", ntohs(arr[i])); - strcat(buf, str); + for (i=0; i<len/sizeof(unsigned short int); i++) { + xsnprintf(str, sizeof(str), "%04x", ntohs(arr[i])); + xstrlcat(buf, str, sizeof(buf)); } return buf; } @@ -823,7 +879,7 @@ get_hex_string(u_int len, const char *fhdata) void print_nfs_args(const nfs_args_t *nap, u_long nfs_version) { - int fhlen = 32; /* default: NFS V.2 file handle length is 32 */ + int fhlen = 32; /* default: NFS V.2 file handle length is 32 */ #ifdef HAVE_TRANSPORT_TYPE_TLI struct netbuf *nbp; struct knetconfig *kncp; @@ -850,7 +906,7 @@ print_nfs_args(const nfs_args_t *nap, u_long nfs_version) nbp->maxlen, nbp->len, get_hex_string(nbp->len, nbp->buf)); nbp = nap->syncaddr; - plog(XLOG_DEBUG, "NA->syncaddr {netbuf} 0x%x", (int) nbp); + plog(XLOG_DEBUG, "NA->syncaddr {netbuf} %p", nbp); kncp = nap->knconf; plog(XLOG_DEBUG, "NA->knconf->semantics %lu", (u_long) kncp->knc_semantics); plog(XLOG_DEBUG, "NA->knconf->protofmly \"%s\"", kncp->knc_protofmly); @@ -858,18 +914,26 @@ print_nfs_args(const nfs_args_t *nap, u_long nfs_version) plog(XLOG_DEBUG, "NA->knconf->rdev %lu", (u_long) kncp->knc_rdev); /* don't print knconf->unused field */ #else /* not HAVE_TRANSPORT_TYPE_TLI */ - sap = (struct sockaddr_in *) &nap->addr; +# ifdef NFS_ARGS_T_ADDR_IS_POINTER + sap = (struct sockaddr_in *) nap->addr; +# else /* not NFS_ARGS_T_ADDR_IS_POINTER */ + sap = (struct sockaddr_in *) &nap->addr; +# endif /* not NFS_ARGS_T_ADDR_IS_POINTER */ plog(XLOG_DEBUG, "NA->addr {sockaddr_in} (len=%d) = \"%s\"", (int) sizeof(struct sockaddr_in), get_hex_string(sizeof(struct sockaddr_in), (const char *)sap)); #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN - plog(XLOG_DEBUG, "NA->addr.sin_len = \"%d\"", sap->sin_len); + /* as per POSIX, sin_len need not be set (used internally by kernel) */ + plog(XLOG_DEBUG, "NA->addr.sin_len = %d", sap->sin_len); #endif /* HAVE_STRUCT_SOCKADDR_SA_LEN */ - plog(XLOG_DEBUG, "NA->addr.sin_family = \"%d\"", sap->sin_family); - plog(XLOG_DEBUG, "NA->addr.sin_port = \"%d\"", sap->sin_port); + plog(XLOG_DEBUG, "NA->addr.sin_family = %d", sap->sin_family); + plog(XLOG_DEBUG, "NA->addr.sin_port = %d", sap->sin_port); plog(XLOG_DEBUG, "NA->addr.sin_addr = \"%s\"", get_hex_string(sizeof(struct in_addr), (const char *) &sap->sin_addr)); #endif /* not HAVE_TRANSPORT_TYPE_TLI */ +#ifdef HAVE_NFS_ARGS_T_ADDRLEN + plog(XLOG_DEBUG, "NA->addrlen = %d", nap->addrlen); +#endif /* ifdef HAVE_NFS_ARGS_T_ADDRLEN */ plog(XLOG_DEBUG, "NA->hostname = \"%s\"", nap->hostname ? nap->hostname : "null"); #ifdef HAVE_NFS_ARGS_T_NAMLEN diff --git a/contrib/amd/libamu/mtab.c b/contrib/amd/libamu/mtab.c index b323097..50ba994 100644 --- a/contrib/amd/libamu/mtab.c +++ b/contrib/amd/libamu/mtab.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: mtab.c,v 1.3.2.8 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/mtab.c * */ @@ -118,14 +117,14 @@ haseq(char *instr) /* * Utility routine which returns a pointer to whatever * follows an = in a mount option. Returns null if option - * doesn't exist or doesn't have an '='. Won't fall for opt,foo=. + * doesn't exist or doesn't have an '='. Won't fail for opt,foo=. */ char * hasmnteq(mntent_t *mnt, char *opt) { if (mnt && opt) { /* disallow null input pointers */ if ( *opt ) { /* disallow the null string as an opt */ - char *str = hasmntopt(mnt, opt); + char *str = amu_hasmntopt(mnt, opt); if ( str ) { /* option was there */ char *eq = str + strlen(opt); /* Look at char just after option */ if (*eq == '=') /* Is it '=' ? */ @@ -138,14 +137,93 @@ hasmnteq(mntent_t *mnt, char *opt) /* - * Utility routine which determines the value of a - * numeric option in the mount options (such as port=%d). - * Returns 0 if the option is not specified. + * Wrapper around hasmntvalerr(), which retains backwards compatibiliy with + * older use of hasmntval(). + * + * XXX: eventually, all use of hasmntval() should be replaced with + * hasmntvalerr(). */ int hasmntval(mntent_t *mnt, char *opt) { - char *str = hasmntopt(mnt, opt); + int err, val = 0; + + err = hasmntvalerr(mnt, opt, &val); + if (err) /* if there was an error (hasmntvalerr returned 1) */ + return 0; /* redundant: val==0 above, but leave here for clarity */ + /* otherwise there was no error */ + return val; +} + + +/* + * Utility routine which determines the value of a numeric option in the + * mount options (such as port=%d), and fills in the value in the argument + * valp (argument won't be touched if no value is set, for example due to an + * error). + * + * Returns non-zero (1) on error; returns 0 on success. + * + * XXX: eventually, all use of hasmntval() should be replaced with + * hasmntvalerr(). + */ +unsigned int +hasmntvalerr(mntent_t *mnt, char *opt, int *valp) +{ + char *str = amu_hasmntopt(mnt, opt); + int err = 1; /* 1 means no good value was set (an error) */ + char *eq, *endptr; + long int i; + + /* exit if no option specificed */ + if (!str) { + goto out; + } + + eq = hasmnteq(mnt, opt); + + if (!eq) { /* no argument to option ('=' sign was missing) */ + plog(XLOG_MAP, "numeric option to \"%s\" missing", opt); + goto out; + } + + /* if got here, then we had an '=' after option name */ + endptr = NULL; + i = strtol(eq, &endptr, 0); /* hex and octal allowed ;-) */ + if (!endptr || + (endptr != eq && (*endptr == ',' || *endptr == '\0'))) { + /* + * endptr set means strtol saw a non-digit. If the non-digit is a + * comma, it's probably the start of the next option. If the comma is + * the first char though, complain about it (foo=,bar is made + * noticeable by this). + * + * Similar reasoning for '\0' instead of comma, it's the end of the + * string. + */ + *valp = (int) i; /* set good value */ + err = 0; /* no error */ + } else { + /* whatever was after the '=' sign wasn't a number */ + plog(XLOG_MAP, "invalid numeric option in \"%s\": \"%s\"", opt, str); + /* fall through to error/exit processing */ + } + + out: + return err; +} + + +/* + * Utility routine which returns the string value of + * an option in the mount options (such as proto=udp). + * Returns NULL if the option is not specified. + * Returns malloc'ed string (caller must free!) + */ +char * +hasmntstr(mntent_t *mnt, char *opt) +{ + char *str = amu_hasmntopt(mnt, opt); if (str) { /* The option was there */ @@ -153,27 +231,20 @@ hasmntval(mntent_t *mnt, char *opt) if (eq) { /* and had an = after it */ - char *endptr = NULL; - long int i = strtol(eq, &endptr, 0); /* hex and octal allowed ;-) */ - - if (!endptr || - /* - * endptr set means strtol saw a non-digit. If the - * non-digit is a comma, it's probably the start of the next - * option. If the comma is the first char though, complain about - * it (foo=,bar is made noticeable by this). - * - * Similar reasoning for '\0' instead of comma, it's the end - * of the string. - */ - (endptr != eq && (*endptr == ',' || *endptr == '\0'))) - return((int) i); - /* whatever was after the '=' sign wasn't a number */ - plog(XLOG_MAP, "invalid numeric option in \"%s\": \"%s\"", opt, str); - } else { - /* No argument to option ('=' sign was missing) */ - plog(XLOG_MAP, "numeric option to \"%s\" missing", opt); + char *endptr = strchr(eq, ','); + + /* if saw no comma, return strdup'd string */ + if (!endptr) + return strdup(eq); + else { + /* else we need to copy only the chars needed */ + int len = endptr - eq; + char *buf = xmalloc(len + 1); + strncpy(buf, eq, len); + buf[len] = '\0'; + return buf; + } } } - return 0; + return NULL; } diff --git a/contrib/amd/libamu/nfs_prot_xdr.c b/contrib/amd/libamu/nfs_prot_xdr.c index cb3368b..df8a0b0 100644 --- a/contrib/amd/libamu/nfs_prot_xdr.c +++ b/contrib/amd/libamu/nfs_prot_xdr.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1989 Jan-Simon Pendry * Copyright (c) 1989 Imperial College of Science, Technology & Medicine * Copyright (c) 1989 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: nfs_prot_xdr.c,v 1.3.2.4 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/nfs_prot_xdr.c * */ diff --git a/contrib/amd/libamu/strerror.c b/contrib/amd/libamu/strerror.c index af10e70..49dd2fc 100644 --- a/contrib/amd/libamu/strerror.c +++ b/contrib/amd/libamu/strerror.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 2002-2004 Ion Badulescu - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 2002-2006 Ion Badulescu + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -38,7 +38,7 @@ * SUCH DAMAGE. * * - * $Id: strerror.c,v 1.2.2.3 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/strerror.c * */ @@ -58,7 +58,7 @@ strerror(int errnum) #ifdef HAVE_EXTERN_SYS_ERRLIST if (errnum < 0 || errnum >= (sizeof(sys_errlist) >> 2)) { static char errstr[30]; - sprintf(errstr, "Unknown error #%d", errnum); + xsnprintf(errstr, sizeof(errstr), "Unknown error #%d", errnum); return errstr; } return sys_errlist[error]; diff --git a/contrib/amd/libamu/strutil.c b/contrib/amd/libamu/strutil.c new file mode 100644 index 0000000..5a1e759 --- /dev/null +++ b/contrib/amd/libamu/strutil.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 1997-2006 Erez Zadok + * Copyright (c) 1990 Jan-Simon Pendry + * Copyright (c) 1990 Imperial College of Science, Technology & Medicine + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Jan-Simon Pendry at Imperial College, London. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgment: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * + * File: am-utils/libamu/strutil.c + * + */ + +/* + * String Utilities. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif /* HAVE_CONFIG_H */ +#include <am_defs.h> +#include <amu.h> + + +char * +strnsave(const char *str, int len) +{ + char *sp = (char *) xmalloc(len + 1); + memmove(sp, str, len); + sp[len] = '\0'; + + return sp; +} + + +/* + * Concatenate three strings and store the result in the buffer pointed to + * by p, making p large enough to hold the strings + */ +char * +str3cat(char *p, char *s1, char *s2, char *s3) +{ + int l1 = strlen(s1); + int l2 = strlen(s2); + int l3 = strlen(s3); + + p = (char *) xrealloc(p, l1 + l2 + l3 + 1); + memmove(p, s1, l1); + memmove(p + l1, s2, l2); + memmove(p + l1 + l2, s3, l3 + 1); + return p; +} + + +/* + * Split s using ch as delimiter and qc as quote character + */ +char ** +strsplit(char *s, int ch, int qc) +{ + char **ivec; + int ic = 0; + int done = 0; + + ivec = (char **) xmalloc((ic + 1) * sizeof(char *)); + + while (!done) { + char *v; + + /* + * skip to split char + */ + while (*s && (ch == ' ' ? (isascii((unsigned char)*s) && isspace((unsigned char)*s)) : *s == ch)) + *s++ = '\0'; + + /* + * End of string? + */ + if (!*s) + break; + + /* + * remember start of string + */ + v = s; + + /* + * skip to split char + */ + while (*s && !(ch == ' ' ? (isascii((unsigned char)*s) && isspace((unsigned char)*s)) : *s == ch)) { + if (*s++ == qc) { + /* + * Skip past string. + */ + s++; + while (*s && *s != qc) + s++; + if (*s == qc) + s++; + } + } + + if (!*s) + done = 1; + *s++ = '\0'; + + /* + * save string in new ivec slot + */ + ivec[ic++] = v; + ivec = (char **) xrealloc((voidp) ivec, (ic + 1) * sizeof(char *)); + if (amuDebug(D_STR)) + plog(XLOG_DEBUG, "strsplit saved \"%s\"", v); + } + + if (amuDebug(D_STR)) + plog(XLOG_DEBUG, "strsplit saved a total of %d strings", ic); + + ivec[ic] = NULL; + + return ivec; +} + + +/* + * Use generic strlcpy to copy a string more carefully, null-terminating it + * as needed. However, if the copied string was truncated due to lack of + * space, then warn us. + * + * For now, xstrlcpy returns VOID because it doesn't look like anywhere in + * the Amd code do we actually use the return value of strncpy/strlcpy. + */ +void +#ifdef DEBUG +_xstrlcpy(const char *filename, int lineno, char *dst, const char *src, size_t len) +#else /* not DEBUG */ +xstrlcpy(char *dst, const char *src, size_t len) +#endif /* not DEBUG */ +{ + if (len == 0) + return; + if (strlcpy(dst, src, len) >= len) +#ifdef DEBUG + plog(XLOG_ERROR, "xstrlcpy(%s:%d): string \"%s\" truncated to \"%s\"", + filename, lineno, src, dst); +#else /* not DEBUG */ + plog(XLOG_ERROR, "xstrlcpy: string \"%s\" truncated to \"%s\"", src, dst); +#endif /* not DEBUG */ +} + + +/* + * Use generic strlcat to concatenate a string more carefully, + * null-terminating it as needed. However, if the copied string was + * truncated due to lack of space, then warn us. + * + * For now, xstrlcat returns VOID because it doesn't look like anywhere in + * the Amd code do we actually use the return value of strncat/strlcat. + */ +void +#ifdef DEBUG +_xstrlcat(const char *filename, int lineno, char *dst, const char *src, size_t len) +#else /* not DEBUG */ +xstrlcat(char *dst, const char *src, size_t len) +#endif /* not DEBUG */ +{ + if (len == 0) + return; + if (strlcat(dst, src, len) >= len) { + /* strlcat does not null terminate if the size of src is equal to len. */ + dst[strlen(dst) - 1] = '\0'; +#ifdef DEBUG + plog(XLOG_ERROR, "xstrlcat(%s:%d): string \"%s\" truncated to \"%s\"", + filename, lineno, src, dst); +#else /* not DEBUG */ + plog(XLOG_ERROR, "xstrlcat: string \"%s\" truncated to \"%s\"", src, dst); +#endif /* not DEBUG */ + } +} + + +/* our version of snprintf */ +int +#if defined(DEBUG) && (defined(HAVE_C99_VARARGS_MACROS) || defined(HAVE_GCC_VARARGS_MACROS)) +_xsnprintf(const char *filename, int lineno, char *str, size_t size, const char *format, ...) +#else /* not DEBUG or no C99/GCC-style vararg cpp macros supported */ +xsnprintf(char *str, size_t size, const char *format, ...) +#endif /* not DEBUG or no C99/GCC-style vararg cpp macros supported */ +{ + va_list ap; + int ret = 0; + + va_start(ap, format); +#if defined(DEBUG) && (defined(HAVE_C99_VARARGS_MACROS) || defined(HAVE_GCC_VARARGS_MACROS)) + ret = _xvsnprintf(filename, lineno, str, size, format, ap); +#else /* not DEBUG or no C99/GCC-style vararg cpp macros supported */ + ret = xvsnprintf(str, size, format, ap); +#endif /* not DEBUG or no C99/GCC-style vararg cpp macros supported */ + va_end(ap); + + return ret; +} + + +/* our version of vsnprintf */ +int +#if defined(DEBUG) && (defined(HAVE_C99_VARARGS_MACROS) || defined(HAVE_GCC_VARARGS_MACROS)) +_xvsnprintf(const char *filename, int lineno, char *str, size_t size, const char *format, va_list ap) +#else /* not DEBUG or no C99/GCC-style vararg cpp macros supported */ +xvsnprintf(char *str, size_t size, const char *format, va_list ap) +#endif /* not DEBUG or no C99/GCC-style vararg cpp macros supported */ +{ + int ret = 0; + +#ifdef HAVE_VSNPRINTF + ret = vsnprintf(str, size, format, ap); +#else /* not HAVE_VSNPRINTF */ + ret = vsprintf(str, format, ap); /* less secure version */ +#endif /* not HAVE_VSNPRINTF */ + /* + * If error or truncation, plog error. + * + * WARNING: we use the static 'maxtrunc' variable below to break out any + * possible infinite recursion between plog() and xvsnprintf(). If it + * ever happens, it'd indicate a bug in Amd. + */ + if (ret < 0 || (size_t) ret >= size) { /* error or truncation occured */ + static int maxtrunc; /* hack to avoid inifinite loop */ + if (++maxtrunc > 10) +#if defined(DEBUG) && (defined(HAVE_C99_VARARGS_MACROS) || defined(HAVE_GCC_VARARGS_MACROS)) + plog(XLOG_ERROR, "xvsnprintf(%s:%d): string %p truncated (ret=%d, format=\"%s\")", + filename, lineno, str, ret, format); +#else /* not DEBUG or no C99/GCC-style vararg cpp macros supported */ + plog(XLOG_ERROR, "xvsnprintf: string %p truncated (ret=%d, format=\"%s\")", + str, ret, format); +#endif /* not DEBUG or no C99/GCC-style vararg cpp macros supported */ + } + + return ret; +} diff --git a/contrib/amd/libamu/wire.c b/contrib/amd/libamu/wire.c index 093f1a6..c1852cd 100644 --- a/contrib/amd/libamu/wire.c +++ b/contrib/amd/libamu/wire.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: wire.c,v 1.8.2.10 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/wire.c * */ @@ -60,6 +59,7 @@ #include <am_defs.h> #include <amu.h> + #ifdef HAVE_IFADDRS_H #include <ifaddrs.h> #endif /* HAVE_IFADDRS_H */ @@ -101,31 +101,32 @@ print_wires(void) int bufcount = 0; int buf_size = 1024; - buf = SALLOC(1024); + buf = SALLOC(buf_size); /* initial allocation (may grow!) */ if (!buf) return NULL; if (!localnets) { - sprintf(buf, "No networks.\n"); + xstrlcpy(buf, "No networks\n", buf_size); return buf; } /* check if there's more than one network */ if (!localnets->ip_next) { - sprintf(buf, - "Network: wire=\"%s\" (netnumber=%s).\n", - localnets->ip_net_name, localnets->ip_net_num); + /* use buf_size for sizeof(buf) because of the realloc() below */ + xsnprintf(buf, buf_size, + "Network: wire=\"%s\" (netnumber=%s).\n", + localnets->ip_net_name, localnets->ip_net_num); return buf; } buf[0] = '\0'; /* null out buffer before appending */ for (i = 1, al = localnets; al; al = al->ip_next, i++) { - sprintf(s, "Network %d: wire=\"%s\" (netnumber=%s).\n", - i, al->ip_net_name, al->ip_net_num); + xsnprintf(s, sizeof(s), "Network %d: wire=\"%s\" (netnumber=%s).\n", + i, al->ip_net_name, al->ip_net_num); bufcount += strlen(s); if (bufcount > buf_size) { buf_size *= 2; buf = xrealloc(buf, buf_size); } - strcat(buf, s); + xstrlcat(buf, s, buf_size); } return buf; } @@ -199,7 +200,7 @@ getwire_lookup(u_long address, u_long netmask, int ishost) */ if (!np) { u_long short_subnet = subnet; - while(short_subnet && (short_subnet & 0x000000ff) == 0) + while (short_subnet && (short_subnet & 0x000000ff) == 0) short_subnet >>= 8; np = getnetbyaddr(short_subnet, AF_INET); if (np) @@ -210,18 +211,18 @@ getwire_lookup(u_long address, u_long netmask, int ishost) } if ((subnet & 0xffffff) == 0) { - sprintf(netNumberBuf, "%lu", C(subnet >> 24)); + xsnprintf(netNumberBuf, sizeof(netNumberBuf), "%lu", C(subnet >> 24)); } else if ((subnet & 0xffff) == 0) { - sprintf(netNumberBuf, "%lu.%lu", - C(subnet >> 24), C(subnet >> 16)); + xsnprintf(netNumberBuf, sizeof(netNumberBuf), "%lu.%lu", + C(subnet >> 24), C(subnet >> 16)); } else if ((subnet & 0xff) == 0) { - sprintf(netNumberBuf, "%lu.%lu.%lu", - C(subnet >> 24), C(subnet >> 16), - C(subnet >> 8)); + xsnprintf(netNumberBuf, sizeof(netNumberBuf), "%lu.%lu.%lu", + C(subnet >> 24), C(subnet >> 16), + C(subnet >> 8)); } else { - sprintf(netNumberBuf, "%lu.%lu.%lu.%lu", - C(subnet >> 24), C(subnet >> 16), - C(subnet >> 8), C(subnet)); + xsnprintf(netNumberBuf, sizeof(netNumberBuf), "%lu.%lu.%lu.%lu", + C(subnet >> 24), C(subnet >> 16), + C(subnet >> 8), C(subnet)); } /* fill in network number (string) */ @@ -237,7 +238,7 @@ getwire_lookup(u_long address, u_long netmask, int ishost) if (hp != NULL) s = (char *) hp->h_name; else - s = inet_dquad(buf, subnet); + s = inet_dquad(buf, sizeof(buf), subnet); } /* fill in network name (string) */ @@ -259,14 +260,14 @@ getwire_lookup(u_long address, u_long netmask, int ishost) * sizeof(buf) needs to be at least 16. */ char * -inet_dquad(char *buf, u_long addr) +inet_dquad(char *buf, size_t l, u_long addr) { addr = ntohl(addr); - sprintf(buf, "%ld.%ld.%ld.%ld", - ((addr >> 24) & 0xff), - ((addr >> 16) & 0xff), - ((addr >> 8) & 0xff), - ((addr >> 0) & 0xff)); + xsnprintf(buf, l, "%ld.%ld.%ld.%ld", + ((addr >> 24) & 0xff), + ((addr >> 16) & 0xff), + ((addr >> 8) & 0xff), + ((addr >> 0) & 0xff)); return buf; } @@ -279,16 +280,17 @@ int islocalnet(u_long addr) { addrlist *al; -#ifdef DEBUG - char buf[16]; -#endif /* DEBUG */ for (al = localnets; al; al = al->ip_next) if (((addr ^ al->ip_addr) & al->ip_mask) == 0) return TRUE; #ifdef DEBUG - plog(XLOG_INFO, "%s is on a remote network", inet_dquad(buf, addr)); + { + char buf[16]; + plog(XLOG_INFO, "%s is on a remote network", + inet_dquad(buf, sizeof(buf), addr)); + } #endif /* DEBUG */ return FALSE; @@ -319,15 +321,16 @@ is_network_member(const char *net) char *netstr = strdup(net), *maskstr; u_long netnum, masknum = 0; maskstr = strchr(netstr, '/'); + maskstr[0] = '\0'; /* null terminate netstr */ maskstr++; - maskstr[-1] = '\0'; /* null terminate netstr */ if (*maskstr == '\0') /* if empty string, make it NULL */ maskstr = NULL; /* check if netmask uses a dotted-quad or bit-length, or not defined at all */ if (maskstr) { if (strchr(maskstr, '.')) { + /* XXX: inet_addr is obsolste, convert to inet_aton() */ masknum = inet_addr(maskstr); - if (masknum < 0) /* can be invalid (-1) or all-1s */ + if (masknum == INADDR_NONE) /* can be invalid (-1) or all-1s */ masknum = 0xffffffff; } else if (NSTRCEQ(maskstr, "0x", 2)) { masknum = strtoul(maskstr, NULL, 16); @@ -354,6 +357,24 @@ is_network_member(const char *net) } +/* + * Determine whether a IP address (netnum) is one of the local interfaces, + * returns TRUE/FALSE. + * Does not include the loopback interface: caller needs to check that. + */ +int +is_interface_local(u_long netnum) +{ + addrlist *al; + + for (al = localnets; al; al = al->ip_next) { + if (al->ip_addr == netnum) + return TRUE; + } + return FALSE; +} + + #ifdef HAVE_GETIFADDRS void getwire(char **name1, char **number1) @@ -381,10 +402,10 @@ getwire(char **name1, char **number1) continue; /* - * If the interface is a loopback, or its not running + * If the interface is the loopback, or it's not running, * then ignore it. */ - if ((ifap->ifa_flags & IFF_LOOPBACK) != 0) + if (S2IN(ifap->ifa_addr) == htonl(INADDR_LOOPBACK)) continue; if ((ifap->ifa_flags & IFF_RUNNING) == 0) continue; @@ -395,7 +416,7 @@ getwire(char **name1, char **number1) al = getwire_lookup(S2IN(ifap->ifa_dstaddr), 0xffffffff, 1); /* append to the end of the list */ - if (!localnets) { + if (!localnets || tail == NULL) { localnets = tail = al; tail->ip_next = NULL; } else { @@ -439,12 +460,6 @@ getwire(char **name1, char **number1) u_long address; addrlist *al = NULL, *tail = NULL; char buf[GFBUFLEN]; -#if 0 - u_long net; - u_long mask; - u_long subnetshift; - char buf[GFBUFLEN], *s; -#endif #ifndef SIOCGIFFLAGS /* if cannot get interface flags, return nothing */ @@ -504,13 +519,11 @@ getwire(char **name1, char **number1) continue; /* - * If the interface is a loopback, or its not running + * If the interface is the loopback, or it's not running, * then ignore it. */ -#ifdef IFF_LOOPBACK - if ((ifr->ifr_flags & IFF_LOOPBACK) != 0) + if (address == htonl(INADDR_LOOPBACK)) continue; -#endif /* IFF_LOOPBACK */ /* * Fix for 0.0.0.0 loopback on SunOS 3.X which defines IFF_ROUTE * instead of IFF_LOOPBACK. diff --git a/contrib/amd/libamu/xdr_func.c b/contrib/amd/libamu/xdr_func.c index 1592a0e..6bd0254 100644 --- a/contrib/amd/libamu/xdr_func.c +++ b/contrib/amd/libamu/xdr_func.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,9 +36,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: xdr_func.c,v 1.4.2.8 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/xdr_func.c * */ @@ -51,10 +50,24 @@ #include <am_defs.h> #include <amu.h> +#ifdef __RPCSVC_MOUNT_H__ +# error IRIX6 should not include rpcsvc/mount.h +#endif /* __RPCSVC_MOUNT_H__ */ /* * MACROS: */ +#ifdef HAVE_FS_AUTOFS +# ifndef AUTOFS_MAXCOMPONENTLEN +# define AUTOFS_MAXCOMPONENTLEN 255 +# endif /* not AUTOFS_MAXCOMPONENTLEN */ +# ifndef AUTOFS_MAXOPTSLEN +# define AUTOFS_MAXOPTSLEN 255 +# endif /* not AUTOFS_MAXOPTSLEN */ +# ifndef AUTOFS_MAXPATHLEN +# define AUTOFS_MAXPATHLEN 1024 +# endif /* not AUTOFS_MAXPATHLEN */ +#endif /* HAVE_FS_AUTOFS */ /* forward definitions, are they needed? */ extern bool_t xdr_exportnode(XDR *xdrs, exportnode *objp); @@ -66,10 +79,8 @@ extern bool_t xdr_name(XDR *xdrs, name *objp); bool_t xdr_attrstat(XDR *xdrs, nfsattrstat *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_attrstat:"); -#endif /* DEBUG */ if (!xdr_nfsstat(xdrs, &objp->ns_status)) { return (FALSE); @@ -92,10 +103,8 @@ xdr_attrstat(XDR *xdrs, nfsattrstat *objp) bool_t xdr_createargs(XDR *xdrs, nfscreateargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_createargs:"); -#endif /* DEBUG */ if (!xdr_diropargs(xdrs, &objp->ca_where)) { return (FALSE); @@ -112,10 +121,8 @@ xdr_createargs(XDR *xdrs, nfscreateargs *objp) bool_t xdr_dirlist(XDR *xdrs, nfsdirlist *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_dirlist:"); -#endif /* DEBUG */ if (!xdr_pointer(xdrs, (char **) &objp->dl_entries, sizeof(nfsentry), (XDRPROC_T_TYPE) xdr_entry)) { return (FALSE); @@ -132,10 +139,8 @@ xdr_dirlist(XDR *xdrs, nfsdirlist *objp) bool_t xdr_diropargs(XDR *xdrs, nfsdiropargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_diropargs:"); -#endif /* DEBUG */ if (!xdr_nfs_fh(xdrs, &objp->da_fhandle)) { return (FALSE); @@ -152,10 +157,8 @@ xdr_diropargs(XDR *xdrs, nfsdiropargs *objp) bool_t xdr_diropokres(XDR *xdrs, nfsdiropokres *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_diropokres:"); -#endif /* DEBUG */ if (!xdr_nfs_fh(xdrs, &objp->drok_fhandle)) { return (FALSE); @@ -172,10 +175,8 @@ xdr_diropokres(XDR *xdrs, nfsdiropokres *objp) bool_t xdr_diropres(XDR *xdrs, nfsdiropres *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_diropres:"); -#endif /* DEBUG */ if (!xdr_nfsstat(xdrs, &objp->dr_status)) { return (FALSE); @@ -198,10 +199,8 @@ xdr_diropres(XDR *xdrs, nfsdiropres *objp) bool_t xdr_dirpath(XDR *xdrs, dirpath *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_dirpath:"); -#endif /* DEBUG */ if (!xdr_string(xdrs, objp, MNTPATHLEN)) { return (FALSE); @@ -215,10 +214,8 @@ xdr_dirpath(XDR *xdrs, dirpath *objp) bool_t xdr_entry(XDR *xdrs, nfsentry *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_entry:"); -#endif /* DEBUG */ if (!xdr_u_int(xdrs, &objp->ne_fileid)) { return (FALSE); @@ -241,10 +238,8 @@ xdr_entry(XDR *xdrs, nfsentry *objp) bool_t xdr_exportnode(XDR *xdrs, exportnode *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_exportnode:"); -#endif /* DEBUG */ if (!xdr_dirpath(xdrs, &objp->ex_dir)) { return (FALSE); @@ -264,10 +259,8 @@ xdr_exportnode(XDR *xdrs, exportnode *objp) bool_t xdr_exports(XDR *xdrs, exports *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_exports:"); -#endif /* DEBUG */ if (!xdr_pointer(xdrs, (char **) objp, sizeof(exportnode), (XDRPROC_T_TYPE) xdr_exportnode)) { return (FALSE); @@ -281,10 +274,8 @@ xdr_exports(XDR *xdrs, exports *objp) bool_t xdr_fattr(XDR *xdrs, nfsfattr *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_fattr:"); -#endif /* DEBUG */ if (!xdr_ftype(xdrs, &objp->na_type)) { return (FALSE); @@ -337,10 +328,8 @@ xdr_fattr(XDR *xdrs, nfsfattr *objp) bool_t xdr_fhandle(XDR *xdrs, fhandle objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_fhandle:"); -#endif /* DEBUG */ if (!xdr_opaque(xdrs, objp, NFS_FHSIZE)) { return (FALSE); @@ -354,10 +343,8 @@ xdr_fhandle(XDR *xdrs, fhandle objp) bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_fhstatus:"); -#endif /* DEBUG */ if (!xdr_u_int(xdrs, &objp->fhs_status)) { return (FALSE); @@ -374,10 +361,8 @@ xdr_fhstatus(XDR *xdrs, fhstatus *objp) bool_t xdr_filename(XDR *xdrs, filename *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_filename:"); -#endif /* DEBUG */ if (!xdr_string(xdrs, objp, NFS_MAXNAMLEN)) { return (FALSE); @@ -391,12 +376,12 @@ xdr_filename(XDR *xdrs, filename *objp) bool_t xdr_ftype(XDR *xdrs, nfsftype *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + enum_t local_obj = *objp; + + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_ftype:"); -#endif /* DEBUG */ - if (!xdr_enum(xdrs, (enum_t *) objp)) { + if (!xdr_enum(xdrs, &local_obj)) { return (FALSE); } return (TRUE); @@ -408,10 +393,8 @@ xdr_ftype(XDR *xdrs, nfsftype *objp) bool_t xdr_groupnode(XDR *xdrs, groupnode *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_groupnode:"); -#endif /* DEBUG */ if (!xdr_name(xdrs, &objp->gr_name)) { return (FALSE); @@ -428,10 +411,8 @@ xdr_groupnode(XDR *xdrs, groupnode *objp) bool_t xdr_groups(XDR *xdrs, groups *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_groups:"); -#endif /* DEBUG */ if (!xdr_pointer(xdrs, (char **) objp, sizeof(groupnode), (XDRPROC_T_TYPE) xdr_groupnode)) { return (FALSE); @@ -445,10 +426,8 @@ xdr_groups(XDR *xdrs, groups *objp) bool_t xdr_linkargs(XDR *xdrs, nfslinkargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_linkargs:"); -#endif /* DEBUG */ if (!xdr_nfs_fh(xdrs, &objp->la_fhandle)) { return (FALSE); @@ -465,10 +444,8 @@ xdr_linkargs(XDR *xdrs, nfslinkargs *objp) bool_t xdr_mountbody(XDR *xdrs, mountbody *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_mountbody:"); -#endif /* DEBUG */ if (!xdr_name(xdrs, &objp->ml_hostname)) { return (FALSE); @@ -488,10 +465,8 @@ xdr_mountbody(XDR *xdrs, mountbody *objp) bool_t xdr_mountlist(XDR *xdrs, mountlist *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_mountlist:"); -#endif /* DEBUG */ if (!xdr_pointer(xdrs, (char **) objp, sizeof(mountbody), (XDRPROC_T_TYPE) xdr_mountbody)) { return (FALSE); @@ -501,94 +476,12 @@ xdr_mountlist(XDR *xdrs, mountlist *objp) #endif /* not HAVE_XDR_MOUNTLIST */ -#if defined(HAVE_FS_NFS3) && !defined(HAVE_XDR_MOUNTRES3) -/* - * This ifdef is a hack: this whole file needs to be compiled - * only if the system has NFS V3 and does not have the xdr_mountres3 - * function. Autoconf should pick this source file to compile only - * if these two conditions apply. - */ - -bool_t -xdr_fhandle3(XDR *xdrs, fhandle3 *objp) -{ -#ifdef DEBUG - amuDebug(D_XDRTRACE) - plog(XLOG_DEBUG, "xdr_fhandle3:"); -#endif /* DEBUG */ - - if (!xdr_bytes(xdrs, - (char **) &objp->fhandle3_val, - (u_int *) &objp->fhandle3_len, - FHSIZE3)) - return (FALSE); - return (TRUE); -} - - -bool_t -xdr_mountstat3(XDR *xdrs, mountstat3 *objp) -{ -#ifdef DEBUG - amuDebug(D_XDRTRACE) - plog(XLOG_DEBUG, "xdr_mountstat3:"); -#endif /* DEBUG */ - - if (!xdr_enum(xdrs, (enum_t *)objp)) - return (FALSE); - return (TRUE); -} - - -bool_t -xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp) -{ -#ifdef DEBUG - amuDebug(D_XDRTRACE) - plog(XLOG_DEBUG, "xdr_mountres3_ok:"); -#endif /* DEBUG */ - - if (!xdr_fhandle3(xdrs, &objp->fhandle)) - return (FALSE); - if (!xdr_array(xdrs, - (char **)&objp->auth_flavors.auth_flavors_val, - (u_int *) &objp->auth_flavors.auth_flavors_len, - ~0, - sizeof (int), - (xdrproc_t) xdr_int)) - return (FALSE); - return (TRUE); -} - - -bool_t -xdr_mountres3(XDR *xdrs, mountres3 *objp) -{ -#ifdef DEBUG - amuDebug(D_XDRTRACE) - plog(XLOG_DEBUG, "xdr_mountres3:"); -#endif /* DEBUG */ - - if (!xdr_mountstat3(xdrs, &objp->fhs_status)) - return (FALSE); - - if (objp->fhs_status == 0) { /* 0 == MNT_OK or MNT3_OK */ - if (!xdr_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo)) - return (FALSE); - } - return (TRUE); -} -#endif /* defined(HAVE_FS_NFS3) && !defined(HAVE_XDR_MOUNTRES3) */ - - #ifndef HAVE_XDR_NAME bool_t xdr_name(XDR *xdrs, name *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_name:"); -#endif /* DEBUG */ if (!xdr_string(xdrs, objp, MNTNAMLEN)) { return (FALSE); @@ -602,10 +495,8 @@ xdr_name(XDR *xdrs, name *objp) bool_t xdr_nfs_fh(XDR *xdrs, am_nfs_fh *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfs_fh:"); -#endif /* DEBUG */ if (!xdr_opaque(xdrs, (caddr_t) objp->fh_data, NFS_FHSIZE)) { return (FALSE); @@ -619,10 +510,8 @@ xdr_nfs_fh(XDR *xdrs, am_nfs_fh *objp) bool_t xdr_nfscookie(XDR *xdrs, nfscookie objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfscookie:"); -#endif /* DEBUG */ if (!xdr_opaque(xdrs, objp, NFS_COOKIESIZE)) { return (FALSE); @@ -636,10 +525,8 @@ xdr_nfscookie(XDR *xdrs, nfscookie objp) bool_t xdr_nfspath(XDR *xdrs, nfspath *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfspath:"); -#endif /* DEBUG */ if (!xdr_string(xdrs, objp, NFS_MAXPATHLEN)) { return (FALSE); @@ -653,12 +540,12 @@ xdr_nfspath(XDR *xdrs, nfspath *objp) bool_t xdr_nfsstat(XDR *xdrs, nfsstat *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + enum_t local_obj = *objp; + + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfsstat:"); -#endif /* DEBUG */ - if (!xdr_enum(xdrs, (enum_t *) objp)) { + if (!xdr_enum(xdrs, &local_obj)) { return (FALSE); } return (TRUE); @@ -670,10 +557,8 @@ xdr_nfsstat(XDR *xdrs, nfsstat *objp) bool_t xdr_nfstime(XDR *xdrs, nfstime *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_nfstime:"); -#endif /* DEBUG */ if (!xdr_u_int(xdrs, (u_int *) &objp->nt_seconds)) { return (FALSE); @@ -690,11 +575,8 @@ xdr_nfstime(XDR *xdrs, nfstime *objp) bool_t xdr_pointer(register XDR *xdrs, char **objpp, u_int obj_size, XDRPROC_T_TYPE xdr_obj) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_pointer:"); -#endif /* DEBUG */ - bool_t more_data; @@ -716,10 +598,8 @@ xdr_pointer(register XDR *xdrs, char **objpp, u_int obj_size, XDRPROC_T_TYPE xdr bool_t xdr_readargs(XDR *xdrs, nfsreadargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_readargs:"); -#endif /* DEBUG */ if (!xdr_nfs_fh(xdrs, &objp->ra_fhandle)) { return (FALSE); @@ -742,10 +622,8 @@ xdr_readargs(XDR *xdrs, nfsreadargs *objp) bool_t xdr_readdirargs(XDR *xdrs, nfsreaddirargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_readdirargs:"); -#endif /* DEBUG */ if (!xdr_nfs_fh(xdrs, &objp->rda_fhandle)) { return (FALSE); @@ -765,10 +643,8 @@ xdr_readdirargs(XDR *xdrs, nfsreaddirargs *objp) bool_t xdr_readdirres(XDR *xdrs, nfsreaddirres *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_readdirres:"); -#endif /* DEBUG */ if (!xdr_nfsstat(xdrs, &objp->rdr_status)) { return (FALSE); @@ -791,10 +667,8 @@ xdr_readdirres(XDR *xdrs, nfsreaddirres *objp) bool_t xdr_readlinkres(XDR *xdrs, nfsreadlinkres *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_readlinkres:"); -#endif /* DEBUG */ if (!xdr_nfsstat(xdrs, &objp->rlr_status)) { return (FALSE); @@ -817,10 +691,8 @@ xdr_readlinkres(XDR *xdrs, nfsreadlinkres *objp) bool_t xdr_readokres(XDR *xdrs, nfsreadokres *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_readokres:"); -#endif /* DEBUG */ if (!xdr_fattr(xdrs, &objp->raok_attributes)) { return (FALSE); @@ -840,10 +712,8 @@ xdr_readokres(XDR *xdrs, nfsreadokres *objp) bool_t xdr_readres(XDR *xdrs, nfsreadres *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_readres:"); -#endif /* DEBUG */ if (!xdr_nfsstat(xdrs, &objp->rr_status)) { return (FALSE); @@ -866,10 +736,8 @@ xdr_readres(XDR *xdrs, nfsreadres *objp) bool_t xdr_renameargs(XDR *xdrs, nfsrenameargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_renameargs:"); -#endif /* DEBUG */ if (!xdr_diropargs(xdrs, &objp->rna_from)) { return (FALSE); @@ -886,10 +754,8 @@ xdr_renameargs(XDR *xdrs, nfsrenameargs *objp) bool_t xdr_sattr(XDR *xdrs, nfssattr *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_sattr:"); -#endif /* DEBUG */ if (!xdr_u_int(xdrs, &objp->sa_mode)) { return (FALSE); @@ -918,10 +784,8 @@ xdr_sattr(XDR *xdrs, nfssattr *objp) bool_t xdr_sattrargs(XDR *xdrs, nfssattrargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_sattrargs:"); -#endif /* DEBUG */ if (!xdr_nfs_fh(xdrs, &objp->sag_fhandle)) { return (FALSE); @@ -938,10 +802,8 @@ xdr_sattrargs(XDR *xdrs, nfssattrargs *objp) bool_t xdr_statfsokres(XDR *xdrs, nfsstatfsokres *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_statfsokres:"); -#endif /* DEBUG */ if (!xdr_u_int(xdrs, &objp->sfrok_tsize)) { return (FALSE); @@ -967,10 +829,8 @@ xdr_statfsokres(XDR *xdrs, nfsstatfsokres *objp) bool_t xdr_statfsres(XDR *xdrs, nfsstatfsres *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_statfsres:"); -#endif /* DEBUG */ if (!xdr_nfsstat(xdrs, &objp->sfr_status)) { return (FALSE); @@ -993,10 +853,8 @@ xdr_statfsres(XDR *xdrs, nfsstatfsres *objp) bool_t xdr_symlinkargs(XDR *xdrs, nfssymlinkargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_symlinkargs:"); -#endif /* DEBUG */ if (!xdr_diropargs(xdrs, &objp->sla_from)) { return (FALSE); @@ -1016,10 +874,8 @@ xdr_symlinkargs(XDR *xdrs, nfssymlinkargs *objp) bool_t xdr_writeargs(XDR *xdrs, nfswriteargs *objp) { -#ifdef DEBUG - amuDebug(D_XDRTRACE) + if (amuDebug(D_XDRTRACE)) plog(XLOG_DEBUG, "xdr_writeargs:"); -#endif /* DEBUG */ if (!xdr_nfs_fh(xdrs, &objp->wra_fhandle)) { return (FALSE); @@ -1042,3 +898,201 @@ xdr_writeargs(XDR *xdrs, nfswriteargs *objp) return (TRUE); } #endif /* not HAVE_XDR_WRITEARGS */ + + +/* + * NFS V3 XDR FUNCTIONS: + */ +#ifdef HAVE_FS_NFS3 +bool_t +xdr_am_fhandle3(XDR *xdrs, am_fhandle3 *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_fhandle3:"); + + if (!xdr_bytes(xdrs, + (char **) &objp->fhandle3_val, + (u_int *) &objp->fhandle3_len, + AM_FHSIZE3)) + return (FALSE); + return (TRUE); +} + + +bool_t +xdr_am_mountstat3(XDR *xdrs, am_mountstat3 *objp) +{ + enum_t local_obj = *objp; + + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_mountstat3:"); + + if (!xdr_enum(xdrs, &local_obj)) + return (FALSE); + return (TRUE); +} + + +bool_t +xdr_am_mountres3_ok(XDR *xdrs, am_mountres3_ok *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_mountres3_ok:"); + + if (!xdr_am_fhandle3(xdrs, &objp->fhandle)) + return (FALSE); + if (!xdr_array(xdrs, + (char **) ((voidp) &objp->auth_flavors.auth_flavors_val), + (u_int *) &objp->auth_flavors.auth_flavors_len, + ~0, + sizeof(int), + (XDRPROC_T_TYPE) xdr_int)) + return (FALSE); + return (TRUE); +} + + +bool_t +xdr_am_mountres3(XDR *xdrs, am_mountres3 *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_mountres3:"); + + if (!xdr_am_mountstat3(xdrs, &objp->fhs_status)) + return (FALSE); + + if (objp->fhs_status == AM_MNT3_OK) { + if (!xdr_am_mountres3_ok(xdrs, &objp->mountres3_u.mountinfo)) + return (FALSE); + } + return (TRUE); +} + + +bool_t +xdr_am_diropargs3(XDR *xdrs, am_diropargs3 *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_diropargs3:"); + + if (!xdr_am_nfs_fh3(xdrs, &objp->dir)) + return (FALSE); + if (!xdr_am_filename3(xdrs, &objp->name)) + return (FALSE); + return (TRUE); +} + + +bool_t +xdr_am_filename3(XDR *xdrs, am_filename3 *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_filename3:"); + + if (!xdr_string(xdrs, objp, ~0)) + return (FALSE); + return (TRUE); +} + + +bool_t +xdr_am_LOOKUP3args(XDR *xdrs, am_LOOKUP3args *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_LOOKUP3args:"); + + if (!xdr_am_diropargs3(xdrs, &objp->what)) + return (FALSE); + return (TRUE); +} + + +bool_t +xdr_am_LOOKUP3res(XDR *xdrs, am_LOOKUP3res *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_LOOKUP3res:"); + + if (!xdr_am_nfsstat3(xdrs, &objp->status)) + return (FALSE); + switch (objp->status) { + case AM_NFS3_OK: + if (!xdr_am_LOOKUP3resok(xdrs, &objp->res_u.ok)) + return (FALSE); + break; + default: + if (!xdr_am_LOOKUP3resfail(xdrs, &objp->res_u.fail)) + return (FALSE); + break; + } + return (TRUE); +} + + +bool_t +xdr_am_LOOKUP3resfail(XDR *xdrs, am_LOOKUP3resfail *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_LOOKUP3resfail:"); + + /* + * Don't xdr post_op_attr: amd doesn't need them, but they require many + * additional xdr functions. + */ +#if 0 + if (!xdr_post_op_attr(xdrs, &objp->dir_attributes)) + return (FALSE); +#endif + return (TRUE); +} + + +bool_t +xdr_am_LOOKUP3resok(XDR *xdrs, am_LOOKUP3resok *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_LOOKUP3resok:"); + + if (!xdr_am_nfs_fh3(xdrs, &objp->object)) + return (FALSE); + /* + * Don't xdr post_op_attr: amd doesn't need them, but they require many + * additional xdr functions. + */ +#if 0 + if (!xdr_post_op_attr(xdrs, &objp->obj_attributes)) + return (FALSE); + if (!xdr_post_op_attr(xdrs, &objp->dir_attributes)) + return (FALSE); +#endif + return (TRUE); +} + + +bool_t +xdr_am_nfs_fh3(XDR *xdrs, am_nfs_fh3 *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_nfs_fh3:"); + + if (!xdr_u_int(xdrs, &objp->am_fh3_length)) + return (FALSE); + if (objp->am_fh3_length > AM_FHSIZE3) + return (FALSE); + if (!xdr_opaque(xdrs, objp->am_fh3_data, objp->am_fh3_length)) + return (FALSE); + return (TRUE); +} + + +bool_t +xdr_am_nfsstat3(XDR *xdrs, am_nfsstat3 *objp) +{ + if (amuDebug(D_XDRTRACE)) + plog(XLOG_DEBUG, "xdr_am_nfsstat3:"); + + if (!xdr_enum(xdrs, (enum_t *)objp)) + return (FALSE); + return (TRUE); +} +#endif /* not HAVE_FS_NFS3 */ diff --git a/contrib/amd/libamu/xutil.c b/contrib/amd/libamu/xutil.c index 5095c23..3a33b9c 100644 --- a/contrib/amd/libamu/xutil.c +++ b/contrib/amd/libamu/xutil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2004 Erez Zadok + * Copyright (c) 1997-2006 Erez Zadok * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990 The Regents of the University of California. @@ -36,12 +36,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * %W% (Berkeley) %G% * - * $Id: xutil.c,v 1.11.2.13 2004/01/06 03:15:24 ezk Exp $ + * File: am-utils/libamu/xutil.c * */ +/* + * Miscellaneous Utilities: Logging, TTY, timers, signals, RPC, memory, etc. + */ + #ifdef HAVE_CONFIG_H # include <config.h> #endif /* HAVE_CONFIG_H */ @@ -56,13 +59,11 @@ FILE *logfp = NULL; static char *am_progname = "unknown"; /* "amd" */ -static char am_hostname[MAXHOSTNAMELEN + 1] = "unknown"; /* Hostname */ +static char am_hostname[MAXHOSTNAMELEN] = "unknown"; /* Hostname */ pid_t am_mypid = -1; /* process ID */ serv_state amd_state; /* amd's state */ int foreground = 1; /* 1 == this is the top-level server */ -#ifdef DEBUG int debug_flags = 0; -#endif /* DEBUG */ #ifdef HAVE_SYSLOG int syslogging; @@ -71,12 +72,11 @@ int xlog_level = XLOG_ALL & ~XLOG_MAP & ~XLOG_STATS; int xlog_level_init = ~0; static int amd_program_number = AMQ_PROGRAM; -time_t clock_valid = 0; -time_t xclock_valid = 0; - #ifdef DEBUG_MEM +# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) static int mem_bytes; static int orig_mem_bytes; +# endif /* not defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) */ #endif /* DEBUG_MEM */ /* forward definitions */ @@ -91,23 +91,21 @@ static void real_plog(int lvl, const char *fmt, va_list vargs) */ struct opt_tab dbg_opt[] = { - {"all", D_ALL}, /* All */ - {"amq", D_AMQ}, /* Register for AMQ program */ - {"daemon", D_DAEMON}, /* Enter daemon mode */ - {"fork", D_FORK}, /* Fork server (nofork = don't fork) */ + {"all", D_ALL}, /* All non-disruptive options */ + {"amq", D_AMQ}, /* Don't register for AMQ program */ + {"daemon", D_DAEMON}, /* Don't enter daemon mode */ + {"fork", D_FORK}, /* Don't fork server */ {"full", D_FULL}, /* Program trace */ #ifdef HAVE_CLOCK_GETTIME {"hrtime", D_HRTIME}, /* Print high resolution time stamps */ #endif /* HAVE_CLOCK_GETTIME */ /* info service specific debugging (hesiod, nis, etc) */ {"info", D_INFO}, -# ifdef DEBUG_MEM {"mem", D_MEM}, /* Trace memory allocations */ -# endif /* DEBUG_MEM */ {"mtab", D_MTAB}, /* Use local mtab file */ - {"readdir", D_READDIR}, /* check on browsable_dirs progress */ + {"readdir", D_READDIR}, /* Check on browsable_dirs progress */ {"str", D_STR}, /* Debug string munging */ - {"test", D_TEST}, /* Full debug - but no daemon */ + {"test", D_TEST}, /* Full debug - no daemon, no amq, local mtab */ {"trace", D_TRACE}, /* Protocol trace */ {"xdrtrace", D_XDRTRACE}, /* Trace xdr routines */ {0, 0} @@ -152,8 +150,7 @@ am_get_progname(void) void am_set_hostname(char *hn) { - strncpy(am_hostname, hn, MAXHOSTNAMELEN); - am_hostname[MAXHOSTNAMELEN] = '\0'; + xstrlcpy(am_hostname, hn, MAXHOSTNAMELEN); } @@ -172,6 +169,13 @@ am_set_mypid(void) } +long +get_server_pid() +{ + return (long) (foreground ? am_mypid : getppid()); +} + + voidp xmalloc(int len) { @@ -187,10 +191,8 @@ xmalloc(int len) do { p = (voidp) malloc((unsigned) len); if (p) { -#if defined(DEBUG) && defined(DEBUG_MEM) - amuDebug(D_MEM) - plog(XLOG_DEBUG, "Allocated size %d; block %#x", len, p); -#endif /* defined(DEBUG) && defined(DEBUG_MEM) */ + if (amuDebug(D_MEM)) + plog(XLOG_DEBUG, "Allocated size %d; block %p", len, p); return p; } if (retries > 0) { @@ -223,9 +225,8 @@ xzalloc(int len) voidp xrealloc(voidp ptr, int len) { -#if defined(DEBUG) && defined(DEBUG_MEM) - amuDebug(D_MEM) plog(XLOG_DEBUG, "Reallocated size %d; block %#x", len, ptr); -#endif /* defined(DEBUG) && defined(DEBUG_MEM) */ + if (amuDebug(D_MEM)) + plog(XLOG_DEBUG, "Reallocated size %d; block %p", len, ptr); if (len == 0) len = 1; @@ -244,20 +245,19 @@ xrealloc(voidp ptr, int len) } -#if defined(DEBUG) && defined(DEBUG_MEM) +#ifdef DEBUG_MEM void dxfree(char *file, int line, voidp ptr) { - amuDebug(D_MEM) - plog(XLOG_DEBUG, "Free in %s:%d: block %#x", file, line, ptr); + if (amuDebug(D_MEM)) + plog(XLOG_DEBUG, "Free in %s:%d: block %p", file, line, ptr); /* this is the only place that must NOT use XFREE()!!! */ free(ptr); ptr = NULL; /* paranoid */ } -#endif /* defined(DEBUG) && defined(DEBUG_MEM) */ -#ifdef DEBUG_MEM +# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) static void checkup_mem(void) { @@ -280,6 +280,7 @@ checkup_mem(void) } malloc_verify(); } +# endif /* not defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) */ #endif /* DEBUG_MEM */ @@ -289,16 +290,16 @@ checkup_mem(void) * 'e' never gets longer than maxlen characters. */ static const char * -expand_error(const char *f, char *e, int maxlen) +expand_error(const char *f, char *e, size_t maxlen) { const char *p; char *q; int error = errno; int len = 0; - for (p = f, q = e; (*q = *p) && len < maxlen; len++, q++, p++) { + for (p = f, q = e; (*q = *p) && (size_t) len < maxlen; len++, q++, p++) { if (p[0] == '%' && p[1] == 'm') { - strcpy(q, strerror(error)); + xstrlcpy(q, strerror(error), maxlen); len += strlen(q) - 1; q += strlen(q) - 1; p++; @@ -318,27 +319,27 @@ show_time_host_and_name(int lvl) static time_t last_t = 0; static char *last_ctime = 0; time_t t; -#ifdef HAVE_CLOCK_GETTIME +#if defined(HAVE_CLOCK_GETTIME) && defined(DEBUG) struct timespec ts; -#endif /* HAVE_CLOCK_GETTIME */ - char nsecs[11] = ""; /* '.' + 9 digits + '\0' */ +#endif /* defined(HAVE_CLOCK_GETTIME) && defined(DEBUG) */ + char nsecs[11]; /* '.' + 9 digits + '\0' */ char *sev; -#ifdef HAVE_CLOCK_GETTIME + nsecs[0] = '\0'; + +#if defined(HAVE_CLOCK_GETTIME) && defined(DEBUG) /* * Some systems (AIX 4.3) seem to implement clock_gettime() as stub * returning ENOSYS. */ if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { t = ts.tv_sec; -#ifdef DEBUG - amuDebug(D_HRTIME) - sprintf(nsecs, ".%09ld", ts.tv_nsec); -#endif /* DEBUG */ + if (amuDebug(D_HRTIME)) + xsnprintf(nsecs, sizeof(nsecs), ".%09ld", ts.tv_nsec); } else -#endif /* HAVE_CLOCK_GETTIME */ - t = clocktime(); +#endif /* defined(HAVE_CLOCK_GETTIME) && defined(DEBUG) */ + t = clocktime(NULL); if (t != last_t) { last_ctime = ctime(&t); @@ -435,29 +436,20 @@ real_plog(int lvl, const char *fmt, va_list vargs) return; #ifdef DEBUG_MEM +# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) checkup_mem(); +# endif /* not defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY) */ #endif /* DEBUG_MEM */ -#ifdef HAVE_VSNPRINTF - /* - * XXX: ptr is 1024 bytes long, but we may write to ptr[strlen(ptr) + 2] - * (to add an '\n', see code below) so we have to limit the string copy - * to 1023 (including the '\0'). - */ - vsnprintf(ptr, 1023, expand_error(fmt, efmt, 1024), vargs); - msg[1022] = '\0'; /* null terminate, to be sure */ -#else /* not HAVE_VSNPRINTF */ /* - * XXX: ptr is 1024 bytes long. It is possible to write into it - * more than 1024 bytes, if efmt is already large, and vargs expand - * as well. This is not as safe as using vsnprintf(). + * Note: xvsnprintf() may call plog() if a truncation happened, but the + * latter has some code to break out of an infinite loop. See comment in + * xsnprintf() below. */ - vsprintf(ptr, expand_error(fmt, efmt, 1023), vargs); - msg[1023] = '\0'; /* null terminate, to be sure */ -#endif /* not HAVE_VSNPRINTF */ + xvsnprintf(ptr, 1023, expand_error(fmt, efmt, 1024), vargs); ptr += strlen(ptr); - if (ptr[-1] == '\n') + if (*(ptr-1) == '\n') *--ptr = '\0'; #ifdef HAVE_SYSLOG @@ -505,7 +497,8 @@ real_plog(int lvl, const char *fmt, va_list vargs) switch (last_count) { case 0: /* never printed at all */ last_count = 1; - strncpy(last_msg, msg, 1024); + if (strlcpy(last_msg, msg, 1024) >= 1024) /* don't use xstrlcpy here (recursive!) */ + fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg); last_lvl = lvl; show_time_host_and_name(lvl); /* mimic syslog header */ fwrite(msg, ptr - msg, 1, logfp); @@ -517,7 +510,8 @@ real_plog(int lvl, const char *fmt, va_list vargs) last_count++; } else { /* last msg printed once, new one differs */ /* last_count remains at 1 */ - strncpy(last_msg, msg, 1024); + if (strlcpy(last_msg, msg, 1024) >= 1024) /* don't use xstrlcpy here (recursive!) */ + fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg); last_lvl = lvl; show_time_host_and_name(lvl); /* mimic syslog header */ fwrite(msg, ptr - msg, 1, logfp); @@ -531,7 +525,8 @@ real_plog(int lvl, const char *fmt, va_list vargs) * cycles like crazy. */ show_time_host_and_name(last_lvl); - sprintf(last_msg, "last message repeated %d times\n", last_count); + xsnprintf(last_msg, sizeof(last_msg), + "last message repeated %d times\n", last_count); fwrite(last_msg, strlen(last_msg), 1, logfp); fflush(logfp); last_count = 0; /* start from scratch */ @@ -542,9 +537,11 @@ real_plog(int lvl, const char *fmt, va_list vargs) last_count++; } else { /* last msg repeated+skipped, new one differs */ show_time_host_and_name(last_lvl); - sprintf(last_msg, "last message repeated %d times\n", last_count); + xsnprintf(last_msg, sizeof(last_msg), + "last message repeated %d times\n", last_count); fwrite(last_msg, strlen(last_msg), 1, logfp); - strncpy(last_msg, msg, 1024); + if (strlcpy(last_msg, msg, 1024) >= 1024) /* don't use xstrlcpy here (recursive!) */ + fprintf(stderr, "real_plog: string \"%s\" truncated to \"%s\"\n", last_msg, msg); last_count = 1; last_lvl = lvl; show_time_host_and_name(lvl); /* mimic syslog header */ @@ -667,6 +664,7 @@ switch_option(char *opt) return rc; } + #ifdef LOG_DAEMON /* * get syslog facility to use. @@ -771,7 +769,7 @@ get_syslog_facility(const char *logfile) * Change current logfile */ int -switch_to_logfile(char *logfile, int old_umask) +switch_to_logfile(char *logfile, int old_umask, int truncate_log) { FILE *new_logfp = stderr; @@ -789,9 +787,6 @@ switch_to_logfile(char *logfile, int old_umask) new_logfp = stderr; openlog(am_get_progname(), LOG_PID -# ifdef LOG_CONS - | LOG_CONS -# endif /* LOG_CONS */ # ifdef LOG_NOWAIT | LOG_NOWAIT # endif /* LOG_NOWAIT */ @@ -803,8 +798,10 @@ switch_to_logfile(char *logfile, int old_umask) plog(XLOG_WARNING, "syslog option not supported, logging unchanged"); #endif /* not HAVE_SYSLOG */ - } else { + } else { /* regular log file */ (void) umask(old_umask); + if (truncate_log) + truncate(logfile, 0); new_logfp = fopen(logfile, "a"); umask(0); } @@ -837,11 +834,14 @@ switch_to_logfile(char *logfile, int old_umask) void unregister_amq(void) { -#ifdef DEBUG - amuDebug(D_AMQ) -#endif /* DEBUG */ + if (!amuDebug(D_AMQ)) { /* find which instance of amd to unregister */ - pmap_unset(get_amd_program_number(), AMQ_VERSION); + u_long amd_prognum = get_amd_program_number(); + + if (pmap_unset(amd_prognum, AMQ_VERSION) != 1) + dlog("failed to de-register Amd program %lu, version %lu", + amd_prognum, AMQ_VERSION); + } } @@ -855,14 +855,21 @@ going_down(int rc) unregister_amq(); } } + +#ifdef MOUNT_TABLE_ON_FILE + /* + * Call unlock_mntlist to free any important resources such as an on-disk + * lock file (/etc/mtab~). + */ + unlock_mntlist(); +#endif /* MOUNT_TABLE_ON_FILE */ + if (foreground) { plog(XLOG_INFO, "Finishing with status %d", rc); } else { -#ifdef DEBUG dlog("background process exiting with status %d", rc); -#endif /* DEBUG */ } - + /* bye bye... */ exit(rc); } @@ -896,10 +903,7 @@ set_amd_program_number(int program) void amu_release_controlling_tty(void) { -#ifdef TIOCNOTTY int fd; -#endif /* TIOCNOTTY */ - int tempfd; /* * In daemon mode, leaving open file descriptors to terminals or pipes @@ -917,11 +921,15 @@ amu_release_controlling_tty(void) * * XXX We should also probably set the SIGPIPE handler to SIG_IGN. */ - tempfd = open("/dev/null", O_RDWR); - fflush(stdin); close(0); dup2(tempfd, 0); - fflush(stdout); close(1); dup2(tempfd, 1); - fflush(stderr); close(2); dup2(tempfd, 2); - close(tempfd); + fd = open("/dev/null", O_RDWR); + if (fd < 0) { + plog(XLOG_WARNING, "Could not open /dev/null for rw: %m"); + } else { + fflush(stdin); close(0); dup2(fd, 0); + fflush(stdout); close(1); dup2(fd, 1); + fflush(stderr); close(2); dup2(fd, 2); + close(fd); + } #ifdef HAVE_SETSID /* XXX: one day maybe use vhangup(2) */ @@ -951,3 +959,133 @@ amu_release_controlling_tty(void) plog(XLOG_ERROR, "unable to release controlling tty"); } + + +/* setup a single signal handler */ +void +setup_sighandler(int signum, void (*handler)(int)) +{ +#ifdef HAVE_SIGACTION + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = 0; /* unnecessary */ + sa.sa_handler = handler; + sigemptyset(&(sa.sa_mask)); /* probably unnecessary too */ + sigaddset(&(sa.sa_mask), signum); + sigaction(signum, &sa, NULL); +#else /* not HAVE_SIGACTION */ + (void) signal(signum, handler); +#endif /* not HAVE_SIGACTION */ +} + + +/* + * Return current time in seconds. If passed a non-null argyument, then + * fill it in with the current time in seconds and microseconds (useful + * for mtime updates). + */ +time_t +clocktime(nfstime *nt) +{ + static struct timeval now; /* keep last time, as default */ + + if (gettimeofday(&now, NULL) < 0) { + plog(XLOG_ERROR, "clocktime: gettimeofday: %m"); + /* hack: force time to have incremented by at least 1 second */ + now.tv_sec++; + } + /* copy seconds and microseconds. may demote a long to an int */ + if (nt) { + nt->nt_seconds = (u_int) now.tv_sec; + nt->nt_useconds = (u_int) now.tv_usec; + } + return (time_t) now.tv_sec; +} + + +/* + * Make all the directories in the path. + */ +int +mkdirs(char *path, int mode) +{ + /* + * take a copy in case path is in readonly store + */ + char *p2 = strdup(path); + char *sp = p2; + struct stat stb; + int error_so_far = 0; + + /* + * Skip through the string make the directories. + * Mostly ignore errors - the result is tested at the end. + * + * This assumes we are root so that we can do mkdir in a + * mode 555 directory... + */ + while ((sp = strchr(sp + 1, '/'))) { + *sp = '\0'; + if (mkdir(p2, mode) < 0) { + error_so_far = errno; + } else { + dlog("mkdir(%s)", p2); + } + *sp = '/'; + } + + if (mkdir(p2, mode) < 0) { + error_so_far = errno; + } else { + dlog("mkdir(%s)", p2); + } + + XFREE(p2); + + return stat(path, &stb) == 0 && + (stb.st_mode & S_IFMT) == S_IFDIR ? 0 : error_so_far; +} + + +/* + * Remove as many directories in the path as possible. + * Give up if the directory doesn't appear to have + * been created by Amd (not mode dr-x) or an rmdir + * fails for any reason. + */ +void +rmdirs(char *dir) +{ + char *xdp = strdup(dir); + char *dp; + + do { + struct stat stb; + /* + * Try to find out whether this was + * created by amd. Do this by checking + * for owner write permission. + */ + if (stat(xdp, &stb) == 0 && (stb.st_mode & 0200) == 0) { + if (rmdir(xdp) < 0) { + if (errno != ENOTEMPTY && + errno != EBUSY && + errno != EEXIST && + errno != EROFS && + errno != EINVAL) + plog(XLOG_ERROR, "rmdir(%s): %m", xdp); + break; + } else { + dlog("rmdir(%s)", xdp); + } + } else { + break; + } + + dp = strrchr(xdp, '/'); + if (dp) + *dp = '\0'; + } while (dp && dp > xdp); + + XFREE(xdp); +} |