1 /*
2  * Copyright (c) 2003
3  *    Motoyuki Kasahara
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2, or (at your option)
8  * any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
15 
16 #ifdef HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include <stdio.h>
21 #include <sys/types.h>
22 
23 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
24 #include <string.h>
25 #if !defined(STDC_HEADERS) && defined(HAVE_MEMORY_H)
26 #include <memory.h>
27 #endif /* not STDC_HEADERS and HAVE_MEMORY_H */
28 #else /* not STDC_HEADERS and not HAVE_STRING_H */
29 #include <strings.h>
30 #endif /* not STDC_HEADERS and not HAVE_STRING_H */
31 
32 #ifdef HAVE_STDLIB_H
33 #include <stdlib.h>
34 #endif
35 
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39 
40 #ifdef HAVE_FCNTL_H
41 #include <fcntl.h>
42 #else
43 #include <sys/file.h>
44 #endif
45 
46 #ifdef HAVE_LIMITS_H
47 #include <limits.h>
48 #endif
49 
50 #ifndef HAVE_STRCHR
51 #define strchr index
52 #define strrchr rindex
53 #endif /* HAVE_STRCHR */
54 
55 #ifndef PATH_MAX
56 #ifdef MAXPATHLEN
57 #define PATH_MAX        MAXPATHLEN
58 #else /* not MAXPATHLEN */
59 #define PATH_MAX        1024
60 #endif /* not MAXPATHLEN */
61 #endif /* not PATH_MAX */
62 
63 #include "ebtiny/eb.h"
64 #include "ebtiny/error.h"
65 
66 
67 /*
68  * Unexported functions.
69  */
70 static EB_Error_Code eb_load_catalog_eb EB_P((EB_Book *, const char *));
71 static EB_Error_Code eb_load_catalog_epwing EB_P((EB_Book *, const char *));
72 
73 
74 void
eb_initialize_book(book)75 eb_initialize_book(book)
76     EB_Book *book;
77 {
78     int i;
79 
80     book->subbook_count = 0;
81     for (i = 0; i < book->subbook_count; i++)
82 	book->subbooks[i][0] = '\0';
83 }
84 
85 
86 void
eb_finalize_book(book)87 eb_finalize_book(book)
88     EB_Book *book;
89 {
90     int i;
91 
92     for (i = 0; i < book->subbook_count; i++)
93 	book->subbooks[i][0] = '\0';
94     book->subbook_count = 0;
95 }
96 
97 
98 EB_Error_Code
eb_load_all_subbooks(book)99 eb_load_all_subbooks(book)
100     EB_Book *book;
101 {
102     return EB_SUCCESS;
103 }
104 
105 
106 EB_Error_Code
eb_bind(book,path)107 eb_bind(book, path)
108     EB_Book *book;
109     const char *path;
110 {
111     EB_Error_Code error_code;
112     size_t path_length;
113 
114     if (book->subbooks != NULL) {
115         eb_finalize_book(book);
116         eb_initialize_book(book);
117     }
118 
119     if (*path != '/')
120 	return EB_ERR_BAD_FILE_NAME;
121 
122     path_length = strlen(path);
123     if (PATH_MAX < path_length + 1 + EB_MAX_FILE_NAME_LENGTH)
124         return EB_ERR_TOO_LONG_FILE_NAME;
125 
126     error_code = eb_load_catalog_eb(book, path);
127     if (error_code != EB_SUCCESS)
128 	error_code = eb_load_catalog_epwing(book, path);
129     if (error_code != EB_SUCCESS)
130 	return error_code;
131 
132     return EB_SUCCESS;
133 }
134 
135 
136 static EB_Error_Code
eb_load_catalog_eb(book,book_path)137 eb_load_catalog_eb(book, book_path)
138     EB_Book *book;
139     const char *book_path;
140 {
141     char catalog_path_name[PATH_MAX + 1];
142     char catalog_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
143     char buffer[40];
144     char *space;
145     EB_Error_Code error_code;
146     int file = -1;
147     int i;
148 
149     /*
150      * Open a catalog file.
151      */
152     error_code = eb_find_file_name(book_path, "catalog",
153 	catalog_file_name);
154     if (error_code != EB_SUCCESS)
155         goto failed;
156 
157     sprintf(catalog_path_name, "%s/%s", book_path, catalog_file_name);
158     file = open(catalog_path_name, O_RDONLY);
159     if (file < 0) {
160 	error_code = EB_ERR_FAIL_OPEN_CAT;
161 	goto failed;
162     }
163 
164     /*
165      * Get the number of subbooks in this book.
166      */
167     if (eb_read_all(file, buffer, 16) != 16) {
168         error_code = EB_ERR_FAIL_READ_CAT;
169         goto failed;
170     }
171 
172     book->subbook_count = (*(unsigned char *)buffer << 8)
173 	+ (*(unsigned char *)(buffer + 1));
174     if (EB_MAX_SUBBOOKS < book->subbook_count)
175 	book->subbook_count = EB_MAX_SUBBOOKS;
176     if (book->subbook_count == 0) {
177 	error_code = EB_ERR_UNEXP_CAT;
178 	goto failed;
179     }
180 
181     /*
182      * Read subbook information.
183      */
184     for (i = 0; i < book->subbook_count; i++) {
185         if (eb_read_all(file, buffer, 40) != 40) {
186 	    error_code = EB_ERR_FAIL_READ_CAT;
187 	    goto failed;
188 	}
189 	strncpy(book->subbooks[i], buffer + 32,
190 	    EB_MAX_DIRECTORY_NAME_LENGTH);
191 	*(book->subbooks[i] + EB_MAX_DIRECTORY_NAME_LENGTH) = '\0';
192         space = strchr(book->subbooks[i], ' ');
193         if (space != NULL)
194             *space = '\0';
195     }
196 
197     close(file);
198     return EB_SUCCESS;
199 
200     /*
201      * An error occurs...
202      */
203   failed:
204     if (0 <= file)
205 	close(file);
206 
207     return error_code;
208 }
209 
210 
211 static EB_Error_Code
eb_load_catalog_epwing(book,book_path)212 eb_load_catalog_epwing(book, book_path)
213     EB_Book *book;
214     const char *book_path;
215 {
216     char catalog_path_name[PATH_MAX + 1];
217     char catalog_file_name[EB_MAX_FILE_NAME_LENGTH + 1];
218     char buffer[164];
219     char *space;
220     EB_Error_Code error_code;
221     int file = -1;
222     int i;
223 
224     /*
225      * Open a catalog file.
226      */
227     error_code = eb_find_file_name(book_path, "catalogs",
228 	catalog_file_name);
229     if (error_code != EB_SUCCESS)
230         goto failed;
231 
232     sprintf(catalog_path_name, "%s/%s", book_path, catalog_file_name);
233     file = open(catalog_path_name, O_RDONLY);
234     if (file < 0) {
235 	error_code = EB_ERR_FAIL_OPEN_CAT;
236 	goto failed;
237     }
238 
239     /*
240      * Get the number of subbooks in this book.
241      */
242     if (eb_read_all(file, buffer, 16) != 16) {
243         error_code = EB_ERR_FAIL_READ_CAT;
244         goto failed;
245     }
246 
247     book->subbook_count = (*(unsigned char *)buffer << 8)
248 	+ (*(unsigned char *)(buffer + 1));
249     if (EB_MAX_SUBBOOKS < book->subbook_count)
250 	book->subbook_count = EB_MAX_SUBBOOKS;
251     if (book->subbook_count == 0) {
252 	error_code = EB_ERR_UNEXP_CAT;
253 	goto failed;
254     }
255 
256     /*
257      * Read subbook information.
258      */
259     for (i = 0; i < book->subbook_count; i++) {
260         if (eb_read_all(file, buffer, 164) != 164) {
261 	    error_code = EB_ERR_FAIL_READ_CAT;
262 	    goto failed;
263 	}
264 	strncpy(book->subbooks[i], buffer + 82,
265 	    EB_MAX_DIRECTORY_NAME_LENGTH);
266 	*(book->subbooks[i] + EB_MAX_DIRECTORY_NAME_LENGTH) = '\0';
267         space = strchr(book->subbooks[i], ' ');
268         if (space != NULL)
269             *space = '\0';
270     }
271 
272     close(file);
273     return EB_SUCCESS;
274 
275     /*
276      * An error occurs...
277      */
278   failed:
279     if (0 <= file)
280 	close(file);
281 
282     return error_code;
283 }
284 
285 
286 EB_Error_Code
eb_subbook_list(book,subbook_list,subbook_count)287 eb_subbook_list(book, subbook_list, subbook_count)
288     EB_Book *book;
289     EB_Subbook_Code *subbook_list;
290     int *subbook_count;
291 {
292     int i;
293 
294     if (book->subbooks == NULL)
295 	return EB_ERR_UNBOUND_BOOK;
296 
297     for (i = 0; i < book->subbook_count; i++)
298 	subbook_list[i] = i;
299     *subbook_count = book->subbook_count;
300 
301     return EB_SUCCESS;
302 }
303 
304 
305 EB_Error_Code
eb_subbook_directory2(book,subbook_code,directory)306 eb_subbook_directory2(book, subbook_code, directory)
307     EB_Book *book;
308     EB_Subbook_Code subbook_code;
309     char *directory;
310 {
311     char *p;
312 
313     if (book->subbooks == NULL)
314 	return EB_ERR_UNBOUND_BOOK;
315 
316     if (subbook_code < 0 || book->subbook_count <= subbook_code)
317         return EB_ERR_NO_SUCH_SUB;
318 
319     strcpy(directory, book->subbooks[subbook_code]);
320     for (p = directory; *p != '\0'; p++) {
321         if ('A' <= *p && *p <= 'Z')
322             *p += ('a' - 'A');
323     }
324 
325     return EB_SUCCESS;
326 }
327 
328