"Fossies" - the Fresh Open Source Software Archive

Member "libisofs-1.5.4/libisofs/data_source.c" (8 Jul 2020, 4321 Bytes) of package /linux/misc/libisofs-1.5.4.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 "data_source.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.4.4_vs_1.4.6.

    1 /*
    2  * Copyright (c) 2007 Vreixo Formoso
    3  * 
    4  * This file is part of the libisofs project; you can redistribute it and/or 
    5  * modify it under the terms of the GNU General Public License version 2 
    6  * or later as published by the Free Software Foundation. 
    7  * See COPYING file for details.
    8  */
    9 
   10 #ifdef HAVE_CONFIG_H
   11 #include "../config.h"
   12 #endif
   13 
   14 #include "libisofs.h"
   15 #include "util.h"
   16 
   17 #include <stdlib.h>
   18 #include <string.h>
   19 #include <sys/types.h>
   20 #include <sys/stat.h>
   21 #include <fcntl.h>
   22 #include <unistd.h>
   23 
   24 /* O_BINARY is needed for Cygwin but undefined elsewhere */
   25 #ifndef O_BINARY
   26 #define O_BINARY 0
   27 #endif
   28 
   29 /**
   30  * Private data for File IsoDataSource
   31  */
   32 struct file_data_src
   33 {
   34     char *path;
   35     int fd;
   36 };
   37 
   38 /**
   39  * Increments the reference counting of the given IsoDataSource.
   40  */
   41 void iso_data_source_ref(IsoDataSource *src)
   42 {
   43     src->refcount++;
   44 }
   45 
   46 /**
   47  * Decrements the reference counting of the given IsoDataSource, freeing it
   48  * if refcount reach 0.
   49  */
   50 void iso_data_source_unref(IsoDataSource *src)
   51 {
   52     if (--src->refcount == 0) {
   53         src->free_data(src);
   54         free(src);
   55     }
   56 }
   57 
   58 static
   59 int ds_open(IsoDataSource *src)
   60 {
   61     int fd;
   62     struct file_data_src *data;
   63 
   64     if (src == NULL || src->data == NULL) {
   65         return ISO_NULL_POINTER;
   66     }
   67 
   68     data = (struct file_data_src*) src->data;
   69     if (data->fd != -1) {
   70         return ISO_FILE_ALREADY_OPENED;
   71     }
   72 
   73     fd = open(data->path, O_RDONLY | O_BINARY);
   74     if (fd == -1) {
   75         return ISO_FILE_ERROR;
   76     }
   77 
   78     data->fd = fd;
   79     return ISO_SUCCESS;
   80 }
   81 
   82 static
   83 int ds_close(IsoDataSource *src)
   84 {
   85     int ret;
   86     struct file_data_src *data;
   87 
   88     if (src == NULL || src->data == NULL) {
   89         return ISO_NULL_POINTER;
   90     }
   91 
   92     data = (struct file_data_src*) src->data;
   93     if (data->fd == -1) {
   94         return ISO_FILE_NOT_OPENED;
   95     }
   96 
   97     /* close can fail if fd is not valid, but that should never happen */
   98     ret = close(data->fd);
   99 
  100     /* in any case we mark file as closed */
  101     data->fd = -1;
  102     return ret == 0 ? ISO_SUCCESS : ISO_FILE_ERROR;
  103 }
  104 
  105 static int ds_read_block(IsoDataSource *src, uint32_t lba, uint8_t *buffer)
  106 {
  107     struct file_data_src *data;
  108 
  109     if (src == NULL || src->data == NULL || buffer == NULL) {
  110         return ISO_NULL_POINTER;
  111     }
  112 
  113     data = (struct file_data_src*) src->data;
  114     if (data->fd == -1) {
  115         return ISO_FILE_NOT_OPENED;
  116     }
  117 
  118     /* goes to requested block */
  119     if (lseek(data->fd, (off_t)lba * (off_t)2048, SEEK_SET) == (off_t) -1) {
  120         return ISO_FILE_SEEK_ERROR;
  121     }
  122 
  123     /* TODO #00008 : guard against partial reads. */
  124     if (read(data->fd, buffer, 2048) != 2048) {
  125         return ISO_FILE_READ_ERROR;
  126     }
  127 
  128     return ISO_SUCCESS;
  129 }
  130 
  131 static
  132 void ds_free_data(IsoDataSource *src)
  133 {
  134     struct file_data_src *data;
  135 
  136     data = (struct file_data_src*)src->data;
  137 
  138     /* close the file if needed */
  139     if (data->fd != -1) {
  140         close(data->fd);
  141     }
  142     free(data->path);
  143     free(data);
  144 }
  145 
  146 /**
  147  * Create a new IsoDataSource from a local file. This is suitable for
  148  * accessing regular .iso images, or to access drives via its block device
  149  * and standard POSIX I/O calls.
  150  * 
  151  * @param path
  152  *     The path of the file
  153  * @param src
  154  *     Will be filled with the pointer to the newly created data source.
  155  * @return
  156  *    1 on success, < 0 on error.
  157  */
  158 int iso_data_source_new_from_file(const char *path, IsoDataSource **src)
  159 {
  160     int ret;
  161     struct file_data_src *data;
  162     IsoDataSource *ds;
  163 
  164     if (path == NULL || src == NULL) {
  165         return ISO_NULL_POINTER;
  166     }
  167 
  168     /* ensure we have read access to the file */
  169     ret = iso_eaccess(path);
  170     if (ret < 0) {
  171         return ret;
  172     }
  173 
  174     data = malloc(sizeof(struct file_data_src));
  175     if (data == NULL) {
  176         return ISO_OUT_OF_MEM;
  177     }
  178 
  179     ds = malloc(sizeof(IsoDataSource));
  180     if (ds == NULL) {
  181         free(data);
  182         return ISO_OUT_OF_MEM;
  183     }
  184 
  185     /* fill data fields */
  186     data->path = strdup(path);
  187     if (data->path == NULL) {
  188         free(data);
  189         free(ds);
  190         return ISO_OUT_OF_MEM;
  191     }
  192 
  193     data->fd = -1;
  194     ds->version = 0;
  195     ds->refcount = 1;
  196     ds->data = data;
  197 
  198     ds->open = ds_open;
  199     ds->close = ds_close;
  200     ds->read_block = ds_read_block;
  201     ds->free_data = ds_free_data;
  202 
  203     *src = ds;
  204     return ISO_SUCCESS;
  205 }