home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mm / ccmd / pwcrunch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-18  |  4.0 KB  |  170 lines

  1. /*
  2.  Copyright (c) 1986, 1990 by The Trustees of Columbia University in
  3.  the City of New York.  Permission is granted to any individual or
  4.  institution to use, copy, or redistribute this software so long as it
  5.  is not sold for profit, provided this copyright notice is retained.
  6.  
  7. */
  8. /*
  9.  * program to create a passwd.crunch file.  This is a passwd table which can
  10.  * be read into memory very quickly.  Note this file is presorted by username.
  11.  * it format is:
  12.  * bytes 1-4: number passwd entries in the passwd file -- written as
  13.  *        write(fd, &int, sizeof(int) -- that is, byteswapped on a vax.
  14.  * n bytes:  passwd entries, with all string pointers as offsets into a single
  15.  *        buffer.  This section will be of size:
  16.  *            (n * sizeof struct passwd)
  17.  *         where n is the number of passwd entries read in above.
  18.  * the rest of the file contains all of the strings from these passwd entries.
  19.  * the address of the buffer this is read into should be added to all of 
  20.  * the pointer fields in each passwd entry.
  21.  */
  22.  
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include <sys/file.h>
  26. #include <stdio.h>
  27. #include <pwd.h>
  28.  
  29. #define GROW 100
  30. #define BUFGROW 1000
  31.  
  32. static struct passwd *ents;
  33. static char *buf;
  34. static int howmany = 0;
  35. static int buflen = 0;
  36. static int used = 0;
  37. static max = 0;
  38. char *malloc(), *realloc();
  39.  
  40. main(argc,argv) 
  41. int argc;
  42. char **argv;
  43. {
  44.     char buf[100];
  45.  
  46.     switch(argc) {
  47.     case 1:
  48.     crunchpw("/etc/passwd.crunch");
  49.     break;
  50.     case 2:
  51.     crunchpw(argv[1]);
  52.     break;
  53.     default:
  54.     fprintf(stderr,"usage: crunchpw [crunchfile]");
  55.     break;
  56.     }
  57. }
  58.  
  59. crunchpw(tofile) {
  60.     struct passwd *p;
  61.     struct stat b1, b2;
  62.  
  63.     if (stat("/etc/passwd", &b1) != 0) {
  64.     perror("/etc/passwd");
  65.     exit(1);
  66.     }
  67.     if (stat(tofile, &b2) == 0 && b2.st_mtime > b1.st_mtime)
  68.     exit(0);
  69.     while(p = getpwent())        /* for all entries */
  70.     crunchpwent(p);            /* compact it */
  71.     write_crunchfile(tofile);        /* write out compacted version */
  72. }
  73.  
  74. /*
  75.  * compact a single passwd entry
  76.  */
  77. crunchpwent(p) 
  78. struct passwd *p;
  79. {
  80.     struct passwd *p1;
  81.  
  82.     if (howmany == max)            /* make space if we need it */
  83.     grow_entries();
  84.     p1 = &ents[howmany];
  85.     bcopy(p,p1,sizeof(struct passwd));    /* copy all the data */
  86.     copystr(&p1->pw_name);        /* and then all of the strings */
  87.     copystr(&p1->pw_passwd);        /* but fix the string ptrs as we go */
  88. #ifdef SYSV
  89.     copystr(&p1->pw_age);
  90. #endif
  91.     copystr(&p1->pw_comment);
  92.     copystr(&p1->pw_gecos);
  93.     copystr(&p1->pw_dir);
  94.     copystr(&p1->pw_shell);
  95.     howmany++;
  96. }
  97.  
  98. /*
  99.  * make more space for entries.
  100.  * we want a contiguous table.
  101.  */
  102. grow_entries() {
  103.     max += GROW;
  104.     if (ents == NULL) {
  105.     ents = (struct passwd *) malloc((max)*sizeof(struct passwd));
  106.     }
  107.     else {
  108.     ents = (struct passwd *) realloc(ents,(max)*sizeof(struct passwd));
  109.     }
  110. }
  111.  
  112. /*
  113.  * copy the string into the buffer we are making, and set the string pointer
  114.  * to be the index into that buffer.
  115.  */
  116. copystr(s)
  117. char **s;
  118. {
  119.     if (used + strlen(*s) > buflen) {    /* expand buffer if necessary */
  120.     buflen += BUFGROW;
  121.     if (buf == NULL) buf = malloc(buflen);
  122.     else buf = realloc(buf,buflen);
  123.     }
  124.     strcpy(&buf[used], *s);        /* copy the string */
  125.     *s = (char *) used;            /* set ptr to be the index */
  126.     used += strlen(&buf[used])+1;    /* count the space */
  127. }
  128.  
  129. pwcmp(p1,p2)
  130. register struct passwd *p1,*p2;
  131. {
  132.     register char *b1 = &buf[(int)p1->pw_name], *b2 = &buf[(int)p2->pw_name];
  133.     return(strcmp(b1,b2));
  134. }
  135.  
  136. /*
  137.  * write out the compacted file
  138.  */
  139. write_crunchfile(tofile) {
  140.     int fd;
  141.     fd = open(tofile,O_WRONLY|O_CREAT,0444);
  142.     if (fd == -1) {
  143.     perror(tofile);
  144.     exit(1);
  145.     }
  146.     xwrite(fd,&howmany,sizeof(howmany)); /* write how many entries */
  147.     qsort(ents, howmany, sizeof(struct passwd), pwcmp);
  148.     xwrite(fd,ents,sizeof(struct passwd)*howmany); /* write the entries */
  149.     xwrite(fd,buf,used);        /* write the strings */
  150.     close(fd);
  151. }
  152.  
  153. xwrite(fd,buf,len)
  154. int fd,len;
  155. char *buf;
  156. {
  157.     int sofar = 0,x;
  158.  
  159.     while(sofar < len) {
  160.     x = write(fd, buf+sofar, len - sofar);
  161.     if (x == -1) {
  162.         perror("write");
  163.         return(-1);
  164.     }
  165.     sofar += x;
  166.     }
  167.     return(len);
  168. }
  169.  
  170.