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