Репозиторий Sisyphus
Последнее обновление: 21 октября 2021 | Пакетов: 17367 | Посещений: 22125746
en ru br
Репозитории ALT
S:0.3-alt5
5.1: 0.3-alt2
4.1: 0.3-alt2
4.0: 0.3-alt2
3.0: 0.3-alt1
www.altlinux.org/Changes

Группа :: Работа с файлами
Пакет: stmpclean

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: stmpclean-0.3-owl-fixes.patch
Скачать


diff -urpN stmpclean-0.3.orig/Makefile stmpclean-0.3/Makefile
--- stmpclean-0.3.orig/Makefile	Fri Mar 21 21:58:00 2003
+++ stmpclean-0.3/Makefile	Wed Jun 11 20:32:26 2003
@@ -2,24 +2,29 @@
 # Written by Stanislav Shalunov.
 # $Id: Makefile,v 1.6 2003/03/21 21:58:00 shalunov Exp $
 
-PREFIX=/usr/local
-BINDIR=$(PREFIX)/sbin
-MANDIR=$(PREFIX)/man/man8
+CC = gcc
+LD = gcc
+CFLAGS = -O2 -fomit-frame-pointer -Wall -W -pedantic
+LDFLAGS = -s
 
-CFLAGS += -O6 -Wall -W -pedantic
+DESTDIR =
+PREFIX = /usr/local
+SBINDIR = $(PREFIX)/sbin
+MANDIR = $(PREFIX)/man
 
 all:		stmpclean stmpclean.0
 
-install:	all
-	if [ ! -d $(BINDIR) ] ; then mkdir -p -m 0755 $(BINDIR); fi
-	if [ ! -d $(MANDIR) ] ; then mkdir -p -m 0755 $(MANDIR); fi
-	install -c -o 0 -g 0 -m 0555 stmpclean $(BINDIR)/
-	install -c -o 0 -g 0 -m 0444 stmpclean.8 $(MANDIR)/
+install:	stmpclean
+	mkdir -p -m 755 $(DESTDIR)$(SBINDIR) $(DESTDIR)$(MANDIR)/man8
+	install -m 700 stmpclean $(DESTDIR)$(SBINDIR)/
+	ln -s stmpclean $(DESTDIR)$(SBINDIR)/tmpwatch
+	install -m 644 stmpclean.8 tmpwatch.8 $(DESTDIR)$(MANDIR)/man8/
 
 stmpclean.o:	stmpclean.c
+	$(CC) $(CFLAGS) -c stmpclean.c
 
 stmpclean:	stmpclean.o
-	$(CC) -o stmpclean stmpclean.o && strip stmpclean
+	$(LD) $(LDFLAGS) -o stmpclean stmpclean.o
 
 stmpclean.0:	stmpclean.8
 	nroff -mandoc stmpclean.8 > stmpclean.0
diff -urpN stmpclean-0.3.orig/stmpclean.8 stmpclean-0.3/stmpclean.8
--- stmpclean-0.3.orig/stmpclean.8	Fri Mar 21 21:44:09 2003
+++ stmpclean-0.3/stmpclean.8	Wed Jun 11 21:40:54 2003
@@ -4,7 +4,9 @@
 .\"
 .\"	$Id: stmpclean.8,v 1.6 2003/03/21 21:44:09 shalunov Exp $
 .\"
-.Dd August 1999
+.\" Last updated on 2003/06/11 by Solar Designer <solar@owl.openwall.com>
+.\"
+.Dd June 2003
 .Dt STMPCLEAN 8
 .Os
 .Sh NAME
@@ -85,21 +87,21 @@ as
 .Pp
 In FreeBSD
 .Nm
-invokation should be placed into the file
+invocation should be placed into the file
 .Pa /etc/periodic/daily/110.clean-tmps .
 In other versions of BSD it should go into the
 .Pa /etc/daily
 script.
-In Linux, check if you have
-.Pa /etc/periodic ,
-and if not, you can just run it from cron; usually you'd have to edit
-.Pa /etc/crontab .
+On LSB-compliant Linux distributions, the invocation of
+.Nm
+may be placed in a script under
+.Pa /etc/cron.daily .
 .Sh SEE ALSO
 .Xr cron 8
 .Sh BUGS
 When
 .Nm
-removes a file from a directory, modification time of the directory
+scans a directory, access time of the directory
 changes and it looks new to
 .Nm
 when it examines it later (if the directory became empty).  Thus,
diff -urpN stmpclean-0.3.orig/stmpclean.c stmpclean-0.3/stmpclean.c
--- stmpclean-0.3.orig/stmpclean.c	Tue Jun 10 19:07:45 2003
+++ stmpclean-0.3/stmpclean.c	Mon Jun 28 17:37:32 2004
@@ -1,9 +1,9 @@
 /*
  * stmpclean.c -- remove old files from a world-writable directory.
  * Written by Stanislav Shalunov, http://www.internet2.edu/~shalunov/
- * 
+ *
  * Copyright (C)  1999, Stanislav Shalunov.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -42,6 +42,7 @@ static const char rcsid[] =
 "$Id: stmpclean.c,v 1.13 2003/06/10 19:07:45 shalunov Exp $";
 #endif
 
+#define _GNU_SOURCE
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/resource.h>
@@ -56,7 +57,16 @@ static const char rcsid[] =
 #include <fcntl.h>
 #include <dirent.h>
 #include <time.h>
+#include <grp.h>
 #include <errno.h>
+#include <libgen.h>
+
+#ifndef O_DIRECTORY
+#define O_DIRECTORY 0
+#endif
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW 0
+#endif
 
 /*
  * How deep to descend into directories?  Won't go any deeper than MAX_DEPTH
@@ -69,13 +79,15 @@ static const char rcsid[] =
 #define SECONDS_IN_A_DAY    (SECONDS_IN_AN_HOUR * 24)
 #define SECONDS_IN_A_WEEK   (SECONDS_IN_A_DAY * 7)
 
-#define GETCWD {if (getcwd(cwd, MAXPATHLEN) == NULL)\
+#define GETCWD {if (getcwd(cwd, sizeof(cwd)) == NULL) \
 		strcpy(cwd, "/FULL/PATH/TOO/LONG");}
 
+/* Are we emulating tmpwatch? */
+static int      am_tmpwatch;
 /* Time at the start of the program, in seconds since beginning of epoch. */
 static time_t   now;
-/* Minimum age (mtime) of a file or empty directory to be deleted. */
-int             minage;
+/* Minimum age (atime) of a file or empty directory to be deleted. */
+static int      minage;
 /* Current working directory is used for logging purposes only. */
 static char     cwd[MAXPATHLEN];
 /* Flag: be verbose? */
@@ -83,8 +95,13 @@ static int      verbose = 0;
 
 /* Print usage message, exit with a failure. */
 void
-usage()
+usage(void)
 {
+	if (am_tmpwatch) {
+		fprintf(stderr, "stmpclean: "
+			"Don't know how to emulate these tmpwatch options.\n");
+		exit(1);
+	}
 	fprintf(stderr,
 		"Usage: stmpclean [-t <timespec>] dir1 [dir2 [dir3]...]]\n\n"
 		"Where time specification <timespec> is a string like 1w\n"
@@ -96,9 +113,10 @@ usage()
 }
 
 /*
- * Parse time specification (a la sendmail queue time), return its value in
- * seconds, or -1 if the spec is invalid.
- * 
+ * Parse time specification (a la sendmail queue time or number of hours
+ * when doing tmpwatch emulation), return its value in seconds, or -1 if
+ * the spec is invalid.
+ *
  * Side effects: Modifies contents of timespec.
  */
 int
@@ -107,14 +125,16 @@ parse_time(timespec)
 {
 	char           *p, *q;
 	char            symbol;
-	int             result, num, multiple;
+	int             result, num, multiple, seconds;
 
 	result = 0;
 	p = timespec;
 	while (*p) {
-		if (!isdigit(*p))
+		if (!isdigit((int)(unsigned char)*p))
+			return -1;
+		for (q = p; isdigit((int)(unsigned char)*q); q++);
+		if (q == p || q - p > 9)
 			return -1;
-		for (q = p; isdigit(*q); q++);
 		symbol = *q;
 		*q = 0;
 		num = atoi(p);
@@ -124,6 +144,8 @@ parse_time(timespec)
 		 * didn't want to have strdup()s here all around, did you?
 		 */
 		*q = symbol;
+		if (am_tmpwatch && symbol)
+			return -1;
 		switch (symbol) {
 		case 'w':
 			multiple = SECONDS_IN_A_WEEK;
@@ -131,6 +153,11 @@ parse_time(timespec)
 		case 'd':
 			multiple = SECONDS_IN_A_DAY;
 			break;
+		case '\0':
+			if (!am_tmpwatch)
+				return -1;
+			q--;
+			/* FALLTHROUGH */
 		case 'h':
 			multiple = SECONDS_IN_AN_HOUR;
 			break;
@@ -143,8 +170,11 @@ parse_time(timespec)
 		default:
 			return -1;
 		}
-		result += num * multiple;
-		if (result < 0)
+		seconds = num * multiple;
+		if (seconds < 0 || seconds / multiple != num)
+			return -1;
+		result += seconds;
+		if (result < seconds)
 			return -1;
 		p = q + 1;
 	}
@@ -157,14 +187,18 @@ setecreds(uid, gid)
 	uid_t           uid;
 	gid_t           gid;
 {
+	gid_t groups[2];
+
+	groups[0] = groups[1] = gid;
 	if (geteuid()) {
-		if ((seteuid(uid) == -1) || (setegid(gid) == -1)) {
+		if (seteuid(uid) || setegid(gid) ||
+		    (uid == 0 && setgroups(1, groups))) {
 			syslog(LOG_ERR, "cannot set EUID/EGID to %d/%d, exiting",
 			       uid, gid);
 			exit(1);
 		}
 	} else {
-		if ((setegid(gid) == -1) || (seteuid(uid) == -1)) {
+		if (setgroups(1, groups) || setegid(gid) || seteuid(uid)) {
 			syslog(LOG_ERR, "cannot set EUID/EGID to %d/%d, exiting",
 			       uid, gid);
 			exit(1);
@@ -201,13 +235,13 @@ isemptydir(dir)
 }
 
 /*
- * Recursively clean directory DIR, descending no deeper than MAX_DEPTH.
+ * Recursively clean directory DIR, descending no deeper than DEPTH.
  * Exit with a failure if a race condition is detected.
  */
 void
-clean_dir(dir, depth)
+clean_dir(dir, depth, specified)
 	char           *dir;
-	int             depth;
+	int             depth, specified;
 {
 	struct stat     st, st_after;
 	int             dir_fd, dot_dot_fd;
@@ -224,7 +258,9 @@ clean_dir(dir, depth)
 		       "reached maximum depth (%d)", dir, cwd, MAX_DEPTH);
 		return;
 	}
-	if (lstat(dir, &st) == -1) {
+	if ((specified ? stat(dir, &st) : lstat(dir, &st)) == -1) {
+		if (errno == ENOENT && !specified)
+			return;
 		GETCWD;
 		syslog(LOG_ERR, "RACE?: lstat(\"%s\") in %s failed: %m, "
 		       "exiting", dir, cwd);
@@ -236,8 +272,11 @@ clean_dir(dir, depth)
 		       dir, cwd);
 		exit(1);
 	}
-	dir_fd = open(dir, O_RDONLY);
+	dir_fd = open(dir, O_RDONLY | O_NONBLOCK | O_DIRECTORY |
+		(specified ? 0 : O_NOFOLLOW));
 	if (dir_fd == -1) {
+		if (errno == ENOENT)
+			return;
 		GETCWD;
 		syslog(LOG_ERR,
 		       "RACE?: cannot open(\"%s\"): %m (lstat was OK), "
@@ -264,7 +303,8 @@ clean_dir(dir, depth)
 	 * We'll chdir up later once done with recursive descend. Hence the
 	 * name.
 	 */
-	dot_dot_fd = open(".", O_RDONLY);
+	dot_dot_fd = open(".",
+		O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_NOFOLLOW);
 	if (dot_dot_fd == -1) {
 		GETCWD;
 		syslog(LOG_ERR, "open(\".\") in %s: %m, exiting", cwd);
@@ -294,6 +334,8 @@ clean_dir(dir, depth)
 		if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))
 			continue;
 		if (lstat(dp->d_name, &st) == -1) {
+			if (errno == ENOENT)
+				continue;
 			GETCWD;
 			syslog(LOG_ERR, "RACE?: lstat(\"%s\") in %s: %m, "
 			       "exiting", dp->d_name, cwd);
@@ -303,11 +345,18 @@ clean_dir(dir, depth)
 			/* Looking at a directory. */
 			if (isemptydir(dp->d_name)) {
 				/* Looking at an empty directory. */
-				if (now - st.st_mtime > minage && st.st_uid) {
+				if (now - st.st_atime > minage && st.st_uid) {
 					/* An old non-root owned directory. */
 					setecreds(st.st_uid, st.st_gid);
 					if (rmdir(dp->d_name) == -1
-					    && errno != EACCES) {
+					    && errno != ENOENT
+					    && errno != EACCES
+					    && errno != EPERM) {
+						if (errno == ENOTEMPTY) {
+							setecreds(0, 0);
+							goto notempty;
+						}
+						setecreds(0, 0);
 						GETCWD;
 						syslog(LOG_ERR, "RACE?: rmdir"
 						       "(\"%s\") in %s: %m, "
@@ -323,16 +372,16 @@ clean_dir(dir, depth)
 					setecreds(0, 0);
 				}
 			} else {
+notempty:
 				/*
 				 * Looking at a non-empty directory. Clean it
 				 * recursively (call ourselves).
 				 */
-				clean_dir(dp->d_name, depth - 1);
+				clean_dir(dp->d_name, depth - 1, 0);
 			}
 		} else {
 			/* Looking at a non-directory. */
-			if ((now - st.st_mtime > minage)
-			    && (now - st.st_ctime > minage)
+			if ((now - st.st_atime > minage)
 			    && st.st_uid
 			    && (st.st_nlink == 1)
 			    && (((st.st_mode & S_IFMT) == S_IFREG)
@@ -342,7 +391,11 @@ clean_dir(dir, depth)
 				 * symlink.
 				 */
 				setecreds(st.st_uid, st.st_gid);
-				if (unlink(dp->d_name) == -1) {
+				if (unlink(dp->d_name) == -1
+				    && errno != ENOENT
+				    && errno != EACCES
+				    && errno != EPERM) {
+					setecreds(0, 0);
 					GETCWD;
 					syslog(LOG_ERR, "RACE?: unlink(\"%s\")"
 					       "in %s: %m, exiting",
@@ -377,15 +430,27 @@ main(argc, argv)
 	/* By default, delete files older than three days. */
 	extern char    *optarg;
 	extern int      optind;
+	char           *me;
 	int             c, i;
 	struct rlimit   rlp;
 
 	if (argc <= 0)
 		usage();
+	me = strdup(argv[0]);
+	if (!me) {
+		errno = ENOMEM;
+		perror("strdup");
+		exit(1);
+	}
+	am_tmpwatch = !strcmp(basename(me), "tmpwatch");
 	openlog("stmpclean", LOG_PID | LOG_CONS | LOG_PERROR, LOG_DAEMON);
 	minage = SECONDS_IN_A_DAY * 3;
-	while ((c = getopt(argc, argv, "vt:")) != -1)
+	while ((c = getopt(argc, argv, am_tmpwatch ? "uafv" : "vt:")) != -1)
 		switch (c) {
+		case 'u':
+		case 'a':
+		case 'f':
+			break;
 		case 't':
 			minage = parse_time(optarg);
 			if (minage == -1)
@@ -399,8 +464,14 @@ main(argc, argv)
 		}
 	argc -= optind;
 	argv += optind;
-	if (argc <= 0)
+	if (argc <= (am_tmpwatch ? 1 : 0))
 		usage();
+	if (am_tmpwatch) {
+		argc--;
+		minage = parse_time(*argv++);
+		if (minage == -1)
+			usage();
+	}
 	/*
 	 * For logging niceties in case one of the directories on the command
 	 * line is bad.
@@ -422,7 +493,7 @@ main(argc, argv)
 			exit(1);
 		}
 	for (i = 0; i < argc; i++)
-		clean_dir(argv[i], MAX_DEPTH);
+		clean_dir(argv[i], MAX_DEPTH, 1);
 	exit(0);
 	/* NOTREACHED */
 }
diff -urpN stmpclean-0.3.orig/tmpwatch.8 stmpclean-0.3/tmpwatch.8
--- stmpclean-0.3.orig/tmpwatch.8	Thu Jan  1 00:00:00 1970
+++ stmpclean-0.3/tmpwatch.8	Sat Mar 30 00:24:51 2002
@@ -0,0 +1 @@
+.so man8/stmpclean.8
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin