"Fossies" - the Fresh Open Source Software Archive 
Member "xorriso-1.5.4/libisofs/data_source.c" (30 Jan 2021, 4321 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 "data_source.c" see the
Fossies "Dox" file reference documentation.
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 }