"Fossies" - the Fresh Open Source Software Archive 
Member "passwdqc-2.0.3/passwdqc_load.c" (23 Jun 2023, 2754 Bytes) of package /linux/privat/passwdqc-2.0.3.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "passwdqc_load.c" see the
Fossies "Dox" file reference documentation and the last
Fossies "Diffs" side-by-side code changes report:
1.4.0_vs_2.0.0.
1 /*
2 * Copyright (c) 2008,2009 by Dmitry V. Levin
3 * Copyright (c) 2021 by Solar Designer
4 * See LICENSE
5 */
6
7 #ifdef _MSC_VER
8 #define _CRT_NONSTDC_NO_WARNINGS /* we use POSIX function names */
9 #define _CRT_SECURE_NO_WARNINGS /* we use fopen(), strerror(), sprintf() */
10 #endif
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <stdarg.h>
16 #include <errno.h>
17 #include <sys/stat.h>
18
19 #include "passwdqc.h"
20 #include "concat.h"
21
22 static char *mkreason(const char *what, const char *pathname,
23 unsigned int lineno, const char *why)
24 {
25 char buf[sizeof(unsigned int) * 3 + 1];
26 const char *at_line = (lineno ? " at line " : "");
27 const char *at_num = (lineno ? buf : "");
28
29 if (lineno)
30 sprintf(buf, "%u", lineno);
31 return concat(what, " \"", pathname, "\"", at_line, at_num, ": ",
32 (why ? why : strerror(errno)), NULL);
33 }
34
35 static int
36 parse_file(FILE *fp, passwdqc_params_t *params, char **reason,
37 const char *pathname)
38 {
39 unsigned int lineno;
40 char buf[8192];
41
42 for (lineno = 1; fgets(buf, sizeof(buf), fp); ++lineno) {
43 char *str, *end, *rt;
44 const char *cstr;
45 int rc;
46
47 if (strlen(buf) >= sizeof(buf) - 1) {
48 *reason = mkreason("Error reading", pathname,
49 lineno, "Line too long");
50 return -1;
51 }
52
53 str = buf + strspn(buf, " \t\r\n");
54 if (!*str || *str == '#')
55 continue;
56
57 if ((end = strpbrk(str, "\r\n")))
58 *end = '\0';
59 else
60 end = str + strlen(str);
61
62 while (end > str && (*--end == ' ' || *end == '\t'))
63 *end = '\0';
64
65 cstr = str;
66 if ((rc = passwdqc_params_parse(params, &rt, 1, &cstr))) {
67 *reason = mkreason("Error loading", pathname,
68 lineno, (rt ? rt : "Out of memory"));
69 free(rt);
70 return rc;
71 }
72 }
73
74 if (!feof(fp) || ferror(fp)) {
75 *reason = mkreason("Error reading", pathname, 0, NULL);
76 return -1;
77 }
78
79 return 0;
80 }
81
82 struct dev_ino_t;
83 struct dev_ino_t {
84 struct dev_ino_t *next;
85 dev_t dev;
86 ino_t ino;
87 };
88
89 static struct dev_ino_t *dev_ino_head;
90
91 int
92 passwdqc_params_load(passwdqc_params_t *params, char **reason,
93 const char *pathname)
94 {
95 int rc;
96 FILE *fp;
97 struct dev_ino_t di, *di_p;
98 struct stat st;
99
100 if (!(fp = fopen(pathname, "r"))) {
101 *reason = mkreason("Error opening", pathname, 0, NULL);
102 return -1;
103 }
104
105 if (fstat(fileno(fp), &st)) {
106 *reason = mkreason("Error stat", pathname, 0, NULL);
107 fclose(fp);
108 return -1;
109 }
110
111 di.dev = st.st_dev;
112 di.ino = st.st_ino;
113 for (di_p = dev_ino_head; di_p; di_p = di_p->next)
114 if (di_p->dev == di.dev && di_p->ino == di.ino)
115 break;
116 if (di_p) {
117 *reason = mkreason("Error opening", pathname, 0,
118 "Loop detected");
119 fclose(fp);
120 return -1;
121 }
122
123 di.next = dev_ino_head;
124 dev_ino_head = &di;
125
126 rc = parse_file(fp, params, reason, pathname);
127 fclose(fp);
128
129 dev_ino_head = dev_ino_head->next;
130 return rc;
131 }