5 changed files with 270 additions and 0 deletions
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 2007 Vreixo Formoso |
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See COPYING file for details. |
||||
*/ |
||||
|
||||
/*
|
||||
* Functions that act on the iso tree. |
||||
*/ |
||||
|
||||
#include "libisofs.h" |
||||
#include "node.h" |
||||
#include "error.h" |
||||
|
||||
#include <stdlib.h> |
||||
#include <string.h> |
||||
#include <time.h> |
||||
|
||||
/**
|
||||
* Add a new directory to the iso tree. |
||||
*
|
||||
* @param parent
|
||||
* the dir where the new directory will be created |
||||
* @param name |
||||
* name for the new dir. If a node with same name already exists on |
||||
* parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. |
||||
* @param dir |
||||
* place where to store a pointer to the newly created dir. No extra |
||||
* ref is addded, so you will need to call iso_node_ref() if you really |
||||
* need it. You can pass NULL in this parameter if you don't need the |
||||
* pointer. |
||||
* @return |
||||
* number of nodes in dir if succes, < 0 otherwise |
||||
* Possible errors: |
||||
* ISO_NULL_POINTER, if parent or name are NULL |
||||
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists |
||||
*/ |
||||
int iso_tree_add_new_dir(IsoDir *parent, const char *name, IsoDir **dir) |
||||
{ |
||||
IsoDir *node; |
||||
IsoNode **pos; |
||||
time_t now; |
||||
|
||||
if (parent == NULL || name == NULL) { |
||||
return ISO_NULL_POINTER; |
||||
} |
||||
|
||||
/* find place where to insert */ |
||||
pos = &(parent->children); |
||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) { |
||||
pos = &((*pos)->next); |
||||
} |
||||
if (*pos != NULL && !strcmp((*pos)->name, name)) { |
||||
/* a node with same name already exists */ |
||||
return ISO_NODE_NAME_NOT_UNIQUE; |
||||
} |
||||
|
||||
node = calloc(1, sizeof(IsoDir)); |
||||
if (node == NULL) { |
||||
return ISO_MEM_ERROR; |
||||
} |
||||
|
||||
node->node.refcount = 1; |
||||
node->node.type = LIBISO_DIR; |
||||
node->node.name = strdup(name); |
||||
if (node->node.name == NULL) { |
||||
free(node); |
||||
return ISO_MEM_ERROR; |
||||
} |
||||
|
||||
/* permissions from parent */ |
||||
node->node.mode = parent->node.mode; |
||||
node->node.uid = parent->node.uid; |
||||
node->node.gid = parent->node.gid; |
||||
node->node.hidden = parent->node.hidden; |
||||
|
||||
/* current time */ |
||||
now = time(NULL); |
||||
node->node.atime = now; |
||||
node->node.ctime = now; |
||||
node->node.mtime = now; |
||||
|
||||
/* add to dir */ |
||||
node->node.parent = parent; |
||||
node->node.next = (*pos)->next; |
||||
*pos = (IsoNode*)node; |
||||
|
||||
if (dir) { |
||||
*dir = node; |
||||
} |
||||
return ISO_SUCCESS; |
||||
} |
||||
|
||||
/**
|
||||
* Add a new symlink to the directory tree. Permissions are set to 0777,
|
||||
* owner and hidden atts are taken from parent. You can modify any of them
|
||||
* later. |
||||
*
|
||||
* @param parent
|
||||
* the dir where the new symlink will be created |
||||
* @param name |
||||
* name for the new dir. If a node with same name already exists on |
||||
* parent, this functions fails with ISO_NODE_NAME_NOT_UNIQUE. |
||||
* @param dest |
||||
* destination of the link |
||||
* @param link |
||||
* place where to store a pointer to the newly created link. No extra |
||||
* ref is addded, so you will need to call iso_node_ref() if you really |
||||
* need it. You can pass NULL in this parameter if you don't need the |
||||
* pointer |
||||
* @return |
||||
* number of nodes in parent if success, < 0 otherwise |
||||
* Possible errors: |
||||
* ISO_NULL_POINTER, if parent, name or dest are NULL |
||||
* ISO_NODE_NAME_NOT_UNIQUE, a node with same name already exists |
||||
* ISO_MEM_ERROR |
||||
*/ |
||||
int iso_tree_add_new_symlink(IsoDir *parent, const char *name,
|
||||
const char *dest, IsoSymlink **link) |
||||
{ |
||||
IsoSymlink *node; |
||||
IsoNode **pos; |
||||
time_t now; |
||||
|
||||
if (parent == NULL || name == NULL || dest == NULL) { |
||||
return ISO_NULL_POINTER; |
||||
} |
||||
|
||||
/* find place where to insert */ |
||||
pos = &(parent->children); |
||||
while (*pos != NULL && strcmp((*pos)->name, name) < 0) { |
||||
pos = &((*pos)->next); |
||||
} |
||||
if (*pos != NULL && !strcmp((*pos)->name, name)) { |
||||
/* a node with same name already exists */ |
||||
return ISO_NODE_NAME_NOT_UNIQUE; |
||||
} |
||||
|
||||
node = calloc(1, sizeof(IsoSymlink)); |
||||
if (node == NULL) { |
||||
return ISO_MEM_ERROR; |
||||
} |
||||
|
||||
node->node.refcount = 1; |
||||
node->node.type = LIBISO_SYMLINK; |
||||
node->node.name = strdup(name); |
||||
if (node->node.name == NULL) { |
||||
free(node); |
||||
return ISO_MEM_ERROR; |
||||
} |
||||
|
||||
node->dest = strdup(dest); |
||||
if (node->dest == NULL) { |
||||
free(node->node.name); |
||||
free(node); |
||||
return ISO_MEM_ERROR; |
||||
} |
||||
|
||||
/* permissions from parent */ |
||||
node->node.mode = S_IFLNK | 0777; |
||||
node->node.uid = parent->node.uid; |
||||
node->node.gid = parent->node.gid; |
||||
node->node.hidden = parent->node.hidden; |
||||
|
||||
/* current time */ |
||||
now = time(NULL); |
||||
node->node.atime = now; |
||||
node->node.ctime = now; |
||||
node->node.mtime = now; |
||||
|
||||
/* add to dir */ |
||||
node->node.parent = parent; |
||||
node->node.next = (*pos)->next; |
||||
*pos = (IsoNode*)node; |
||||
|
||||
if (link) { |
||||
*link = node; |
||||
} |
||||
return ISO_SUCCESS; |
||||
} |
Loading…
Reference in new issue