From 1746898cefcb17f58b5cf27b4dad3d28236f1152 Mon Sep 17 00:00:00 2001 From: Lennart Weller Date: Mon, 5 Sep 2016 10:27:21 +0200 Subject: Imported Upstream version 1.3.0+dfsg --- src/proc_self_mountinfo.c | 347 ++++++++++++++++++++++++---------------------- 1 file changed, 179 insertions(+), 168 deletions(-) (limited to 'src/proc_self_mountinfo.c') diff --git a/src/proc_self_mountinfo.c b/src/proc_self_mountinfo.c index 45630b4c0..51aea7aee 100644 --- a/src/proc_self_mountinfo.c +++ b/src/proc_self_mountinfo.c @@ -1,231 +1,242 @@ -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include -#include -#include - #include "common.h" -#include "log.h" -#include "appconfig.h" - -#include "proc_self_mountinfo.h" // find the mount info with the given major:minor // in the supplied linked list of mountinfo structures struct mountinfo *mountinfo_find(struct mountinfo *root, unsigned long major, unsigned long minor) { - struct mountinfo *mi; + struct mountinfo *mi; - for(mi = root; mi ; mi = mi->next) - if(mi->major == major && mi->minor == minor) - return mi; + for(mi = root; mi ; mi = mi->next) + if(mi->major == major && mi->minor == minor) + return mi; - return NULL; + return NULL; } // find the mount info with the given filesystem and mount_source // in the supplied linked list of mountinfo structures struct mountinfo *mountinfo_find_by_filesystem_mount_source(struct mountinfo *root, const char *filesystem, const char *mount_source) { - struct mountinfo *mi; - uint32_t filesystem_hash = simple_hash(filesystem), mount_source_hash = simple_hash(mount_source); - - for(mi = root; mi ; mi = mi->next) - if(mi->filesystem - && mi->mount_source - && mi->filesystem_hash == filesystem_hash - && mi->mount_source_hash == mount_source_hash - && !strcmp(mi->filesystem, filesystem) - && !strcmp(mi->mount_source, mount_source)) - return mi; - - return NULL; + struct mountinfo *mi; + uint32_t filesystem_hash = simple_hash(filesystem), mount_source_hash = simple_hash(mount_source); + + for(mi = root; mi ; mi = mi->next) + if(mi->filesystem + && mi->mount_source + && mi->filesystem_hash == filesystem_hash + && mi->mount_source_hash == mount_source_hash + && !strcmp(mi->filesystem, filesystem) + && !strcmp(mi->mount_source, mount_source)) + return mi; + + return NULL; } struct mountinfo *mountinfo_find_by_filesystem_super_option(struct mountinfo *root, const char *filesystem, const char *super_options) { - struct mountinfo *mi; - uint32_t filesystem_hash = simple_hash(filesystem); + struct mountinfo *mi; + uint32_t filesystem_hash = simple_hash(filesystem); - size_t solen = strlen(super_options); + size_t solen = strlen(super_options); - for(mi = root; mi ; mi = mi->next) - if(mi->filesystem - && mi->super_options - && mi->filesystem_hash == filesystem_hash - && !strcmp(mi->filesystem, filesystem)) { + for(mi = root; mi ; mi = mi->next) + if(mi->filesystem + && mi->super_options + && mi->filesystem_hash == filesystem_hash + && !strcmp(mi->filesystem, filesystem)) { - // super_options is a comma separated list - char *s = mi->super_options, *e; - while(*s) { - e = ++s; - while(*e && *e != ',') e++; + // super_options is a comma separated list + char *s = mi->super_options, *e; + while(*s) { + e = s + 1; + while(*e && *e != ',') e++; - size_t len = e - s; - if(len == solen && !strncmp(s, super_options, len)) - return mi; + size_t len = e - s; + if(len == solen && !strncmp(s, super_options, len)) + return mi; - if(*e == ',') s = ++e; - else s = e; - } - } + if(*e == ',') s = ++e; + else s = e; + } + } - return NULL; + return NULL; } // free a linked list of mountinfo structures void mountinfo_free(struct mountinfo *mi) { - if(unlikely(!mi)) - return; + if(unlikely(!mi)) + return; - if(likely(mi->next)) - mountinfo_free(mi->next); + if(likely(mi->next)) + mountinfo_free(mi->next); - if(mi->root) free(mi->root); - if(mi->mount_point) free(mi->mount_point); - if(mi->mount_options) free(mi->mount_options); + freez(mi->root); + freez(mi->mount_point); + freez(mi->mount_options); /* - if(mi->optional_fields_count) { - int i; - for(i = 0; i < mi->optional_fields_count ; i++) - free(*mi->optional_fields[i]); - } - free(mi->optional_fields); + if(mi->optional_fields_count) { + int i; + for(i = 0; i < mi->optional_fields_count ; i++) + free(*mi->optional_fields[i]); + } + free(mi->optional_fields); */ - free(mi->filesystem); - free(mi->mount_source); - free(mi->super_options); - free(mi); + freez(mi->filesystem); + freez(mi->mount_source); + freez(mi->super_options); + freez(mi); +} + +static char *strdupz_decoding_octal(const char *string) { + char *buffer = strdupz(string); + + char *d = buffer; + const char *s = string; + + while(*s) { + if(unlikely(*s == '\\')) { + s++; + if(likely(isdigit(*s) && isdigit(s[1]) && isdigit(s[2]))) { + char c = *s++ - '0'; + c <<= 3; + c |= *s++ - '0'; + c <<= 3; + c |= *s++ - '0'; + *d++ = c; + } + else *d++ = '_'; + } + else *d++ = *s++; + } + *d = '\0'; + + return buffer; } // read the whole mountinfo into a linked list struct mountinfo *mountinfo_read() { - procfile *ff = NULL; + procfile *ff = NULL; + + char filename[FILENAME_MAX + 1]; + snprintfz(filename, FILENAME_MAX, "%s/proc/self/mountinfo", global_host_prefix); + ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT); + if(!ff) { + snprintfz(filename, FILENAME_MAX, "%s/proc/1/mountinfo", global_host_prefix); + ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT); + if(!ff) return NULL; + } + + ff = procfile_readall(ff); + if(!ff) return NULL; - char filename[FILENAME_MAX + 1]; - snprintfz(filename, FILENAME_MAX, "%s/proc/self/mountinfo", global_host_prefix); - ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT); - if(!ff) { - snprintfz(filename, FILENAME_MAX, "%s/proc/1/mountinfo", global_host_prefix); - ff = procfile_open(filename, " \t", PROCFILE_FLAG_DEFAULT); - if(!ff) return NULL; - } + struct mountinfo *root = NULL, *last = NULL, *mi = NULL; - ff = procfile_readall(ff); - if(!ff) return NULL; + unsigned long l, lines = procfile_lines(ff); + for(l = 0; l < lines ;l++) { + if(procfile_linewords(ff, l) < 5) + continue; - struct mountinfo *root = NULL, *last = NULL, *mi = NULL; + mi = mallocz(sizeof(struct mountinfo)); - unsigned long l, lines = procfile_lines(ff); - for(l = 0; l < lines ;l++) { - if(procfile_linewords(ff, l) < 5) - continue; + if(unlikely(!root)) + root = last = mi; + else + last->next = mi; - mi = malloc(sizeof(struct mountinfo)); - if(unlikely(!mi)) fatal("Cannot allocate memory for mountinfo"); + last = mi; + mi->next = NULL; - if(unlikely(!root)) - root = last = mi; - else - last->next = mi; + unsigned long w = 0; + mi->id = strtoul(procfile_lineword(ff, l, w), NULL, 10); w++; + mi->parentid = strtoul(procfile_lineword(ff, l, w), NULL, 10); w++; - last = mi; - mi->next = NULL; + char *major = procfile_lineword(ff, l, w), *minor; w++; + for(minor = major; *minor && *minor != ':' ;minor++) ; - unsigned long w = 0; - mi->id = strtoul(procfile_lineword(ff, l, w), NULL, 10); w++; - mi->parentid = strtoul(procfile_lineword(ff, l, w), NULL, 10); w++; + if(!*minor) { + error("Cannot parse major:minor on '%s' at line %lu of '%s'", major, l + 1, filename); + continue; + } - char *major = procfile_lineword(ff, l, w), *minor; w++; - for(minor = major; *minor && *minor != ':' ;minor++) ; - *minor = '\0'; - minor++; + *minor = '\0'; + minor++; - mi->major = strtoul(major, NULL, 10); - mi->minor = strtoul(minor, NULL, 10); + mi->major = strtoul(major, NULL, 10); + mi->minor = strtoul(minor, NULL, 10); - mi->root = strdup(procfile_lineword(ff, l, w)); w++; - if(unlikely(!mi->root)) fatal("Cannot allocate memory"); - mi->root_hash = simple_hash(mi->root); + mi->root = strdupz(procfile_lineword(ff, l, w)); w++; + mi->root_hash = simple_hash(mi->root); - mi->mount_point = strdup(procfile_lineword(ff, l, w)); w++; - if(unlikely(!mi->mount_point)) fatal("Cannot allocate memory"); - mi->mount_point_hash = simple_hash(mi->mount_point); + mi->mount_point = strdupz_decoding_octal(procfile_lineword(ff, l, w)); w++; + mi->mount_point_hash = simple_hash(mi->mount_point); - mi->mount_options = strdup(procfile_lineword(ff, l, w)); w++; - if(unlikely(!mi->mount_options)) fatal("Cannot allocate memory"); + mi->mount_options = strdupz(procfile_lineword(ff, l, w)); w++; - // count the optional fields + // count the optional fields /* - unsigned long wo = w; + unsigned long wo = w; */ - mi->optional_fields_count = 0; - char *s = procfile_lineword(ff, l, w); - while(*s && *s != '-') { - w++; - s = procfile_lineword(ff, l, w); - mi->optional_fields_count++; - } + mi->optional_fields_count = 0; + char *s = procfile_lineword(ff, l, w); + while(*s && *s != '-') { + w++; + s = procfile_lineword(ff, l, w); + mi->optional_fields_count++; + } /* - if(unlikely(mi->optional_fields_count)) { - // we have some optional fields - // read them into a new array of pointers; - - mi->optional_fields = malloc(mi->optional_fields_count * sizeof(char *)); - if(unlikely(!mi->optional_fields)) - fatal("Cannot allocate memory for %d mountinfo optional fields", mi->optional_fields_count); - - int i; - for(i = 0; i < mi->optional_fields_count ; i++) { - *mi->optional_fields[wo] = strdup(procfile_lineword(ff, l, w)); - if(!mi->optional_fields[wo]) fatal("Cannot allocate memory"); - wo++; - } - } - else - mi->optional_fields = NULL; + if(unlikely(mi->optional_fields_count)) { + // we have some optional fields + // read them into a new array of pointers; + + mi->optional_fields = malloc(mi->optional_fields_count * sizeof(char *)); + if(unlikely(!mi->optional_fields)) + fatal("Cannot allocate memory for %d mountinfo optional fields", mi->optional_fields_count); + + int i; + for(i = 0; i < mi->optional_fields_count ; i++) { + *mi->optional_fields[wo] = strdup(procfile_lineword(ff, l, w)); + if(!mi->optional_fields[wo]) fatal("Cannot allocate memory"); + wo++; + } + } + else + mi->optional_fields = NULL; */ - if(likely(*s == '-')) { - w++; + if(likely(*s == '-')) { + w++; - mi->filesystem = strdup(procfile_lineword(ff, l, w)); w++; - if(!mi->filesystem) fatal("Cannot allocate memory"); - mi->filesystem_hash = simple_hash(mi->filesystem); + mi->filesystem = strdupz(procfile_lineword(ff, l, w)); w++; + mi->filesystem_hash = simple_hash(mi->filesystem); - mi->mount_source = strdup(procfile_lineword(ff, l, w)); w++; - if(!mi->mount_source) fatal("Cannot allocate memory"); - mi->mount_source_hash = simple_hash(mi->mount_source); + mi->mount_source = strdupz(procfile_lineword(ff, l, w)); w++; + mi->mount_source_hash = simple_hash(mi->mount_source); - mi->super_options = strdup(procfile_lineword(ff, l, w)); w++; - if(!mi->super_options) fatal("Cannot allocate memory"); - } - else { - mi->filesystem = NULL; - mi->mount_source = NULL; - mi->super_options = NULL; - } + mi->super_options = strdupz(procfile_lineword(ff, l, w)); w++; + } + else { + mi->filesystem = NULL; + mi->mount_source = NULL; + mi->super_options = NULL; + } /* - info("MOUNTINFO: %u %u %u:%u root '%s', mount point '%s', mount options '%s', filesystem '%s', mount source '%s', super options '%s'", - mi->id, - mi->parentid, - mi->major, - mi->minor, - mi->root, - mi->mount_point, - mi->mount_options, - mi->filesystem, - mi->mount_source, - mi->super_options - ); + info("MOUNTINFO: %u %u %u:%u root '%s', mount point '%s', mount options '%s', filesystem '%s', mount source '%s', super options '%s'", + mi->id, + mi->parentid, + mi->major, + mi->minor, + mi->root, + mi->mount_point, + mi->mount_options, + mi->filesystem, + mi->mount_source, + mi->super_options + ); */ - } + } - procfile_close(ff); - return root; + procfile_close(ff); + return root; } -- cgit v1.2.3