"Fossies" - the Fresh Open Source Software Archive

Member "xorriso-1.5.4/libisofs/builder.c" (30 Jan 2021, 8455 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "builder.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.4.8_vs_1.5.1.

    1 /*
    2  * Copyright (c) 2007 Vreixo Formoso
    3  * Copyright (c) 2009 - 2015 Thomas Schmitt
    4  * 
    5  * This file is part of the libisofs project; you can redistribute it and/or 
    6  * modify it under the terms of the GNU General Public License version 2 
    7  * or later as published by the Free Software Foundation. 
    8  * See COPYING file for details.
    9  */
   10 
   11 #ifdef HAVE_CONFIG_H
   12 #include "../config.h"
   13 #endif
   14 
   15 /* libisofs.h defines aaip_xinfo_func */
   16 #include "libisofs.h"
   17 
   18 #include "builder.h"
   19 #include "node.h"
   20 #include "fsource.h"
   21 #include "image.h"
   22 #include "aaip_0_2.h"
   23 #include "util.h"
   24 #include "messages.h"
   25 
   26 #include <stdlib.h>
   27 #include <string.h>
   28 #include <limits.h>
   29 #include <stdio.h>
   30 
   31 
   32 
   33 void iso_node_builder_ref(IsoNodeBuilder *builder)
   34 {
   35     ++builder->refcount;
   36 }
   37 
   38 void iso_node_builder_unref(IsoNodeBuilder *builder)
   39 {
   40     if (--builder->refcount == 0) {
   41         /* free private data */
   42         builder->free(builder);
   43         free(builder);
   44     }
   45 }
   46 
   47 static
   48 int default_create_file(IsoNodeBuilder *builder, IsoImage *image,
   49                         IsoFileSource *src, IsoFile **file)
   50 {
   51     int ret;
   52     struct stat info;
   53     IsoStream *stream;
   54     IsoFile *node;
   55     char *name;
   56 
   57     if (builder == NULL || src == NULL || file == NULL) {
   58         return ISO_NULL_POINTER;
   59     }
   60 
   61     ret = iso_file_source_stat(src, &info);
   62     if (ret < 0) {
   63         return ret;
   64     }
   65 
   66     /* this will fail if src is a dir, is not accessible... */
   67     ret = iso_file_source_stream_new(src, &stream);
   68     if (ret < 0) {
   69         return ret;
   70     }
   71 
   72     /* take a ref to the src, as stream has taken our ref */
   73     iso_file_source_ref(src);
   74     
   75     name = iso_file_source_get_name(src);
   76     if ((int) strlen(name) > image->truncate_length) {
   77         ret = iso_truncate_rr_name(image->truncate_mode,
   78                                    image->truncate_length, name, 0);
   79         if (ret < 0) {
   80             iso_stream_unref(stream);
   81             free(name);
   82             return ret;
   83         }
   84     }
   85     ret = iso_node_new_file(name, stream, &node);
   86     if (ret < 0) {
   87         iso_stream_unref(stream);
   88         free(name);
   89         return ret;
   90     }
   91 
   92     /* fill node fields */
   93     iso_node_set_permissions((IsoNode*)node, info.st_mode);
   94     iso_node_set_uid((IsoNode*)node, info.st_uid);
   95     iso_node_set_gid((IsoNode*)node, info.st_gid);
   96     iso_node_set_atime((IsoNode*)node, info.st_atime);
   97     iso_node_set_mtime((IsoNode*)node, info.st_mtime);
   98     iso_node_set_ctime((IsoNode*)node, info.st_ctime);
   99     iso_node_set_uid((IsoNode*)node, info.st_uid);
  100 
  101     *file = node;
  102     return ISO_SUCCESS;
  103 }
  104 
  105 static
  106 int default_create_node(IsoNodeBuilder *builder, IsoImage *image,
  107                         IsoFileSource *src, char *in_name, IsoNode **node)
  108 {
  109     int ret, name_is_attached = 0;
  110     struct stat info;
  111     IsoNode *new;
  112     IsoFilesystem *fs;
  113     char *name = NULL;
  114     unsigned char *aa_string = NULL;
  115     char *a_text = NULL, *d_text = NULL;
  116     char *dest = NULL;
  117     IsoSymlink *link;
  118 
  119     if (builder == NULL || src == NULL || node == NULL) {
  120         {ret = ISO_NULL_POINTER; goto ex;}
  121     }
  122 
  123     /* get info about source */
  124     if (iso_tree_get_follow_symlinks(image)) {
  125         ret = iso_file_source_stat(src, &info);
  126     } else {
  127         ret = iso_file_source_lstat(src, &info);
  128     }
  129     if (ret < 0) {
  130         goto ex;
  131     }
  132 
  133     if (in_name == NULL) {
  134         name = iso_file_source_get_name(src);
  135     } else {
  136         name = strdup(in_name);
  137         if (name == NULL) {
  138             ret = ISO_OUT_OF_MEM; goto ex;
  139         }
  140     }
  141 
  142     if ((int) strlen(name) > image->truncate_length) {
  143         ret = iso_truncate_rr_name(image->truncate_mode,
  144                                    image->truncate_length, name, 0);
  145         if (ret < 0)
  146             goto ex;
  147     }
  148     fs = iso_file_source_get_filesystem(src);
  149     new = NULL;
  150 
  151     switch (info.st_mode & S_IFMT) {
  152     case S_IFREG:
  153         {
  154             /* source is a regular file */
  155             IsoStream *stream;
  156             IsoFile *file;
  157             ret = iso_file_source_stream_new(src, &stream);
  158             if (ret < 0) {
  159                 break;
  160             }
  161             /* take a ref to the src, as stream has taken our ref */
  162             iso_file_source_ref(src);
  163             
  164             /* create the file */
  165             ret = iso_node_new_file(name, stream, &file);
  166             if (ret < 0) {
  167                 iso_stream_unref(stream);
  168             }
  169             new = (IsoNode*) file;
  170         }
  171         break;
  172     case S_IFDIR:
  173         {
  174             /* source is a directory */
  175             IsoDir *dir;
  176             ret = iso_node_new_dir(name, &dir);
  177             new = (IsoNode*)dir;
  178         }
  179         break;
  180     case S_IFLNK:
  181         {
  182             /* source is a symbolic link */
  183             LIBISO_ALLOC_MEM(dest, char, LIBISOFS_NODE_PATH_MAX);
  184             ret = iso_file_source_readlink(src, dest, LIBISOFS_NODE_PATH_MAX);
  185             if (ret < 0) {
  186                 break;
  187             }
  188             ret = iso_node_new_symlink(name, strdup(dest), &link);
  189             new = (IsoNode*) link;
  190             if (fs != NULL) {
  191                 link->fs_id = fs->get_id(fs);
  192                 if (link->fs_id != 0) {
  193                     link->st_ino = info.st_ino;
  194                     link->st_dev = info.st_dev;
  195                 }
  196             }
  197         }
  198         break;
  199     case S_IFSOCK:
  200     case S_IFBLK:
  201     case S_IFCHR:
  202     case S_IFIFO:
  203         {
  204             /* source is an special file */
  205             IsoSpecial *special;
  206             ret = iso_node_new_special(name, info.st_mode, info.st_rdev, 
  207                                        &special);
  208             new = (IsoNode*) special;
  209             if (fs != NULL) {
  210                 special->fs_id = fs->get_id(fs);
  211                 if (special->fs_id != 0) {
  212                     special->st_ino = info.st_ino;
  213                     special->st_dev = info.st_dev;
  214                 }
  215             }
  216         }
  217         break;
  218     default:
  219         ret = ISO_BAD_FSRC_FILETYPE;
  220         goto ex;
  221     }
  222     
  223     if (ret < 0)
  224         goto ex;
  225     name_is_attached = 1;
  226 
  227     /* fill fields */
  228     iso_node_set_perms_internal(new, info.st_mode, 1);
  229     iso_node_set_uid(new, info.st_uid);
  230     iso_node_set_gid(new, info.st_gid);
  231     iso_node_set_atime(new, info.st_atime);
  232     iso_node_set_mtime(new, info.st_mtime);
  233     iso_node_set_ctime(new, info.st_ctime);
  234     iso_node_set_uid(new, info.st_uid);
  235 
  236     /* Eventually set S_IRWXG from ACL */
  237     if (image->builder_ignore_acl) {
  238         ret = iso_file_source_get_aa_string(src, &aa_string, 4);
  239         if (ret >= 0 && aa_string != NULL)
  240             iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text, 16);
  241         if (ret >= 0 && a_text != NULL) {
  242             aaip_cleanout_st_mode(a_text, &(info.st_mode), 4 | 16);
  243             iso_node_set_perms_internal(new, info.st_mode, 1);
  244         }
  245         iso_aa_get_acl_text(aa_string, info.st_mode, &a_text, &d_text,
  246                             1 << 15); /* free ACL texts */
  247         if(aa_string != NULL)
  248             free(aa_string);
  249         aa_string = NULL;
  250     }
  251 
  252     /* Obtain ownership of eventual AAIP string */
  253     ret = iso_file_source_get_aa_string(src, &aa_string,
  254             1 | (image->builder_ignore_acl << 1) |
  255                 (image->builder_ignore_ea << 2) |
  256                 (image->builder_take_all_ea << 3));
  257     if(ret == 2)
  258       image->blind_on_local_get_attrs = 1;
  259     if (ret > 0 && aa_string != NULL) {
  260         ret = iso_node_add_xinfo(new, aaip_xinfo_func, aa_string);
  261         if (ret < 0)
  262             goto ex;
  263     } else if(aa_string != NULL) {
  264         free(aa_string);
  265     }
  266 
  267     *node = new;
  268 
  269     ret = ISO_SUCCESS;
  270 ex:;
  271     if (name != NULL && !name_is_attached)
  272         free(name);
  273     LIBISO_FREE_MEM(dest);
  274     return ret;
  275 }
  276 
  277 static
  278 void default_free(IsoNodeBuilder *builder)
  279 {
  280     /* The .free() method of IsoNodeBuilder shall free private data but not
  281        the builder itself. The latter is done in iso_node_builder_unref().
  282     */
  283     return;
  284 }
  285 
  286 int iso_node_basic_builder_new(IsoNodeBuilder **builder)
  287 {
  288     IsoNodeBuilder *b;
  289 
  290     if (builder == NULL) {
  291         return ISO_NULL_POINTER;
  292     }
  293 
  294     b = malloc(sizeof(IsoNodeBuilder));
  295     if (b == NULL) {
  296         return ISO_OUT_OF_MEM;
  297     }
  298 
  299     b->refcount = 1;
  300     b->create_file_data = NULL;
  301     b->create_node_data = NULL;
  302     b->create_file = default_create_file;
  303     b->create_node = default_create_node;
  304     b->free = default_free;
  305 
  306     *builder = b;
  307     return ISO_SUCCESS;
  308 }