runshare 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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