From: kay.sievers@vrfy.org Date: Thu, 4 Mar 2004 02:16:35 +0000 (-0800) Subject: [PATCH] cleanup mult field string handling X-Git-Tag: 022~36 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=9fe3f9a9389bb06cf645d33cbb2b45e1f63d737c [PATCH] cleanup mult field string handling Here I try to cleanup our various multifield iteration over the strings. Inspired by our nice list.h we now have a macro to iterate over the string and process the parts of it: It makes the code more readable and we don't change the string while we process it like the former strsep() does. Example: foreach_strpart(dev->symlink, " ", pos, len) { if (strncmp(&dev->symlink[pos], find_name, len) != 0) continue; ... } For the callout part selector %c{2} we separate now not only by space but also newline and return characters, cause some programs may give multiline values back. A possible RESULT match must contain wildcards for these characters. Also a bug in the recent udevinfo symlink query feature is fixed. --- diff --git a/namedev.c b/namedev.c index ed8d6c180..74d4d7646 100644 --- a/namedev.c +++ b/namedev.c @@ -214,14 +214,12 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, struct sysfs_device *sysfs_device) { char temp[NAME_SIZE]; - char temp1[NAME_SIZE]; char *tail; char *pos; - char *pos2; - char *pos3; char *attr; int len; int i; + int spos, slen; char c; struct sysfs_attribute *tmpattr; @@ -278,20 +276,17 @@ static void apply_format(struct udevice *udev, char *string, size_t maxsize, if (attr != NULL) i = atoi(attr); if (i > 0) { - strfieldcpy(temp1, udev->program_result); - pos2 = temp1; - while (i) { + foreach_strpart(udev->program_result, " \n\r", spos, slen) { i--; - pos3 = strsep(&pos2, " "); - if (pos3 == NULL) { - dbg("requested part of result string not found"); + if (i == 0) break; - } } - if (pos3) { - strnfieldcat(string, pos3, maxsize); - dbg("substitute part of result string '%s'", pos3); + if (i > 0) { + dbg("requested part of result string not found"); + break; } + strnfieldcat(string, udev->program_result + spos, slen+1); + dbg("substitute part of result string '%s'", pos); } else { strnfieldcat(string, udev->program_result, maxsize); dbg("substitute result string '%s'", udev->program_result); diff --git a/udev-add.c b/udev-add.c index ed0286d1f..c28256a5a 100644 --- a/udev-add.c +++ b/udev-add.c @@ -186,16 +186,16 @@ static int unlink_entry(char *filename) static int create_node(struct udevice *dev, int fake) { - char filename[255]; - char linktarget[255]; - char partitionname[255]; - char *linkname; - char *symlinks; + char filename[NAME_SIZE]; + char linkname[NAME_SIZE]; + char linktarget[NAME_SIZE]; + char partitionname[NAME_SIZE]; int retval = 0; uid_t uid = 0; gid_t gid = 0; int i; int tail; + int pos, len; strfieldcpy(filename, udev_root); strfieldcat(filename, dev->name); @@ -279,47 +279,41 @@ static int create_node(struct udevice *dev, int fake) selinux_add_node(filename); /* create symlink if requested */ - if (dev->symlink[0] != '\0') { - symlinks = dev->symlink; - while (1) { - linkname = strsep(&symlinks, " "); - if (linkname == NULL || linkname[0] == '\0') - break; - - strfieldcpy(filename, udev_root); - strfieldcat(filename, linkname); - dbg("symlink '%s' to node '%s' requested", filename, dev->name); - if (!fake) - if (strrchr(linkname, '/')) - create_path(filename); - - /* optimize relative link */ - linktarget[0] = '\0'; - i = 0; - tail = 0; - while ((dev->name[i] == linkname[i]) && dev->name[i]) { - if (dev->name[i] == '/') - tail = i+1; - i++; - } - while (linkname[i] != '\0') { - if (linkname[i] == '/') - strfieldcat(linktarget, "../"); - i++; - } + foreach_strpart(dev->symlink, " ", pos, len) { + strnfieldcpy(linkname, dev->symlink + pos, len+1); + strfieldcpy(filename, udev_root); + strfieldcat(filename, linkname); + dbg("symlink '%s' to node '%s' requested", filename, dev->name); + if (!fake) + if (strrchr(linkname, '/')) + create_path(filename); + + /* optimize relative link */ + linktarget[0] = '\0'; + i = 0; + tail = 0; + while ((dev->name[i] == linkname[i]) && dev->name[i]) { + if (dev->name[i] == '/') + tail = i+1; + i++; + } + while (linkname[i] != '\0') { + if (linkname[i] == '/') + strfieldcat(linktarget, "../"); + i++; + } - strfieldcat(linktarget, &dev->name[tail]); + strfieldcat(linktarget, &dev->name[tail]); - if (!fake) - unlink_entry(filename); + if (!fake) + unlink_entry(filename); - dbg("symlink(%s, %s)", linktarget, filename); - if (!fake) { - retval = symlink(linktarget, filename); - if (retval != 0) - dbg("symlink(%s, %s) failed with error '%s'", - linktarget, filename, strerror(errno)); - } + dbg("symlink(%s, %s)", linktarget, filename); + if (!fake) { + retval = symlink(linktarget, filename); + if (retval != 0) + dbg("symlink(%s, %s) failed with error '%s'", + linktarget, filename, strerror(errno)); } } diff --git a/udev-remove.c b/udev-remove.c index dcd460bed..93adcc780 100644 --- a/udev-remove.c +++ b/udev-remove.c @@ -67,12 +67,12 @@ static int delete_path(char *path) static int delete_node(struct udevice *dev) { - char filename[255]; - char partitionname[255]; - char *symlinks; - char *linkname; + char filename[NAME_SIZE]; + char linkname[NAME_SIZE]; + char partitionname[NAME_SIZE]; int retval; int i; + int pos, len; strfieldcpy(filename, udev_root); strfieldcat(filename, dev->name); @@ -101,28 +101,22 @@ static int delete_node(struct udevice *dev) if (strchr(dev->name, '/')) delete_path(filename); - if (dev->symlink[0] != '\0') { - symlinks = dev->symlink; - while (1) { - linkname = strsep(&symlinks, " "); - if (linkname == NULL) - break; - - strfieldcpy(filename, udev_root); - strfieldcat(filename, linkname); - - dbg("unlinking symlink '%s'", filename); - retval = unlink(filename); - if (errno == ENOENT) - retval = 0; - if (retval) { - dbg("unlink(%s) failed with error '%s'", - filename, strerror(errno)); - return retval; - } - if (strchr(dev->symlink, '/')) { - delete_path(filename); - } + foreach_strpart(dev->symlink, " ", pos, len) { + strnfieldcpy(linkname, dev->symlink + pos, len+1); + strfieldcpy(filename, udev_root); + strfieldcat(filename, linkname); + + dbg("unlinking symlink '%s'", filename); + retval = unlink(filename); + if (errno == ENOENT) + retval = 0; + if (retval) { + dbg("unlink(%s) failed with error '%s'", + filename, strerror(errno)); + return retval; + } + if (strchr(dev->symlink, '/')) { + delete_path(filename); } } diff --git a/udev.h b/udev.h index 5737c84c9..9327e9091 100644 --- a/udev.h +++ b/udev.h @@ -97,6 +97,12 @@ do { \ snprintf((to) + strlen(to), maxsize - strlen(to)-1, "%u", i); \ } while (0) +#define foreach_strpart(str, separator, pos, len) \ + for(pos = 0, len = strcspn(str, separator); \ + (pos) < strlen(str); \ + pos = pos + (len) + 1, len = strcspn((str) + pos, separator)) \ + if (len > 0) + static inline char *get_action(void) { char *action; diff --git a/udevdb.c b/udevdb.c index 95bc06ce6..22d439d63 100644 --- a/udevdb.c +++ b/udevdb.c @@ -179,7 +179,8 @@ static int find_found; static int find_device_by_name(char *path, struct udevice *dev) { - int l, i, j; + int pos, len; + if (strncmp(dev->name, find_name, sizeof(dev->name)) == 0) { memcpy(find_dev, dev, sizeof(struct udevice)); strnfieldcpy(find_path, path, NAME_SIZE); @@ -188,20 +189,18 @@ static int find_device_by_name(char *path, struct udevice *dev) return 1; } /* look for matching symlink*/ - l = strlen(dev->symlink); - if (!l) - return 0; - i = j = 0; - do { - j = strcspn(&dev->symlink[i], " "); - if (j && strncmp(&dev->symlink[i], find_name, j) == 0) { - memcpy(find_dev, dev, sizeof(struct udevice)); - strnfieldcpy(find_path, path, NAME_SIZE); - find_found = 1; - return 1; - } - i = i + j + 1; - } while (i < l); + foreach_strpart(dev->symlink, " ", pos, len) { + if (strncmp(&dev->symlink[pos], find_name, len) != 0) + continue; + + if (len != strlen(find_name)) + continue; + + memcpy(find_dev, dev, sizeof(struct udevice)); + strnfieldcpy(find_path, path, NAME_SIZE); + find_found = 1; + return 1; + } return 0; } diff --git a/udevinfo.8 b/udevinfo.8 index 528fa4ad9..e087e2d1f 100644 --- a/udevinfo.8 +++ b/udevinfo.8 @@ -35,6 +35,8 @@ Specify the sysfs path of the device to query. .TP .BI \-n " name" Specify the name of the node or the symlink for the device to query. +Partition names generated with the NAME{all_partitons} option can not be +queried, the main device must be used instead. .TP .B \-a Print all