/* utxsplit -- makes smaller wtmpx-format files from larger ones Copyright (C) 1999 Ed Cashin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include int main(int argc, char *argv[]) { extern char *optarg; extern int optind; int c, i; int begin = 0; /* beginning utmpx entry (zero-based offsets) */ int end = 0; /* the zero-based offset of the ending entry (zero means do all) */ char *infile = NULL; char *outfile = NULL; struct utmpx utx; int in_fd, out_fd; char *usage = "usage: utxsplit [ -b begin ] [ -e end ] -f {filename} > outfile\n" "... where begin is number of first utmpx record to read\n" " and end is number of last one (0 means do them all)\n" " filename is the utmpx-format file to read entries from\n" " outfile is the new utmpx-format file\n"; while ((c = getopt(argc, argv, "b:e:o:i:")) != EOF) { switch (c) { case 'b': begin = atoi(optarg); break; case 'e': end = atoi(optarg); break; case 'i': infile = strdup(optarg); break; case 'o': outfile = strdup(optarg); break; case '?': fprintf(stderr, usage); exit (2); break; default: break; } /* end switch */ } /* end while */ /* (now optind is the index of any remaining cmd-line args) */ /* don't need to do this because for loop fails on weird values of begin */ // if (begin < 0) /* handle weird begin-end numbers */ // begin = 0; /* don't need to do this: weird end will default to reading to EOF */ // if (end > 0 && end < begin) // end = begin; if ( (! infile) || (! outfile) ) { fprintf(stderr, usage); exit(EXIT_FAILURE); } if ( (in_fd = open(infile, O_RDONLY)) == -1 ) { perror(infile); exit(EXIT_FAILURE); } if ( (out_fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0664)) == -1 ) { perror(outfile); exit(EXIT_FAILURE); } /* while (read(in_fd, &utx, sizeof(utx)) == sizeof(utx)) */ /* printf("user=%s:type=%d\n", utx.ut_user, utx.ut_type); */ for (i = 1; i < begin; ++i) { if (read(in_fd, &utx, sizeof(utx)) != sizeof(utx)) { fprintf(stderr, "no more entries\n"); exit(EXIT_SUCCESS); } } ++end; /* end now points to the number of one _after_ the last one they want */ while ( i++ != end ) { if (read(in_fd, &utx, sizeof(utx)) != sizeof(utx)) { fprintf(stderr, "no more entries\n"); exit(EXIT_SUCCESS); } if (write(out_fd, &utx, sizeof(utx)) == -1) { perror("writing to output"); exit(EXIT_FAILURE); } } if (infile) free(infile); if (outfile) free(outfile); return 0; }