Пример #1
0
/*
 * NAME:	vol->readmdb()
 * DESCRIPTION:	load Master Directory Block into memory
 */
int v_readmdb(hfsvol *vol)
{
    if (l_getmdb(vol, &vol->mdb, 0) == -1)
        goto fail;

    if (vol->mdb.drSigWord != HFS_SIGWORD)
    {
        if (vol->mdb.drSigWord == HFS_SIGWORD_MFS)
            ERROR(EINVAL, "MFS volume format not supported");
        else
            ERROR(EINVAL, "not a Macintosh HFS volume");
    }

    if (vol->mdb.drAlBlkSiz % HFS_BLOCKSZ != 0)
        ERROR(EINVAL, "bad volume allocation block size");

    vol->lpa = vol->mdb.drAlBlkSiz >> HFS_BLOCKSZ_BITS;

    /* extents pseudo-file structs */

    vol->ext.f.cat.u.fil.filStBlk   = vol->mdb.drXTExtRec[0].xdrStABN;
    vol->ext.f.cat.u.fil.filLgLen   = vol->mdb.drXTFlSize;
    vol->ext.f.cat.u.fil.filPyLen   = vol->mdb.drXTFlSize;

    vol->ext.f.cat.u.fil.filCrDat   = vol->mdb.drCrDate;
    vol->ext.f.cat.u.fil.filMdDat   = vol->mdb.drLsMod;

    vol->ext.f.cat.u.fil.filClpSize = vol->mdb.drXTClpSiz;

    memcpy(&vol->ext.f.cat.u.fil.filExtRec,
           &vol->mdb.drXTExtRec, sizeof(ExtDataRec));

    f_selectfork(&vol->ext.f, fkData);

    /* catalog pseudo-file structs */

    vol->cat.f.cat.u.fil.filStBlk   = vol->mdb.drCTExtRec[0].xdrStABN;
    vol->cat.f.cat.u.fil.filLgLen   = vol->mdb.drCTFlSize;
    vol->cat.f.cat.u.fil.filPyLen   = vol->mdb.drCTFlSize;

    vol->cat.f.cat.u.fil.filCrDat   = vol->mdb.drCrDate;
    vol->cat.f.cat.u.fil.filMdDat   = vol->mdb.drLsMod;

    vol->cat.f.cat.u.fil.filClpSize = vol->mdb.drCTClpSiz;

    memcpy(&vol->cat.f.cat.u.fil.filExtRec,
           &vol->mdb.drCTExtRec, sizeof(ExtDataRec));

    f_selectfork(&vol->cat.f, fkData);

    return 0;

fail:
    return -1;
}
Пример #2
0
/*
 * NAME:	main()
 * DESCRIPTION:	program entry
 */
int main(int argc, char *argv[])
{
  char *path;
  int nparts, pnum, result;
  hfsvol vol;

  suid_init();

  if (argc == 2)
    {
      if (strcmp(argv[1], "--version") == 0)
	{
	  printf("%s - %s\n", hfsutils_version, hfsutils_copyright);
	  printf("`%s --license' for licensing information.\n", argv[0]);
	  return 0;
	}
      else if (strcmp(argv[1], "--license") == 0)
	{
	  printf("\n%s", hfsutils_license);
	  return 0;
	}
    }

  options = HFSCK_REPAIR;

  while (1)
    {
      int opt;

      opt = getopt(argc, argv, "vna");
      if (opt == EOF)
	break;

      switch (opt)
	{
	case '?':
	  return usage(argv);

	case 'v':
	  options |= HFSCK_VERBOSE;
	  break;

	case 'n':
	  options &= ~HFSCK_REPAIR;
	  break;

	case 'a':
	  options |= HFSCK_YES;
	  break;
	}
    }

  if (argc - optind < 1 ||
      argc - optind > 2)
    return usage(argv);

  path = argv[optind];

  suid_enable();
  nparts = hfs_nparts(path);
  suid_disable();

  if (nparts == 0)
    {
      fprintf(stderr, "%s: partitioned medium contains no HFS partitions\n",
	      argv[0]);
      return 1;
    }

  if (argc - optind == 2)
    {
      pnum = atoi(argv[optind + 1]);

      if (pnum < 0)
	{
	  fprintf(stderr, "%s: invalid partition number\n", argv[0]);
	  return 1;
	}

      if (nparts == -1 && pnum > 0)
	{
	  fprintf(stderr, "%s: warning: ignoring partition number for"
		  " non-partitioned medium\n", argv[0]);
	  pnum = 0;
	}
      else if (nparts > 0 && pnum == 0)
	{
	  fprintf(stderr, "%s: cannot specify whole medium"
		  " (has %d partition%s)\n", argv[0], nparts,
		  nparts == 1 ? "" : "s");
	  return 1;
	}
      else if (nparts > 0 && pnum > nparts)
	{
	  fprintf(stderr, "%s: invalid partition number (only %d available)\n",
		  argv[0], nparts);
	  return 1;
	}
    }
  else
    {
      if (nparts > 1)
	{
	  fprintf(stderr, "%s: must specify partition number (%d available)\n",
		  argv[0], nparts);
	  return 1;
	}
      else if (nparts == -1)
	pnum = 0;
      else
	pnum = 1;
    }

  v_init(&vol, HFS_OPT_NOCACHE);

  if (REPAIR)
    {
      suid_enable();
      result = v_open(&vol, path, HFS_MODE_RDWR);
      suid_disable();

      if (result == -1)
	{
	  vol.flags |= HFS_VOL_READONLY;

	  suid_enable();
	  result = v_open(&vol, path, HFS_MODE_RDONLY);
	  suid_disable();
	}
    }

  if (result == -1)
    {
      perror(path);
      return 1;
    }

  if (REPAIR && (vol.flags & HFS_VOL_READONLY))
    {
      fprintf(stderr, "%s: warning: %s not writable; cannot repair\n",
	      argv[0], path);

      options &= ~HFSCK_REPAIR;
    }

  if (v_geometry(&vol, pnum) == -1 ||
      l_getmdb(&vol, &vol.mdb, 0) == -1)
    {
      perror(path);
      v_close(&vol);
      return 1;
    }

  result = hfsck(&vol);

  vol.flags |= HFS_VOL_MOUNTED;

  if (v_close(&vol) == -1)
    {
      perror("closing volume");
      return 1;
    }

  return result;
}