home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sbin / fsck / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-20  |  7.0 KB  |  287 lines

  1. /*
  2.  * Copyright (c) 1980, 1986 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)main.c    5.27 (Berkeley) 8/7/90";
  42. #endif /* not lint */
  43.  
  44. #include <sys/param.h>
  45. #include <ufs/dinode.h>
  46. #include <ufs/fs.h>
  47. #include <fstab.h>
  48. #include <stdlib.h>
  49. #include <string.h>
  50. #include <ctype.h>
  51. #include <stdio.h>
  52. #include "fsck.h"
  53.  
  54. void    catch(), catchquit(), voidquit();
  55. int    returntosingle;
  56.  
  57. main(argc, argv)
  58.     int    argc;
  59.     char    *argv[];
  60. {
  61.     int ch;
  62.     int ret, maxrun = 0;
  63.     extern int docheck(), checkfilesys();
  64.     extern char *optarg;
  65.     extern int optind;
  66.  
  67.     sync();
  68.     while ((ch = getopt(argc, argv, "cdpnNyYb:l:m:")) != EOF) {
  69.         switch (ch) {
  70.         case 'p':
  71.             preen++;
  72.             break;
  73.  
  74.         case 'b':
  75.             bflag = argtoi('b', "number", optarg, 10);
  76.             printf("Alternate super block location: %d\n", bflag);
  77.             break;
  78.  
  79.         case 'c':
  80.             cvtflag++;
  81.             break;
  82.  
  83.         case 'd':
  84.             debug++;
  85.             break;
  86.  
  87.         case 'l':
  88.             maxrun = argtoi('l', "number", optarg, 10);
  89.             break;
  90.  
  91.         case 'm':
  92.             lfmode = argtoi('m', "mode", optarg, 8);
  93.             if (lfmode &~ 07777)
  94.                 errexit("bad mode to -m: %o\n", lfmode);
  95.             printf("** lost+found creation mode %o\n", lfmode);
  96.             break;
  97.  
  98.         case 'n':
  99.         case 'N':
  100.             nflag++;
  101.             yflag = 0;
  102.             break;
  103.  
  104.         case 'y':
  105.         case 'Y':
  106.             yflag++;
  107.             nflag = 0;
  108.             break;
  109.  
  110.         default:
  111.             errexit("%c option?\n", ch);
  112.         }
  113.     }
  114.     argc -= optind;
  115.     argv += optind;
  116.     if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  117.         (void)signal(SIGINT, catch);
  118.     if (preen)
  119.         (void)signal(SIGQUIT, catchquit);
  120.     if (argc) {
  121.         while (argc-- > 0)
  122.             (void)checkfilesys(*argv++, (char *)0, 0L, 0);
  123.         exit(0);
  124.     }
  125.     ret = checkfstab(preen, maxrun, docheck, checkfilesys);
  126.     if (returntosingle)
  127.         exit(2);
  128.     exit(ret);
  129. }
  130.  
  131. argtoi(flag, req, str, base)
  132.     int flag;
  133.     char *req, *str;
  134.     int base;
  135. {
  136.     char *cp;
  137.     int ret;
  138.  
  139.     ret = (int)strtol(str, &cp, base);
  140.     if (cp == str || *cp)
  141.         errexit("-%c flag requires a %s\n", flag, req);
  142.     return (ret);
  143. }
  144.  
  145. /*
  146.  * Determine whether a filesystem should be checked.
  147.  */
  148. docheck(fsp)
  149.     register struct fstab *fsp;
  150. {
  151.  
  152.     if (strcmp(fsp->fs_vfstype, "ufs") ||
  153.         (strcmp(fsp->fs_type, FSTAB_RW) &&
  154.          strcmp(fsp->fs_type, FSTAB_RO)) ||
  155.         fsp->fs_passno == 0)
  156.         return (0);
  157.     return (1);
  158. }
  159.  
  160. /*
  161.  * Check the specified filesystem.
  162.  */
  163. /* ARGSUSED */
  164. checkfilesys(filesys, mntpt, auxdata, child)
  165.     char *filesys, *mntpt;
  166.     long auxdata;
  167. {
  168.     daddr_t n_ffree, n_bfree;
  169.     struct dups *dp;
  170.     struct zlncnt *zlnp;
  171.  
  172.     if (preen && child)
  173.         (void)signal(SIGQUIT, voidquit);
  174.     devname = filesys;
  175.     if (debug && preen)
  176.         pwarn("starting\n");
  177.     if (setup(filesys) == 0) {
  178.         if (preen)
  179.             pfatal("CAN'T CHECK FILE SYSTEM.");
  180.         return (0);
  181.     }
  182.     /*
  183.      * 1: scan inodes tallying blocks used
  184.      */
  185.     if (preen == 0) {
  186.         printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
  187.         if (hotroot)
  188.             printf("** Root file system\n");
  189.         printf("** Phase 1 - Check Blocks and Sizes\n");
  190.     }
  191.     pass1();
  192.  
  193.     /*
  194.      * 1b: locate first references to duplicates, if any
  195.      */
  196.     if (duplist) {
  197.         if (preen)
  198.             pfatal("INTERNAL ERROR: dups with -p");
  199.         printf("** Phase 1b - Rescan For More DUPS\n");
  200.         pass1b();
  201.     }
  202.  
  203.     /*
  204.      * 2: traverse directories from root to mark all connected directories
  205.      */
  206.     if (preen == 0)
  207.         printf("** Phase 2 - Check Pathnames\n");
  208.     pass2();
  209.  
  210.     /*
  211.      * 3: scan inodes looking for disconnected directories
  212.      */
  213.     if (preen == 0)
  214.         printf("** Phase 3 - Check Connectivity\n");
  215.     pass3();
  216.  
  217.     /*
  218.      * 4: scan inodes looking for disconnected files; check reference counts
  219.      */
  220.     if (preen == 0)
  221.         printf("** Phase 4 - Check Reference Counts\n");
  222.     pass4();
  223.  
  224.     /*
  225.      * 5: check and repair resource counts in cylinder groups
  226.      */
  227.     if (preen == 0)
  228.         printf("** Phase 5 - Check Cyl groups\n");
  229.     pass5();
  230.  
  231.     /*
  232.      * print out summary statistics
  233.      */
  234.     n_ffree = sblock.fs_cstotal.cs_nffree;
  235.     n_bfree = sblock.fs_cstotal.cs_nbfree;
  236.     pwarn("%ld files, %ld used, %ld free ",
  237.         n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree);
  238.     printf("(%ld frags, %ld blocks, %.1f%% fragmentation)\n",
  239.         n_ffree, n_bfree, (float)(n_ffree * 100) / sblock.fs_dsize);
  240.     if (debug &&
  241.         (n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree))
  242.         printf("%ld files missing\n", n_files);
  243.     if (debug) {
  244.         n_blks += sblock.fs_ncg *
  245.             (cgdmin(&sblock, 0) - cgsblock(&sblock, 0));
  246.         n_blks += cgsblock(&sblock, 0) - cgbase(&sblock, 0);
  247.         n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize);
  248.         if (n_blks -= maxfsblock - (n_ffree + sblock.fs_frag * n_bfree))
  249.             printf("%ld blocks missing\n", n_blks);
  250.         if (duplist != NULL) {
  251.             printf("The following duplicate blocks remain:");
  252.             for (dp = duplist; dp; dp = dp->next)
  253.                 printf(" %ld,", dp->dup);
  254.             printf("\n");
  255.         }
  256.         if (zlnhead != NULL) {
  257.             printf("The following zero link count inodes remain:");
  258.             for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
  259.                 printf(" %lu,", zlnp->zlncnt);
  260.             printf("\n");
  261.         }
  262.     }
  263.     zlnhead = (struct zlncnt *)0;
  264.     duplist = (struct dups *)0;
  265.     inocleanup();
  266.     if (fsmodified) {
  267.         (void)time(&sblock.fs_time);
  268.         sbdirty();
  269.     }
  270.     ckfini();
  271.     free(blockmap);
  272.     free(statemap);
  273.     free((char *)lncntp);
  274.     if (!fsmodified)
  275.         return (0);
  276.     if (!preen) {
  277.         printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
  278.         if (hotroot)
  279.             printf("\n***** REBOOT UNIX *****\n");
  280.     }
  281.     if (hotroot) {
  282.         sync();
  283.         return (4);
  284.     }
  285.     return (0);
  286. }
  287.