runshare 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,218 @@
1
+ /*
2
+ * No copyright is claimed. This code is in the public domain; do with
3
+ * it what you wish.
4
+ */
5
+ #ifndef PATHNAMES_H
6
+ #define PATHNAMES_H
7
+
8
+ #ifdef HAVE_PATHS_H
9
+ # include <paths.h>
10
+ #endif
11
+
12
+ #ifndef __STDC__
13
+ # error "we need an ANSI compiler"
14
+ #endif
15
+
16
+ /* used by kernel in /proc (e.g. /proc/swaps) for deleted files */
17
+ #define PATH_DELETED_SUFFIX " (deleted)"
18
+
19
+ /* DEFPATHs from <paths.h> don't include /usr/local */
20
+ #undef _PATH_DEFPATH
21
+
22
+ #ifdef USE_USRDIR_PATHS_ONLY
23
+ # define _PATH_DEFPATH "/usr/local/bin:/usr/bin"
24
+ #else
25
+ # define _PATH_DEFPATH "/usr/local/bin:/bin:/usr/bin"
26
+ #endif
27
+
28
+ #undef _PATH_DEFPATH_ROOT
29
+
30
+ #ifdef USE_USRDIR_PATHS_ONLY
31
+ # define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
32
+ #else
33
+ # define _PATH_DEFPATH_ROOT "/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
34
+ #endif
35
+
36
+ #define _PATH_HUSHLOGIN ".hushlogin"
37
+ #define _PATH_HUSHLOGINS "/etc/hushlogins"
38
+
39
+ #define _PATH_NOLOGIN_TXT "/etc/nologin.txt"
40
+
41
+ #ifndef _PATH_MAILDIR
42
+ # define _PATH_MAILDIR "/var/spool/mail"
43
+ #endif
44
+ #define _PATH_MOTDFILE "/usr/share/misc/motd:/run/motd:/etc/motd"
45
+ #ifndef _PATH_NOLOGIN
46
+ # define _PATH_NOLOGIN "/etc/nologin"
47
+ #endif
48
+ #define _PATH_VAR_NOLOGIN "/var/run/nologin"
49
+
50
+ #ifndef _PATH_LOGIN
51
+ # define _PATH_LOGIN "/bin/login"
52
+ #endif
53
+ #define _PATH_SHUTDOWN "/sbin/shutdown"
54
+ #define _PATH_POWEROFF "/sbin/poweroff"
55
+
56
+ #define _PATH_TERMCOLORS_DIRNAME "terminal-colors.d"
57
+ #define _PATH_TERMCOLORS_DIR "/etc/" _PATH_TERMCOLORS_DIRNAME
58
+
59
+ /* login paths */
60
+ #define _PATH_PASSWD "/etc/passwd"
61
+ #define _PATH_GSHADOW "/etc/gshadow"
62
+ #define _PATH_GROUP "/etc/group"
63
+ #define _PATH_SHADOW_PASSWD "/etc/shadow"
64
+ #define _PATH_SHELLS "/etc/shells"
65
+
66
+ #ifndef _PATH_TMP
67
+ # define _PATH_TMP "/tmp/"
68
+ #endif
69
+
70
+ #ifndef _PATH_BTMP
71
+ # define _PATH_BTMP "/var/log/btmp"
72
+ #endif
73
+
74
+ #define _PATH_ISSUE_FILENAME "issue"
75
+ #define _PATH_ISSUE_DIRNAME _PATH_ISSUE_FILENAME ".d"
76
+
77
+ #define _PATH_ISSUE "/etc/" _PATH_ISSUE_FILENAME
78
+ #define _PATH_ISSUEDIR "/etc/" _PATH_ISSUE_DIRNAME
79
+
80
+ #define _PATH_OS_RELEASE_ETC "/etc/os-release"
81
+ #define _PATH_OS_RELEASE_USR "/usr/lib/os-release"
82
+ #define _PATH_NUMLOCK_ON _PATH_RUNSTATEDIR "/numlock-on"
83
+ #define _PATH_LOGINDEFS "/etc/login.defs"
84
+
85
+ /* misc paths */
86
+ #define _PATH_WORDS "/usr/share/dict/words"
87
+ #define _PATH_WORDS_ALT "/usr/share/dict/web2"
88
+
89
+ /* mount paths */
90
+ #define _PATH_FILESYSTEMS "/etc/filesystems"
91
+ #define _PATH_PROC_SWAPS "/proc/swaps"
92
+ #define _PATH_PROC_FILESYSTEMS "/proc/filesystems"
93
+ #define _PATH_PROC_MOUNTS "/proc/mounts"
94
+ #define _PATH_PROC_PARTITIONS "/proc/partitions"
95
+ #define _PATH_PROC_DEVICES "/proc/devices"
96
+ #define _PATH_PROC_MOUNTINFO "/proc/self/mountinfo"
97
+ #define _PATH_PROC_LOCKS "/proc/locks"
98
+ #define _PATH_PROC_CDROMINFO "/proc/sys/dev/cdrom/info"
99
+
100
+ #define _PATH_PROC_UIDMAP "/proc/self/uid_map"
101
+ #define _PATH_PROC_GIDMAP "/proc/self/gid_map"
102
+ #define _PATH_PROC_SETGROUPS "/proc/self/setgroups"
103
+
104
+ #define _PATH_PROC_FDDIR "/proc/self/fd"
105
+
106
+ #define _PATH_PROC_ATTR_CURRENT "/proc/self/attr/current"
107
+ #define _PATH_PROC_ATTR_EXEC "/proc/self/attr/exec"
108
+ #define _PATH_PROC_CAPLASTCAP "/proc/sys/kernel/cap_last_cap"
109
+
110
+
111
+ #define _PATH_SYS_BLOCK "/sys/block"
112
+ #define _PATH_SYS_DEVBLOCK "/sys/dev/block"
113
+ #define _PATH_SYS_DEVCHAR "/sys/dev/char"
114
+ #define _PATH_SYS_CLASS "/sys/class"
115
+ #define _PATH_SYS_SCSI "/sys/bus/scsi"
116
+
117
+ #define _PATH_SYS_SELINUX "/sys/fs/selinux"
118
+ #define _PATH_SYS_APPARMOR "/sys/kernel/security/apparmor"
119
+
120
+ #ifndef _PATH_MOUNTED
121
+ # ifdef MOUNTED /* deprecated */
122
+ # define _PATH_MOUNTED MOUNTED
123
+ # else
124
+ # define _PATH_MOUNTED "/etc/mtab"
125
+ # endif
126
+ #endif
127
+
128
+ #ifndef _PATH_MNTTAB
129
+ # ifdef MNTTAB /* deprecated */
130
+ # define _PATH_MNTTAB MNTTAB
131
+ # else
132
+ # define _PATH_MNTTAB "/etc/fstab"
133
+ # endif
134
+ #endif
135
+
136
+ #ifndef _PATH_DEV
137
+ /*
138
+ * The tailing '/' in _PATH_DEV is there for compatibility with libc.
139
+ */
140
+ # define _PATH_DEV "/dev/"
141
+ #endif
142
+
143
+ #define _PATH_DEV_MAPPER "/dev/mapper"
144
+
145
+ #define _PATH_DEV_MEM "/dev/mem"
146
+
147
+ #define _PATH_DEV_LOOP "/dev/loop"
148
+ #define _PATH_DEV_LOOPCTL "/dev/loop-control"
149
+
150
+ /* udev paths */
151
+ #define _PATH_DEV_BYLABEL "/dev/disk/by-label"
152
+ #define _PATH_DEV_BYUUID "/dev/disk/by-uuid"
153
+ #define _PATH_DEV_BYID "/dev/disk/by-id"
154
+ #define _PATH_DEV_BYPATH "/dev/disk/by-path"
155
+ #define _PATH_DEV_BYPARTLABEL "/dev/disk/by-partlabel"
156
+ #define _PATH_DEV_BYPARTUUID "/dev/disk/by-partuuid"
157
+
158
+ /* hwclock paths */
159
+ #ifdef CONFIG_ADJTIME_PATH
160
+ # define _PATH_ADJTIME CONFIG_ADJTIME_PATH
161
+ #else
162
+ # define _PATH_ADJTIME "/etc/adjtime"
163
+ #endif
164
+
165
+ #ifdef __ia64__
166
+ # define _PATH_RTC_DEV "/dev/efirtc"
167
+ #else
168
+ # define _PATH_RTC_DEV "/dev/rtc0"
169
+ #endif
170
+
171
+ /* raw paths*/
172
+ #define _PATH_RAWDEVDIR "/dev/raw/"
173
+ #define _PATH_RAWDEVCTL _PATH_RAWDEVDIR "rawctl"
174
+ /* deprecated */
175
+ #define _PATH_RAWDEVCTL_OLD "/dev/rawctl"
176
+
177
+ #define _PATH_PROC_KERNEL "/proc/sys/kernel"
178
+
179
+ /* ipc paths */
180
+ #define _PATH_PROC_SYSV_MSG "/proc/sysvipc/msg"
181
+ #define _PATH_PROC_SYSV_SEM "/proc/sysvipc/sem"
182
+ #define _PATH_PROC_SYSV_SHM "/proc/sysvipc/shm"
183
+ #define _PATH_PROC_IPC_MSGMAX _PATH_PROC_KERNEL "/msgmax"
184
+ #define _PATH_PROC_IPC_MSGMNB _PATH_PROC_KERNEL "/msgmnb"
185
+ #define _PATH_PROC_IPC_MSGMNI _PATH_PROC_KERNEL "/msgmni"
186
+ #define _PATH_PROC_IPC_SEM _PATH_PROC_KERNEL "/sem"
187
+ #define _PATH_PROC_IPC_SHMALL _PATH_PROC_KERNEL "/shmall"
188
+ #define _PATH_PROC_IPC_SHMMAX _PATH_PROC_KERNEL "/shmmax"
189
+ #define _PATH_PROC_IPC_SHMMNI _PATH_PROC_KERNEL "/shmmni"
190
+
191
+ /* util clamp */
192
+ #define _PATH_PROC_UCLAMP_MIN _PATH_PROC_KERNEL "/sched_util_clamp_min"
193
+ #define _PATH_PROC_UCLAMP_MAX _PATH_PROC_KERNEL "/sched_util_clamp_max"
194
+
195
+ /* irqtop paths */
196
+ #define _PATH_PROC_INTERRUPTS "/proc/interrupts"
197
+ #define _PATH_PROC_SOFTIRQS "/proc/softirqs"
198
+ #define _PATH_PROC_UPTIME "/proc/uptime"
199
+
200
+ /* kernel command line */
201
+ #define _PATH_PROC_CMDLINE "/proc/cmdline"
202
+
203
+
204
+ /* logger paths */
205
+ #define _PATH_DEVLOG "/dev/log"
206
+
207
+ /* ctrlaltdel paths */
208
+ #define _PATH_PROC_CTRL_ALT_DEL "/proc/sys/kernel/ctrl-alt-del"
209
+
210
+ /* lscpu paths */
211
+ #define _PATH_PROC_CPUINFO "/proc/cpuinfo"
212
+
213
+ /* rfkill paths */
214
+ #define _PATH_DEV_RFKILL "/dev/rfkill"
215
+ #define _PATH_SYS_RFKILL "/sys/class/rfkill"
216
+
217
+
218
+ #endif /* PATHNAMES_H */
@@ -0,0 +1,14 @@
1
+ #ifndef UTIL_LINUX_PWDUTILS_H
2
+ #define UTIL_LINUX_PWDUTILS_H
3
+
4
+ #include <sys/types.h>
5
+ #include <pwd.h>
6
+ #include <grp.h>
7
+
8
+ extern struct passwd *xgetpwnam(const char *username, char **pwdbuf);
9
+ extern struct group *xgetgrnam(const char *groupname, char **grpbuf);
10
+ extern struct passwd *xgetpwuid(uid_t uid, char **pwdbuf);
11
+ extern char *xgetlogin(void);
12
+
13
+ #endif /* UTIL_LINUX_PWDUTILS_H */
14
+
@@ -0,0 +1,8 @@
1
+ #ifndef SIGNAMES_H
2
+ #define SIGNAMES_H
3
+
4
+ int signame_to_signum(const char *sig);
5
+ const char *signum_to_signame(int signum);
6
+ int get_signame_by_idx(size_t idx, const char **signame, int *signum);
7
+
8
+ #endif /* SIGNAMES_H */
@@ -0,0 +1,393 @@
1
+ #ifndef UTIL_LINUX_STRUTILS
2
+ #define UTIL_LINUX_STRUTILS
3
+
4
+ #include <stdlib.h>
5
+ #include <inttypes.h>
6
+ #include <string.h>
7
+ #include <sys/types.h>
8
+ #include <ctype.h>
9
+ #include <stdio.h>
10
+ #include <errno.h>
11
+ #include <time.h>
12
+
13
+ #include "c.h"
14
+
15
+ /* initialize a custom exit code for all *_or_err functions */
16
+ extern void strutils_set_exitcode(int exit_code);
17
+
18
+ extern int parse_size(const char *str, uintmax_t *res, int *power);
19
+ extern int strtosize(const char *str, uintmax_t *res);
20
+ extern uintmax_t strtosize_or_err(const char *str, const char *errmesg);
21
+
22
+ extern int ul_strtos64(const char *str, int64_t *num, int base);
23
+ extern int ul_strtou64(const char *str, uint64_t *num, int base);
24
+ extern int ul_strtos32(const char *str, int32_t *num, int base);
25
+ extern int ul_strtou32(const char *str, uint32_t *num, int base);
26
+
27
+ extern int64_t str2num_or_err(const char *str, int base, const char *errmesg, int64_t low, int64_t up);
28
+ extern uint64_t str2unum_or_err(const char *str, int base, const char *errmesg, uint64_t up);
29
+
30
+ #define strtos64_or_err(_s, _e) str2num_or_err(_s, 10, _e, 0, 0)
31
+ #define strtou64_or_err(_s, _e) str2unum_or_err(_s, 10, _e, 0)
32
+ #define strtox64_or_err(_s, _e) str2unum_or_err(_s, 16, _e, 0)
33
+
34
+ #define strtos32_or_err(_s, _e) (int32_t) str2num_or_err(_s, 10, _e, INT32_MIN, INT32_MAX)
35
+ #define strtou32_or_err(_s, _e) (uint32_t) str2unum_or_err(_s, 10, _e, UINT32_MAX)
36
+ #define strtox32_or_err(_s, _e) (uint32_t) str2unum_or_err(_s, 16, _e, UINT32_MAX)
37
+
38
+ #define strtos16_or_err(_s, _e) (int16_t) str2num_or_err(_s, 10, _e, INT16_MIN, INT16_MAX)
39
+ #define strtou16_or_err(_s, _e) (uint16_t) str2unum_or_err(_s, 10, _e, UINT16_MAX)
40
+ #define strtox16_or_err(_s, _e) (uint16_t) str2unum_or_err(_s, 16, _e, UINT16_MAX)
41
+
42
+ extern double strtod_or_err(const char *str, const char *errmesg);
43
+ extern long double strtold_or_err(const char *str, const char *errmesg);
44
+
45
+ extern long strtol_or_err(const char *str, const char *errmesg);
46
+ extern unsigned long strtoul_or_err(const char *str, const char *errmesg);
47
+
48
+ extern void strtotimeval_or_err(const char *str, struct timeval *tv,
49
+ const char *errmesg);
50
+ extern time_t strtotime_or_err(const char *str, const char *errmesg);
51
+
52
+ extern int isdigit_strend(const char *str, const char **end);
53
+ #define isdigit_string(_s) isdigit_strend(_s, NULL)
54
+
55
+ extern int isxdigit_strend(const char *str, const char **end);
56
+ #define isxdigit_string(_s) isxdigit_strend(_s, NULL)
57
+
58
+
59
+ extern int parse_switch(const char *arg, const char *errmesg, ...);
60
+
61
+ #ifndef HAVE_MEMPCPY
62
+ extern void *mempcpy(void *restrict dest, const void *restrict src, size_t n);
63
+ #endif
64
+ #ifndef HAVE_STRNLEN
65
+ extern size_t strnlen(const char *s, size_t maxlen);
66
+ #endif
67
+ #ifndef HAVE_STRNDUP
68
+ extern char *strndup(const char *s, size_t n);
69
+ #endif
70
+ #ifndef HAVE_STRNCHR
71
+ extern char *strnchr(const char *s, size_t maxlen, int c);
72
+ #endif
73
+
74
+ /* caller guarantees n > 0 */
75
+ static inline void xstrncpy(char *dest, const char *src, size_t n)
76
+ {
77
+ size_t len = src ? strlen(src) : 0;
78
+
79
+ if (!len)
80
+ return;
81
+ len = min(len, n - 1);
82
+ memcpy(dest, src, len);
83
+ dest[len] = 0;
84
+ }
85
+
86
+ /* This is like strncpy(), but based on memcpy(), so compilers and static
87
+ * analyzers do not complain when sizeof(destination) is the same as 'n' and
88
+ * result is not terminated by zero.
89
+ *
90
+ * Use this function to copy string to logs with fixed sizes (wtmp/utmp. ...)
91
+ * where string terminator is optional.
92
+ */
93
+ static inline void *str2memcpy(void *dest, const char *src, size_t n)
94
+ {
95
+ size_t bytes = strlen(src) + 1;
96
+
97
+ if (bytes > n)
98
+ bytes = n;
99
+
100
+ memcpy(dest, src, bytes);
101
+ return dest;
102
+ }
103
+
104
+ static inline char *mem2strcpy(char *dest, const void *src, size_t n, size_t nmax)
105
+ {
106
+ if (n + 1 > nmax)
107
+ n = nmax - 1;
108
+
109
+ memcpy(dest, src, n);
110
+ dest[nmax-1] = '\0';
111
+ return dest;
112
+ }
113
+
114
+ /* Reallocate @str according to @newstr and copy @newstr to @str; returns new @str.
115
+ * The @str is not modified if reallocation failed (like classic realloc()).
116
+ */
117
+ static inline char * __attribute__((warn_unused_result))
118
+ strrealloc(char *str, const char *newstr)
119
+ {
120
+ size_t nsz, osz;
121
+
122
+ if (!str)
123
+ return newstr ? strdup(newstr) : NULL;
124
+ if (!newstr)
125
+ return NULL;
126
+
127
+ osz = strlen(str);
128
+ nsz = strlen(newstr);
129
+
130
+ if (nsz > osz)
131
+ str = realloc(str, nsz + 1);
132
+ if (str)
133
+ memcpy(str, newstr, nsz + 1);
134
+ return str;
135
+ }
136
+
137
+ /* Copy string @str to struct @stru to member addressed by @offset */
138
+ static inline int strdup_to_offset(void *stru, size_t offset, const char *str)
139
+ {
140
+ char **o;
141
+ char *p = NULL;
142
+
143
+ if (!stru)
144
+ return -EINVAL;
145
+
146
+ o = (char **) ((char *) stru + offset);
147
+ if (str) {
148
+ p = strdup(str);
149
+ if (!p)
150
+ return -ENOMEM;
151
+ }
152
+
153
+ free(*o);
154
+ *o = p;
155
+ return 0;
156
+ }
157
+
158
+ /* Copy string __str to struct member _m of the struct _s */
159
+ #define strdup_to_struct_member(_s, _m, _str) \
160
+ strdup_to_offset((void *) _s, offsetof(__typeof__(*(_s)), _m), _str)
161
+
162
+ /* Copy string addressed by @offset between two structs */
163
+ static inline int strdup_between_offsets(void *stru_dst, void *stru_src, size_t offset)
164
+ {
165
+ char **src;
166
+ char **dst;
167
+ char *p = NULL;
168
+
169
+ if (!stru_src || !stru_dst)
170
+ return -EINVAL;
171
+
172
+ src = (char **) ((char *) stru_src + offset);
173
+ dst = (char **) ((char *) stru_dst + offset);
174
+
175
+ if (*src) {
176
+ p = strdup(*src);
177
+ if (!p)
178
+ return -ENOMEM;
179
+ }
180
+
181
+ free(*dst);
182
+ *dst = p;
183
+ return 0;
184
+ }
185
+
186
+ /* Copy string addressed by struct member between two instances of the same
187
+ * struct type */
188
+ #define strdup_between_structs(_dst, _src, _m) \
189
+ strdup_between_offsets((void *)_dst, (void *)_src, offsetof(__typeof__(*(_src)), _m))
190
+
191
+
192
+ extern char *xstrmode(mode_t mode, char *str);
193
+
194
+ /* Options for size_to_human_string() */
195
+ enum
196
+ {
197
+ SIZE_SUFFIX_1LETTER = 0,
198
+ SIZE_SUFFIX_3LETTER = (1 << 0),
199
+ SIZE_SUFFIX_SPACE = (1 << 1),
200
+ SIZE_DECIMAL_2DIGITS = (1 << 2)
201
+ };
202
+
203
+ extern char *size_to_human_string(int options, uint64_t bytes);
204
+
205
+ extern int string_to_idarray(const char *list, int ary[], size_t arysz,
206
+ int (name2id)(const char *, size_t));
207
+ extern int string_add_to_idarray(const char *list, int ary[],
208
+ size_t arysz, size_t *ary_pos,
209
+ int (name2id)(const char *, size_t));
210
+
211
+ extern int string_to_bitarray(const char *list, char *ary,
212
+ int (*name2bit)(const char *, size_t));
213
+
214
+ extern int string_to_bitmask(const char *list,
215
+ unsigned long *mask,
216
+ long (*name2flag)(const char *, size_t));
217
+ extern int parse_range(const char *str, int *lower, int *upper, int def);
218
+
219
+ extern int streq_paths(const char *a, const char *b);
220
+
221
+ /*
222
+ * Match string beginning.
223
+ */
224
+ static inline const char *startswith(const char *s, const char *prefix)
225
+ {
226
+ size_t sz = prefix ? strlen(prefix) : 0;
227
+
228
+ if (s && sz && strncmp(s, prefix, sz) == 0)
229
+ return s + sz;
230
+ return NULL;
231
+ }
232
+
233
+ /*
234
+ * Case insensitive match string beginning.
235
+ */
236
+ static inline const char *startswith_no_case(const char *s, const char *prefix)
237
+ {
238
+ size_t sz = prefix ? strlen(prefix) : 0;
239
+
240
+ if (s && sz && strncasecmp(s, prefix, sz) == 0)
241
+ return s + sz;
242
+ return NULL;
243
+ }
244
+
245
+ /*
246
+ * Match string ending.
247
+ */
248
+ static inline const char *endswith(const char *s, const char *postfix)
249
+ {
250
+ size_t sl = s ? strlen(s) : 0;
251
+ size_t pl = postfix ? strlen(postfix) : 0;
252
+
253
+ if (pl == 0)
254
+ return s + sl;
255
+ if (sl < pl)
256
+ return NULL;
257
+ if (memcmp(s + sl - pl, postfix, pl) != 0)
258
+ return NULL;
259
+ return s + sl - pl;
260
+ }
261
+
262
+ /*
263
+ * Skip leading white space.
264
+ */
265
+ static inline const char *skip_space(const char *p)
266
+ {
267
+ while (isspace(*p))
268
+ ++p;
269
+ return p;
270
+ }
271
+
272
+ static inline const char *skip_blank(const char *p)
273
+ {
274
+ while (isblank(*p))
275
+ ++p;
276
+ return p;
277
+ }
278
+
279
+
280
+ /* Removes whitespace from the right-hand side of a string (trailing
281
+ * whitespace).
282
+ *
283
+ * Returns size of the new string (without \0).
284
+ */
285
+ static inline size_t rtrim_whitespace(unsigned char *str)
286
+ {
287
+ size_t i;
288
+
289
+ if (!str)
290
+ return 0;
291
+ i = strlen((char *) str);
292
+ while (i) {
293
+ i--;
294
+ if (!isspace(str[i])) {
295
+ i++;
296
+ break;
297
+ }
298
+ }
299
+ str[i] = '\0';
300
+ return i;
301
+ }
302
+
303
+ /* Removes whitespace from the left-hand side of a string.
304
+ *
305
+ * Returns size of the new string (without \0).
306
+ */
307
+ static inline size_t ltrim_whitespace(unsigned char *str)
308
+ {
309
+ size_t len;
310
+ unsigned char *p;
311
+
312
+ if (!str)
313
+ return 0;
314
+ for (p = str; *p && isspace(*p); p++);
315
+
316
+ len = strlen((char *) p);
317
+
318
+ if (p > str)
319
+ memmove(str, p, len + 1);
320
+
321
+ return len;
322
+ }
323
+
324
+ /* Removes left-hand, right-hand and repeating whitespaces.
325
+ */
326
+ static inline size_t __normalize_whitespace(
327
+ const unsigned char *src,
328
+ size_t sz,
329
+ unsigned char *dst,
330
+ size_t len)
331
+ {
332
+ size_t i, x = 0;
333
+ int nsp = 0, intext = 0;
334
+
335
+ if (!sz)
336
+ goto done;
337
+
338
+ for (i = 0, x = 0; i < sz && x < len - 1; ) {
339
+ if (isspace(src[i]))
340
+ nsp++;
341
+ else
342
+ nsp = 0, intext = 1;
343
+
344
+ if (nsp > 1 || (nsp && !intext))
345
+ i++;
346
+ else
347
+ dst[x++] = src[i++];
348
+ }
349
+ if (nsp && x > 0) /* tailing space */
350
+ x--;
351
+ done:
352
+ dst[x] = '\0';
353
+ return x;
354
+ }
355
+
356
+ static inline size_t normalize_whitespace(unsigned char *str)
357
+ {
358
+ size_t sz = strlen((char *) str);
359
+ return __normalize_whitespace(str, sz, str, sz + 1);
360
+ }
361
+
362
+ static inline void strrep(char *s, int find, int replace)
363
+ {
364
+ while (s && *s && (s = strchr(s, find)) != NULL)
365
+ *s++ = replace;
366
+ }
367
+
368
+ static inline void strrem(char *s, int rem)
369
+ {
370
+ char *p;
371
+
372
+ if (!s)
373
+ return;
374
+ for (p = s; *s; s++) {
375
+ if (*s != rem)
376
+ *p++ = *s;
377
+ }
378
+ *p = '\0';
379
+ }
380
+
381
+ extern char *strnconcat(const char *s, const char *suffix, size_t b);
382
+ extern char *strconcat(const char *s, const char *suffix);
383
+ extern char *strfconcat(const char *s, const char *format, ...)
384
+ __attribute__ ((__format__ (__printf__, 2, 3)));
385
+
386
+ extern int strappend(char **a, const char *b);
387
+
388
+ extern const char *split(const char **state, size_t *l, const char *separator, int quoted);
389
+
390
+ extern int skip_fline(FILE *fp);
391
+ extern int ul_stralnumcmp(const char *p1, const char *p2);
392
+
393
+ #endif