Exemple #1
0
/*
 * NAME:	vol->mkdir()
 * DESCRIPTION:	create a new HFS directory
 */
int v_mkdir(hfsvol *vol, long parid, const char *name)
{
    CatKeyRec key;
    CatDataRec data;
    long id;
    byte record[HFS_MAX_CATRECLEN];
    int i, reclen;

    if (bt_space(&vol->cat, 2) == -1)
        goto fail;

    id = vol->mdb.drNxtCNID++;
    vol->flags |= HFS_VOL_UPDATE_MDB;

    /* create directory record */

    data.cdrType   = cdrDirRec;
    data.cdrResrv2 = 0;

    data.u.dir.dirFlags = 0;
    data.u.dir.dirVal   = 0;
    data.u.dir.dirDirID = id;
    data.u.dir.dirCrDat = d_mtime(time(0));
    data.u.dir.dirMdDat = data.u.dir.dirCrDat;
    data.u.dir.dirBkDat = 0;

    memset(&data.u.dir.dirUsrInfo,  0, sizeof(data.u.dir.dirUsrInfo));
    memset(&data.u.dir.dirFndrInfo, 0, sizeof(data.u.dir.dirFndrInfo));
    for (i = 0; i < 4; ++i)
        data.u.dir.dirResrv[i] = 0;

    r_makecatkey(&key, parid, name);
    r_packcatrec(&key, &data, record, &reclen);

    if (bt_insert(&vol->cat, record, reclen) == -1)
        goto fail;

    /* create thread record */

    data.cdrType   = cdrThdRec;
    data.cdrResrv2 = 0;

    data.u.dthd.thdResrv[0] = 0;
    data.u.dthd.thdResrv[1] = 0;
    data.u.dthd.thdParID    = parid;
    strcpy(data.u.dthd.thdCName, name);

    r_makecatkey(&key, id, "");
    r_packcatrec(&key, &data, record, &reclen);

    if (bt_insert(&vol->cat, record, reclen) == -1 ||
            v_adjvalence(vol, parid, 1, 1) == -1)
        goto fail;

    return 0;

fail:
    return -1;
}
Exemple #2
0
	void BItree<Dtype>::bt_insert(TreeNode*& root, TreeNode* n) {
		if (root == NULL) {
			root = n;
			return;
		}

		if (n->val < root->val) {
			bt_insert(root->left, n);
		}
		else {
			bt_insert(root->right, n);
		}
	}
Exemple #3
0
int main (int argc, char *argv[]) {
	
	struct node *tree = NULL;
	struct node *lookup;
	struct in_addr ip;
	int idx;
	int random;
	char text[64];
	
	printf ("Binary tree test\n");
	
	for (idx = 0; idx < 10; idx++) {
		sprintf (text, "chiave %d", rand() % 16);
		bt_insert (&tree, text, &ip, idx);
	}
	
	printf ("Printing\n");
	print_tree (tree);
	
	for (idx = 0; idx < 16; idx++) {
		sprintf (text, "chiave %d", idx);
		lookup = bt_search (tree, text);
		if (lookup == NULL)
			printf ("%s not found\n", text);
		else
			printf ("%s has been found with idx %d\n", lookup->key, lookup->expires);
	}
	
	bt_delete_tree (tree);
	
	printf ("Done\n");
	
}
Exemple #4
0
void test_bt_1(CuTest* tc) {
	int val;
	int i;
	bt* tree;

	tree = bt_new(sizeof(int), 4);

	printf("Empty:\n");
	bt_print(tree, print_int);
	printf("\n");

	{
		int vals[] = { 10, 5, 100, 10, 50, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 200,200,200,200,200,250,150 };
		for (i=0; i<sizeof(vals)/sizeof(int); i++) {
			val = vals[i];
			printf("Insert %i:\n", val);
			bt_insert(tree, &val, 0, compare_ints);
			//bt_print(tree, print_int);
			printf("\n");
		}
	}

	printf("Values: ");
	for (i=0; i<tree->N; i++) {
        int val = *(int*)bt_access(tree, i);
		printf("%i ", val);
        // these tests depend on the values in the "vals" array above.
        if (i < 11) {
            CuAssertIntEquals(tc, 1, val);
        } else if (i < 12) {
            CuAssertIntEquals(tc, 5, val);
        } else if (i < 14) {
            CuAssertIntEquals(tc, 10, val);
        } else if (i < 16) {
            CuAssertIntEquals(tc, 50, val);
        } else if (i < 17) {
            CuAssertIntEquals(tc, 100, val);
        } else if (i < 18) {
            CuAssertIntEquals(tc, 150, val);
        } else if (i < 23) {
            CuAssertIntEquals(tc, 200, val);
        } else {
            CuAssertIntEquals(tc, 250, val);
        }
	}
	printf("\n");

	{
		int vals[] = { 0, 1, 2, 9, 10, 11, 49, 50, 51, 99, 100, 101, 149, 150, 151, 199, 200, 201, 249, 250, 251 };
        int doesit[]={ 0, 1, 0, 0, 1,   0,  0,  1,  0,  0,   1,   0,   0,   1,   0,   0,   1,   0,   0,   1,   0 };
		for (i=0; i<sizeof(vals)/sizeof(int); i++) {
            int youthink;
			val = vals[i];
            youthink = bt_contains(tree, &val, compare_ints);
			printf("Contains %i: %s\n", val, (youthink ? "yes" : "no"));
            CuAssertIntEquals(tc, doesit[i], youthink);
		}
	}
	bt_free(tree);
}
TREE_NODE bt_insert(element_type element, BTREE T){

  TREE_NODE tmp;

  if(T == NULL){
    return new_node(element);
  }
  else{
    if(element < T->element){
      tmp = bt_insert(element, T->left);
      T->left = tmp;
    }
    if(element > T->element){
      tmp = bt_insert(element, T->right);
      T->right = tmp;
    }
    return T;
  }
}
Exemple #6
0
static int rdbLoadRow(FILE *fp, bt *btr) {
    void   *UUbuf;
    uint32  ssize;
    if ((ssize = rdbLoadLen(fp, NULL)) == REDIS_RDB_LENERR) return -1;
    void *bt_val = UU(btr) ? &UUbuf : bt_malloc(ssize, btr);
    if (fread(bt_val, ssize, 1, fp) == 0) return -1;
    if (btr->numkeys == TRANSITION_ONE_MAX) {
        btr = abt_resize(btr, TRANSITION_TWO_BTREE);
    }
    if UU(btr) bt_insert(btr, UUbuf);
    else       bt_insert(btr, bt_val);
BTREE creat_tree(element_type *array, int total, BTREE T){

  int i;
  BTREE p;

  T->element = *array;
  p = T;

  for(i=1; i<total; i++)
    bt_insert(*(array+i), p); 

  return T;

}
Exemple #8
0
/* Moves P around in BT to compensate for its key having
   changed.  Returns a null pointer if successful.  If P's new
   value is equal to that of some other node in BT, returns the
   other node after removing P from BT.

   This function is an optimization only if it is likely that P
   can actually retain its relative position in BT, e.g. its key
   has only been adjusted slightly.  Otherwise, it is more
   efficient to simply remove P from BT, change its key, and
   re-insert P.

   It is not safe to update more than one node's key, then to
   call this function for each node.  Instead, update a single
   node's key, call this function, update another node's key, and
   so on.  Alternatively, remove all affected nodes from the
   tree, update their keys, then re-insert all of them. */
struct bt_node *
bt_changed (struct bt *bt, struct bt_node *p)
{
  struct bt_node *prev = bt_prev (bt, p);
  struct bt_node *next = bt_next (bt, p);

  if ((prev != NULL && bt->compare (prev, p, bt->aux) >= 0)
      || (next != NULL && bt->compare (p, next, bt->aux) >= 0))
    {
      bt_delete (bt, p);
      return bt_insert (bt, p);
    }
  return NULL;
 }
TREE_NODE bt_insert(element_type element, BTREE T){
  
  if(T == NULL){
    T = (TREE_NODE)malloc(sizeof(struct btree_node));
    if(T == NULL){
      printf("insert malloc error\n");
      exit(1);
    }
    else{
      T->element = element;
      T->left = NULL;
      T->right = NULL;
    }
  }
  else
  if(element < T->element){
    T->left = bt_insert(element, T->left);
  }
  else
  if(element > T->element){
    T->right = bt_insert(element, T->right);
  } 
  return T; 
}
Exemple #10
0
void test_bt_many(CuTest* tc) {
	int val;
	int i;
	bt* tree;

	printf("Inserting many items...\n");
	tree = bt_new(sizeof(int), 32);
	for (i=0; i<100000; i++) {
		val = rand() % 1000;
		bt_insert(tree, &val, 0, compare_ints);
		//bt_check(tree);
	}
	printf("Checking...\n");
	CuAssertIntEquals(tc, 0, bt_check(tree));
	printf("Done.\n");
	
	bt_free(tree);
}
int main(int argc, char *argv[]){

  element_type array[20];
  int i;
  BTREE T = NULL;
  
  for(i=0; i<20; i++){
    array[i] = random(200);
    printf("%d ", array[i]);
    T = bt_insert(array[i], T);
  }
  printf("\n");
  
  inorder(T);
  printf("\n");

  treefree(T);
  return 0;
}
smcp_node_t
smcp_node_init(
	smcp_node_t self, smcp_node_t node, const char* name
) {
	smcp_node_t ret = NULL;

	require(self || (self = smcp_node_alloc()), bail);

	ret = (smcp_node_t)self;

	ret->request_handler = (void*)&smcp_default_request_handler;

	if (node) {
		require(name, bail);
		ret->name = name;
#if SMCP_NODE_ROUTER_USE_BTREE
		bt_insert(
			(void**)&((smcp_node_t)node)->children,
			ret,
			(bt_compare_func_t)smcp_node_compare,
			(bt_delete_func_t)smcp_node_delete,
			NULL
		);
#else
		ll_prepend(
			(void**)&((smcp_node_t)node)->children,
			(void*)ret
		);
#endif
		ret->parent = node;
	}

	DEBUG_PRINTF("%s: %p",__func__,ret);

bail:
	return ret;
}
Exemple #13
0
/*
 * NAME:	hfs->rename()
 * DESCRIPTION:	change the name of and/or move a file or directory
 */
int hfs_rename(hfsvol *vol, const char *srcpath, const char *dstpath)
{
  hfsvol *srcvol;
  CatDataRec src, dst;
  unsigned long srcid, dstid;
  CatKeyRec key;
  char srcname[HFS_MAX_FLEN + 1], dstname[HFS_MAX_FLEN + 1];
  byte record[HFS_MAX_CATRECLEN];
  unsigned int reclen;
  int found, isdir, moving;
  node n;

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, srcpath, &src, &srcid, srcname, 0) <= 0)
    goto fail;

  isdir  = (src.cdrType == cdrDirRec);
  srcvol = vol;

  found = v_resolve(&vol, dstpath, &dst, &dstid, dstname, 0);
  if (found == -1)
    goto fail;

  if (vol != srcvol)
    ERROR(EINVAL, "can't move across volumes");

  if (dstid == 0)
    ERROR(ENOENT, "bad destination path");

  if (found &&
      dst.cdrType == cdrDirRec &&
      dst.u.dir.dirDirID != src.u.dir.dirDirID)
    {
      dstid = dst.u.dir.dirDirID;
      strcpy(dstname, srcname);

      found = v_catsearch(vol, dstid, dstname, 0, 0, 0);
      if (found == -1)
	goto fail;
    }

  moving = (srcid != dstid);

  if (found)
    {
      const char *ptr;

      ptr = strrchr(dstpath, ':');
      if (ptr == 0)
	ptr = dstpath;
      else
	++ptr;

      if (*ptr)
	strcpy(dstname, ptr);

      if (! moving && strcmp(srcname, dstname) == 0)
	goto done;  /* source and destination are identical */

      if (moving || d_relstring(srcname, dstname))
	ERROR(EEXIST, "can't use destination name");
    }

  /* can't move anything into the root directory's parent */

  if (moving && dstid == HFS_CNID_ROOTPAR)
    ERROR(EINVAL, "can't move above root directory");

  if (moving && isdir)
    {
      unsigned long id;

      /* can't move root directory anywhere */

      if (src.u.dir.dirDirID == HFS_CNID_ROOTDIR)
	ERROR(EINVAL, "can't move root directory");

      /* make sure we aren't trying to move a directory inside itself */

      for (id = dstid; id != HFS_CNID_ROOTDIR; id = dst.u.dthd.thdParID)
	{
	  if (id == src.u.dir.dirDirID)
	    ERROR(EINVAL, "can't move directory inside itself");

	  if (v_getdthread(vol, id, &dst, 0) <= 0)
	    goto fail;
	}
    }

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  /* change volume name */

  if (dstid == HFS_CNID_ROOTPAR)
    {
      if (! validvname(dstname))
	goto fail;

      strcpy(vol->mdb.drVN, dstname);
      vol->flags |= HFS_VOL_UPDATE_MDB;
    }

  /* remove source record */

  r_makecatkey(&key, srcid, srcname);
  r_packcatkey(&key, record, 0);

  if (bt_delete(&vol->cat, record) == -1)
    goto fail;

  /* insert destination record */

  r_makecatkey(&key, dstid, dstname);
  r_packcatrec(&key, &src, record, &reclen);

  if (bt_insert(&vol->cat, record, reclen) == -1)
    goto fail;

  /* update thread record */

  if (isdir)
    {
      if (v_getdthread(vol, src.u.dir.dirDirID, &dst, &n) <= 0)
	goto fail;

      dst.u.dthd.thdParID = dstid;
      strcpy(dst.u.dthd.thdCName, dstname);

      if (v_putcatrec(&dst, &n) == -1)
	goto fail;
    }
  else
    {
      found = v_getfthread(vol, src.u.fil.filFlNum, &dst, &n);
      if (found == -1)
	goto fail;

      if (found)
	{
	  dst.u.fthd.fthdParID = dstid;
	  strcpy(dst.u.fthd.fthdCName, dstname);

	  if (v_putcatrec(&dst, &n) == -1)
	    goto fail;
	}
    }

  /* update directory valences */

  if (moving)
    {
      if (v_adjvalence(vol, srcid, isdir, -1) == -1 ||
	  v_adjvalence(vol, dstid, isdir,  1) == -1)
	goto fail;
    }

done:
  return 0;

fail:
  return -1;
}
Exemple #14
0
int
main() {
    struct bt_node *root;
    int i, n;

    root = bt_node_new(651);
#if 0
    n = 20;
    /*
    for(i = n; i >= 1; --i) {
    	root = bt_insert(root, i, i+1);
    	bt_dump(root);
    }
    printf("----------------\n");

    root = bt_node_new(5);
    */
    for(i = 1; i <= n; ++i) {
        root = bt_insert(root, i, i+1);
    }
    bt_dump(root);
    printf("----------------\n");
    bt_save(root, "/tmp/large.bin");
    root = bt_load("/tmp/large.bin");
    bt_dump(root);
    return 0;
#endif

    n = 1000*1000;
    //n = 20;
#if 1
    struct timespec t0, t1, t2, t3, t4;

    clock_gettime(CLOCK_MONOTONIC, &t0);
    //for(i = n; i >= 1; i--) {
    for(i = 1; i < n; i++) {
        struct bt_entry *e;
        char *key = calloc(20, 1);
        sprintf(key, "key-%d", i);
        root = bt_insert(root, key, strlen(key), i+1, 0);
        continue;
        e = bt_lookup(root, key, strlen(key)); /* immediate read-back */
        if(e && e->value_offset != (uint32_t)i+1) {
            printf("at k=[%d]: %d\n", i, e->value_offset);
        }
    }
    clock_gettime(CLOCK_MONOTONIC, &t1);
    printf("saving index of %d elements.\n", n);
    bt_save(root, "/tmp/large.bin");
    clock_gettime(CLOCK_MONOTONIC, &t2);
//	bt_dump(root);
    bt_free(root);
    printf("saved.\n");
    uint32_t offset, size;
    char *key = malloc(40);
    sprintf(key, "key-%d", 1 + (rand() % (n-1)));

    if(0 == bt_find("/tmp/large.bin", key, strlen(key), &offset, &size)) {
        printf("%s: offset=%d, size=%d\n", key, (int)offset, (int)size);
    } else {
        printf("could not find %s\n", key);
    }
    return 0;
//	root = bt_load("/tmp/large.bin");
//	clock_gettime(CLOCK_MONOTONIC, &t3);
//	printf("loaded.\n");
    bt_dump(root);

    for(i = 1; i < n; i++) {
        char *key = calloc(20, 1);
        sprintf(key, "key-%d", i);
        struct bt_entry *e = bt_lookup(root, key, strlen(key)); /* read-back after the whole insertion */
        if(!e) {
            printf("e=nil.\n");
        } else if(e->value_offset != (uint32_t)i+1) {
            printf("at k=[%d]: %d\n", i, e->value_offset);
        }
    }
    clock_gettime(CLOCK_MONOTONIC, &t4);
    printf("checked.\n");

    float mili0 = t0.tv_sec * 1000 + t0.tv_nsec / 1000000;
    float mili1 = t1.tv_sec * 1000 + t1.tv_nsec / 1000000;
    float mili2 = t2.tv_sec * 1000 + t2.tv_nsec / 1000000;
    float mili3 = t3.tv_sec * 1000 + t3.tv_nsec / 1000000;
    float mili4 = t4.tv_sec * 1000 + t4.tv_nsec / 1000000;

    printf("build time: %0.2f sec.\n", (mili1 - mili0)/1000.0);
    printf("dump time: %0.2f sec.\n", (mili2 - mili1)/1000.0);
    printf("reload time: %0.2f sec.\n", (mili3 - mili2)/1000.0);
    printf("check time: %0.2f sec.\n", (mili4 - mili3)/1000.0);

    /*
    root = bt_node_new(5);
    bt_insert(root, 706);
    bt_insert(root, 176);
    bt_insert(root, 601);
    bt_insert(root, 153);
    bt_insert(root, 513);
    bt_insert(root, 773);
    */

#endif
    return EXIT_SUCCESS;
}
Exemple #15
0
void catalog_before_commit(bool is_commit)
{
/*
 * Final journal commit. Done by single transaction at a time
 */
    if (!is_commit) { return; }

    try {
        catalog_journal_record *r;
        xptr *tree;
        bt_key name;
        char * htname;

        catalog_validate_objects();

        catalog_lock_metadata();

        cs_initp();
        r = local_catalog->catalog_journal;
        while (r != NULL) {
            switch (r->type) {
              case catalog_journal_record::add_name:
                tree = &(CATALOG_NAME_TREE(r->nor.object_type));
                name.setnew(r->nor.name_to_save->name);
                if (*tree == XNULL) { *tree = bt_create(xs_string); }
                bt_insert(*tree, name, r->nor.name_to_save->obj->p);
                break;

              case catalog_journal_record::del_name:
                tree = &(CATALOG_NAME_TREE(r->nor.object_type));
                name.setnew(r->nor.name_to_save->name);
                bt_delete(*tree, name, r->nor.name_to_save->obj->p);
                htname = catalog_ht_fullname_string(r->nor.object_type, r->nor.name_to_save->name, NULL);
                local_catalog->masterdata.htable = sbtrie_delete_str(local_catalog->masterdata.htable, htname);
                free(htname);
                break;

              case catalog_journal_record::add_htable_record:
                local_catalog->masterdata.htable = sbtrie_insert_str(local_catalog->masterdata.htable, r->htr.name, r->htr.data, strlen(r->htr.data) + 2, true);
                break;
            }

            r = r->next;
            local_catalog->masterdata_updated = true;
        }

        local_catalog->catalog_journal = NULL;

        if (local_catalog->masterdata_updated) {
            WRITEP(catalog_masterblock);

            memcpy(
                &(((catalog_master_record *) XADDR(catalog_masterblock))->masterdata),
                &(local_catalog->masterdata),
                sizeof(catalog_name_trees));

            local_catalog->masterdata_updated = false;
        }

        if (!tr_globals::is_ro_mode) {
            WRITEP(catalog_masterblock);

            memcpy(
                &(((catalog_master_record *) XADDR(catalog_masterblock))->last_nid_size),
                &last_nid_size,
                sizeof(int));

            memcpy(
                ((catalog_master_record *) XADDR(catalog_masterblock))->last_nid,
                last_nid,
                last_nid_size);
        }
    } catch (ANY_SE_EXCEPTION) {
        catalog_unlock_metadata();
        throw;
    }
}
Exemple #16
0
/*
 * NAME:	file->alloc()
 * DESCRIPTION:	reserve disk blocks for a file
 */
int f_alloc(hfsfile *file)
{
  hfsvol *vol = file->vol;
  ExtDescriptor blocks;
  ExtDataRec *extrec;
  unsigned long *pylen, clumpsz;
  unsigned int start, end;
  node n;
  int i;

  clumpsz = file->clump;
  if (clumpsz == 0)
    clumpsz = vol->mdb.drClpSiz;

  blocks.xdrNumABlks = clumpsz / vol->mdb.drAlBlkSiz;

  if (v_allocblocks(vol, &blocks) < 0)
    return -1;

  /* update the file's extents */

  f_getptrs(file, 0, &pylen, &extrec);

  start  = file->fabn;
  end    = *pylen / vol->mdb.drAlBlkSiz;

  n.nnum = 0;
  i      = -1;

  while (start < end)
    {
      for (i = 0; i < 3; ++i)
	{
	  unsigned int num;

	  num    = file->ext[i].xdrNumABlks;
	  start += num;

	  if (start == end)
	    break;
	  else if (start > end)
	    {
	      v_freeblocks(vol, &blocks);
	      ERROR(EIO, "file extents exceed file physical length");
	      return -1;
	    }
	  else if (num == 0)
	    {
	      v_freeblocks(vol, &blocks);
	      ERROR(EIO, "empty file extent");
	      return -1;
	    }
	}

      if (start == end)
	break;

      if (v_extsearch(file, start, &file->ext, &n) <= 0)
	{
	  v_freeblocks(vol, &blocks);
	  return -1;
	}

      file->fabn = start;
    }

  if (i >= 0 &&
      file->ext[i].xdrStABN + file->ext[i].xdrNumABlks == blocks.xdrStABN)
    file->ext[i].xdrNumABlks += blocks.xdrNumABlks;
  else
    {
      /* create a new extent descriptor */

      if (++i < 3)
	file->ext[i] = blocks;
      else
	{
	  ExtKeyRec key;
	  unsigned char record[HFS_EXTRECMAXLEN];
	  int reclen;

	  /* record is full; create a new one */

	  file->ext[0] = blocks;

	  for (i = 1; i < 3; ++i)
	    {
	      file->ext[i].xdrStABN    = 0;
	      file->ext[i].xdrNumABlks = 0;
	    }

	  file->fabn = start;

	  r_makeextkey(&key, file->fork, file->cat.u.fil.filFlNum, end);
	  r_packextkey(&key, record, &reclen);
	  r_packextdata(&file->ext, HFS_RECDATA(record), &reclen);

	  if (bt_insert(&vol->ext, record, reclen) < 0)
	    {
	      v_freeblocks(vol, &blocks);
	      return -1;
	    }

	  i = -1;
	}
    }

  if (i >= 0)
    {
      /* store the modified extent record */

      if (file->fabn)
	{
	  if ((n.nnum == 0 &&
	       v_extsearch(file, file->fabn, 0, &n) <= 0) ||
	      v_putextrec(&file->ext, &n) < 0)
	    {
	      v_freeblocks(vol, &blocks);
	      return -1;
	    }
	}
      else
	memcpy(extrec, file->ext, sizeof(ExtDataRec));
    }

  *pylen += blocks.xdrNumABlks * vol->mdb.drAlBlkSiz;

  file->flags |= HFS_UPDATE_CATREC;

  return blocks.xdrNumABlks;
}
Exemple #17
0
		void btTreeInsert(Dtype e) { bt_insert(root, e); }
Exemple #18
0
	void BItree<Dtype>::bt_insert(TreeNode*& root, Dtype e) {
		bt_insert(root, new TreeNode(e));
	}
Exemple #19
0
int hfs_callback_format(oscallback func, void* cookie, int mode,
	const char* vname)
#endif
{
  hfsvol vol;
  btree *ext = &vol.ext;
  btree *cat = &vol.cat;
  unsigned int i, *badalloc = 0;

  v_init(&vol, mode);

  if (! validvname(vname))
    goto fail;

#ifdef CP_NOT_USED
  if (v_open(&vol, path, HFS_MODE_RDWR) == -1 ||
      v_geometry(&vol, pnum) == -1)
    goto fail;
#else
  if (v_callback_open(&vol, func, cookie) != 0 ||
	  v_geometry(&vol, 0) != 0)
	goto fail;
#endif

  /* initialize volume geometry */

  vol.lpa = 1 + ((vol.vlen - 6) >> 16);

  if (vol.flags & HFS_OPT_2048)
    vol.lpa = (vol.lpa + 3) & ~3;

  vol.vbmsz = (vol.vlen / vol.lpa + 0x0fff) >> 12;

  vol.mdb.drSigWord  = HFS_SIGWORD;
  vol.mdb.drCrDate   = d_mtime(time(0));
  vol.mdb.drLsMod    = vol.mdb.drCrDate;
  vol.mdb.drAtrb     = 0;
  vol.mdb.drNmFls    = 0;
  vol.mdb.drVBMSt    = 3;
  vol.mdb.drAllocPtr = 0;

  vol.mdb.drAlBlkSiz = vol.lpa << HFS_BLOCKSZ_BITS;
  vol.mdb.drClpSiz   = vol.mdb.drAlBlkSiz << 2;
  vol.mdb.drAlBlSt   = vol.mdb.drVBMSt + vol.vbmsz;

  if (vol.flags & HFS_OPT_2048)
    vol.mdb.drAlBlSt = ((vol.vstart & 3) + vol.mdb.drAlBlSt + 3) & ~3;

  vol.mdb.drNmAlBlks = (vol.vlen - 2 - vol.mdb.drAlBlSt) / vol.lpa;

  vol.mdb.drNxtCNID  = HFS_CNID_ROOTDIR;  /* modified later */
  vol.mdb.drFreeBks  = vol.mdb.drNmAlBlks;

  strcpy(vol.mdb.drVN, vname);

  vol.mdb.drVolBkUp  = 0;
  vol.mdb.drVSeqNum  = 0;
  vol.mdb.drWrCnt    = 0;

  vol.mdb.drXTClpSiz = vol.mdb.drNmAlBlks / 128 * vol.mdb.drAlBlkSiz;
  vol.mdb.drCTClpSiz = vol.mdb.drXTClpSiz;

  vol.mdb.drNmRtDirs = 0;
  vol.mdb.drFilCnt   = 0;
  vol.mdb.drDirCnt   = -1;  /* incremented when root directory is created */

  for (i = 0; i < 8; ++i)
    vol.mdb.drFndrInfo[i] = 0;

  vol.mdb.drEmbedSigWord            = 0x0000;
  vol.mdb.drEmbedExtent.xdrStABN    = 0;
  vol.mdb.drEmbedExtent.xdrNumABlks = 0;

  /* vol.mdb.drXTFlSize */
  /* vol.mdb.drCTFlSize */

  /* vol.mdb.drXTExtRec[0..2] */
  /* vol.mdb.drCTExtRec[0..2] */

  vol.flags |= HFS_VOL_UPDATE_MDB | HFS_VOL_UPDATE_ALTMDB;

  /* initialize volume bitmap */

  vol.vbm = ALLOC(block, vol.vbmsz);
  if (vol.vbm == 0)
    ERROR(ENOMEM, 0);

  memset(vol.vbm, 0, vol.vbmsz << HFS_BLOCKSZ_BITS);

  vol.flags |= HFS_VOL_UPDATE_VBM;

  /* perform initial bad block sparing */

#ifdef CP_NOT_USED
  if (nbadblocks > 0)
    {
      if (nbadblocks * 4 > vol.vlen)
	ERROR(EINVAL, "volume contains too many bad blocks");

      badalloc = ALLOC(unsigned int, nbadblocks);
      if (badalloc == 0)
	ERROR(ENOMEM, 0);

      if (vol.mdb.drNmAlBlks == 1594)
	vol.mdb.drFreeBks = --vol.mdb.drNmAlBlks;

      for (i = 0; i < nbadblocks; ++i)
	{
	  unsigned long bnum;
	  unsigned int anum;

	  bnum = badblocks[i];

	  if (bnum < vol.mdb.drAlBlSt || bnum == vol.vlen - 2)
	    ERROR(EINVAL, "can't spare critical bad block");
	  else if (bnum >= vol.vlen)
	    ERROR(EINVAL, "bad block not in volume");

	  anum = (bnum - vol.mdb.drAlBlSt) / vol.lpa;

	  if (anum < vol.mdb.drNmAlBlks)
	    BMSET(vol.vbm, anum);

	  badalloc[i] = anum;
	}

      vol.mdb.drAtrb |= HFS_ATRB_BBSPARED;
    }
#endif

  /* create extents overflow file */

  n_init(&ext->hdrnd, ext, ndHdrNode, 0);

  ext->hdrnd.nnum       = 0;
  ext->hdrnd.nd.ndNRecs = 3;
  ext->hdrnd.roff[1]    = 0x078;
  ext->hdrnd.roff[2]    = 0x0f8;
  ext->hdrnd.roff[3]    = 0x1f8;

  memset(HFS_NODEREC(ext->hdrnd, 1), 0, 128);

  ext->hdr.bthDepth    = 0;
  ext->hdr.bthRoot     = 0;
  ext->hdr.bthNRecs    = 0;
  ext->hdr.bthFNode    = 0;
  ext->hdr.bthLNode    = 0;
  ext->hdr.bthNodeSize = HFS_BLOCKSZ;
  ext->hdr.bthKeyLen   = 0x07;
  ext->hdr.bthNNodes   = 0;
  ext->hdr.bthFree     = 0;
  for (i = 0; i < 76; ++i)
    ext->hdr.bthResv[i] = 0;

  ext->map = ALLOC(byte, HFS_MAP1SZ);
  if (ext->map == 0)
    ERROR(ENOMEM, 0);

  memset(ext->map, 0, HFS_MAP1SZ);
  BMSET(ext->map, 0);

  ext->mapsz = HFS_MAP1SZ;
  ext->flags = HFS_BT_UPDATE_HDR;

  /* create catalog file */

  n_init(&cat->hdrnd, cat, ndHdrNode, 0);

  cat->hdrnd.nnum       = 0;
  cat->hdrnd.nd.ndNRecs = 3;
  cat->hdrnd.roff[1]    = 0x078;
  cat->hdrnd.roff[2]    = 0x0f8;
  cat->hdrnd.roff[3]    = 0x1f8;

  memset(HFS_NODEREC(cat->hdrnd, 1), 0, 128);

  cat->hdr.bthDepth    = 0;
  cat->hdr.bthRoot     = 0;
  cat->hdr.bthNRecs    = 0;
  cat->hdr.bthFNode    = 0;
  cat->hdr.bthLNode    = 0;
  cat->hdr.bthNodeSize = HFS_BLOCKSZ;
  cat->hdr.bthKeyLen   = 0x25;
  cat->hdr.bthNNodes   = 0;
  cat->hdr.bthFree     = 0;
  for (i = 0; i < 76; ++i)
    cat->hdr.bthResv[i] = 0;

  cat->map = ALLOC(byte, HFS_MAP1SZ);
  if (cat->map == 0)
    ERROR(ENOMEM, 0);

  memset(cat->map, 0, HFS_MAP1SZ);
  BMSET(cat->map, 0);

  cat->mapsz = HFS_MAP1SZ;
  cat->flags = HFS_BT_UPDATE_HDR;

  /* allocate space for header nodes (and initial extents) */

  if (bt_space(ext, 1) == -1 ||
      bt_space(cat, 1) == -1)
    goto fail;

  --ext->hdr.bthFree;
  --cat->hdr.bthFree;

  /* create extent records for bad blocks */

#ifdef CP_NOT_USED
  if (nbadblocks > 0)
    {
      hfsfile bbfile;
      ExtDescriptor extent;
      ExtDataRec *extrec;
      ExtKeyRec key;
      byte record[HFS_MAX_EXTRECLEN];
      unsigned int reclen;

      f_init(&bbfile, &vol, HFS_CNID_BADALLOC, "bad blocks");

      qsort(badalloc, nbadblocks, sizeof(*badalloc),
	    (int (*)(const void *, const void *)) compare);

      for (i = 0; i < nbadblocks; ++i)
	{
	  if (i == 0 || badalloc[i] != extent.xdrStABN)
	    {
	      extent.xdrStABN    = badalloc[i];
	      extent.xdrNumABlks = 1;

	      if (extent.xdrStABN < vol.mdb.drNmAlBlks &&
		  f_addextent(&bbfile, &extent) == -1)
		goto fail;
	    }
	}

      /* flush local extents into extents overflow file */

      f_getptrs(&bbfile, &extrec, 0, 0);

      r_makeextkey(&key, bbfile.fork, bbfile.cat.u.fil.filFlNum, 0);
      r_packextrec(&key, extrec, record, &reclen);

      if (bt_insert(&vol.ext, record, reclen) == -1)
	goto fail;
    }
#endif

  vol.flags |= HFS_VOL_MOUNTED;

  /* create root directory */

  if (v_mkdir(&vol, HFS_CNID_ROOTPAR, vname) == -1)
    goto fail;

  vol.mdb.drNxtCNID = 16;  /* first CNID not reserved by Apple */

  /* write boot blocks */

  if (m_zerobb(&vol) == -1)
    goto fail;

  /* zero other unused space, if requested */

  if (vol.flags & HFS_OPT_ZERO)
    {
      block b;
      unsigned long bnum;

      memset(&b, 0, sizeof(b));

      /* between MDB and VBM (never) */

      for (bnum = 3; bnum < vol.mdb.drVBMSt; ++bnum)
	b_writelb(&vol, bnum, &b);

      /* between VBM and first allocation block (sometimes if HFS_OPT_2048) */

      for (bnum = vol.mdb.drVBMSt + vol.vbmsz; bnum < vol.mdb.drAlBlSt; ++bnum)
	b_writelb(&vol, bnum, &b);

      /* between last allocation block and alternate MDB (sometimes) */

      for (bnum = vol.mdb.drAlBlSt + vol.mdb.drNmAlBlks * vol.lpa;
	   bnum < vol.vlen - 2; ++bnum)
	b_writelb(&vol, bnum, &b);

      /* final block (always) */

      b_writelb(&vol, vol.vlen - 1, &b);
    }

  /* flush remaining state and close volume */

  if (v_close(&vol) == -1)
    goto fail;

  FREE(badalloc);

  return 0;

fail:
  v_close(&vol);

  FREE(badalloc);

  return -1;
}
Exemple #20
0
/*
 * NAME:	hfs->create()
 * DESCRIPTION:	create and open a new file
 */
hfsfile *hfs_create(hfsvol *vol, const char *path,
		    const char *type, const char *creator)
{
  hfsfile *file = 0;
  unsigned long parid;
  char name[HFS_MAX_FLEN + 1];
  CatKeyRec key;
  byte record[HFS_MAX_CATRECLEN];
  unsigned reclen;
  int found;

  if (getvol(&vol) == -1)
    goto fail;

  file = ALLOC(hfsfile, 1);
  if (file == 0)
    ERROR(ENOMEM, 0);

  found = v_resolve(&vol, path, &file->cat, &parid, name, 0);
  if (found == -1 || parid == 0)
    goto fail;

  if (found)
    ERROR(EEXIST, 0);

  if (parid == HFS_CNID_ROOTPAR)
    ERROR(EINVAL, 0);

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  /* create file `name' in parent `parid' */

  if (bt_space(&vol->cat, 1) == -1)
    goto fail;

  f_init(file, vol, vol->mdb.drNxtCNID++, name);
  vol->flags |= HFS_VOL_UPDATE_MDB;

  file->parid = parid;

  /* create catalog record */

  file->cat.u.fil.filUsrWds.fdType =
    d_getsl((const unsigned char *) type);
  file->cat.u.fil.filUsrWds.fdCreator =
    d_getsl((const unsigned char *) creator);

  file->cat.u.fil.filCrDat = d_mtime(time(0));
  file->cat.u.fil.filMdDat = file->cat.u.fil.filCrDat;

  r_makecatkey(&key, file->parid, file->name);
  r_packcatrec(&key, &file->cat, record, &reclen);

  if (bt_insert(&vol->cat, record, reclen) == -1 ||
      v_adjvalence(vol, file->parid, 0, 1) == -1)
    goto fail;

  /* package file handle for user */

  file->next = vol->files;

  if (vol->files)
    vol->files->prev = file;

  vol->files = file;

  return file;

fail:
  FREE(file);
  return 0;
}
Exemple #21
0
void rbt_insert( /*@in@*/ RBT_ROOT *root , RBT_NODE *x )
{
  RBT_NODE *y ;

  rbt_validate( root , root->node , NULL ) ;

  HQTRACE( rbt_debug ,
           ( "rbt_insert: [%x] %x" , root , x->key )) ;

  bt_insert( root , x ) ;

  x->red = TRUE ;

  while ( x != root->node && x->p->red ) {
    if ( x->p == x->p->p->left ) {
      y = x->p->p->right ;

      if ( y->red ) {
        x->p->red = FALSE ;
        y->red = FALSE ;
        x->p->p->red = TRUE ;
        x = x->p->p ;
      }
      else {
        if ( x == x->p->right ) {
          x = x->p ;
          rbt_leftrotate( root , x ) ;
        }

        x->p->red = FALSE ;
        x->p->p->red = TRUE ;
        rbt_rightrotate( root , x->p->p ) ;
      }
    }
    else {
      y = x->p->p->left ;

      if ( y->red ) {
        x->p->red = FALSE ;
        y->red = FALSE ;
        x->p->p->red = TRUE ;
        x = x->p->p ;
      }
      else {
        if ( x == x->p->left ) {
          x = x->p ;
          rbt_rightrotate( root , x ) ;
        }

        x->p->red = FALSE ;
        x->p->p->red = TRUE ;
        rbt_leftrotate( root , x->p->p ) ;
      }
    }
  }

  root->node->red = FALSE ;
  root->count++ ;

  rbt_validate( root , root->node , NULL ) ;
}
Exemple #22
0
/*
 * NAME:	vol->newfolder()
 * DESCRIPTION:	create a new HFS folder
 */
int v_newfolder(hfsvol *vol, long parid, char *name)
{
  CatKeyRec key;
  CatDataRec data;
  long id;
  unsigned char record[HFS_CATRECMAXLEN];
  int i, reclen;

  if (bt_space(&vol->cat, 2) < 0)
    return -1;

  id = vol->mdb.drNxtCNID++;
  vol->flags |= HFS_UPDATE_MDB;

  /* create directory record */

  data.cdrType   = cdrDirRec;
  data.cdrResrv2 = 0;

  data.u.dir.dirFlags = 0;
  data.u.dir.dirVal   = 0;
  data.u.dir.dirDirID = id;
#ifdef UHFS
  data.u.dir.dirCrDat = 0;
#else
  data.u.dir.dirCrDat = d_tomtime(time(0));
#endif
  data.u.dir.dirMdDat = data.u.dir.dirCrDat;
  data.u.dir.dirBkDat = 0;

  memset(&data.u.dir.dirUsrInfo,  0, sizeof(data.u.dir.dirUsrInfo));
  memset(&data.u.dir.dirFndrInfo, 0, sizeof(data.u.dir.dirFndrInfo));
  for (i = 0; i < 4; ++i)
    data.u.dir.dirResrv[i] = 0;

  r_makecatkey(&key, parid, name);
  r_packcatkey(&key, record, &reclen);
  r_packcatdata(&data, HFS_RECDATA(record), &reclen);

  if (bt_insert(&vol->cat, record, reclen) < 0)
    return -1;

  /* create thread record */

  data.cdrType   = cdrThdRec;
  data.cdrResrv2 = 0;

  data.u.dthd.thdResrv[0] = 0;
  data.u.dthd.thdResrv[1] = 0;
  data.u.dthd.thdParID    = parid;
  strcpy(data.u.dthd.thdCName, name);

  r_makecatkey(&key, id, "");
  r_packcatkey(&key, record, &reclen);
  r_packcatdata(&data, HFS_RECDATA(record), &reclen);

  if (bt_insert(&vol->cat, record, reclen) < 0 ||
      v_adjvalence(vol, parid, 1, 1) < 0)
    return -1;

  return 0;
}
Exemple #23
0
/*
 * NAME:	file->addextent()
 * DESCRIPTION:	add an extent to a file
 */
int f_addextent(hfsfile *file, ExtDescriptor *blocks)
{
  hfsvol *vol = file->vol;
  ExtDataRec *extrec;
  ULongInt *pylen;
  unsigned int start, end;
  node n;
  int i;

  f_getptrs(file, &extrec, 0, &pylen);

  start  = file->fabn;
  end    = *pylen / vol->mdb.drAlBlkSiz;

  n.nnum = 0;
  i      = -1;

  while (start < end)
    {
      for (i = 0; i < 3; ++i)
	{
	  unsigned int num;

	  num    = file->ext[i].xdrNumABlks;
	  start += num;

	  if (start == end)
	    break;
	  else if (start > end)
	    ERROR(EIO, "file extents exceed file physical length");
	  else if (num == 0)
	    ERROR(EIO, "empty file extent");
	}

      if (start == end)
	break;

      if (v_extsearch(file, start, &file->ext, &n) <= 0)
	goto fail;

      file->fabn = start;
    }

  if (i >= 0 &&
      file->ext[i].xdrStABN + file->ext[i].xdrNumABlks == blocks->xdrStABN)
    file->ext[i].xdrNumABlks += blocks->xdrNumABlks;
  else
    {
      /* create a new extent descriptor */

      if (++i < 3)
	file->ext[i] = *blocks;
      else
	{
	  ExtKeyRec key;
	  byte record[HFS_MAX_EXTRECLEN];
	  unsigned int reclen;

	  /* record is full; create a new one */

	  file->ext[0] = *blocks;

	  for (i = 1; i < 3; ++i)
	    {
	      file->ext[i].xdrStABN    = 0;
	      file->ext[i].xdrNumABlks = 0;
	    }

	  file->fabn = start;

	  r_makeextkey(&key, file->fork, file->cat.u.fil.filFlNum, end);
	  r_packextrec(&key, &file->ext, record, &reclen);

	  if (bt_insert(&vol->ext, record, reclen) == -1)
	    goto fail;

	  i = -1;
	}
    }

  if (i >= 0)
    {
      /* store the modified extent record */

      if (file->fabn)
	{
	  if ((n.nnum == 0 &&
	       v_extsearch(file, file->fabn, 0, &n) <= 0) ||
	      v_putextrec(&file->ext, &n) == -1)
	    goto fail;
	}
      else
	memcpy(extrec, &file->ext, sizeof(ExtDataRec));
    }

  *pylen += blocks->xdrNumABlks * vol->mdb.drAlBlkSiz;

  file->flags |= HFS_FILE_UPDATE_CATREC;

  return 0;

fail:
  return -1;
}
Exemple #24
0
/*
 * NAME:	hfs->create()
 * DESCRIPTION:	create a new file
 */
int hfs_create(hfsvol *vol, char *path, char *type, char *creator)
{
  CatKeyRec key;
  CatDataRec data;
  long id, parid;
  char name[HFS_MAX_FLEN + 1];
  unsigned char record[HFS_CATRECMAXLEN];
  int found, i, reclen;

  if (v_getvol(&vol) < 0)
    return -1;

  found = v_resolve(&vol, path, &data, &parid, name, 0);
  if (found < 0 || parid == 0)
    return -1;
  else if (found)
    {
      ERROR(EEXIST, 0);
      return -1;
    }

  if (parid == HFS_CNID_ROOTPAR)
    {
      ERROR(EINVAL, 0);
      return -1;
    }

  if (vol->flags & HFS_READONLY)
    {
      ERROR(EROFS, 0);
      return -1;
    }

  /* create file `name' in parent `parid' */

  if (bt_space(&vol->cat, 1) < 0)
    return -1;

  id = vol->mdb.drNxtCNID++;
  vol->flags |= HFS_UPDATE_MDB;

  /* create file record */

  data.cdrType   = cdrFilRec;
  data.cdrResrv2 = 0;

  data.u.fil.filFlags = 0;
  data.u.fil.filTyp   = 0;

  memset(&data.u.fil.filUsrWds, 0, sizeof(data.u.fil.filUsrWds));

  data.u.fil.filUsrWds.fdType    = d_getl((unsigned char *) type);
  data.u.fil.filUsrWds.fdCreator = d_getl((unsigned char *) creator);

  data.u.fil.filFlNum  = id;
  data.u.fil.filStBlk  = 0;
  data.u.fil.filLgLen  = 0;
  data.u.fil.filPyLen  = 0;
  data.u.fil.filRStBlk = 0;
  data.u.fil.filRLgLen = 0;
  data.u.fil.filRPyLen = 0;
  data.u.fil.filCrDat  = d_tomtime(/*time*/(0));
  data.u.fil.filMdDat  = data.u.fil.filCrDat;
  data.u.fil.filBkDat  = 0;

  memset(&data.u.fil.filFndrInfo, 0, sizeof(data.u.fil.filFndrInfo));

  data.u.fil.filClpSize = 0;

  for (i = 0; i < 3; ++i)
    {
      data.u.fil.filExtRec[i].xdrStABN     = 0;
      data.u.fil.filExtRec[i].xdrNumABlks  = 0;

      data.u.fil.filRExtRec[i].xdrStABN    = 0;
      data.u.fil.filRExtRec[i].xdrNumABlks = 0;
    }

  data.u.fil.filResrv = 0;

  r_makecatkey(&key, parid, name);
  r_packcatkey(&key, record, &reclen);
  r_packcatdata(&data, HFS_RECDATA(record), &reclen);

  if (bt_insert(&vol->cat, record, reclen) < 0 ||
      v_adjvalence(vol, parid, 0, 1) < 0)
    return -1;

  return 0;
}