+ if (strcasecmp(key, "GROUP") == 0) {
+ valid = 1;
+ if (rules->resolve_names && (!strchr(value, '$') && !strchr(value, '%'))) {
+ char *endptr;
+ strtoul(value, &endptr, 10);
+ if (endptr[0] != '\0') {
+ char group[32];
+ gid_t gid = lookup_group(value);
+ dbg("replacing groupname='%s' by id=%i", value, gid);
+ sprintf(group, "%u", (unsigned int) gid);
+ add_rule_key(rule, &rule->group, operation, group);
+ continue;
+ }
+ }
+
+ add_rule_key(rule, &rule->group, operation, value);
+ continue;
+ }
+
+ if (strcasecmp(key, "MODE") == 0) {
+ rule->mode = strtol(value, NULL, 8);
+ rule->mode_operation = operation;
+ valid = 1;
+ continue;
+ }
+
+ if (strcasecmp(key, "RUN") == 0) {
+ add_rule_key(rule, &rule->run, operation, value);
+ valid = 1;
+ continue;
+ }
+
+ if (strcasecmp(key, "OPTIONS") == 0) {
+ if (strstr(value, "last_rule") != NULL) {
+ dbg("last rule to be applied");
+ rule->last_rule = 1;
+ }
+ if (strstr(value, "ignore_device") != NULL) {
+ dbg("device should be ignored");
+ rule->ignore_device = 1;
+ }
+ if (strstr(value, "ignore_remove") != NULL) {
+ dbg("remove event should be ignored");
+ rule->ignore_remove = 1;
+ }
+ if (strstr(value, "all_partitions") != NULL) {
+ dbg("creation of partition nodes requested");
+ rule->partitions = DEFAULT_PARTITIONS_COUNT;
+ }
+ valid = 1;
+ continue;
+ }
+
+ err("unknown key '%s'", key);
+ }
+
+ /* skip line if not any valid key was found */
+ if (!valid)
+ goto invalid;
+
+ /* grow buffer and add rule */
+ rule_size = sizeof(struct udev_rule) + rule->bufsize;
+ padding = (sizeof(size_t) - rule_size % sizeof(size_t)) % sizeof(size_t);
+ dbg("add %zi padding bytes", padding);
+ rule_size += padding;
+ rule->bufsize += padding;
+
+ rules->buf = realloc(rules->buf, rules->bufsize + rule_size);
+ if (!rules->buf) {
+ err("realloc failed");
+ goto exit;
+ }
+ dbg("adding rule to offset %zi", rules->bufsize);
+ memcpy(rules->buf + rules->bufsize, rule, rule_size);
+ rules->bufsize += rule_size;
+exit:
+ free(rule);
+ return 0;
+
+invalid:
+ free(rule);
+ err("invalid rule '%s:%u'", filename, lineno);
+ return -1;
+}