Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!olivea!uunet!zephyr.ens.tek.com!tektronix!percy!percival.rain.com!nerd From: nerd@percival.rain.com (Michael Galassi) Newsgroups: comp.sys.next Subject: Re: Trimmer for /usr/adm/wtmp Message-ID: <1991Jun19.162436.13902@percy.rain.com> Date: 19 Jun 91 16:24:36 GMT References: <1991Jun19.022344.26696@agate.berkeley.edu> Sender: news@percy.rain.com (news maintainer) Organization: Percy's UNIX, Portland, OR. Lines: 102 Nntp-Posting-Host: percival.rain.com izumi@pinoko.berkeley.edu (Izumi Ohzawa) writes: >Here's a little more reasonable file trimmer for /usr/adm/wtmp file. >With the default monthly script (/usr/adm/monthly), the wtmp file >is wiped clean on the first of each month. It also wipes out >/usr/adm/lastlog, which shouldn't be necessary (lastlog doesn't grow). You got it right there, whoever wrote monthly was asleep. I use a slightly more paranoid program which is somewhat faster. It only does one read of the wtmp file and stores the part to keep in a malloced buffer. This works nicely as the wtmp structure is only 36 bytes so even keeping 5000 entries only consumes 176 K. cheers, -m --- cut here for wtrim, watch out for .signature at the end --- /* ** by Michael Galassi -- nerd@percival.rain.com ** this is public domain, you can even say you wrote it, ** I don't care compile with: ** cc -ansi -O wtrim.c -o wtrim -object -s */ #include #include #include #include #include #define WTMP "/usr/adm/wtmp" #define OWTMP "/usr/adm/wtmp.old" #define DEFTRIM 1000 void main(int argc, char *argv[]) { int size; int fd; struct stat st; struct utmp *ptr; if (argc == 2) size = atoi(argv[1]) * sizeof(struct utmp); else if (argc == 1) size = DEFTRIM * sizeof(struct utmp); else { fprintf(stderr, "usage: %s [count]\n", argv[0]); exit(1); } if (stat(WTMP, &st) < 0) { fprintf(stderr, "%s: can't stat " WTMP "\n", argv[0]); exit(1); } if (st.st_size <= size) /* already OK */ exit(0); if ((fd = open(WTMP, O_CREAT|O_RDWR, 0644)) < 0) { fprintf(stderr, "%s: can't open " WTMP "\n", argv[0]); exit(1); } if (lseek(fd, st.st_size - size, L_SET) != st.st_size - size) { fprintf(stderr, "%s: can't lseek in " WTMP "\n", argv[0]); close(fd); exit(1); } if ((ptr = (struct utmp *) malloc(size)) == (void *)NULL) { fprintf(stderr, "%s: can't malloc %d bytes\n", argv[0], size); close(fd); exit(1); } if (read(fd, ptr, size) != size) { fprintf(stderr, "%s: can't malloc %d bytes\n", argv[0], size); free(ptr); close(fd); exit(1); } close(fd); unlink(OWTMP); if (rename(WTMP, OWTMP) < 0) { fprintf(stderr, "%s: can't rename " WTMP " to " OWTMP "\n", argv[0]); free(ptr); exit(1); } if ((fd = open(WTMP, O_CREAT|O_WRONLY, 0644)) < 0) { fprintf(stderr, "%s: can't open new " WTMP "\n", argv[0]); free(ptr); rename(OWTMP, WTMP); exit(1); } if (write(fd, ptr, size) != size) { fprintf(stderr, "%s: can't write new " WTMP "\n", argv[0]); free(ptr); close(fd); unlink(WTMP); rename(OWTMP, WTMP); exit(1); } close(fd); free(ptr); exit(0); } -- Michael Galassi | nerd@percival.rain.com MS-DOS: The ultimate PC virus. | ...!tektronix!percy!nerd