summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-07-01 23:43:13 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-07-01 23:43:13 +0000
commit8e9188479696191bcbea99e619d20f272646b14a (patch)
tree52b974f53f8f1623491d28c9b5269a080fbeac09
parenta250b86f879e0f3153b2c1716629bba602b378cb (diff)
Add support for -a dirs on different filesystems.
From FreeBSD via S. Deinhard.
-rw-r--r--usr.bin/newsyslog/newsyslog.c98
1 files changed, 72 insertions, 26 deletions
diff --git a/usr.bin/newsyslog/newsyslog.c b/usr.bin/newsyslog/newsyslog.c
index 7b3ad5ff1a1..6e6eb7486e6 100644
--- a/usr.bin/newsyslog/newsyslog.c
+++ b/usr.bin/newsyslog/newsyslog.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: newsyslog.c,v 1.73 2003/06/26 21:59:10 deraadt Exp $ */
+/* $OpenBSD: newsyslog.c,v 1.74 2003/07/01 23:43:12 millert Exp $ */
/*
* Copyright (c) 1999, 2002, 2003 Todd C. Miller <Todd.Miller@courtesan.com>
@@ -71,7 +71,7 @@
*/
#ifndef lint
-static const char rcsid[] = "$OpenBSD: newsyslog.c,v 1.73 2003/06/26 21:59:10 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: newsyslog.c,v 1.74 2003/07/01 23:43:12 millert Exp $";
#endif /* not lint */
#ifndef CONF
@@ -160,29 +160,31 @@ char hostname[MAXHOSTNAMELEN]; /* Hostname */
char *daytime; /* timenow in human readable form */
char *arcdir; /* Dir to put archives in (if it exists) */
-void do_entry(struct conf_entry *);
-void parse_args(int, char **);
-void usage(void);
-struct conf_entry *parse_file(int *);
-char *missing_field(char *, char *, int);
-void dotrim(struct conf_entry *);
-int log_trim(char *);
-void compress_log(struct conf_entry *);
-off_t sizefile(char *);
-int age_old_log(struct conf_entry *);
-char *sob(char *);
-char *son(char *);
-int isnumberstr(char *);
-int domonitor(struct conf_entry *);
-FILE *openmail(void);
-void child_killer(int);
-void run_command(char *);
-void send_signal(char *, int);
-char *lstat_log(char *, size_t, int);
-int stat_suffix(char *, size_t, char *, struct stat *,
- int (*)(const char *, struct stat *));
-time_t parse8601(char *);
-time_t parseDWM(char *);
+FILE *openmail(void);
+char *lstat_log(char *, size_t, int);
+char *missing_field(char *, char *, int);
+char *sob(char *);
+char *son(char *);
+int age_old_log(struct conf_entry *);
+int domonitor(struct conf_entry *);
+int isnumberstr(char *);
+int log_trim(char *);
+int movefile(char *, char *, uid_t, gid_t, int);
+int stat_suffix(char *, size_t, char *, struct stat *,
+ int (*)(const char *, struct stat *));
+off_t sizefile(char *);
+struct conf_entry *
+ parse_file(int *);
+time_t parse8601(char *);
+time_t parseDWM(char *);
+void child_killer(int);
+void compress_log(struct conf_entry *);
+void do_entry(struct conf_entry *);
+void dotrim(struct conf_entry *);
+void parse_args(int, char **);
+void run_command(char *);
+void send_signal(char *, int);
+void usage(void);
int
main(int argc, char **argv)
@@ -825,7 +827,8 @@ dotrim(struct conf_entry *ent)
(void)snprintf(file1, sizeof(file1), "%s.0", oldlog);
if (noaction)
printf("\tmv %s to %s\n", ent->log, file1);
- else if (rename(ent->log, file1))
+ else if (movefile(ent->log, file1, ent->uid, ent->gid,
+ ent->permissions))
warn("can't mv %s to %s", ent->log, file1);
}
@@ -1317,3 +1320,46 @@ parseDWM(char *s)
}
return (mktime(&tm));
}
+
+/*
+ * Move a file using rename(2) is possible and copying if not.
+ */
+int
+movefile(char *from, char *to, uid_t owner_uid, gid_t group_gid, int perm)
+{
+ FILE *src, *dst;
+ int i;
+
+ /* try rename(2) first */
+ i = rename(from, to);
+ if (i == 0 || errno != EXDEV)
+ return (i);
+
+ /* different filesystem, have to copy the file */
+ if ((src = fopen(from, "r")) == NULL)
+ err(1, "can't fopen %s for reading", from);
+ if ((dst = fopen(to, "w")) == NULL)
+ err(1, "can't fopen %s for writing", to);
+ if (owner_uid != (uid_t)-1 || group_gid != (gid_t)-1) {
+ if (fchown(fileno(dst), owner_uid, group_gid))
+ err(1, "can't fchown %s", to);
+ }
+ if (fchmod(fileno(dst), perm))
+ err(1, "can't fchmod %s", to);
+
+ while ((i = getc(src)) != EOF) {
+ if ((putc(i, dst)) == EOF)
+ err(1, "error writing to %s", to);
+ }
+
+ if (ferror(src))
+ err(1, "error reading from %s", from);
+ if ((fclose(src)) != 0)
+ err(1, "can't fclose %s", to);
+ if ((fclose(dst)) != 0)
+ err(1, "can't fclose %s", from);
+ if ((unlink(from)) != 0)
+ err(1, "can't unlink %s", from);
+
+ return (0);
+}