summaryrefslogtreecommitdiff
path: root/usr.bin/rdistd
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/rdistd')
-rw-r--r--usr.bin/rdistd/filesys-os.c116
-rw-r--r--usr.bin/rdistd/filesys.c104
-rw-r--r--usr.bin/rdistd/filesys.h170
-rw-r--r--usr.bin/rdistd/rdistd.c34
-rw-r--r--usr.bin/rdistd/server.c751
5 files changed, 554 insertions, 621 deletions
diff --git a/usr.bin/rdistd/filesys-os.c b/usr.bin/rdistd/filesys-os.c
index 449dd124f4d..cef5e5e1d0e 100644
--- a/usr.bin/rdistd/filesys-os.c
+++ b/usr.bin/rdistd/filesys-os.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: filesys-os.c,v 1.7 2003/04/05 20:31:58 deraadt Exp $ */
+/* $OpenBSD: filesys-os.c,v 1.8 2003/05/14 01:34:35 millert Exp $ */
/*
* Copyright (c) 1983 Regents of the University of California.
@@ -33,18 +33,20 @@
* SUCH DAMAGE.
*/
+#include "defs.h"
#ifndef lint
#if 0
-static char RCSid[] =
-"$From: filesys-os.c,v 6.17 1996/01/17 21:02:45 mcooper Exp mcooper $";
+static char RCSid[] __attribute__((__unused__)) =
+"$From: filesys-os.c,v 1.5 1999/08/04 15:57:33 christos Exp $";
#else
-static char RCSid[] =
-"$OpenBSD: filesys-os.c,v 1.7 2003/04/05 20:31:58 deraadt Exp $";
+static char RCSid[] __attribute__((__unused__)) =
+"$OpenBSD: filesys-os.c,v 1.8 2003/05/14 01:34:35 millert Exp $";
#endif
-static char sccsid[] = "@(#)filesys-os.c";
+static char sccsid[] __attribute__((__unused__)) =
+"@(#)filesys-os.c";
-static char copyright[] =
+static char copyright[] __attribute__((__unused__)) =
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
@@ -53,16 +55,8 @@ static char copyright[] =
* OS specific file system routines
*/
-#include "defs.h"
-#include "filesys.h"
-
#if FSI_TYPE == FSI_GETFSSTAT
static struct statfs *mnt = NULL;
-#if FSTYPENAME
-#define f_type_eq(a, b) (! strcmp (((struct statfs *) (a))->f_fstypename, (b)))
-#else /* !FSTYPENAME */
-#define f_type_eq(a, b) (((struct statfs *) a)->f_type == (b))
-#endif /* !FSTYPENAME */
#endif /* FSI_GETFSSTAT */
#if FSI_TYPE == FSI_MNTCTL
@@ -78,10 +72,8 @@ static int entries_left;
/*
* AIX version of setmountent()
*/
-FILE *setmountent(file, mode)
- /*ARGSUSED*/
- char *file;
- char *mode;
+FILE *
+setmountent(const char *file, const char *mode)
{
ulong size;
@@ -104,10 +96,8 @@ FILE *setmountent(file, mode)
/*
* getfsstat() version of get mount info routines.
*/
-FILE *setmountent(file, mode)
- /*ARGSUSED*/
- char *file;
- char *mode;
+FILE *
+setmountent(const char *file, const char *mode)
{
long size;
@@ -137,9 +127,8 @@ FILE *setmountent(file, mode)
/*
* Iterate over mount entries
*/
-mntent_t *getmountent(fptr)
- /*ARGSUSED*/
- FILE *fptr;
+mntent_t *
+getmountent(FILE *fptr)
{
static mntent_t mntstruct;
@@ -172,9 +161,8 @@ mntent_t *getmountent(fptr)
/*
* getfsstat() version of getmountent()
*/
-mntent_t *getmountent(fptr)
- /*ARGSUSED*/
- FILE *fptr;
+mntent_t *
+getmountent(FILE *fptr)
{
static mntent_t mntstruct;
static char remote_dev[MAXHOSTNAMELEN+MAXPATHLEN+1];
@@ -192,9 +180,14 @@ mntent_t *getmountent(fptr)
if (mnt->f_flags & M_RDONLY)
mntstruct.me_flags |= MEFLAG_READONLY;
#endif
- if (f_type_eq(mnt, MOUNT_NFS)) {
- (void) snprintf(remote_dev, sizeof remote_dev,
- "%s", mnt->f_mntfromname);
+
+#ifdef HAVE_FSTYPENAME
+ if (strcmp(mnt->f_fstypename, "nfs") == 0)
+#else
+ if (mnt->f_type == MOUNT_NFS)
+#endif /* HAVE_FSTYPENAME */
+ {
+ strlcpy(remote_dev, mnt->f_mntfromname, sizeof(remote_dev));
mntstruct.me_path = remote_dev;
mntstruct.me_type = METYPE_NFS;
} else {
@@ -213,9 +206,8 @@ mntent_t *getmountent(fptr)
/*
* Done with iterations
*/
-void endmountent(fptr)
- /*ARGSUSED*/
- FILE *fptr;
+void
+endmountent(FILE *fptr)
{
mnt = NULL;
@@ -230,10 +222,8 @@ void endmountent(fptr)
/*
* Prepare to iterate over mounted filesystem list
*/
-FILE *setmountent(file, mode)
- /*ARGSUSED*/
- char *file;
- char *mode;
+FILE *
+setmountent(const char *file, const char *mode)
{
return(fopen(file, mode));
}
@@ -241,9 +231,8 @@ FILE *setmountent(file, mode)
/*
* Done with iteration
*/
-void endmountent(fptr)
- /*ARGSUSED*/
- FILE *fptr;
+void
+endmountent(FILE *fptr)
{
fclose(fptr);
}
@@ -251,8 +240,8 @@ void endmountent(fptr)
/*
* Iterate over mount entries
*/
-mntent_t *getmountent(fptr)
- FILE *fptr;
+mntent_t *
+getmountent(FILE *fptr)
{
static mntent_t me;
static struct mnttab mntent;
@@ -288,10 +277,8 @@ mntent_t *getmountent(fptr)
/*
* Prepare to iterate over mounted filesystem list
*/
-FILE *setmountent(file, mode)
- /*ARGSUSED*/
- char *file;
- char *mode;
+FILE *
+setmountent(const char *file, const char *mode)
{
return(setmntent(file, mode));
}
@@ -299,9 +286,8 @@ FILE *setmountent(file, mode)
/*
* Done with iteration
*/
-void endmountent(fptr)
- /*ARGSUSED*/
- FILE *fptr;
+void
+endmountent(FILE *fptr)
{
endmntent(fptr);
}
@@ -309,15 +295,15 @@ void endmountent(fptr)
/*
* Iterate over mount entries
*/
-mntent_t *getmountent(fptr)
- FILE *fptr;
+mntent_t *
+getmountent(FILE *fptr)
{
static mntent_t me;
struct mntent *mntent;
bzero((char *)&me, sizeof(mntent_t));
- if (mntent = getmntent(fptr)) {
+ if ((mntent = getmntent(fptr)) != NULL) {
me.me_path = mntent->mnt_dir;
me.me_type = mntent->mnt_type;
if (mntent->mnt_opts && hasmntopt(mntent, MNTOPT_RO))
@@ -347,18 +333,15 @@ mntent_t *getmountent(fptr)
static int startmounts = 0;
-FILE *setmountent(file, mode)
- /*ARGSUSED*/
- char *file;
- char *mode;
+FILE *
+setmountent(const char *file, const char *mode)
{
startmounts = 0;
- return(stdin); /* XXX - need to return something! */
+ return((FILE *) 1);
}
-void endmountent(fptr)
- /*ARGSUSED*/
- FILE *fptr;
+void
+endmountent(FILE *fptr)
{
/* NOOP */
}
@@ -366,9 +349,8 @@ void endmountent(fptr)
/*
* Iterate over mounted filesystems using getmnt()
*/
-mntent_t *getmountent(fptr)
- /*ARGSUSED*/
- FILE *fptr;
+mntent_t *
+getmountent(FILE *fptr)
{
struct fs_data fs_data;
static mntent_t me;
@@ -394,8 +376,8 @@ mntent_t *getmountent(fptr)
/*
* Make a new (copy) of a mntent structure.
*/
-mntent_t *newmountent(old)
- mntent_t *old;
+mntent_t *
+newmountent(const mntent_t *old)
{
mntent_t *new;
diff --git a/usr.bin/rdistd/filesys.c b/usr.bin/rdistd/filesys.c
index 4ec9c0c56b2..74d3739d2af 100644
--- a/usr.bin/rdistd/filesys.c
+++ b/usr.bin/rdistd/filesys.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: filesys.c,v 1.8 2003/04/05 20:31:58 deraadt Exp $ */
+/* $OpenBSD: filesys.c,v 1.9 2003/05/14 01:34:35 millert Exp $ */
/*
* Copyright (c) 1983 Regents of the University of California.
@@ -33,18 +33,21 @@
* SUCH DAMAGE.
*/
+#include "defs.h"
+
#ifndef lint
#if 0
-static char RCSid[] =
-"$From: filesys.c,v 6.24 1996/01/30 01:57:07 mcooper Exp $";
+static char RCSid[] __attribute__((__unused__)) =
+"$From: filesys.c,v 1.2 1999/08/04 15:57:33 christos Exp $";
#else
-static char RCSid[] =
-"$OpenBSD: filesys.c,v 1.8 2003/04/05 20:31:58 deraadt Exp $";
+static char RCSid[] __attribute__((__unused__)) =
+"$OpenBSD: filesys.c,v 1.9 2003/05/14 01:34:35 millert Exp $";
#endif
-static char sccsid[] = "@(#)filesys.c";
+static char sccsid[] __attribute__((__unused__)) =
+"@(#)filesys.c";
-static char copyright[] =
+static char copyright[] __attribute__((__unused__)) =
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
@@ -54,8 +57,6 @@ static char copyright[] =
* about mounted filesystems.
*/
-#include "defs.h"
-#include "filesys.h"
jmp_buf env;
@@ -63,10 +64,8 @@ jmp_buf env;
* Given a pathname, find the fullest component that exists.
* If statbuf is not NULL, set it to point at our stat buffer.
*/
-char *find_file(pathname, statbuf, isvalid)
- char *pathname;
- struct stat *statbuf;
- int *isvalid;
+char *
+find_file(char *pathname, struct stat *statbuf, int *isvalid)
{
static char last_pathname[MAXPATHLEN];
static char file[MAXPATHLEN + 3];
@@ -92,7 +91,7 @@ char *find_file(pathname, statbuf, isvalid)
return(file);
}
- if ((int)strlen(pathname) > sizeof(file)+3) {
+ if (strlen(pathname) > sizeof(file) + 3) {
error("%s: Name to large for buffer.", pathname);
return(NULL);
}
@@ -100,18 +99,18 @@ char *find_file(pathname, statbuf, isvalid)
/*
* Save for next time
*/
- (void) strlcpy(last_pathname, pathname, sizeof last_pathname);
+ (void) strlcpy(last_pathname, pathname, sizeof(last_pathname));
if (*pathname == '/')
- (void) strlcpy(file, pathname, sizeof file);
+ (void) strlcpy(file, pathname, sizeof(file));
else {
/*
* Ensure we have a directory (".") in our path
* so we have something to stat in case the file
* does not exist.
*/
- (void) strlcpy(file, "./", sizeof file);
- (void) strlcat(file, pathname, sizeof file);
+ (void) strlcpy(file, "./", sizeof(file));
+ (void) strlcat(file, pathname, sizeof(file));
}
while (lstat(file, &filestat) != 0) {
@@ -124,12 +123,12 @@ char *find_file(pathname, statbuf, isvalid)
* Normally we want to change /dir1/dir2/file
* into "/dir1/dir2/."
*/
- if ((p = (char *) strrchr(file, '/'))) {
+ if ((p = (char *) strrchr(file, '/')) != NULL) {
if (strcmp(p, "/.") == 0) {
- *p = CNULL;
+ *p = CNULL;
} else {
- *++p = '.';
- *++p = CNULL;
+ *++p = '.';
+ *++p = CNULL;
}
} else {
/*
@@ -182,9 +181,8 @@ char *find_file(pathname, statbuf, isvalid)
/*
* Find the device that "filest" is on in the "mntinfo" linked list.
*/
-mntent_t *findmnt(filest, mntinfo)
- struct stat *filest;
- struct mntinfo *mntinfo;
+mntent_t *
+findmnt(struct stat *filest, struct mntinfo *mntinfo)
{
struct mntinfo *mi;
@@ -201,9 +199,8 @@ mntent_t *findmnt(filest, mntinfo)
/*
* Is "mnt" a duplicate of any of the mntinfo->mi_mnt elements?
*/
-int isdupmnt(mnt, mntinfo)
- mntent_t *mnt;
- struct mntinfo *mntinfo;
+int
+isdupmnt(mntent_t *mnt, struct mntinfo *mntinfo)
{
struct mntinfo *m;
@@ -217,7 +214,8 @@ int isdupmnt(mnt, mntinfo)
/*
* Alarm clock
*/
-void wakeup()
+void
+wakeup(int dummy)
{
debugmsg(DM_CALL, "wakeup() in filesys.c called");
longjmp(env, 1);
@@ -227,8 +225,8 @@ void wakeup()
* Make a linked list of mntinfo structures.
* Use "mi" as the base of the list if it's non NULL.
*/
-struct mntinfo *makemntinfo(mi)
- struct mntinfo *mi;
+struct mntinfo *
+makemntinfo(struct mntinfo *mi)
{
FILE *mfp;
static struct mntinfo *mntinfo;
@@ -251,7 +249,7 @@ struct mntinfo *makemntinfo(mi)
}
mntinfo = mi;
- while ((mnt = getmountent(mfp))) {
+ while ((mnt = getmountent(mfp)) != NULL) {
debugmsg(DM_MISC, "mountent = '%s' (%s)",
mnt->me_path, mnt->me_type);
@@ -284,7 +282,8 @@ struct mntinfo *makemntinfo(mi)
* Add entry to list
*/
if (mntinfo) {
- for (m = mntinfo; m->mi_nxt; m = m->mi_nxt);
+ for (m = mntinfo; m->mi_nxt; m = m->mi_nxt)
+ continue;
m->mi_nxt = newmi;
} else
mntinfo = newmi;
@@ -303,10 +302,8 @@ struct mntinfo *makemntinfo(mi)
* If "statbuf" is not NULL it is used as the stat buffer too avoid
* stat()'ing the file again back in server.c.
*/
-mntent_t *getmntpt(pathname, statbuf, isvalid)
- char *pathname;
- struct stat *statbuf;
- int *isvalid;
+mntent_t *
+getmntpt(char *pathname, struct stat *statbuf, int *isvalid)
{
static struct mntinfo *mntinfo = NULL;
static struct stat filestat;
@@ -334,16 +331,16 @@ mntent_t *getmntpt(pathname, statbuf, isvalid)
/*
* Find the mnt that pathname is on.
*/
- if ((mnt = findmnt(pstat, mntinfo)))
+ if ((mnt = findmnt(pstat, mntinfo)) != NULL)
return(mnt);
/*
* We failed to find correct mnt, so maybe it's a newly
* mounted filesystem. We rebuild mntinfo and try again.
*/
- if ((tmpmi = makemntinfo(mntinfo))) {
+ if ((tmpmi = makemntinfo(mntinfo)) != NULL) {
mntinfo = tmpmi;
- if ((mnt = findmnt(pstat, mntinfo)))
+ if ((mnt = findmnt(pstat, mntinfo)) != NULL)
return(mnt);
}
@@ -357,10 +354,8 @@ mntent_t *getmntpt(pathname, statbuf, isvalid)
/*
* Is "path" NFS mounted? Return 1 if it is, 0 if not, or -1 on error.
*/
-int is_nfs_mounted(path, statbuf, isvalid)
- char *path;
- struct stat *statbuf;
- int *isvalid;
+int
+is_nfs_mounted(char *path, struct stat *statbuf, int *isvalid)
{
mntent_t *mnt;
@@ -383,10 +378,8 @@ int is_nfs_mounted(path, statbuf, isvalid)
* Is "path" on a read-only mounted filesystem?
* Return 1 if it is, 0 if not, or -1 on error.
*/
-int is_ro_mounted(path, statbuf, isvalid)
- char *path;
- struct stat *statbuf;
- int *isvalid;
+int
+is_ro_mounted(char *path, struct stat *statbuf, int *isvalid)
{
mntent_t *mnt;
@@ -404,11 +397,8 @@ int is_ro_mounted(path, statbuf, isvalid)
* Is "path" a symlink?
* Return 1 if it is, 0 if not, or -1 on error.
*/
-int is_symlinked(path, statbuf, isvalid)
- /*ARGSUSED*/
- char *path;
- struct stat *statbuf;
- int *isvalid;
+int
+is_symlinked(char *path, struct stat *statbuf, int *isvalid)
{
static struct stat stb;
@@ -432,10 +422,8 @@ int is_symlinked(path, statbuf, isvalid)
* Filesystem values < 0 indicate unsupported or unavailable
* information.
*/
-int getfilesysinfo(file, freespace, freefiles)
- char *file;
- long *freespace;
- long *freefiles;
+int
+getfilesysinfo(char *file, long *freespace, long *freefiles)
{
#if defined(STATFS_TYPE)
static statfs_t statfsbuf;
@@ -457,7 +445,7 @@ int getfilesysinfo(file, freespace, freefiles)
#if STATFS_TYPE == STATFS_SYSV
r = statfs(mntpt, &statfsbuf, sizeof(statfs_t), 0);
#endif
-#if STATFS_TYPE == STATFS_BSD
+#if STATFS_TYPE == STATFS_BSD || STATFS_TYPE == STATFS_44BSD
r = statfs(mntpt, &statfsbuf);
#endif
#if STATFS_TYPE == STATFS_OSF1
diff --git a/usr.bin/rdistd/filesys.h b/usr.bin/rdistd/filesys.h
deleted file mode 100644
index 9e54bab4b8e..00000000000
--- a/usr.bin/rdistd/filesys.h
+++ /dev/null
@@ -1,170 +0,0 @@
-/* $OpenBSD: filesys.h,v 1.4 1998/06/26 21:20:49 millert Exp $ */
-
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * 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 acknowledgement:
- * 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.
- */
-
-/*
- * $From: filesys.h,v 6.19 1995/12/12 00:46:46 mcooper Exp $
- * @(#)filesys.h
- */
-
-#ifndef __filesys_h__
-#define __filesys_h__
-
-/*
- * File System information
- */
-
-/*
- * Mount information
- */
-#if FSI_TYPE == FSI_GETMNT
-# include <sys/types.h>
-# include <sys/param.h>
-# include <sys/mount.h>
-# define MOUNTED_FILE "<none>"
-#endif
-
-#if FSI_TYPE == FSI_GETFSSTAT
-# include <sys/types.h>
-# include <sys/mount.h>
-# define MOUNTED_FILE "<none>"
-#endif
-
-#if FSI_TYPE == FSI_MNTCTL
-# include <sys/mntctl.h>
-# define MOUNTED_FILE "<none>"
-#endif
-
-#if FSI_TYPE == FSI_GETMNTENT
-# include <mntent.h>
-# define MOUNTED_FILE MOUNTED
-#endif
-
-#if FSI_TYPE == FSI_GETMNTENT2
-#if defined(MNTTAB_H)
-# include MNTTAB_H
-#endif /* MNTTAB_H */
-#if defined(MNTENT_H)
-# include MNTENT_H
-#endif /* MNTENT_H */
-# define MOUNTED_FILE MNTTAB
-#endif /* FSI_GETMNTENT2 */
-
-#if !defined(MOUNTED_FILE) && defined(MNT_MNTTAB) /* HPUX */
-# define MOUNTED_FILE MNT_MNTTAB
-#endif /* MNT_MNTTAB */
-
-/*
- * NCR OS defines bcopy and bzero
- */
-#if defined(NCR)
-#undef bcopy
-#undef bzero
-#endif /* NCR */
-
-/*
- * Stat Filesystem
- */
-#if defined(STATFS_TYPE)
-#if defined(ultrix)
- typedef struct fs_data statfs_t;
-# define f_bavail fd_req.bfreen
-# define f_bsize fd_req.bsize
-# define f_ffree fd_req.gfree
-#else
-#if defined(_AIX) || STATFS_TYPE == STATFS_SYSV
-# include <sys/statfs.h>
- typedef struct statfs statfs_t;
-# define f_bavail f_bfree
-#else
-#if defined(SVR4)
-# include <sys/statvfs.h>
- typedef struct statvfs statfs_t;
-# define statfs(mp,sb) statvfs(mp,sb)
-#else
-#if defined(BSD386) || defined(__bsdi__) || defined(__OpenBSD__) || defined(FREEBSD) || STATFS_TYPE == STATFS_OSF1
- typedef struct statfs statfs_t;
-#else
-# include <sys/vfs.h>
- typedef struct statfs statfs_t;
-#endif /* BSD386 */
-#endif /* SVR4 */
-#endif /* _AIX */
-#endif /* ultrix */
-#endif /* STATFS_TYPE */
-
-/*
- * Mount Entry definetions
- */
-#ifndef METYPE_OTHER
-#define METYPE_OTHER "other"
-#endif
-#ifndef METYPE_NFS
-#define METYPE_NFS "nfs"
-#endif
-#ifndef MEFLAG_READONLY
-#define MEFLAG_READONLY 0x01
-#endif
-#ifndef MEFLAG_IGNORE
-#define MEFLAG_IGNORE 0x02
-#endif
-
-/*
- * Our internal mount entry type
- */
-struct _mntent {
- char *me_path; /* Mounted path */
- char *me_type; /* Type of mount */
- int me_flags; /* Mount flags */
-};
-typedef struct _mntent mntent_t;
-
-/*
- * Internal mount information type
- */
-struct mntinfo {
- mntent_t *mi_mnt;
- struct stat *mi_statb;
- struct mntinfo *mi_nxt;
-};
-
-/*
- * Declarations
- */
-FILE *setmountent();
-mntent_t *getmountent();
-mntent_t *newmountent();
-void endmountent();
-
-#endif /* __filesys_h__ */
diff --git a/usr.bin/rdistd/rdistd.c b/usr.bin/rdistd/rdistd.c
index cfe201c2591..d582a7d7e0a 100644
--- a/usr.bin/rdistd/rdistd.c
+++ b/usr.bin/rdistd/rdistd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rdistd.c,v 1.4 1998/06/26 21:20:51 millert Exp $ */
+/* $OpenBSD: rdistd.c,v 1.5 2003/05/14 01:34:35 millert Exp $ */
/*
* Copyright (c) 1983 Regents of the University of California.
@@ -33,29 +33,33 @@
* SUCH DAMAGE.
*/
+#include "defs.h"
+
#ifndef lint
#if 0
-static char RCSid[] =
-"$From: rdistd.c,v 6.22 1995/12/11 23:37:35 mcooper Exp $";
+static char RCSid[] __attribute__((__unused__)) =
+"$From: rdistd.c,v 1.2 1999/08/04 15:57:33 christos Exp $";
#else
-static char RCSid[] =
-"$OpenBSD: rdistd.c,v 1.4 1998/06/26 21:20:51 millert Exp $";
+static char RCSid[] __attribute__((__unused__)) =
+"$OpenBSD: rdistd.c,v 1.5 2003/05/14 01:34:35 millert Exp $";
#endif
-static char sccsid[] = "@(#)rdistd.c";
+static char sccsid[] __attribute__((__unused__)) =
+"@(#)rdistd.c";
-static char copyright[] =
+static char copyright[] __attribute__((__unused__)) =
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
-
-#include "defs.h"
+int main(int, char **, char **);
+static void usage(void);
/*
* Print usage message
*/
-static void usage()
+static void
+usage(void)
{
fprintf(stderr, "usage: %s -S [ -DV ]\n", progname);
exit(1);
@@ -67,14 +71,14 @@ char localmsglist[] = "syslog=ferror";
* The Beginning
*/
int
-main(argc, argv, envp)
- int argc;
- char **argv;
- char **envp;
+main(int argc, char **argv, char **envp)
{
+ extern char *__progname;
char *cp;
int c;
+ progname = __progname;
+
if (init(argc, argv, envp) < 0)
exit(1);
@@ -108,7 +112,7 @@ main(argc, argv, envp)
rem_w = fileno(stdout);
/* Set logging */
- if ((cp = msgparseopts(localmsglist, TRUE)))
+ if ((cp = msgparseopts(localmsglist, TRUE)) != NULL)
fatalerr("Bad message logging option (%s): %s",
localmsglist, cp);
diff --git a/usr.bin/rdistd/server.c b/usr.bin/rdistd/server.c
index 23001b6e78e..9454f590562 100644
--- a/usr.bin/rdistd/server.c
+++ b/usr.bin/rdistd/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.13 2003/04/19 17:22:30 millert Exp $ */
+/* $OpenBSD: server.c,v 1.14 2003/05/14 01:34:35 millert Exp $ */
/*
* Copyright (c) 1983 Regents of the University of California.
@@ -32,18 +32,21 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
+#include "defs.h"
+
#ifndef lint
#if 0
-static char RCSid[] =
-"$From: server.c,v 6.85 1996/03/12 22:55:38 mcooper Exp $";
+static char RCSid[] __attribute__((__unused__)) =
+"$From: server.c,v 1.10 1999/08/04 15:57:33 christos Exp $";
#else
-static char RCSid[] =
-"$OpenBSD: server.c,v 1.13 2003/04/19 17:22:30 millert Exp $";
+static char RCSid[] __attribute__((__unused__)) =
+"$OpenBSD: server.c,v 1.14 2003/05/14 01:34:35 millert Exp $";
#endif
-static char sccsid[] = "@(#)server.c 5.3 (Berkeley) 6/7/86";
+static char sccsid[] __attribute__((__unused__)) =
+"@(#)server.c 5.3 (Berkeley) 6/7/86";
-static char copyright[] =
+static char copyright[] __attribute__((__unused__)) =
"@(#) Copyright (c) 1983 Regents of the University of California.\n\
All rights reserved.\n";
#endif /* not lint */
@@ -52,8 +55,6 @@ static char copyright[] =
* Server routines
*/
-#include "defs.h"
-
char tempname[sizeof _RDIST_TMP + 1]; /* Tmp file name */
char buf[BUFSIZ]; /* general purpose buffer */
char target[MAXPATHLEN]; /* target/source directory name */
@@ -65,11 +66,32 @@ static long min_freespace = 0; /* Minimium free space on a filesystem */
static long min_freefiles = 0; /* Minimium free # files on a filesystem */
int oumask; /* Old umask */
+static int cattarget(char *);
+static int setownership(char *, int, UID_T, GID_T, int);
+static int setfilemode(char *, int, int, int);
+static int fchog(int, char *, char *, char *, int);
+static int removefile(struct stat *, int);
+static void doclean(char *);
+static void clean(char *);
+static void dospecial(char *);
+static void docmdspecial(void);
+static void query(char *);
+static int chkparent(char *, opt_t);
+static char *savetarget(char *, opt_t);
+static void recvfile(char *, opt_t, int, char *, char *, time_t, time_t, off_t);
+static void recvdir(opt_t, int, char *, char *);
+static void recvlink(char *, opt_t, int, off_t);
+static void hardlink(char *);
+static void setconfig(char *);
+static void recvit(char *, int);
+static void dochmog(char *);
+static void settarget(char *, int);
+
/*
* Cat "string" onto the target buffer with error checking.
*/
-static int cattarget(string)
- char *string;
+static int
+cattarget(char *string)
{
if (strlen(string) + strlen(target) + 2 > sizeof(target)) {
message(MT_INFO, "target buffer is not large enough.");
@@ -80,8 +102,8 @@ static int cattarget(string)
return(-10);
}
- (void) snprintf(ptarget, target + sizeof(target) - ptarget,
- "/%s", string);
+ (void) snprintf(ptarget, sizeof(target) - (ptarget - target),
+ "/%s", string);
return(0);
}
@@ -89,47 +111,47 @@ static int cattarget(string)
/*
* Set uid and gid ownership of a file.
*/
-static int setownership(file, fd, uid, gid)
- char *file;
- int fd;
- UID_T uid;
- GID_T gid;
+static int
+setownership(char *file, int fd, UID_T uid, GID_T gid, int link)
{
int status = -1;
/*
* We assume only the Superuser can change uid ownership.
*/
- if (getuid() == 0) {
-#if defined(HAVE_FCHOWN)
- if (fd != -1)
- status = fchown(fd, (CHOWN_UID_T) uid,
- (CHOWN_GID_T) gid);
+ if (getuid() != 0)
+ uid = -1;
+
+ /*
+ * If we are dealing with a symlink, only try to change it if
+ * we have lchown, if we don't leave it alone.
+ */
+#if defined(HAVE_LCHOWN)
+ if (link)
+ status = lchown(file, (CHOWN_UID_T) uid,
+ (CHOWN_GID_T) gid);
+#else
+ if (link)
+ return 0;
#endif
- if (status < 0)
- status = chown(file, (CHOWN_UID_T) uid,
- (CHOWN_GID_T) gid);
-
- if (status < 0) {
- message(MT_NOTICE, "%s: chown %d:%d failed: %s",
- target, (UID_T) uid, (GID_T) gid, SYSERR);
- return(-1);
- }
- } else {
+
#if defined(HAVE_FCHOWN)
- if (fd != -1)
- status = fchown(fd, (CHOWN_UID_T) -1,
- (CHOWN_GID_T) gid);
+ if (fd != -1 && !link)
+ status = fchown(fd, (CHOWN_UID_T) uid,
+ (CHOWN_GID_T) gid);
#endif
- if (status < 0)
- status = chown(file, (CHOWN_UID_T) -1,
- (CHOWN_GID_T) gid);
+ if (status < 0 && !link)
+ status = chown(file, (CHOWN_UID_T) uid,
+ (CHOWN_GID_T) gid);
- if (status < 0) {
+ if (status < 0) {
+ if (uid == (UID_T) -1)
message(MT_NOTICE, "%s: chgrp %d failed: %s",
- target, (GID_T) gid, SYSERR);
- return(-1);
- }
+ target, gid, SYSERR);
+ else
+ message(MT_NOTICE, "%s: chown %d.%d failed: %s",
+ target, uid, gid, SYSERR);
+ return(-1);
}
return(0);
@@ -138,22 +160,32 @@ static int setownership(file, fd, uid, gid)
/*
* Set mode of a file
*/
-static int setfilemode(file, fd, mode)
- char *file;
- int fd;
- int mode;
+static int
+setfilemode(char *file, int fd, int mode, int link)
{
int status = -1;
if (mode == -1)
return(0);
+ /*
+ * If we are dealing with a symlink, only try to change it if
+ * we have lchown, if we don't leave it alone.
+ */
+#if defined(HAVE_LCHMOD)
+ if (link)
+ status = lchmod(file, mode);
+#else
+ if (link)
+ return 0;
+#endif
+
#if defined(HAVE_FCHMOD)
- if (fd != -1)
+ if (fd != -1 && !link)
status = fchmod(fd, mode);
#endif
- if (status < 0)
+ if (status < 0 && !link)
status = chmod(file, mode);
if (status < 0) {
@@ -163,41 +195,16 @@ static int setfilemode(file, fd, mode)
return(0);
}
-
-/*
- * Get group entry. This routine takes a string argument (name).
- * If name is of form ":N" a lookup for gid N is done.
- * Otherwise a lookup by name is done.
- */
-static struct group *mygetgroup(name)
- char *name;
-{
- struct group *gr;
-
- if (*name == ':')
- gr = getgrgid(atoi(name + 1));
- else
- gr = getgrnam(name);
-
- return(gr);
-}
-
/*
* Change owner, group and mode of file.
*/
-static int fchog(fd, file, owner, group, mode)
- int fd;
- char *file, *owner, *group;
- int mode;
+static int
+fchog(int fd, char *file, char *owner, char *group, int mode)
{
- struct group *gr = NULL;
- static char last_group[128];
- static char last_owner[128];
- static GID_T last_gid = (GID_T)-2;
- static UID_T last_uid = (UID_T)-2;
- static GID_T last_primegid;
+ static struct group *gr = NULL;
extern char *locuser;
int i;
+ struct stat st;
UID_T uid;
GID_T gid;
GID_T primegid = (GID_T)-2;
@@ -206,8 +213,7 @@ static int fchog(fd, file, owner, group, mode)
if (userid == 0) { /* running as root; take anything */
if (*owner == ':') {
uid = (UID_T) atoi(owner + 1);
- } else if (last_uid == (UID_T)-2 ||
- strcmp(owner, last_owner) != 0) {
+ } else if (pw == NULL || strcmp(owner, pw->pw_name) != 0) {
if ((pw = getpwnam(owner)) == NULL) {
if (mode != -1 && IS_ON(mode, S_ISUID)) {
message(MT_NOTICE,
@@ -219,14 +225,11 @@ static int fchog(fd, file, owner, group, mode)
message(MT_NOTICE,
"%s: unknown login name \"%s\"",
target, owner);
- } else {
- uid = last_uid = pw->pw_uid;
- primegid = last_primegid = pw->pw_gid;
- strlcpy(last_owner, owner, sizeof last_owner);
- }
+ } else
+ uid = pw->pw_uid;
} else {
- uid = last_uid;
- primegid = last_primegid;
+ uid = pw->pw_uid;
+ primegid = pw->pw_gid;
}
if (*group == ':') {
gid = (GID_T) atoi(group + 1);
@@ -248,14 +251,10 @@ static int fchog(fd, file, owner, group, mode)
}
gid = (GID_T) -1;
- if (last_gid < (GID_T)0 || strcmp(group, last_group) != 0) {
- /*
- * Invalid cached values so we need to do a new lookup.
- */
- if ((gr = mygetgroup(group))) {
- last_gid = gid = gr->gr_gid;
- strlcpy(last_group, gr->gr_name, sizeof last_group);
- } else {
+ if (gr == NULL || strcmp(group, gr->gr_name) != 0) {
+ if ((*group == ':' &&
+ (getgrgid(gid = atoi(group + 1)) == NULL))
+ || ((gr = (struct group *)getgrnam(group)) == NULL)) {
if (mode != -1 && IS_ON(mode, S_ISGID)) {
message(MT_NOTICE,
"%s: unknown group \"%s\", clearing setgid",
@@ -265,24 +264,15 @@ static int fchog(fd, file, owner, group, mode)
message(MT_NOTICE,
"%s: unknown group \"%s\"",
target, group);
- }
- } else {
- /*
- * Use the cached values.
- */
- gid = last_gid;
- }
+ } else
+ gid = gr->gr_gid;
+ } else
+ gid = gr->gr_gid;
- /*
- * We need to check non-root users to make sure they're a member
- * of the group. If they are not, we don't set that gid ownership.
- */
if (userid && gid >= 0 && gid != primegid) {
- if (!gr)
- gr = mygetgroup(group);
if (gr)
for (i = 0; gr->gr_mem[i] != NULL; i++)
- if (strcmp(locuser, gr->gr_mem[i]) == 0)
+ if (strcmp(locuser, gr->gr_mem[i]) == 0)
goto ok;
if (mode != -1 && IS_ON(mode, S_ISGID)) {
message(MT_NOTICE,
@@ -293,12 +283,16 @@ static int fchog(fd, file, owner, group, mode)
gid = (GID_T) -1;
}
ok:
+ if (stat(file, &st) == -1) {
+ error("%s: Stat failed %s", file, SYSERR);
+ return -1;
+ }
/*
* Set uid and gid ownership. If that fails, strip setuid and
* setgid bits from mode. Once ownership is set, successful
* or otherwise, set the new file mode.
*/
- if (setownership(file, fd, uid, gid) < 0) {
+ if (setownership(file, fd, uid, gid, S_ISLNK(st.st_mode)) < 0) {
if (mode != -1 && IS_ON(mode, S_ISUID)) {
message(MT_NOTICE,
"%s: chown failed, clearing setuid", target);
@@ -310,7 +304,7 @@ ok:
mode &= ~S_ISGID;
}
}
- (void) setfilemode(file, fd, mode);
+ (void) setfilemode(file, fd, mode, S_ISLNK(st.st_mode));
return(0);
@@ -320,8 +314,8 @@ ok:
* Remove a file or directory (recursively) and send back an acknowledge
* or an error message.
*/
-static int removefile(statb)
- struct stat *statb;
+static int
+removefile(struct stat *statb, int silent)
{
DIR *d;
static DIRENTRY *dp;
@@ -333,11 +327,20 @@ static int removefile(statb)
switch (statb->st_mode & S_IFMT) {
case S_IFREG:
case S_IFLNK:
+ case S_IFCHR:
+ case S_IFBLK:
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+#endif
+#ifdef S_IFIFO
+ case S_IFIFO:
+#endif
if (unlink(target) < 0) {
if (errno == ETXTBSY) {
- message(MT_REMOTE|MT_NOTICE,
- "%s: unlink failed: %s",
- target, SYSERR);
+ if (!silent)
+ message(MT_REMOTE|MT_NOTICE,
+ "%s: unlink failed: %s",
+ target, SYSERR);
return(0);
} else {
error("%s: unlink failed: %s", target, SYSERR);
@@ -362,29 +365,33 @@ static int removefile(statb)
optarget = ptarget;
len = ptarget - target;
- while ((dp = readdir(d))) {
+ while ((dp = readdir(d)) != NULL) {
if ((D_NAMLEN(dp) == 1 && dp->d_name[0] == '.') ||
(D_NAMLEN(dp) == 2 && dp->d_name[0] == '.' &&
dp->d_name[1] == '.'))
continue;
if (len + 1 + (int)strlen(dp->d_name) >= MAXPATHLEN - 1) {
- message(MT_REMOTE|MT_WARNING, "%s/%s: Name too long",
- target, dp->d_name);
+ if (!silent)
+ message(MT_REMOTE|MT_WARNING,
+ "%s/%s: Name too long",
+ target, dp->d_name);
continue;
}
ptarget = optarget;
*ptarget++ = '/';
cp = dp->d_name;;
- while ((*ptarget++ = *cp++))
- ;
+ while ((*ptarget++ = *cp++) != '\0')
+ continue;
ptarget--;
if (lstat(target, &stb) < 0) {
- message(MT_REMOTE|MT_WARNING, "%s: lstat failed: %s",
- target, SYSERR);
+ if (!silent)
+ message(MT_REMOTE|MT_WARNING,
+ "%s: lstat failed: %s",
+ target, SYSERR);
continue;
}
- if (removefile(&stb) < 0)
+ if (removefile(&stb, 0) < 0)
++failures;
}
(void) closedir(d);
@@ -399,6 +406,10 @@ static int removefile(statb)
return(-1);
}
removed:
+#if NEWWAY
+ if (!silent)
+ message(MT_CHANGE|MT_REMOTE, "%s: removed", target);
+#else
/*
* We use MT_NOTICE instead of MT_CHANGE because this function is
* sometimes called by other functions that are suppose to return a
@@ -406,6 +417,7 @@ removed:
* the Rdist protocol is re-done. Sigh.
*/
message(MT_NOTICE|MT_REMOTE, "%s: removed", target);
+#endif
return(0);
}
@@ -413,8 +425,8 @@ removed:
* Check the current directory (initialized by the 'T' command to server())
* for extraneous files and remove them.
*/
-static void doclean(cp)
- char *cp;
+static void
+doclean(char *cp)
{
DIR *d;
DIRENTRY *dp;
@@ -422,6 +434,7 @@ static void doclean(cp)
char *optarget, *ep;
int len;
opt_t opts;
+ char targ[MAXPATHLEN*4];
opts = strtol(cp, &ep, 8);
if (*ep != CNULL) {
@@ -436,7 +449,7 @@ static void doclean(cp)
optarget = ptarget;
len = ptarget - target;
- while ((dp = readdir(d))) {
+ while ((dp = readdir(d)) != NULL) {
if ((D_NAMLEN(dp) == 1 && dp->d_name[0] == '.') ||
(D_NAMLEN(dp) == 2 && dp->d_name[0] == '.' &&
dp->d_name[1] == '.'))
@@ -450,8 +463,8 @@ static void doclean(cp)
ptarget = optarget;
*ptarget++ = '/';
cp = dp->d_name;;
- while ((*ptarget++ = *cp++))
- ;
+ while ((*ptarget++ = *cp++) != '\0')
+ continue;
ptarget--;
if (lstat(target, &stb) < 0) {
message(MT_REMOTE|MT_WARNING, "%s: lstat failed: %s",
@@ -459,7 +472,8 @@ static void doclean(cp)
continue;
}
- (void) sendcmd(CC_QUERY, "%s", dp->d_name);
+ ENCODE(targ, dp->d_name);
+ (void) sendcmd(CC_QUERY, "%s", targ);
(void) remline(cp = buf, sizeof(buf), TRUE);
if (*cp != CC_YES)
@@ -469,7 +483,7 @@ static void doclean(cp)
message(MT_REMOTE|MT_INFO, "%s: need to remove",
target);
else
- (void) removefile(&stb);
+ (void) removefile(&stb, 0);
}
(void) closedir(d);
@@ -480,8 +494,8 @@ static void doclean(cp)
/*
* Frontend to doclean().
*/
-static void clean(cp)
- char *cp;
+static void
+clean(char *cp)
{
doclean(cp);
(void) sendcmd(CC_END, NULL);
@@ -493,9 +507,14 @@ static void clean(cp)
* We can't really set an alarm timeout here since we
* have no idea how long the command should take.
*/
-static void dospecial(cmd)
- char *cmd;
+static void
+dospecial(char *xcmd)
{
+ char cmd[BUFSIZ];
+ if (DECODE(cmd, xcmd) == -1) {
+ error("dospecial: Cannot decode command.");
+ return;
+ }
runcommand(cmd);
}
@@ -507,7 +526,8 @@ static void dospecial(cmd)
* E_FILES. When an RC_COMMAND is finally received, the E_FILES variable
* is stuffed into our environment and a normal dospecial() command is run.
*/
-static void docmdspecial()
+static void
+docmdspecial(void)
{
char *cp;
char *cmd, *env = NULL;
@@ -576,11 +596,17 @@ static void docmdspecial()
* QC_YES - exists and its a directory or symbolic link
* QC_ERRMSGmessage - error message
*/
-static void query(name)
- char *name;
+static void
+query(char *xname)
{
static struct stat stb;
int s = -1, stbvalid = 0;
+ char name[MAXPATHLEN];
+
+ if (DECODE(name, xname) == -1) {
+ error("query: Cannot decode filename");
+ return;
+ }
if (catname && cattarget(name) < 0)
return;
@@ -641,9 +667,18 @@ static void query(name)
case S_IFLNK:
case S_IFDIR:
case S_IFREG:
+#ifdef notyet
+ case S_IFCHR:
+ case S_IFBLK:
+#ifdef S_IFSOCK
+ case S_IFSOCK:
+#endif
+#ifdef S_IFIFO
+ case S_IFIFO:
+#endif
+#endif
(void) sendcmd(QC_YES, "%ld %ld %o %s %s",
- (long) stb.st_size,
- stb.st_mtime,
+ (long) stb.st_size, stb.st_mtime,
stb.st_mode & 07777,
getusername(stb.st_uid, target, options),
getgroupname(stb.st_gid, target, options));
@@ -659,9 +694,8 @@ static void query(name)
/*
* Check to see if parent directory exists and create one if not.
*/
-static int chkparent(name, opts)
- char *name;
- opt_t opts;
+static int
+chkparent(char *name, opt_t opts)
{
char *cp;
struct stat stb;
@@ -697,8 +731,8 @@ static int chkparent(name, opts)
/*
* Save a copy of 'file' by renaming it.
*/
-static char *savetarget(file)
- char *file;
+static char *
+savetarget(char *file, opt_t opts)
{
static char savefile[MAXPATHLEN];
@@ -707,11 +741,38 @@ static char *savetarget(file)
return(NULL);
}
- (void) snprintf(savefile, sizeof savefile, "%s%s", file, SAVE_SUFFIX);
+ if (IS_ON(opts, DO_HISTORY)) {
+ int i;
+ struct stat st;
+ /*
+ * There is a race here, but the worst that can happen
+ * is to lose a version of the file
+ */
+ for (i = 1; i < 1000; i++) {
+ (void) snprintf(savefile, sizeof(savefile),
+ "%s;%.3d", file, i);
+ if (stat(savefile, &st) == -1 && errno == ENOENT)
+ break;
+
+ }
+ if (i == 1000) {
+ message(MT_NOTICE,
+ "%s: More than 1000 versions for %s; reusing 1\n",
+ savefile, SYSERR);
+ i = 1;
+ (void) snprintf(savefile, sizeof(savefile),
+ "%s;%.3d", file, i);
+ }
+ }
+ else {
+ (void) snprintf(savefile, sizeof(savefile), "%s%s",
+ file, SAVE_SUFFIX);
- if (unlink(savefile) != 0 && errno != ENOENT) {
- message(MT_NOTICE, "%s: remove failed: %s", savefile, SYSERR);
- return(NULL);
+ if (unlink(savefile) != 0 && errno != ENOENT) {
+ message(MT_NOTICE, "%s: remove failed: %s",
+ savefile, SYSERR);
+ return(NULL);
+ }
}
if (rename(file, savefile) != 0 && errno != ENOENT) {
@@ -724,37 +785,13 @@ static char *savetarget(file)
}
/*
- * See if buf is all zeros (sparse check)
- */
-static int iszeros (buf, size)
- char *buf;
- off_t size;
-{
- while (size > 0) {
- if (*buf != CNULL)
- return(0);
- buf++;
- size--;
- }
-
- return(1);
-}
-
-
-/*
* Receive a file
*/
-static void recvfile(new, opts, mode, owner, group, mtime, atime, size)
- /*ARGSUSED*/
- char *new;
- opt_t opts;
- int mode;
- char *owner, *group;
- time_t mtime;
- time_t atime;
- off_t size;
+static void
+recvfile(char *new, opt_t opts, int mode, char *owner, char *group,
+ time_t mtime, time_t atime, off_t size)
{
- int f, wrerr, olderrno, lastwashole = 0, wassparse = 0;
+ int f, wrerr, olderrno;
off_t i;
char *cp;
char *savefile = NULL;
@@ -801,31 +838,7 @@ static void recvfile(new, opts, mode, owner, group, mtime, atime, size)
amt = BUFSIZ;
if (i + amt > size)
amt = size - i;
- if (IS_ON(opts, DO_SPARSE) && iszeros(buf, amt)) {
- if (lseek (f, amt, SEEK_CUR) < 0L) {
- olderrno = errno;
- wrerr++;
- }
- lastwashole = 1;
- wassparse++;
- } else {
- if (wrerr == 0 && xwrite(f, buf, amt) != amt) {
- olderrno = errno;
- wrerr++;
- }
- lastwashole = 0;
- }
- }
-
- if (lastwashole) {
-#if defined(HAVE_FTRUNCATE)
- if (write (f, "", 1) != 1 || ftruncate (f, size) < 0)
-#else
- /* Seek backwards one character and write a null. */
- if (lseek (f, (off_t) -1, SEEK_CUR) < 0L
- || write (f, "", 1) != 1)
-#endif
- {
+ if (wrerr == 0 && xwrite(f, buf, amt) != amt) {
olderrno = errno;
wrerr++;
}
@@ -861,6 +874,7 @@ static void recvfile(new, opts, mode, owner, group, mtime, atime, size)
errno = 0;
if ((f2 = fopen(new, "r")) == NULL) {
error("%s: open for read failed: %s", new, SYSERR);
+ (void) fclose(f1);
(void) close(f);
(void) unlink(new);
return;
@@ -916,7 +930,7 @@ static void recvfile(new, opts, mode, owner, group, mtime, atime, size)
* Try to save target file from being over-written
*/
if (IS_ON(opts, DO_SAVETARGETS))
- if ((savefile = savetarget(target)) == NULL) {
+ if ((savefile = savetarget(target, opts)) == NULL) {
(void) unlink(new);
return;
}
@@ -929,7 +943,7 @@ static void recvfile(new, opts, mode, owner, group, mtime, atime, size)
char *saveptr = ptarget;
ptarget = &target[strlen(target)];
- removefile(&statbuff);
+ removefile(&statbuff, 0);
ptarget = saveptr;
}
@@ -937,37 +951,60 @@ static void recvfile(new, opts, mode, owner, group, mtime, atime, size)
* Install new (temporary) file as the actual target
*/
if (rename(new, target) < 0) {
+ static char fmt[] = "%s -> %s: rename failed: %s";
+ struct stat stb;
/*
* If the rename failed due to "Text file busy", then
* try to rename the target file and retry the rename.
*/
- if (errno == ETXTBSY) {
+ switch (errno) {
+ case ETXTBSY:
/* Save the target */
- if ((savefile = savetarget(target)) != NULL) {
+ if ((savefile = savetarget(target, opts)) != NULL) {
/* Retry installing new file as target */
if (rename(new, target) < 0) {
- error("%s -> %s: rename failed: %s",
- new, target, SYSERR);
+ error(fmt, new, target, SYSERR);
/* Try to put back save file */
if (rename(savefile, target) < 0)
- error(
- "%s -> %s: rename failed: %s",
- savefile, target,
- SYSERR);
+ error(fmt,
+ savefile, target, SYSERR);
+ (void) unlink(new);
} else
message(MT_NOTICE, "%s: renamed to %s",
target, savefile);
+ /*
+ * XXX: We should remove the savefile here.
+ * But we are nice to nfs clients and
+ * we keep it.
+ */
}
- } else {
- error("%s -> %s: rename failed: %s",
- new, target, SYSERR);
+ break;
+ case EISDIR:
+ /*
+ * See if target is a directory and remove it if it is
+ */
+ if (lstat(target, &stb) == 0) {
+ if (S_ISDIR(stb.st_mode)) {
+ char *optarget = ptarget;
+ for (ptarget = target; *ptarget;
+ ptarget++);
+ /* If we failed to remove, we'll catch
+ it later */
+ (void) removefile(&stb, 1);
+ ptarget = optarget;
+ }
+ }
+ if (rename(new, target) >= 0)
+ break;
+ /*FALLTHROUGH*/
+
+ default:
+ error(fmt, new, target, SYSERR);
(void) unlink(new);
+ break;
}
}
- if (wassparse)
- message (MT_NOTICE, "%s: was sparse", target);
-
if (IS_ON(opts, DO_COMPARE))
message(MT_REMOTE|MT_CHANGE, "%s: updated", target);
else
@@ -977,10 +1014,8 @@ static void recvfile(new, opts, mode, owner, group, mtime, atime, size)
/*
* Receive a directory
*/
-static void recvdir(opts, mode, owner, group)
- opt_t opts;
- int mode;
- char *owner, *group;
+static void
+recvdir(opt_t opts, int mode, char *owner, char *group)
{
static char lowner[100], lgroup[100];
char *cp;
@@ -1040,20 +1075,22 @@ static void recvdir(opts, mode, owner, group)
o = (owner[0] == ':') ? opts & DO_NUMCHKOWNER :
opts;
- if ((cp = getusername(stb.st_uid, target, o)))
+ if ((cp = getusername(stb.st_uid, target, o))
+ != NULL)
if (strcmp(owner, cp))
(void) strlcpy(lowner, cp,
- sizeof lowner);
+ sizeof(lowner));
}
if (!IS_ON(opts, DO_NOCHKGROUP) && group) {
int o;
o = (group[0] == ':') ? opts & DO_NUMCHKGROUP :
opts;
- if ((cp = getgroupname(stb.st_gid, target, o)))
+ if ((cp = getgroupname(stb.st_gid, target, o))
+ != NULL)
if (strcmp(group, cp))
(void) strlcpy(lgroup, cp,
- sizeof lgroup);
+ sizeof(lgroup));
}
/*
@@ -1065,12 +1102,12 @@ static void recvdir(opts, mode, owner, group)
(cp = getusername(stb.st_uid,
target, opts)))
(void) strlcpy(lowner, cp,
- sizeof lowner);
+ sizeof(lowner));
if (lgroup[0] == CNULL &&
(cp = getgroupname(stb.st_gid,
target, opts)))
(void) strlcpy(lgroup, cp,
- sizeof lgroup);
+ sizeof(lgroup));
if (IS_ON(opts, DO_VERIFY))
message(MT_NOTICE,
@@ -1128,14 +1165,13 @@ static void recvdir(opts, mode, owner, group)
/*
* Receive a link
*/
-static void recvlink(new, opts, mode, size)
- char *new;
- opt_t opts;
- int mode;
- off_t size;
+static void
+recvlink(char *new, opt_t opts, int mode, off_t size)
{
+ char tbuf[MAXPATHLEN];
struct stat stb;
char *optarget;
+ int uptodate;
off_t i;
/*
@@ -1149,6 +1185,27 @@ static void recvlink(new, opts, mode, size)
return;
}
+ uptodate = 0;
+ if ((i = readlink(target, tbuf, sizeof(tbuf))) != -1) {
+ tbuf[i] = '\0';
+ if (i == size && strncmp(buf, tbuf, (int) size) == 0)
+ uptodate = 1;
+ }
+ mode &= 0777;
+
+ if (IS_ON(opts, DO_VERIFY) || uptodate) {
+ if (uptodate)
+ message(MT_REMOTE|MT_INFO, "");
+ else
+ message(MT_REMOTE|MT_INFO, "%s: need to update",
+ target);
+ if (IS_ON(opts, DO_COMPARE))
+ return;
+ (void) sendcmd(C_END, NULL);
+ (void) response();
+ return;
+ }
+
/*
* Make new symlink using a temporary name
*/
@@ -1162,37 +1219,13 @@ static void recvlink(new, opts, mode, size)
}
/*
- * Do comparison of what link is pointing to if enabled
- */
- mode &= 0777;
- if (IS_ON(opts, DO_COMPARE)) {
- char tbuf[MAXPATHLEN];
-
- if ((i = readlink(target, tbuf, sizeof(tbuf)-1)) != -1)
- tbuf[i] = '\0';
- if (i != -1 && i == size && strncmp(buf, tbuf, (size_t) size) == 0) {
- (void) unlink(new);
- ack();
- return;
- }
- if (IS_ON(opts, DO_VERIFY)) {
- (void) unlink(new);
- message(MT_REMOTE|MT_INFO, "%s: need to update",
- target);
- (void) sendcmd(C_END, NULL);
- (void) response();
- return;
- }
- }
-
- /*
* See if target is a directory and remove it if it is
*/
if (lstat(target, &stb) == 0) {
if (S_ISDIR(stb.st_mode)) {
optarget = ptarget;
for (ptarget = target; *ptarget; ptarget++);
- if (removefile(&stb) < 0) {
+ if (removefile(&stb, 0) < 0) {
ptarget = optarget;
(void) unlink(new);
(void) sendcmd(C_END, NULL);
@@ -1215,10 +1248,7 @@ static void recvlink(new, opts, mode, size)
return;
}
- if (IS_ON(opts, DO_COMPARE))
- message(MT_REMOTE|MT_CHANGE, "%s: updated", target);
- else
- ack();
+ message(MT_REMOTE|MT_CHANGE, "%s: updated", target);
/*
* Indicate end of receive operation
@@ -1230,14 +1260,15 @@ static void recvlink(new, opts, mode, size)
/*
* Creat a hard link to existing file.
*/
-static void hardlink(cmd)
- char *cmd;
+static void
+hardlink(char *cmd)
{
struct stat stb;
int exists = 0;
- char *oldname, *newname;
+ char *xoldname, *xnewname;
char *cp = cmd;
static char expbuf[BUFSIZ];
+ char oldname[BUFSIZ], newname[BUFSIZ];
/* Skip over opts */
(void) strtol(cp, &cp, 8);
@@ -1246,23 +1277,32 @@ static void hardlink(cmd)
return;
}
- oldname = strtok(cp, " ");
- if (oldname == NULL) {
+ xoldname = strtok(cp, " ");
+ if (xoldname == NULL) {
error("hardlink: oldname name not delimited");
return;
}
- newname = strtok(NULL, " ");
- if (newname == NULL) {
+ if (DECODE(oldname, xoldname) == -1) {
+ error("hardlink: Cannot decode oldname");
+ return;
+ }
+
+ xnewname = strtok(NULL, " ");
+ if (xnewname == NULL) {
error("hardlink: new name not specified");
return;
}
+ if (DECODE(newname, xnewname) == -1) {
+ error("hardlink: Cannot decode newname");
+ return;
+ }
+
if (exptilde(expbuf, oldname, sizeof(expbuf)) == NULL) {
error("hardlink: tilde expansion failed");
return;
}
- oldname = expbuf;
if (catname && cattarget(newname) < 0) {
error("Cannot set newname target.");
@@ -1287,7 +1327,7 @@ static void hardlink(cmd)
error("%s: unlink failed: %s", target, SYSERR);
return;
}
- if (link(oldname, target) < 0) {
+ if (link(expbuf, target) < 0) {
error("%s: cannot link to %s: %s", target, oldname, SYSERR);
return;
}
@@ -1302,8 +1342,8 @@ static void hardlink(cmd)
* SC_FREESPACE - Set minimium free space of filesystem
* SC_FREEFILES - Set minimium free number of files of filesystem
*/
-static void setconfig(cmd)
- char *cmd;
+static void
+setconfig(char *cmd)
{
char *cp = cmd;
char *estr;
@@ -1315,7 +1355,7 @@ static void setconfig(cmd)
*/
if (!fromhost) {
fromhost = xstrdup(cp);
- message(MT_SYSLOG, "startup for %s", fromhost);
+ message(MT_SYSLOG, "startup for %s", fromhost);
#if defined(SETARGS) || defined(HAVE_SETPROCTITLE)
setproctitle("serving %s", cp);
#endif /* SETARGS || HAVE_SETPROCTITLE */
@@ -1323,7 +1363,7 @@ static void setconfig(cmd)
break;
case SC_FREESPACE: /* Minimium free space */
- if (!isdigit(*cp)) {
+ if (!isdigit((unsigned char)*cp)) {
fatalerr("Expected digit, got '%s'.", cp);
return;
}
@@ -1331,7 +1371,7 @@ static void setconfig(cmd)
break;
case SC_FREEFILES: /* Minimium free files */
- if (!isdigit(*cp)) {
+ if (!isdigit((unsigned char)*cp)) {
fatalerr("Expected digit, got '%s'.", cp);
return;
}
@@ -1339,13 +1379,21 @@ static void setconfig(cmd)
break;
case SC_LOGGING: /* Logging options */
- if ((estr = msgparseopts(cp, TRUE))) {
+ if ((estr = msgparseopts(cp, TRUE)) != NULL) {
fatalerr("Bad message option string (%s): %s",
cp, estr);
return;
}
break;
+ case SC_DEFOWNER:
+ (void) strlcpy(defowner, cp, sizeof(defowner));
+ break;
+
+ case SC_DEFGROUP:
+ (void) strlcpy(defgroup, cp, sizeof(defgroup));
+ break;
+
default:
message(MT_NOTICE, "Unknown config command \"%s\".", cp-1);
return;
@@ -1355,9 +1403,8 @@ static void setconfig(cmd)
/*
* Receive something
*/
-static void recvit(cmd, type)
- char *cmd;
- int type;
+static void
+recvit(char *cmd, int type)
{
int mode;
opt_t opts;
@@ -1365,6 +1412,7 @@ static void recvit(cmd, type)
time_t mtime, atime;
char *owner, *group, *file;
char new[MAXPATHLEN];
+ char fileb[MAXPATHLEN];
long freespace = -1, freefiles = -1;
char *cp = cmd;
@@ -1432,14 +1480,19 @@ static void recvit(cmd, type)
}
/*
- * Get file name. Can't use strtok() since there could
+ * Get file name. Can't use strtok() since there could
* be white space in the file name.
*/
- file = group + strlen(group) + 1;
- if (file == NULL) {
+ if (DECODE(fileb, group + strlen(group) + 1) == -1) {
+ error("recvit: Cannot decode file name");
+ return;
+ }
+
+ if (fileb[0] == '\0') {
error("recvit: no file name");
return;
}
+ file = fileb;
debugmsg(DM_MISC,
"recvit: opts = %04o mode = %04o size = %d mtime = %d",
@@ -1449,15 +1502,15 @@ static void recvit(cmd, type)
owner, group, file, catname, (type == S_IFDIR) ? 1 : 0);
if (type == S_IFDIR) {
- if (catname >= sizeof(sptarget)) {
+ if ((size_t) catname >= sizeof(sptarget)) {
error("%s: too many directory levels", target);
return;
}
sptarget[catname] = ptarget;
if (catname++) {
*ptarget++ = '/';
- while ((*ptarget++ = *file++))
- ;
+ while ((*ptarget++ = *file++) != '\0')
+ continue;
ptarget--;
}
} else {
@@ -1470,12 +1523,13 @@ static void recvit(cmd, type)
}
file = strrchr(target, '/');
if (file == NULL)
- (void) strlcpy(new, tempname, sizeof new);
+ (void) strlcpy(new, tempname, sizeof(new));
else if (file == target)
- (void) snprintf(new, sizeof new, "/%s", tempname);
+ (void) snprintf(new, sizeof(new), "/%s", tempname);
else {
*file = CNULL;
- (void) snprintf(new, sizeof new, "%s/%s", target, tempname);
+ (void) snprintf(new, sizeof(new), "%s/%s", target,
+ tempname);
*file = '/';
}
(void) mktemp(new);
@@ -1535,14 +1589,93 @@ static void recvit(cmd, type)
}
/*
+ * Chmog something
+ */
+static void
+dochmog(char *cmd)
+{
+ int mode;
+ opt_t opts;
+ char *owner, *group, *file;
+ char *cp = cmd;
+ char fileb[MAXPATHLEN];
+
+ /*
+ * Get rdist option flags
+ */
+ opts = strtol(cp, &cp, 8);
+ if (*cp++ != ' ') {
+ error("dochmog: options not delimited");
+ return;
+ }
+
+ /*
+ * Get file mode
+ */
+ mode = strtol(cp, &cp, 8);
+ if (*cp++ != ' ') {
+ error("dochmog: mode not delimited");
+ return;
+ }
+
+ /*
+ * Get file owner name
+ */
+ owner = strtok(cp, " ");
+ if (owner == NULL) {
+ error("dochmog: owner name not delimited");
+ return;
+ }
+
+ /*
+ * Get file group name
+ */
+ group = strtok(NULL, " ");
+ if (group == NULL) {
+ error("dochmog: group name not delimited");
+ return;
+ }
+
+ /*
+ * Get file name. Can't use strtok() since there could
+ * be white space in the file name.
+ */
+ if (DECODE(fileb, group + strlen(group) + 1) == -1) {
+ error("dochmog: Cannot decode file name");
+ return;
+ }
+
+ if (fileb[0] == '\0') {
+ error("dochmog: no file name");
+ return;
+ }
+ file = fileb;
+
+ debugmsg(DM_MISC,
+ "dochmog: opts = %04o mode = %04o", opts, mode);
+ debugmsg(DM_MISC,
+ "dochmog: owner = '%s' group = '%s' file = '%s' catname = %d",
+ owner, group, file, catname);
+
+ if (catname && cattarget(file) < 0) {
+ error("Cannot set newname target.");
+ return;
+ }
+
+ (void) fchog(-1, target, owner, group, mode);
+
+ ack();
+}
+
+/*
* Set target information
*/
-static void settarget(cmd, isdir)
- char *cmd;
- int isdir;
+static void
+settarget(char *cmd, int isdir)
{
char *cp = cmd;
opt_t opts;
+ char file[BUFSIZ];
catname = isdir;
@@ -1556,6 +1689,11 @@ static void settarget(cmd, isdir)
}
options = opts;
+ if (DECODE(file, cp) == -1) {
+ error("settarget: Cannot decode target name");
+ return;
+ }
+
/*
* Handle target
*/
@@ -1571,7 +1709,8 @@ static void settarget(cmd, isdir)
/*
* Cleanup in preparation for exiting.
*/
-extern void cleanup()
+void
+cleanup(int dummy)
{
/* We don't need to do anything */
}
@@ -1579,25 +1718,23 @@ extern void cleanup()
/*
* Server routine to read requests and process them.
*/
-extern void server()
+void
+server(void)
{
static char cmdbuf[BUFSIZ];
char *cp;
int n;
extern jmp_buf finish_jmpbuf;
- if (setjmp(finish_jmpbuf)) {
- setjmp_ok = FALSE;
+ if (setjmp(finish_jmpbuf))
return;
- }
- setjmp_ok = TRUE;
(void) signal(SIGHUP, sighandler);
(void) signal(SIGINT, sighandler);
(void) signal(SIGQUIT, sighandler);
(void) signal(SIGTERM, sighandler);
(void) signal(SIGPIPE, sighandler);
(void) umask(oumask = umask(0));
- (void) strlcpy(tempname, _RDIST_TMP, sizeof tempname);
+ (void) strlcpy(tempname, _RDIST_TMP, sizeof(tempname));
if (fromhost) {
message(MT_SYSLOG, "Startup for %s", fromhost);
#if defined(SETARGS)
@@ -1611,20 +1748,17 @@ extern void server()
(void) sendcmd(S_VERSION, NULL);
if (remline(cmdbuf, sizeof(cmdbuf), TRUE) < 0) {
- setjmp_ok = FALSE;
error("server: expected control record");
return;
}
- if (cmdbuf[0] != S_VERSION || !isdigit(cmdbuf[1])) {
- setjmp_ok = FALSE;
+ if (cmdbuf[0] != S_VERSION || !isdigit((unsigned char)cmdbuf[1])) {
error("Expected version command, received: \"%s\".", cmdbuf);
return;
}
proto_version = atoi(&cmdbuf[1]);
if (proto_version != VERSION) {
- setjmp_ok = FALSE;
error("Protocol version %d is not supported.", proto_version);
return;
}
@@ -1637,10 +1771,8 @@ extern void server()
*/
for ( ; ; ) {
n = remline(cp = cmdbuf, sizeof(cmdbuf), TRUE);
- if (n == -1) { /* EOF */
- setjmp_ok = FALSE;
+ if (n == -1) /* EOF */
return;
- }
if (n == 0) {
error("server: expected control record");
continue;
@@ -1703,11 +1835,9 @@ extern void server()
docmdspecial();
continue;
-#ifdef DOCHMOD
- case C_CHMOD: /* Set mode */
- dochmod(cp);
+ case C_CHMOG: /* Set owner, group, mode */
+ dochmog(cp);
continue;
-#endif /* DOCHMOD */
case C_ERRMSG: /* Normal error message */
if (cp && *cp)
@@ -1717,7 +1847,6 @@ extern void server()
case C_FERRMSG: /* Fatal error message */
if (cp && *cp)
message(MT_FERROR|MT_NOREMOTE, "%s", cp);
- setjmp_ok = FALSE;
return;
default: