1 /* @(#)findline.c 1.18 09/07/10 Copyright 1985, 1995-2003 J. Schilling */
2 /*
3 * findline
4 * get a line from a file with matching string in a given field
5 *
6 * ofindline
7 * get a line from open file with matching string in a given field
8 *
9 * getbroken
10 * separate a line into fields
11 *
12 * all fill pointers into the given array, allocated to new storage
13 *
14 * Copyright (c) 1985, 1995-2003 J. Schilling
15 */
16 /*
17 * The contents of this file are subject to the terms of the
18 * Common Development and Distribution License, Version 1.0 only
19 * (the "License"). You may not use this file except in compliance
20 * with the License.
21 *
22 * See the file CDDL.Schily.txt in this distribution for details.
23 * A copy of the CDDL is also available via the Internet at
24 * http://www.opensource.org/licenses/cddl1.txt
25 *
26 * When distributing Covered Code, include this CDDL HEADER in each
27 * file and include the License file CDDL.Schily.txt from this distribution.
28 */
29
30 #define USE_LARGEFILES /* We must make this module large file aware */
31
32 #include <schily/mconfig.h>
33 #include <schily/stdio.h>
34 #include <schily/standard.h>
35 #include <schily/stdlib.h>
36 #include <schily/unistd.h> /* Include sys/types.h to make off_t available */
37 #include <schily/string.h>
38 #include <schily/schily.h>
39
40 #define MAXLBUF 4096
41
42 /*
43 * Return codes:
44 */
45 #define SUCCESS 1 /* Found match */
46 #define NO_MATCH -1 /* Found no line with matching string */
47 #define ARG_ERROR -2 /* Bad parameter combination: */
48 /* calls raisecond("findline_arg_err") before */
49 #define OPEN_ERROR -3 /* Cannot open file */
50 #define NO_MEM -4 /* No memory: */
51 /* calls raisescond("findline_storage") before */
52
53 EXPORT int ofindline __PR((FILE *, char, const char *, int,
54 char **, int));
55 EXPORT int findline __PR((const char *, char, const char *, int,
56 char **, int));
57 EXPORT int getbroken __PR((FILE *, char *, char, char **, int));
58
59 LOCAL char *savestr __PR((const char *));
60
61 #ifdef PROTOTYPES
62 EXPORT int
ofindline(FILE * f,char delim,const char * string,int field,char * array[],int arraysize)63 ofindline(FILE *f,
64 char delim,
65 const char *string,
66 int field,
67 char *array[],
68 int arraysize)
69 #else
70 EXPORT int
71 ofindline(f, delim, string, field, array, arraysize)
72 FILE *f;
73 char delim;
74 char *string;
75 int field;
76 char *array[];
77 int arraysize;
78 #endif
79 {
80 int i;
81 char lbuf[MAXLBUF];
82
83 if (field >= arraysize) {
84 raisecond("findline_arg_err", 0L);
85 return (ARG_ERROR);
86 }
87
88 fileseek(f, (off_t)0); /* XXX ??? Interface �ndern!!! */
89 for (;;) {
90 if (getbroken(f, lbuf, delim, array, arraysize) < 0) {
91 return (NO_MATCH);
92 }
93 if (streql(string, array[field])) {
94 for (i = 0; i < arraysize; i++) {
95 if ((array[i] = savestr(array[i])) == NULL) {
96 raisecond("findline_storage", 0L);
97 while (--i >= 0)
98 free(array[i]);
99 return (NO_MEM);
100 }
101 }
102 return (SUCCESS);
103 }
104 }
105 }
106
107 #ifdef PROTOTYPES
108 EXPORT int
findline(const char * fname,char delim,const char * string,int field,char * array[],int arraysize)109 findline(const char *fname,
110 char delim,
111 const char *string,
112 int field,
113 char *array[],
114 int arraysize)
115 #else
116 EXPORT int
117 findline(fname, delim, string, field, array, arraysize)
118 char *fname;
119 char delim;
120 char *string;
121 int field;
122 char *array[];
123 int arraysize;
124 #endif
125 {
126 FILE *f;
127 int ret;
128
129 if ((f = fileopen(fname, "r")) == 0)
130 return (OPEN_ERROR);
131
132 ret = ofindline(f, delim, string, field, array, arraysize);
133 fclose(f);
134 return (ret);
135 }
136
137 #ifdef PROTOTYPES
138 EXPORT int
getbroken(FILE * f,char * linebuf,char delim,char * array[],int len)139 getbroken(FILE *f,
140 char *linebuf,
141 char delim,
142 char *array[],
143 int len)
144 #else
145 EXPORT int
146 getbroken(f, linebuf, delim, array, len)
147 FILE *f;
148 char *linebuf;
149 char delim;
150 char *array[];
151 int len;
152 #endif
153 {
154 if (fgetline(f, linebuf, MAXLBUF) < 0)
155 return (EOF);
156
157 breakline(linebuf, delim, array, len);
158 return (SUCCESS);
159 }
160
161 LOCAL char *
savestr(s)162 savestr(s)
163 register const char *s;
164 {
165 register char *p;
166 char *ret;
167
168 if ((p = malloc(strlen(s)+1)) == NULL)
169 return (p);
170 ret = p;
171 while ((*p++ = *s++) != '\0')
172 /* LINTED */
173 ;
174 return (ret);
175 }
176