just vlen. Bug discovered when started using xstrlcpy().
* ALL: convert from using strcat to the safer xstrlcat, and from
strcpy to safer xstrlcpy.
* hlfsd/hlfsd.h: remove old fatalerror() and ERRM macros.
* hlfsd/hlfsd.c (fatalerror): new function instead of macro.
Easier to use xstrlcat in this new function.
* amd/amd.h, include/am_utils.h, amd/amd.c: moved 'hostd' extern
from am_utils.h to amd.h, and define its size as a macro that
could be passed to xstrl*().
+2005-10-05 Erez Zadok <ezk@cs.sunysb.edu>
+
+ * amd/opts.c (expand_op): should check BUFSPACE for vlen+1, not
+ just vlen. Bug discovered when started using xstrlcpy().
+
+ * ALL: convert from using strcat to the safer xstrlcat, and from
+ strcpy to safer xstrlcpy.
+
2005-10-04 Erez Zadok <ezk@cs.sunysb.edu>
+ * hlfsd/hlfsd.h: remove old fatalerror() and ERRM macros.
+
+ * hlfsd/hlfsd.c (fatalerror): new function instead of macro.
+ Easier to use xstrlcat in this new function.
+
+ * amd/amd.h, include/am_utils.h, amd/amd.c: moved 'hostd' extern
+ from am_utils.h to amd.h, and define its size as a macro that
+ could be passed to xstrl*().
+
* ALL: convert from using sprintf to the safer xsnprintf.
* mk-amd-map/Makefile.am (LDADD): link with libamu to get
* pawd goes into an infinite loop on type:=auto
* consistent search for file system mnttab/mount names
* convert all sprintf to safer xsnprintf
+ * convert all strcat to safer xstrlcat
+ * convert all strcpy to safer xstrlcpy
Amd now understands a new log_option called "defaults" which is synonymous
with "fatal,error,user,warning,info" (and is also what logging happens by
void
-ops_showamfstypes(char *buf)
+ops_showamfstypes(char *buf, size_t l)
{
struct am_ops **ap;
- int l = 0;
+ int linesize = 0;
buf[0] = '\0';
for (ap = vops; *ap; ap++) {
- strcat(buf, (*ap)->fs_type);
+ xstrlcat(buf, (*ap)->fs_type, l);
if (ap[1])
- strcat(buf, ", ");
- l += strlen((*ap)->fs_type) + 2;
- if (l > 62) {
- l = 0;
- strcat(buf, "\n ");
+ xstrlcat(buf, ", ", l);
+ linesize += strlen((*ap)->fs_type) + 2;
+ if (linesize > 62) {
+ linesize = 0;
+ xstrlcat(buf, "\n ", l);
}
}
}
static void
-ops_show1(char *buf, int *lp, const char *name)
+ops_show1(char *buf, size_t l, int *linesizep, const char *name)
{
- strcat(buf, name);
- strcat(buf, ", ");
- *lp += strlen(name) + 2;
- if (*lp > 60) {
- strcat(buf, "\t\n");
- *lp = 0;
+ xstrlcat(buf, name, l);
+ xstrlcat(buf, ", ", l);
+ *linesizep += strlen(name) + 2;
+ if (*linesizep > 60) {
+ xstrlcat(buf, "\t\n", l);
+ *linesizep = 0;
}
}
void
-ops_showfstypes(char *buf)
+ops_showfstypes(char *buf, size_t l)
{
- int l = 0;
+ int linesize = 0;
buf[0] = '\0';
#ifdef MNTTAB_TYPE_AUTOFS
- ops_show1(buf, &l, MNTTAB_TYPE_AUTOFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_AUTOFS);
#endif /* MNTTAB_TYPE_AUTOFS */
#ifdef MNTTAB_TYPE_CACHEFS
- ops_show1(buf, &l, MNTTAB_TYPE_CACHEFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_CACHEFS);
#endif /* MNTTAB_TYPE_CACHEFS */
#ifdef MNTTAB_TYPE_CDFS
- ops_show1(buf, &l, MNTTAB_TYPE_CDFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_CDFS);
#endif /* MNTTAB_TYPE_CDFS */
#ifdef MNTTAB_TYPE_CFS
- ops_show1(buf, &l, MNTTAB_TYPE_CFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_CFS);
#endif /* MNTTAB_TYPE_CFS */
#ifdef MNTTAB_TYPE_LOFS
- ops_show1(buf, &l, MNTTAB_TYPE_LOFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_LOFS);
#endif /* MNTTAB_TYPE_LOFS */
#ifdef MNTTAB_TYPE_EFS
- ops_show1(buf, &l, MNTTAB_TYPE_EFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_EFS);
#endif /* MNTTAB_TYPE_EFS */
#ifdef MNTTAB_TYPE_MFS
- ops_show1(buf, &l, MNTTAB_TYPE_MFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_MFS);
#endif /* MNTTAB_TYPE_MFS */
#ifdef MNTTAB_TYPE_NFS
- ops_show1(buf, &l, MNTTAB_TYPE_NFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_NFS);
#endif /* MNTTAB_TYPE_NFS */
#ifdef MNTTAB_TYPE_NFS3
- ops_show1(buf, &l, "nfs3"); /* always hard-code as nfs3 */
+ ops_show1(buf, l, &linesize, "nfs3"); /* always hard-code as nfs3 */
#endif /* MNTTAB_TYPE_NFS3 */
#ifdef MNTTAB_TYPE_NULLFS
- ops_show1(buf, &l, MNTTAB_TYPE_NULLFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_NULLFS);
#endif /* MNTTAB_TYPE_NULLFS */
#ifdef MNTTAB_TYPE_PCFS
- ops_show1(buf, &l, MNTTAB_TYPE_PCFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_PCFS);
#endif /* MNTTAB_TYPE_PCFS */
#ifdef MNTTAB_TYPE_TFS
- ops_show1(buf, &l, MNTTAB_TYPE_TFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_TFS);
#endif /* MNTTAB_TYPE_TFS */
#ifdef MNTTAB_TYPE_TMPFS
- ops_show1(buf, &l, MNTTAB_TYPE_TMPFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_TMPFS);
#endif /* MNTTAB_TYPE_TMPFS */
#ifdef MNTTAB_TYPE_UFS
- ops_show1(buf, &l, MNTTAB_TYPE_UFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_UFS);
#endif /* MNTTAB_TYPE_UFS */
#ifdef MNTTAB_TYPE_UMAPFS
- ops_show1(buf, &l, MNTTAB_TYPE_UMAPFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_UMAPFS);
#endif /* MNTTAB_TYPE_UMAPFS */
#ifdef MNTTAB_TYPE_UNIONFS
- ops_show1(buf, &l, MNTTAB_TYPE_UNIONFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_UNIONFS);
#endif /* MNTTAB_TYPE_UNIONFS */
#ifdef MNTTAB_TYPE_XFS
- ops_show1(buf, &l, MNTTAB_TYPE_XFS);
+ ops_show1(buf, l, &linesize, MNTTAB_TYPE_XFS);
#endif /* MNTTAB_TYPE_XFS */
/* terminate with a period, newline, and NULL */
buf[strlen(buf) - 4] = '\0';
else
buf[strlen(buf) - 2] = '\0';
- strcat(buf, ".\n");
+ xstrlcat(buf, ".\n", l);
}
/* check if string starts with 'no' and chop it */
if (NSTREQ(opt, "no", 2)) {
- strcpy(buf, &opt[2]);
+ xstrlcpy(buf, &opt[2], sizeof(buf));
} else {
/* finally return a string prepended with 'no' */
- strcpy(buf, "no");
- strcat(buf, opt);
+ xstrlcpy(buf, "no", sizeof(buf));
+ xstrlcat(buf, opt, sizeof(buf));
}
return buf;
}
char *eq; /* pointer to whatever follows '=' within temp */
char oneopt[80]; /* one option w/o value if any */
char *revoneopt; /* reverse of oneopt */
- int len = strlen(opts1) + strlen(opts2) + 2; /* space for "," and NULL */
+ size_t len = strlen(opts1) + strlen(opts2) + 2; /* space for "," and NULL */
char *s1 = strdup(opts1); /* copy of opts1 to munge */
/* initialization */
continue;
/* add option to returned string */
if (newstr && newstr[0]) {
- strcat(newstr, ",");
- strcat(newstr, tmpstr);
+ xstrlcat(newstr, ",", len);
+ xstrlcat(newstr, tmpstr, len);
} else {
- strcpy(newstr, tmpstr);
+ xstrlcpy(newstr, tmpstr, len);
}
}
/* finally, append opts2 itself */
if (newstr && newstr[0]) {
- strcat(newstr, ",");
- strcat(newstr, opts2);
+ xstrlcat(newstr, ",", len);
+ xstrlcat(newstr, opts2, len);
} else {
- strcpy(newstr, opts2);
+ xstrlcpy(newstr, opts2, len);
}
XFREE(s1);
char pid_fsname[SIZEOF_PID_FSNAME]; /* "kiska.southseas.nz:(pid%d)" */
char *hostdomain = "unknown.domain";
-char hostd[2 * MAXHOSTNAMELEN + 1]; /* Host+domain */
+#define SIZEOF_HOSTD (2 * MAXHOSTNAMELEN + 1) /* Host+domain */
+char hostd[SIZEOF_HOSTD]; /* Host+domain */
char *endian = ARCH_ENDIAN; /* Big or Little endian */
char *cpu = HOST_CPU; /* CPU type */
char *PrimNetName; /* name of primary network */
*domdot++ = '\0';
hostdomain = domdot;
}
- strcpy(hostd, hostname);
+ xstrlcpy(hostd, hostname, SIZEOF_HOSTD);
am_set_hostname(hostname);
/*
extern int mapc_keyiter(mnt_map *, key_fun, opaque_t);
extern void mapc_reload(void);
extern int mapc_search(mnt_map *, char *, char **);
-extern void mapc_showtypes(char *buf);
+extern void mapc_showtypes(char *buf, size_t l);
extern int mapc_type_exists(const char *type);
extern void mk_fattr(nfsfattr *, nfsftype);
extern int mount_auto_node(char *, opaque_t);
extern void new_ttl(am_node *);
extern void nfs_quick_reply(am_node *mp, int error);
extern void normalize_slash(char *);
-extern void ops_showamfstypes(char *buf);
-extern void ops_showfstypes(char *outbuf);
+extern void ops_showamfstypes(char *buf, size_t l);
+extern void ops_showfstypes(char *outbuf, size_t l);
extern void rem_que(qelem *);
extern void reschedule_timeout_mp(void);
extern void restart(void);
extern void wakeup_task(int, int, wchan_t);
#define SIZEOF_PID_FSNAME (16 + MAXHOSTNAMELEN)
extern char pid_fsname[SIZEOF_PID_FSNAME]; /* "kiska.southseas.nz:(pid%d)" */
+#define SIZEOF_HOSTD (2 * MAXHOSTNAMELEN + 1)
+extern char hostd[SIZEOF_HOSTD]; /* Host+domain */
/*
* Global variables.
for (j = 0; j < n_export; j++) {
ex = ep[j];
if (ex) {
- strcpy(rfs_dir, ex->ex_dir);
+ /*
+ * Note: the sizeof space left in rfs_dir is what's left in fs_name
+ * after strchr() above returned a pointer _inside_ fs_name. The
+ * calculation below also takes into account that rfs_dir was
+ * incremented by the ++ above.
+ */
+ xstrlcpy(rfs_dir, ex->ex_dir, sizeof(fs_name) - (rfs_dir - fs_name));
make_mntpt(mntpt, sizeof(mntpt), ex, mf->mf_mount);
if (do_mount(&fp[j], mntpt, fs_name, mf) == 0)
ok = TRUE;
****************************************************************************/
static void
-set_auto_attrcache_timeout(char *preopts, size_t l, char *opts)
+set_auto_attrcache_timeout(char *preopts, char *opts, size_t l)
{
#ifdef MNTTAB_OPT_NOAC
*/
if (gopt.auto_attrcache == 0) {
xsnprintf(preopts, l, ",%s", MNTTAB_OPT_NOAC);
- strcat(opts, preopts);
+ xstrlcat(opts, preopts, l);
}
#endif /* MNTTAB_OPT_NOAC */
*/
#ifdef MNTTAB_OPT_ACTIMEO
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTIMEO, gopt.auto_attrcache);
- strcat(opts, preopts);
+ xstrlcat(opts, preopts, l);
#else /* MNTTAB_OPT_ACTIMEO */
# ifdef MNTTAB_OPT_ACDIRMIN
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTDIRMIN, gopt.auto_attrcache);
- strcat(opts, preopts);
+ xstrlcat(opts, preopts, l);
# endif /* MNTTAB_OPT_ACDIRMIN */
# ifdef MNTTAB_OPT_ACDIRMAX
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTDIRMAX, gopt.auto_attrcache);
- strcat(opts, preopts);
+ xstrlcat(opts, preopts, l);
# endif /* MNTTAB_OPT_ACDIRMAX */
# ifdef MNTTAB_OPT_ACREGMIN
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTREGMIN, gopt.auto_attrcache);
- strcat(opts, preopts);
+ xstrlcat(opts, preopts, l);
# endif /* MNTTAB_OPT_ACREGMIN */
# ifdef MNTTAB_OPT_ACREGMAX
xsnprintf(preopts, l, ",%s=%d", MNTTAB_OPT_ACTREGMAX, gopt.auto_attrcache);
- strcat(opts, preopts);
+ xstrlcat(opts, preopts, l);
# endif /* MNTTAB_OPT_ACREGMAX */
#endif /* MNTTAB_OPT_ACTIMEO */
}
amfs_toplvl_mount(am_node *mp, mntfs *mf)
{
struct stat stb;
- char opts[256], preopts[256];
+#define SIZEOF_OPTS 256
+ char opts[SIZEOF_OPTS], preopts[SIZEOF_OPTS];
int error;
/*
{
preopts[0] = '\0';
#ifdef MNTTAB_OPT_INTR
- strcat(preopts, MNTTAB_OPT_INTR);
- strcat(preopts, ",");
+ xstrlcat(preopts, MNTTAB_OPT_INTR, SIZEOF_OPTS);
+ xstrlcat(preopts, ",", SIZEOF_OPTS);
#endif /* MNTTAB_OPT_INTR */
#ifdef MNTTAB_OPT_IGNORE
- strcat(preopts, MNTTAB_OPT_IGNORE);
- strcat(preopts, ",");
+ xstrlcat(preopts, MNTTAB_OPT_IGNORE, SIZEOF_OPTS);
+ xstrlcat(preopts, ",", SIZEOF_OPTS);
#endif /* MNTTAB_OPT_IGNORE */
#ifdef WANT_TIMEO_AND_RETRANS_ON_TOPLVL
- xsnprintf(opts, sizeof(opts), "%s%s,%s=%d,%s=%d,%s=%d,%s,map=%s",
+ xsnprintf(opts, SIZEOF_OPTS, "%s%s,%s=%d,%s=%d,%s=%d,%s,map=%s",
#else /* WANT_TIMEO_AND_RETRANS_ON_TOPLVL */
- xsnprintf(opts, sizeof(opts), "%s%s,%s=%d,%s,map=%s",
+ xsnprintf(opts, SIZEOF_OPTS, "%s%s,%s=%d,%s,map=%s",
#endif /* WANT_TIMEO_AND_RETRANS_ON_TOPLVL */
preopts,
MNTTAB_OPT_RW,
mf->mf_ops->fs_type, mf->mf_info);
#ifdef MNTTAB_OPT_NOAC
if (gopt.auto_attrcache == 0) {
- strcat(opts, ",");
- strcat(opts, MNTTAB_OPT_NOAC);
+ xstrlcat(opts, ",", SIZEOF_OPTS);
+ xstrlcat(opts, MNTTAB_OPT_NOAC, SIZEOF_OPTS);
} else
#endif /* MNTTAB_OPT_NOAC */
- set_auto_attrcache_timeout(preopts, sizeof(preopts), opts);
+ set_auto_attrcache_timeout(preopts, opts, SIZEOF_OPTS);
}
/* now do the mount */
char *
strealloc(char *p, char *s)
{
- int len = strlen(s) + 1;
+ size_t len = strlen(s) + 1;
p = (char *) xrealloc((voidp) p, len);
- strcpy(p, s);
+ xstrlcpy(p, s, len);
#ifdef DEBUG_MEM
# if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_VERIFY)
malloc_verify();
* Most kernels have a name length restriction (64 bytes)...
*/
if (strlen(fs_hostname) >= MAXHOSTNAMELEN)
- strcpy(fs_hostname + MAXHOSTNAMELEN - 3, "..");
+ xstrlcpy(fs_hostname + MAXHOSTNAMELEN - 3, "..",
+ sizeof(fs_hostname) - MAXHOSTNAMELEN + 3);
#ifdef HOSTNAMESZ
/*
* ... and some of these restrictions are 32 bytes (HOSTNAMESZ)
* add the proper header file to the conf/nfs_prot/nfs_prot_*.h file.
*/
if (strlen(fs_hostname) >= HOSTNAMESZ)
- strcpy(fs_hostname + HOSTNAMESZ - 3, "..");
+ xstrlcpy(fs_hostname + HOSTNAMESZ - 3, "..",
+ sizeof(fs_hostname) - HOSTNAMESZ + 3));
#endif /* HOSTNAMESZ */
/*
char tmpbuf[1024];
char *wire_buf;
int wire_buf_len = 0;
- size_t len; /* max allocated length (to avoid buf overflow) */
+ size_t len; /* max allocated length (to avoid buf overflow) */
/*
* First get dynamic string listing all known networks.
xstrlcat(vers, tmpbuf, len);
xstrlcat(vers, "Map support for: ", len);
- mapc_showtypes(tmpbuf);
+ mapc_showtypes(tmpbuf, sizeof(tmpbuf));
xstrlcat(vers, tmpbuf, len);
xstrlcat(vers, ".\nAMFS: ", len);
- ops_showamfstypes(tmpbuf);
+ ops_showamfstypes(tmpbuf, sizeof(tmpbuf));
xstrlcat(vers, tmpbuf, len);
xstrlcat(vers, ", inherit.\nFS: ", len); /* hack: "show" that we support type:=inherit */
- ops_showfstypes(tmpbuf);
+ ops_showfstypes(tmpbuf, sizeof(tmpbuf));
xstrlcat(vers, tmpbuf, len);
/* append list of networks if available */
hostdomain = gopt.sub_domain;
if (*hostdomain == '.')
hostdomain++;
- strcat(hostd, ".");
- strcat(hostd, hostdomain);
+ xstrlcat(hostd, ".", SIZEOF_HOSTD);
+ xstrlcat(hostd, hostdomain, SIZEOF_HOSTD);
#ifdef MOUNT_TABLE_ON_FILE
if (amuDebug(D_MTAB))
#ifdef DBM_SUFFIX
char dbfilename[256];
- strcpy(dbfilename, map);
- strcat(dbfilename, DBM_SUFFIX);
+ xstrlcpy(dbfilename, map, sizeof(dbfilename));
+ xstrlcat(dbfilename, DBM_SUFFIX, sizeof(dbfilename));
error = stat(dbfilename, &stb);
#else /* not DBM_SUFFIX */
error = fstat(dbm_pagfno(db), &stb);
#ifdef DBM_SUFFIX
char dbfilename[256];
- strcpy(dbfilename, map);
- strcat(dbfilename, DBM_SUFFIX);
+ xstrlcpy(dbfilename, map, sizeof(dbfilename));
+ xstrlcat(dbfilename, DBM_SUFFIX, sizeof(dbfilename));
error = stat(dbfilename, &stb);
#else /* not DBM_SUFFIX */
error = fstat(dbm_pagfno(db), &stb);
do {
q = strrchr(p, '/');
if (q) {
- strcat(rhost, q + 1);
- strcat(rhost, ".");
+ xstrlcat(rhost, q + 1, sizeof(rhost));
+ xstrlcat(rhost, ".", sizeof(rhost));
*q = '\0';
} else {
- strcat(rhost, p);
+ xstrlcat(rhost, p, sizeof(rhost));
}
} while (q);
void
-mapc_showtypes(char *buf)
+mapc_showtypes(char *buf, size_t l)
{
map_type *mt=NULL, *lastmt;
- int l = 0, i;
+ int linesize = 0, i;
i = sizeof(maptypes) / sizeof(maptypes[0]);
lastmt = maptypes + i;
buf[0] = '\0';
for (mt = maptypes; mt < lastmt; mt++) {
- strcat(buf, mt->name);
+ xstrlcat(buf, mt->name, l);
if (mt == (lastmt-1))
- break; /* if last one, don't do strcat's that follow */
- l += strlen(mt->name);
+ break; /* if last one, don't do xstrlcat's that follows */
+ linesize += strlen(mt->name);
if (--i > 0) {
- strcat(buf, ", ");
- l += 2;
+ xstrlcat(buf, ", ", l);
+ linesize += 2;
}
- if (l > 54) {
- l = 0;
- strcat(buf, "\n\t\t ");
+ if (linesize > 54) {
+ linesize = 0;
+ xstrlcat(buf, "\n\t\t ", l);
}
}
}
* For example:
* "src/gnu/gcc" -> "src / gnu / *" -> "src / *"
*/
- strcpy(wildname, key);
+ xstrlcpy(wildname, key, sizeof(wildname));
while (error && (subp = strrchr(wildname, '/'))) {
- strcpy(subp, "/*");
+ /*
+ * sizeof space left in subp is sizeof wildname minus what's left
+ * after the strchr above returned a pointer inside wildname into
+ * subp.
+ */
+ xstrlcpy(subp, "/*", sizeof(wildname) - (subp - wildname));
dlog("mapc recurses on %s", wildname);
error = mapc_meta_search(m, wildname, pval, MREC_PART);
if (error)
cfm->cfm_flags & CFM_MOUNT_TYPE_AUTOFS ? "autofs" : "nfs",
get_full_path(map, cfm->cfm_search_path, cfm->cfm_type));
if (opts && opts[0] != '\0') {
- strcat(str, ";");
- strcat(str, opts);
+ xstrlcat(str, ";", sizeof(str));
+ xstrlcat(str, opts, sizeof(str));
}
if (cfm->cfm_flags & CFM_BROWSABLE_DIRS_FULL)
- strcat(str, ";opts:=rw,fullybrowsable");
+ xstrlcat(str, ";opts:=rw,fullybrowsable", sizeof(str));
if (cfm->cfm_flags & CFM_BROWSABLE_DIRS)
- strcat(str, ";opts:=rw,browsable");
+ xstrlcat(str, ";opts:=rw,browsable", sizeof(str));
if (cfm->cfm_type) {
- strcat(str, ";maptype:=");
- strcat(str, cfm->cfm_type);
+ xstrlcat(str, ";maptype:=", sizeof(str));
+ xstrlcat(str, cfm->cfm_type, sizeof(str));
}
} else {
- strcpy(str, opts);
+ xstrlcpy(str, opts, sizeof(str));
}
} else {
if (map)
"cache:=mapdefault;type:=toplvl;fs:=\"%s\";%s",
map, opts ? opts : "");
else
- strcpy(str, opts);
+ xstrlcpy(str, opts, sizeof(str));
}
mapc_repl_kv(root_map, strdup((char *)dir), strdup(str));
}
return map;
/* now break path into components, and search in each */
- strcpy(component, path);
+ xstrlcpy(component, path, sizeof(component));
str = strtok(component, ":");
do {
- strcpy(full_path, str);
+ xstrlcpy(full_path, str, sizeof(full_path));
len = strlen(full_path);
if (full_path[len - 1] != '/') /* add trailing "/" if needed */
- strcat(full_path, "/");
- strcat(full_path, map);
+ xstrlcat(full_path, "/", sizeof(full_path));
+ xstrlcat(full_path, map, sizeof(full_path));
if (access(full_path, R_OK) == 0)
return full_path;
str = strtok(NULL, ":");
am_LOOKUP3args args3;
#endif /* HAVE_FS_NFS3 */
char *wnfs_path;
+ size_t l;
if (!nfs_auth) {
error = make_nfs_auth();
/*
* Use native path like the rest of amd (cf. RFC 2054, 6.1).
*/
- wnfs_path = (char *) xmalloc(strlen(fp->fh_path) + 2);
+ l = strlen(fp->fh_path) + 2;
+ wnfs_path = (char *) xmalloc(l);
wnfs_path[0] = 0x80;
- strcpy(wnfs_path + 1, fp->fh_path);
+ xstrlcpy(wnfs_path + 1, fp->fh_path, l - 1);
/* find the right program and lookup procedure */
#ifdef HAVE_FS_NFS3
#ifdef MAXHOSTNAMELEN
/* most kernels have a name length restriction */
if (strlen(host) >= MAXHOSTNAMELEN)
- strcpy(host + MAXHOSTNAMELEN - 3, "..");
+ xstrlcpy(host + MAXHOSTNAMELEN - 3, "..",
+ sizeof(host) - MAXHOSTNAMELEN + 3);
#endif /* MAXHOSTNAMELEN */
/*
break;
}
- if (BUFSPACE(ep, vlen)) {
- strcpy(ep, vptr);
+ if (BUFSPACE(ep, vlen+1)) {
+ xstrlcpy(ep, vptr, vlen+1);
ep += vlen;
} else {
plog(XLOG_ERROR, EXPAND_ERROR, opt);
int vlen = strlen(env);
if (BUFSPACE(ep, vlen)) {
- strcpy(ep, env);
+ xstrlcpy(ep, env, vlen);
ep += vlen;
} else {
plog(XLOG_ERROR, EXPAND_ERROR, opt);
* Finish off the expansion
*/
if (BUFSPACE(ep, strlen(cp))) {
- strcpy(ep, cp);
+ xstrlcpy(ep, cp, strlen(cp));
/* ep += strlen(ep); */
} else {
plog(XLOG_ERROR, EXPAND_ERROR, opt);
* Display a pwd data
*/
static void
-show_pwd(amq_mount_tree *mt, char *path, int *flag)
+show_pwd(amq_mount_tree *mt, char *path, size_t l, int *flag)
{
int len;
len = strlen(mt->mt_mountpoint);
if (NSTREQ(path, mt->mt_mountpoint, len) &&
!STREQ(mt->mt_directory, mt->mt_mountpoint)) {
- char buf[MAXPATHLEN+1];
- strcpy(buf, mt->mt_directory);
- strcat(buf, &path[len]);
- strcpy(path, buf);
+ char buf[MAXPATHLEN+1]; /* must be same size as 'path' */
+ xstrlcpy(buf, mt->mt_directory, sizeof(buf));
+ xstrlcat(buf, &path[len], sizeof(buf));
+ xstrlcpy(path, buf, l);
*flag = 1;
}
- show_pwd(mt->mt_next, path, flag);
+ show_pwd(mt->mt_next, path, l, flag);
mt = mt->mt_child;
}
}
mt = mlp->amq_mount_tree_list_val[i];
while (1) {
flag = 0;
- show_pwd(mt, path, &flag);
+ show_pwd(mt, path, sizeof(path), &flag);
if (!flag) {
printf("%s\n", path);
break;
if (len != 0 && NSTREQ(mt->mt_mountpoint, dir, len) &&
((dir[len] == '\0') || (dir[len] == '/'))) {
char tmp_buf[MAXPATHLEN];
- strcpy(tmp_buf, mt->mt_directory);
- strcat(tmp_buf, &dir[len]);
- strcpy(newdir, tmp_buf);
+ xstrlcpy(tmp_buf, mt->mt_directory, sizeof(tmp_buf));
+ xstrlcat(tmp_buf, &dir[len], sizeof(tmp_buf));
+ xstrlcpy(newdir, tmp_buf, sizeof(newdir));
return 1;
}
}
#ifdef DEBUG
fprintf(stderr, "A match, munging....\n");
#endif /* DEBUG */
- strcpy(transform, "/home/");
- strcat(transform, username);
- if (*ch) strcat(transform, ch);
+ xstrlcpy(transform, "/home/", sizeof(transform));
+ xstrlcat(transform, username, sizeof(transform));
+ if (*ch)
+ xstrlcat(transform, ch, sizeof(transform));
#ifdef DEBUG
fprintf(stderr, "Munged to <%s>\n", transform);
#endif /* DEBUG */
if (clnt == 0)
return dir;
- strcpy(transform,dir);
+ xstrlcpy(transform, dir, sizeof(transform));
while ( (mlp = amqproc_export_1((voidp)0, clnt)) &&
find_mlp(mlp,transform) ) {
- strcpy(transform,newdir);
+ xstrlcpy(transform, newdir, sizeof(transform));
}
return transform;
}
/* getawd() is a substitute for getwd() which transforms the path */
static char *
-getawd(char *path)
+getawd(char *path, size_t l)
{
#ifdef HAVE_GETCWD
char *wd = getcwd(path, MAXPATHLEN);
if (wd == NULL) {
return NULL;
}
- strcpy(path, transform_dir(wd));
+ xstrlcpy(path, transform_dir(wd), l);
return path;
}
char tmp_buf[MAXPATHLEN], *wd;
if (argc == 1) {
- wd = getawd(tmp_buf);
+ wd = getawd(tmp_buf, sizeof(tmp_buf));
if (wd == NULL) {
fprintf(stderr, "pawd: %s\n", tmp_buf);
exit(1);
* SET MOUNT ARGS
*/
if (uname(&utsname) < 0) {
- strcpy(buf, "localhost.autofs");
+ xstrlcpy(buf, "localhost.autofs", sizeof(buf));
} else {
- strcpy(buf, utsname.nodename);
- strcat(buf, ".autofs");
+ xstrlcpy(buf, utsname.nodename, sizeof(buf));
+ xstrlcat(buf, ".autofs", sizeof(buf));
}
#ifdef HAVE_AUTOFS_ARGS_T_ADDR
fh->addr.buf = strdup(buf);
#define NEED_AUTOFS_SPACE_HACK
-static inline char *autofs_strdup_space_hack(char *s)
+static inline char *
+autofs_strdup_space_hack(char *s)
{
/*
* autofs hack: append a space to the directory name
* Returns malloc'ed space which needs to be freed by the caller.
*/
extern void *malloc(size_t);
- char *tmp = malloc(strlen(s) + 2);
- strcpy(tmp, s);
- strcat(tmp, " ");
+ size_t l = strlen(s) + 2;
+ char *tmp = malloc(l);
+ xstrlcpy(tmp, s, l);
+ xstrlcat(tmp, " ", l);
return tmp;
}
* SET MOUNT ARGS
*/
if (uname(&utsname) < 0) {
- strcpy(buf, "localhost.autofs");
+ xstrlcpy(buf, "localhost.autofs", sizeof(buf));
} else {
- strcpy(buf, utsname.nodename);
- strcat(buf, ".autofs");
+ xstrlcpy(buf, utsname.nodename, sizeof(buf));
+ xstrlcat(buf, ".autofs", sizeof(buf));
}
#ifdef HAVE_AUTOFS_ARGS_T_ADDR
fh->addr.buf = strdup(buf);
const struct opt_map *std_opts;
const struct fs_opts *dev_opts;
char *opt, *topts, *xoptstr;
+ size_t l;
if (optstr == NULL)
return NULL;
xoptstr = strdup(optstr); /* because strtok is destructive below */
*noauto = 0;
- *xopts = (char *) xmalloc (strlen(optstr) + 2);
- topts = (char *) xmalloc (strlen(optstr) + 2);
+ l = strlen(optstr) + 2;
+ *xopts = (char *) xmalloc(l);
+ topts = (char *) xmalloc(l);
*topts = '\0';
**xopts = '\0';
!NSTREQ(std_opts->opt, opt, strlen(std_opts->opt)))
++std_opts;
if (!(*noauto = STREQ(opt, MNTTAB_OPT_NOAUTO)) || std_opts->opt) {
- strcat(topts, opt);
- strcat(topts, ",");
+ xstrlcat(topts, opt, l);
+ xstrlcat(topts, ",", l);
if (std_opts->inv)
*flags &= ~std_opts->mask;
else
++dev_opts;
}
if (dev_opts->opt && *xopts) {
- strcat(*xopts, opt);
- strcat(*xopts, ",");
+ xstrlcat(*xopts, opt, l);
+ xstrlcat(*xopts, ",", l);
}
}
/*
char *cp;
char mcp[128];
- strcpy(mcp, mnttabname);
+ xstrlcpy(mcp, mnttabname, sizeof(mcp));
cp = strrchr(mcp, '/');
if (cp) {
memmove(tmpname, mcp, cp - mcp);
tmpname[0] = '.';
tmpname[1] = '\0';
}
- strcat(tmpname, "/mtabXXXXXX");
+ xstrlcat(tmpname, "/mtabXXXXXX", sizeof(tmpname));
retries = 0;
enfile1:
#ifdef HAVE_MKSTEMP
* Concoct a temporary name in the same directory as the target mount
* table so that rename() will work.
*/
- strcpy(mcp, mnttabname);
+ xstrlcpy(mcp, mnttabname, sizeof(mcp));
cp = strrchr(mcp, '/');
if (cp) {
memmove(tmpname, mcp, cp - mcp);
tmpname[0] = '.';
tmpname[1] = '\0';
}
- strcat(tmpname, "/mtabXXXXXX");
+ xstrlcat(tmpname, "/mtabXXXXXX", sizeof(tmpname));
retries = 0;
enfile1:
#ifdef HAVE_MKSTEMP
FILE *mfp;
int error = 0;
/*
- * Concoct a temporary name in the same
- * directory as the target mount table
- * so that rename() will work.
+ * Concoct a temporary name in the same directory as the target mount
+ * table so that rename() will work.
*/
char tmpname[64];
int retries;
int tmpfd;
char *cp;
char *mcp = mnttabname;
+
cp = strrchr(mcp, '/');
if (cp) {
memmove(tmpname, mcp, cp - mcp);
tmpname[0] = '.';
tmpname[1] = '\0';
}
- strcat(tmpname, "/mtabXXXXXX");
+ xstrlcat(tmpname, "/mtabXXXXXX", sizeof(tmpname));
retries = 0;
enfile1:
#ifdef HAVE_MKSTEMP
#endif /* HAVE_FS_NFS3 */
at = strchr(mp->f_mntfromname, '@');
if (at != '\0') {
- strcpy(mntfrombuf, (at + 1));
- strcat(mntfrombuf, ":");
+ xstrlcpy(mntfrombuf, (at + 1), sizeof(mntfrombuf));
+ xstrlcat(mntfrombuf, ":", sizeof(mntfrombuf));
strncat(mntfrombuf, mp->f_mntfromname, (at - mp->f_mntfromname));
mntfromptr = mntfrombuf;
}
static char *
compute_hostpath(char *hn)
{
- char *p = strdup(hn);
+ char *p = xmalloc(MAXPATHLEN);
char *d;
char path[MAXPATHLEN];
+ xstrlcpy(p, hn, MAXPATHLEN);
domain_strip(p, hostname);
path[0] = '\0';
d = strrchr(p, '.');
if (d) {
*d = '\0';
- strcat(path, d + 1);
- strcat(path, "/");
+ xstrlcat(path, d + 1, sizeof(path));
+ xstrlcat(path, "/", sizeof(path));
} else {
- strcat(path, p);
+ xstrlcat(path, p, sizeof(path));
}
} while (d);
fsi_log("hostpath of '%s' is '%s'", hn, path);
- strcpy(p, path);
+ xstrlcpy(p, path, MAXPATHLEN);
return p;
}
char sublink[1024];
sublink[0] = '\0';
if (exp_namelen < namelen) {
- strcat(sublink, mp->m_name + exp_namelen + 1);
+ xstrlcat(sublink, mp->m_name + exp_namelen + 1, sizeof(sublink));
if (mvolnlen < volnlen)
- strcat(sublink, "/");
+ xstrlcat(sublink, "/", sizeof(sublink));
}
if (mvolnlen < volnlen)
- strcat(sublink, ap->a_volname + mvolnlen + 1);
+ xstrlcat(sublink, ap->a_volname + mvolnlen + 1, sizeof(sublink));
fprintf(af, ";sublink:=%s", sublink);
}
}
+void
+fatalerror(char *str)
+{
+#define ERRM ": %m"
+ size_t l = strlen(str) + sizeof(ERRM) - 1;
+ char *tmp = strnsave(str, l);
+ xstrlcat(tmp, ERRM, l);
+ fatal(tmp);
+}
+
+
int
main(int argc, char *argv[])
{
if (mntopts) {
mnt.mnt_opts = mntopts;
} else {
- strcpy(preopts, default_mntopts);
+ xstrlcpy(preopts, default_mntopts, sizeof(preopts));
/*
* Turn off all kinds of attribute and symlink caches as
* much as possible. Also make sure that mount does not
* show up to df.
*/
#ifdef MNTTAB_OPT_INTR
- strcat(preopts, ",");
- strcat(preopts, MNTTAB_OPT_INTR);
+ xstrlcat(preopts, ",", sizeof(preopts));
+ xstrlcat(preopts, MNTTAB_OPT_INTR, sizeof(preopts));
#endif /* MNTTAB_OPT_INTR */
#ifdef MNTTAB_OPT_IGNORE
- strcat(preopts, ",");
- strcat(preopts, MNTTAB_OPT_IGNORE);
+ xstrlcat(preopts, ",", sizeof(preopts));
+ xstrlcat(preopts, MNTTAB_OPT_IGNORE, sizeof(preopts));
#endif /* MNTTAB_OPT_IGNORE */
#ifdef MNT2_GEN_OPT_CACHE
- strcat(preopts, ",nocache");
+ xstrlcat(preopts, ",nocache", sizeof(preopts));
#endif /* MNT2_GEN_OPT_CACHE */
#ifdef MNT2_NFS_OPT_SYMTTL
- strcat(preopts, ",symttl=0");
+ xstrlcat(preopts, ",symttl=0", sizeof(preopts));
#endif /* MNT2_NFS_OPT_SYMTTL */
mnt.mnt_opts = preopts;
}
/* Most kernels have a name length restriction. */
if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN)
- strcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..");
+ xstrlcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..",
+ sizeof(progpid_fs) - MAXHOSTNAMELEN + 3);
genflags = compute_mount_flags(&mnt);
if (!STREQ(&mess[messlen + 1 - sizeof(ERRM)], ERRM))
fprintf(stderr, "%s: %s\n", am_get_progname(), mess);
else {
- strcpy(lessmess, mess);
+ xstrlcpy(lessmess, mess, sizeof(lessmess));
lessmess[messlen - 4] = '\0';
fprintf(stderr, "%s: %s: %s\n",
# define DEFAULT_LOGFILE 0
#endif /* not HAVE)_SYSLOG */
-#define ERRM ": %m"
-#define fatalerror(str) \
- (fatal (strcat (strnsave ((str), strlen ((str)) + sizeof (ERRM) - 1), ERRM)))
/*
* TYPEDEFS:
plog(XLOG_ERROR, "no user name on line %d of %s", passwd_line, passwdfile);
goto readent;
}
- strcpy(pw_name, cp); /* will show up in passwd_ent.pw_name */
+ /* pw_name will show up in passwd_ent.pw_name */
+ xstrlcpy(pw_name, cp, sizeof(pw_name));
/* skip passwd */
strtok(NULL, ":");
plog(XLOG_ERROR, "no home dir on line %d of %s", passwd_line, passwdfile);
goto readent;
}
- strcpy(pw_dir, cp); /* will show up in passwd_ent.pw_dir */
+ /* pw_dir will show up in passwd_ent.pw_dir */
+ xstrlcpy(pw_dir, cp, sizeof(pw_dir));
/* the rest of the fields are unimportant and not being considered */
extern char *endian; /* "big" */
extern char *hostdomain; /* "southseas.nz" */
extern char copyright[]; /* Copyright info */
-extern char hostd[]; /* "kiska.southseas.nz" */
extern char version[]; /* Version info */
/*
extern void rpc_msg_init(struct rpc_msg *, u_long, u_long, u_long);
extern void set_amd_program_number(u_long program);
extern void show_opts(int ch, struct opt_tab *);
-extern void xstrlcpy(char *dst, const char *src, size_t len);
extern void xstrlcat(char *dst, const char *src, size_t len);
+extern void xstrlcpy(char *dst, const char *src, size_t len);
extern void unregister_amq(void);
extern voidp xmalloc(int);
extern voidp xrealloc(voidp, int);
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))
/* 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
int error = 0;
#ifdef MOUNT_TABLE_ON_FILE
char *zopts = NULL, *xopts = NULL;
+ size_t l;
#endif /* MOUNT_TABLE_ON_FILE */
char *mnt_dir = NULL;
* 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
{
else /* e.g. System Vr4 */
xsnprintf(optsbuf, sizeof(optsbuf), "%s=%08lx",
MNTTAB_OPT_DEV, (u_long) stb.st_dev);
- append_opts(zopts, optsbuf);
+ append_opts(zopts, l, optsbuf);
}
}
# endif /* MNTTAB_OPT_DEV */
char optsbuf[48];
xsnprintf(optsbuf, sizeof(optsbuf),
"%s=%d", MNTTAB_OPT_VERS, NFS_VERSION3);
- append_opts(zopts, optsbuf);
+ append_opts(zopts, l, optsbuf);
}
# endif /* defined(HAVE_FS_NFS3) && defined(MNTTAB_OPT_VERS) */
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, optsbuf);
+ append_opts(zopts, l, optsbuf);
}
# endif /* MNTTAB_OPT_PROTO */
memcpy(&arr[0], &fhdata[0], len);
for (i=0; i<len/sizeof(unsigned short int); i++) {
xsnprintf(str, sizeof(str), "%04x", ntohs(arr[i]));
- strcat(buf, str);
+ xstrlcat(buf, str, sizeof(buf));
}
return buf;
}
buf_size *= 2;
buf = xrealloc(buf, buf_size);
}
- strcat(buf, s);
+ xstrlcat(buf, s, buf_size);
}
return buf;
}
* '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;
for (p = f, q = e; (*q = *p) && 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++;