home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1359 < prev    next >
Internet Message Format  |  1990-12-28  |  8KB

  1. From: friedl@mtndew.UUCP (Steve Friedl)
  2. Newsgroups: alt.sources
  3. Subject: [comp.unix.questions] Re: Tip about lost+found
  4. Message-ID: <12144@stag.math.lsa.umich.edu>
  5. Date: 21 May 90 19:53:57 GMT
  6.  
  7. Archive-name: mklostandfound/21-May-90
  8. Original-posting-by: friedl@mtndew.UUCP (Steve Friedl)
  9. Original-subject: Re: Tip about lost+found
  10. Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
  11.  
  12. [This is an experimental alt.sources re-posting from the newsgroup(s)
  13. comp.unix.questions. Comments on this service to emv@math.lsa.umich.edu 
  14. (Edward Vielmetti).]
  15.  
  16.  
  17. > Otherwise you'll need
  18. > to increase the number of slots in your lost+found directory (easily
  19. > done by writing a script that creates a whole bunch of empty files in
  20. > that directory and then deletes them again).
  21.  
  22. I make filesystems so often that I got tired of writing the
  23. traditional shell script to make the lost+found directory, and in
  24. the process I ended up writing a C program to do it faster.
  25.  
  26. It turns out that rather than creating a bunch of files, which
  27. involves making lots of inodes, it is much faster to make one
  28. file and then make lots of links to it.  When done this way, the
  29. dominant operation is where it should be: writing directory
  30. entries to extend lost+found.
  31.  
  32. I put this program (included shortly) in /etc/mkl+f and it has
  33. proved to be really handy.  What I'd like to know is why in the
  34. world doesn't mkfs build a populated lost+found when it makes
  35. the filesystem?  It seems to me to be the ideal place for it
  36. (at least by request with some command-line option).
  37.  
  38. Another tip: make your lost+found directory drwx------.
  39. Otherwise, secret files that previously relied on protected
  40. parent directories suddenly can find themselves out in the open.
  41. A few packages (CrystalWriter, for instance), stick their trash
  42. files in lost+found, so do this only if you know you can.
  43.  
  44. The program follows:
  45.  
  46. #---------------------------------- cut here -------------------------
  47.  
  48. /*
  49.  * mkl+f.c
  50.  *
  51.  * written by :    Stephen J. Friedl
  52.  *        Software Consultant
  53.  *        Tustin, CA  92680
  54.  *        uunet!mtndew!friedl
  55.  *
  56.  * Description:
  57.  *
  58.  *    This makes a lot of directory entries in the current directory.
  59.  *    It starts by creat()ing the file ..000 and linking all the rest
  60.  *    to it.  This method is over twice as fast as creat()ing the files
  61.  *    one at a time.  This is because a creat() has to make an entire
  62.  *    inode, while a link just updates the directory and one inode's
  63.  *    link count.  All the files are removed when done.  The program
  64.  *    exits on errors.
  65.  *
  66.  *    This program probably won't work on a BSD or SVR4.0 system.
  67.  *
  68.  *     ===NOTE=== This program is in the public domain and can be
  69.  *    used by any person for any reason with no restrictions
  70.  *    whatsoever.  Have fun, folks.
  71.  *
  72.  * HISTORY
  73.  *     Tue Jan 28 23:22:53 PST 1986 by SJF
  74.  *    > created
  75.  */
  76. #include    <stdio.h>
  77. #include    <string.h>
  78. #include    <fcntl.h>
  79. #include    <errno.h>
  80. #include    <sys/types.h>
  81. #include    <sys/stat.h>
  82.  
  83. /*----------------------------------------------------------------------
  84.  * this is the desired size of the lost+found directory
  85.  */
  86. #define        L_F_SIZE    (4*1024)    /* size of directory    */
  87.  
  88. #ifdef    __STDC__
  89. #  include    <stdlib.h>
  90. #  include    <stdarg.h>
  91. #  define    Void        void
  92. #  define    PROTO(name,args) name ( args )
  93. #else
  94. #  include    <varargs.h>
  95. #  define    Void        char
  96. #  define    const        /*nothing*/
  97. #  define    PROTO(name,args) name ( )
  98.  
  99. extern char *malloc();
  100. extern void exit();
  101. #endif
  102.  
  103. #ifndef    EXIT_SUCCESS
  104. #  define    EXIT_SUCCESS    0
  105. #  define    EXIT_FAILURE    1
  106. #endif
  107.  
  108. #define        fpr        (void)fprintf
  109. #define        spr        (void)sprintf
  110.  
  111. /*----------------------------------------------------------------------
  112.  * We keep a list of all files created here so we can remove them later.
  113.  * We don't do any bounds checking when adding a new name to the list
  114.  * because we statically allocate enough up front.
  115.  */
  116. #define        savefile(fname)        (FileTbl[Nfiles++] = strsave(fname))
  117.  
  118. static char const    *FileTbl[L_F_SIZE];    /* list of files    */
  119. static int        Nfiles = 0;        /* # of elements in above */
  120.  
  121.  
  122.  
  123. static char const     *ProgName,        /* program name        */
  124.             *LinkFile;        /* file to link to    */
  125. static int        dot_fd;            /* fildes of current dir */
  126.  
  127. static PROTO(long dot_size, ( void ) );
  128. static PROTO(char *strsave, ( char const * ) );
  129. static PROTO(void die,        ( char const *, ... ) );
  130.  
  131. /*ARGSUSED*/
  132. main(argc, argv)
  133. int    argc;
  134. char    *argv[];
  135. {
  136. int    i, fd;
  137.  
  138.     ProgName = argv[0];
  139.  
  140.     /*--------------------------------------------------------------
  141.      * open the current directory so we can get the size quickly
  142.      * without having to know the size of a directory entry (feature).
  143.      */
  144.     if (dot_fd = open(".", O_RDONLY), dot_fd < 0)
  145.         die("can't open current directory (errno = %d)", errno);
  146.  
  147.     /*--------------------------------------------------------------
  148.      * are we already done?
  149.      */
  150.     if (dot_size() >= L_F_SIZE)
  151.         die("current directory is already large enough");
  152.  
  153.     /*--------------------------------------------------------------
  154.      * first touch the first file and die on error.
  155.      */
  156.     LinkFile = "..000";
  157.  
  158.     if (fd = creat(LinkFile, 0), fd < 0)
  159.         die("can't create initial file %s (errno = %d)", LinkFile);
  160.     (void)close(fd);
  161.     savefile(LinkFile);
  162.  
  163.     /*--------------------------------------------------------------
  164.      * now loop while the size is not enough.  Before we make a
  165.      * new link, make sure we're not trashing some current file.
  166.      */
  167.     while (dot_size() < L_F_SIZE)
  168.     {
  169.     char        buf[100];
  170.     static int    counter = 0;
  171.  
  172.         spr(buf, "..%03d", counter++);
  173.         if (file_exists(buf))
  174.             continue;
  175.         if (link(LinkFile, buf) != 0)
  176.             die("can't link(\"%s\", \"%s\") (errno=%d)", LinkFile,
  177.               buf, errno);
  178.         savefile(buf);
  179.     }
  180.     (void)close(dot_fd);
  181.  
  182.     /*--------------------------------------------------------------
  183.      * now clean up all the files we previously created.
  184.      */
  185.     for (i = 0; i < Nfiles; i++)
  186.     {
  187.     char const *fname = FileTbl[i];
  188.  
  189.         if (unlink(fname) != 0)
  190.             die("can't unlink(\"%s\") - errno=%d", fname, errno);
  191.     }
  192.  
  193.     exit(EXIT_SUCCESS);
  194.     /* NOTREACHED */
  195. }
  196.  
  197. /* 
  198.  * exists()
  199.  *
  200.  *    Given a filename, return TRUE if the file exists and
  201.  *    FALSE if not.  If we're able to stat the file, we assume
  202.  *    that the file exists...
  203.  */
  204. static int
  205. file_exists(fname)
  206. char const *fname;
  207. {
  208. struct stat    stbuf;
  209.  
  210.     return(stat(fname, &stbuf) == 0);
  211. }
  212.  
  213. /*
  214.  * strsave()
  215.  *
  216.  *    Given a string, save it into managed memory
  217.  */
  218. static char *
  219. strsave(str)
  220. char const *str;
  221. {
  222. char *p;
  223.  
  224.     if (p = malloc(strlen(str)+1), p == NULL)
  225.         die("out of memory in strsave()");
  226.     return(strcpy(p, str));
  227. }
  228.  
  229. /*
  230.  * dot_size()
  231.  *
  232.  *    Return the size of the current directory.  Die
  233.  *    if we can't find it (this should never happen).
  234.  */
  235. static long
  236. dot_size()
  237. {
  238. struct stat    stbuf;
  239.  
  240.     if (fstat(dot_fd, &stbuf) < 0)
  241.         die("cannot stat current dir (errno = %d)", errno);
  242.     return(stbuf.st_size);
  243. }
  244.  
  245. /*
  246.  * die()
  247.  *
  248.  *    Given a printf-style argument list, format a message to the
  249.  *    standard error stream including the program name, then exit
  250.  *    with a failure status
  251.  */
  252.  
  253. #ifdef    __STDC__
  254.  
  255. static void
  256. die(char const *format, ...)
  257. {
  258. va_list    args;
  259.  
  260.     (void)fprintf(stderr, "%s: ", ProgName);
  261.  
  262.     va_start(args, format);
  263.     (void)vfprintf(stderr, format, args);
  264.     va_end(args);
  265.  
  266.     (void)fputc('\n', stderr);
  267.     exit(EXIT_FAILURE);
  268. }
  269.  
  270. #else /*__STDC__*/
  271.  
  272. /*VARARGS*/
  273. static void
  274. die(va_alist)
  275. va_dcl
  276. {
  277. va_list    args;
  278. char    *format;
  279.  
  280.     (void)fprintf(stderr, "%s: ", ProgName);
  281.  
  282.     va_start(args);
  283.     format = va_arg(args, char *);
  284.     (void)vfprintf(stderr, format, args);
  285.     va_end(args);
  286.  
  287.     (void)fputc('\n', stderr);
  288.     exit(EXIT_FAILURE);
  289. }
  290.  
  291. #endif     /* __STDC__ */
  292.  
  293. #---------------------------------- cut here -------------------------
  294.  
  295.  
  296. -- 
  297. Stephen J. Friedl, KA8CMY / Software Consultant / Tustin, CA / 3B2-kind-of-guy
  298. +1 714 544 6561 voice   /   friedl@vsi.com   /   {uunet,attmail}!mtndew!friedl
  299.  
  300. What's Spaf gonna do if Purdue hires RTM?
  301.