1 /*****************************************************************************
3 * Library for check_disk
6 * Copyright (c) 1999-2024 Monitoring Plugins Development Team
10 * This file contains utilities for check_disk. These are tested by libtap
13 * This program is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 *****************************************************************************/
30 #include "utils_disk.h"
31 #include "gl/fsusage.h"
34 void np_add_name(struct name_list
**list
, const char *name
) {
35 struct name_list
*new_entry
;
36 new_entry
= (struct name_list
*)malloc(sizeof *new_entry
);
37 new_entry
->name
= (char *)name
;
38 new_entry
->next
= *list
;
42 /* @brief Initialises a new regex at the begin of list via regcomp(3)
44 * @details if the regex fails to compile the error code of regcomp(3) is returned
45 * and list is not modified, otherwise list is modified to point to the new
47 * @param list Pointer to a linked list of regex_list elements
48 * @param regex the string containing the regex which should be inserted into the list
49 * @param clags the cflags parameter for regcomp(3)
51 int np_add_regex(struct regex_list
**list
, const char *regex
, int cflags
) {
52 struct regex_list
*new_entry
= (struct regex_list
*)malloc(sizeof *new_entry
);
54 if (new_entry
== NULL
) {
55 die(STATE_UNKNOWN
, _("Cannot allocate memory: %s"), strerror(errno
));
58 int regcomp_result
= regcomp(&new_entry
->regex
, regex
, cflags
);
60 if (!regcomp_result
) {
62 new_entry
->next
= *list
;
70 return regcomp_result
;
74 /* Initialises a new parameter at the end of list */
75 struct parameter_list
*np_add_parameter(struct parameter_list
**list
, const char *name
) {
76 struct parameter_list
*current
= *list
;
77 struct parameter_list
*new_path
;
78 new_path
= (struct parameter_list
*)malloc(sizeof *new_path
);
79 new_path
->name
= (char *)malloc(strlen(name
) + 1);
80 new_path
->best_match
= NULL
;
81 new_path
->name_next
= NULL
;
82 new_path
->name_prev
= NULL
;
83 new_path
->freespace_bytes
= NULL
;
84 new_path
->freespace_units
= NULL
;
85 new_path
->freespace_percent
= NULL
;
86 new_path
->usedspace_bytes
= NULL
;
87 new_path
->usedspace_units
= NULL
;
88 new_path
->usedspace_percent
= NULL
;
89 new_path
->usedinodes_percent
= NULL
;
90 new_path
->freeinodes_percent
= NULL
;
91 new_path
->group
= NULL
;
92 new_path
->dfree_pct
= -1;
93 new_path
->dused_pct
= -1;
95 new_path
->available
= 0;
96 new_path
->available_to_root
= 0;
98 new_path
->dused_units
= 0;
99 new_path
->dfree_units
= 0;
100 new_path
->dtotal_units
= 0;
101 new_path
->inodes_total
= 0;
102 new_path
->inodes_free
= 0;
103 new_path
->inodes_free_to_root
= 0;
104 new_path
->inodes_used
= 0;
105 new_path
->dused_inodes_percent
= 0;
106 new_path
->dfree_inodes_percent
= 0;
108 strcpy(new_path
->name
, name
);
110 if (current
== NULL
) {
112 new_path
->name_prev
= NULL
;
114 while (current
->name_next
) {
115 current
= current
->name_next
;
117 current
->name_next
= new_path
;
118 new_path
->name_prev
= current
;
123 /* Delete a given parameter from list and return pointer to next element*/
124 struct parameter_list
*np_del_parameter(struct parameter_list
*item
, struct parameter_list
*prev
) {
128 struct parameter_list
*next
;
131 next
= item
->name_next
;
136 next
->name_prev
= prev
;
139 prev
->name_next
= next
;
149 /* returns a pointer to the struct found in the list */
150 struct parameter_list
*np_find_parameter(struct parameter_list
*list
, const char *name
) {
151 struct parameter_list
*temp_list
;
152 for (temp_list
= list
; temp_list
; temp_list
= temp_list
->name_next
) {
153 if (!strcmp(temp_list
->name
, name
))
160 void np_set_best_match(struct parameter_list
*desired
, struct mount_entry
*mount_list
, bool exact
) {
161 struct parameter_list
*d
;
162 for (d
= desired
; d
; d
= d
->name_next
) {
163 if (!d
->best_match
) {
164 struct mount_entry
*me
;
165 size_t name_len
= strlen(d
->name
);
166 size_t best_match_len
= 0;
167 struct mount_entry
*best_match
= NULL
;
170 /* set best match if path name exactly matches a mounted device name */
171 for (me
= mount_list
; me
; me
= me
->me_next
) {
172 if (strcmp(me
->me_devname
, d
->name
) == 0) {
173 if (get_fs_usage(me
->me_mountdir
, me
->me_devname
, &fsp
) >= 0) {
179 /* set best match by directory name if no match was found by devname */
181 for (me
= mount_list
; me
; me
= me
->me_next
) {
182 size_t len
= strlen(me
->me_mountdir
);
184 (best_match_len
<= len
&& len
<= name_len
&& (len
== 1 || strncmp(me
->me_mountdir
, d
->name
, len
) == 0))) ||
185 (exact
&& strcmp(me
->me_mountdir
, d
->name
) == 0)) {
186 if (get_fs_usage(me
->me_mountdir
, me
->me_devname
, &fsp
) >= 0) {
188 best_match_len
= len
;
195 d
->best_match
= best_match
;
197 d
->best_match
= NULL
; /* Not sure why this is needed as it should be null on initialisation */
203 /* Returns true if name is in list */
204 bool np_find_name(struct name_list
*list
, const char *name
) {
205 const struct name_list
*n
;
207 if (list
== NULL
|| name
== NULL
) {
210 for (n
= list
; n
; n
= n
->next
) {
211 if (!strcmp(name
, n
->name
)) {
218 /* Returns true if name is in list */
219 bool np_find_regmatch(struct regex_list
*list
, const char *name
) {
229 for (; list
; list
= list
->next
) {
230 /* Emulate a full match as if surrounded with ^( )$
231 by checking whether the match spans the whole name */
232 if (!regexec(&list
->regex
, name
, 1, &m
, 0) && m
.rm_so
== 0 && m
.rm_eo
== len
) {
240 bool np_seen_name(struct name_list
*list
, const char *name
) {
241 const struct name_list
*s
;
242 for (s
= list
; s
; s
= s
->next
) {
243 if (!strcmp(s
->name
, name
)) {
250 bool np_regex_match_mount_entry(struct mount_entry
*me
, regex_t
*re
) {
251 if (regexec(re
, me
->me_devname
, (size_t)0, NULL
, 0) == 0 || regexec(re
, me
->me_mountdir
, (size_t)0, NULL
, 0) == 0) {