libite 2.6.1
lfile.c
Go to the documentation of this file.
1/* Parse UNIX /etc configuration files like /etc/protocols and /etc/services
2 *
3 * Copyright (c) 2015-2021 Joachim Wiberg <troglobit@gmail.com>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
24
25#include <errno.h>
26#include <stdio.h> /* FILE */
27#include <stdlib.h> /* atoi() */
28#include <string.h> /* strlen(), strncmp(), strtok_r() */
29#include <sys/param.h> /* MAX() */
30
32typedef struct lfile {
33 FILE *fp;
34 char buf[256];
35 char *save;
36 const char *sep;
37} lfile_t;
38
46lfile_t *lfopen(const char *file, const char *sep)
47{
48 lfile_t *lf;
49
50 if (!file || !sep) {
51 errno = EINVAL;
52 return NULL;
53 }
54
55 /* Use calloc for clearing buf on behalf of lftok() */
56 lf = calloc(sizeof(*lf), sizeof(char));
57 if (lf) {
58 lf->fp = fopen(file, "r");
59 lf->sep = sep;
60 lf->save = lf->buf;
61
62 if (!lf->fp) {
63 free(lf);
64 return NULL;
65 }
66 }
67
68 return lf;
69}
70
75void lfclose(lfile_t *lf)
76{
77 if (!lf)
78 return;
79
80 if (lf->fp)
81 fclose(lf->fp);
82 free(lf);
83}
84
92char *lftok(lfile_t *lf)
93{
94 char *token;
95
96 if (!lf || !lf->fp || !lf->sep) {
97 errno = EINVAL;
98 return NULL;
99 }
100
101 token = strtok_r(NULL, lf->sep, &lf->save);
102 if (token)
103 return token;
104
105 while (fgets(lf->buf, sizeof(lf->buf), lf->fp)) {
106 if (lf->buf[0] == '#')
107 continue;
108
109 token = strtok_r(lf->buf, lf->sep, &lf->save);
110 if (token)
111 return token;
112 }
113
114 errno = ENOENT;
115 return NULL;
116}
117
131char *lfgetkey(lfile_t *lf, const char *key)
132{
133 char *token;
134
135 while ((token = lftok(lf))) {
136 if (token[0] == '#')
137 continue;
138
139 if (!strncmp(token, key, MAX(strlen(token), strlen(key))))
140 return lftok(lf);
141 }
142
143 return NULL;
144}
145
156int lfgetint(lfile_t *lf, const char *key)
157{
158 char *token = lfgetkey(lf, key);
159
160 if (token)
161 return atoi(token);
162
163 return -1;
164}
165
177int fgetint(const char *file, const char *sep, const char *key)
178{
179 int val = -1;
180 lfile_t *lf;
181
182 lf = lfopen(file, sep);
183 if (lf) {
184 val = lfgetint(lf, key);
185 lfclose(lf);
186 }
187
188 return val;
189}
190
char * lftok(lfile_t *lf)
Definition lfile.c:92
int lfgetint(lfile_t *lf, const char *key)
Definition lfile.c:156
void lfclose(lfile_t *lf)
Definition lfile.c:75
lfile_t * lfopen(const char *file, const char *sep)
Definition lfile.c:46
int fgetint(const char *file, const char *sep, const char *key)
Definition lfile.c:177
char * lfgetkey(lfile_t *lf, const char *key)
Definition lfile.c:131