1 /*
2 * Copyright (C) 1999-2004 Etymon Systems, Inc.
3 *
4 * Authors: Nassib Nassar
5 */
6
7 /* new */
8
9 #include <string.h>
10 #include "util.h"
11
afopendbf(const char * db,int type,const char * mode)12 FILE *afopendbf(const char *db, int type, const char *mode)
13 {
14 char fn[ETYMON_MAX_PATH_SIZE];
15 FILE *f;
16
17 if (afmakefn(type, db, fn) < 0)
18 return NULL;
19 f = fopen(fn, mode);
20 return f ? f : aferrn(AFEDBIO);
21 }
22
closefile(FILE * f)23 static inline int closefile(FILE *f)
24 {
25 if (f) {
26 if (fclose(f) == EOF)
27 return aferr(AFEDBIO);
28 }
29 return 0;
30 }
31
afclosedbf(Affile * f)32 int afclosedbf(Affile *f)
33 {
34 if (closefile(f->info) < 0)
35 return -1;
36 if (closefile(f->doctab) < 0)
37 return -1;
38 if (closefile(f->udict) < 0)
39 return -1;
40 if (closefile(f->upost) < 0)
41 return -1;
42 if (closefile(f->ufield) < 0)
43 return -1;
44 if (closefile(f->lpost) < 0)
45 return -1;
46 if (closefile(f->lfield) < 0)
47 return -1;
48 if (closefile(f->fdef) < 0)
49 return -1;
50 if (closefile(f->uword) < 0)
51 return -1;
52 if (closefile(f->lword) < 0)
53 return -1;
54 if (closefile(f->lock) < 0)
55 return -1;
56 return 0;
57 }
58
getftfn(int type)59 static inline char *getftfn(int type)
60 {
61 if (type < sizeof affntab)
62 return affntab[type];
63 else
64 return aferrn(AFEINVAL);
65 }
66
67 /* buf is assumed to have capacity ETYMON_MAX_PATH_SIZE */
afmakefn(int type,const char * db,char * buf)68 int afmakefn(int type, const char *db, char *buf)
69 {
70 int dblen, extlen;
71 char *ext;
72
73 dblen = strlen(db);
74 memcpy(buf, db, dblen);
75 buf += dblen;
76 ext = getftfn(type);
77 if (!ext)
78 return -1;
79 extlen = strlen(ext);
80 if ((dblen + extlen) >= ETYMON_MAX_PATH_SIZE)
81 return aferr(AFEBUFOVER);
82 memcpy(buf, ext, extlen + 1);
83 return 0;
84 }
85
86 /*
87 int afgetfsize_nonansi(FILE *f, off_t *size)
88 {
89 struct stat st;
90
91 if (fstat(fileno(f), &st) < 0)
92 return aferr(AFEDBIO);
93 *size = st.st_size;
94 return 0;
95 }
96 */
97
afgetfsize(FILE * f,off_t * size)98 int afgetfsize(FILE *f, off_t *size)
99 {
100 off_t save;
101
102 if ((save = ftello(f)) < 0)
103 return aferr(AFEDBIO);
104 if (fseeko(f, 0, SEEK_END) < 0)
105 return aferr(AFEDBIO);
106 if ((*size = ftello(f)) < 0)
107 return aferr(AFEDBIO);
108 if (fseeko(f, save, SEEK_SET) < 0)
109 return aferr(AFEDBIO);
110 return 0;
111 }
112
afprintvp(int verbose,int minimum)113 void afprintvp(int verbose, int minimum)
114 {
115 int x;
116
117 for (x = 2; x < minimum; x++)
118 printf("+");
119 if (minimum > 2)
120 printf(" ");
121 }
122
afprintv(int verbose,int minimum,const char * msg)123 void afprintv(int verbose, int minimum, const char *msg)
124 {
125 if (verbose >= minimum) {
126 afprintvp(verbose, minimum);
127 printf("%s\n", msg);
128 }
129 }
130
131 /* old */
132
133 #include <stdlib.h>
134 #include <stdio.h>
135 #include <unistd.h>
136 #include <ctype.h>
137 #include <sys/types.h>
138 #include <sys/stat.h>
139 #include <fcntl.h>
140
141 #define ETYMON_UTIL_MAX_ARG_SIZE 4096
142
143 /**
144 Constructs a path name using a dbname as the stem and appending an
145 extension depending on the type of file requested.
146
147 @param ftype the type of file (e.g. ETYMON_DB_INFO).
148 @param dbname the database name to use as a stem.
149 @param buf the buffer to construct the path in (assumed to have
150 capacity ETYMON_MAX_PATH_SIZE)
151 */
etymon_db_construct_path(int ftype,const char * dbname,char * buf)152 void etymon_db_construct_path(int ftype, const char* dbname, char* buf) {
153 int leftover; /* extra space in buf after dbname is copied in */
154 /* start with dbname as the stem */
155 strncpy(buf, dbname, ETYMON_MAX_PATH_SIZE - 1);
156 buf[ETYMON_MAX_PATH_SIZE - 1] = '\0';
157 leftover = ETYMON_MAX_PATH_SIZE - strlen(buf) - 1;
158 /* now add the proper extension */
159 switch (ftype) {
160 case ETYMON_DBF_INFO:
161 strncat(buf, ETYMON_DBF_INFO_EXT, leftover);
162 break;
163 case ETYMON_DBF_DOCTABLE:
164 strncat(buf, ETYMON_DBF_DOCTABLE_EXT, leftover);
165 break;
166 case ETYMON_DBF_UDICT:
167 strncat(buf, ETYMON_DBF_UDICT_EXT, leftover);
168 break;
169 case ETYMON_DBF_UPOST:
170 strncat(buf, ETYMON_DBF_UPOST_EXT, leftover);
171 break;
172 case ETYMON_DBF_UFIELD:
173 strncat(buf, ETYMON_DBF_UFIELD_EXT, leftover);
174 break;
175 case ETYMON_DBF_LPOST:
176 strncat(buf, ETYMON_DBF_LPOST_EXT, leftover);
177 break;
178 case ETYMON_DBF_LFIELD:
179 strncat(buf, ETYMON_DBF_LFIELD_EXT, leftover);
180 break;
181 case ETYMON_DBF_LOCK:
182 strncat(buf, ETYMON_DBF_LOCK_EXT, leftover);
183 break;
184 case ETYMON_DBF_FDEF:
185 strncat(buf, ETYMON_DBF_FDEF_EXT, leftover);
186 break;
187 case ETYMON_DBF_UWORD:
188 strncat(buf, ETYMON_DBF_UWORD_EXT, leftover);
189 break;
190 case ETYMON_DBF_LWORD:
191 strncat(buf, ETYMON_DBF_LWORD_EXT, leftover);
192 break;
193 default:
194 break;
195 }
196 }
197
198
etymon_tolower(char * s)199 void etymon_tolower(char* s) {
200 char* p = s;
201
202 while (*p != '\0') {
203 *p = tolower(*p);
204 p++;
205 }
206 }
207
208
etymon_split_options(int argc,char * argv[])209 char*** etymon_split_options(int argc, char *argv[]) {
210 /*
211 we're going to create a 2-dimensional array that looks something like this:
212 { { "-d", "dbname" },
213 { "-f", "file1", "file2", "file3" } }
214 to do that we need to first figure out which argv[] are options flags.
215 the starts array keeps track of the start of each option group
216 */
217 int* starts;
218 int starts_count;
219 int r;
220 char*** options;
221 starts = (int*)(malloc(sizeof(int) * argc));
222 starts_count = 0;
223 for (r = 1; r < argc; r++) {
224 /* check if it's an option flag */
225 if (argv[r][0] == '-') {
226 if ( (argv[r][1] == '\0') || (argv[r][1] != '-') ) {
227 /* yes, it's an option flag */
228 starts[starts_count++] = r;
229 }
230 }
231 }
232 /* in the last element of starts we store the next (imaginary) start number */
233 starts[starts_count] = argc;
234 /* now the starts array contains a list of the indicies of argv[] which contain options flags
235 so we we next build the options array based on this information */
236 options = (char***)(malloc(sizeof(char**) * (starts_count + 1)));
237 for (r = 0; r < starts_count; r++) {
238 /* size is the number of columns in this row of the array */
239 int size = starts[r+1] - starts[r];
240 int c;
241 options[r] = (char**)(malloc(sizeof(char*) * (size + 1)));
242 for (c = 0; c < size; c++) {
243 char* s = argv[starts[r] + c];
244 /* convert leading "--" to "-" in option arguments */
245 if ( (c > 0) && (strncmp(s, "--", 2) == 0) ) {
246 options[r][c] = (char*)(malloc(strlen(s)));
247 strcpy(options[r][c], s + 1);
248 } else {
249 options[r][c] = (char*)(malloc(strlen(s) + 1));
250 strcpy(options[r][c], s);
251 }
252 }
253 options[r][size] = NULL;
254 }
255 options[starts_count] = NULL;
256 free(starts);
257 return options;
258 }
259
260
etymon_doctable_getinfo(char * dbname,ETYMON_DOCTABLE * doctable)261 void etymon_doctable_getinfo(char* dbname, ETYMON_DOCTABLE* doctable) {
262 char fn[ETYMON_MAX_PATH_SIZE];
263 int fd;
264
265 /* need to check for buffer overrun */
266 etymon_db_construct_path(ETYMON_DBF_DOCTABLE, dbname, fn);
267 fd = open(fn, O_RDONLY | ETYMON_AF_O_LARGEFILE, ETYMON_DB_PERM);
268 /* need to check for missing database and transient I/O failures */
269 if (read(fd, doctable, sizeof(ETYMON_DOCTABLE)) == -1) {
270 perror("doctable_getinfo():read()");
271 }
272 close(fd);
273 }
274