+ struct token *token = &rule_tmp->token[rule_tmp->token_cur];
+ const char *attr = data;
+ mode_t mode = 0000;
+
+ switch (type) {
+ case TK_M_WAITFOR:
+ case TK_M_ACTION:
+ case TK_M_DEVPATH:
+ case TK_M_KERNEL:
+ case TK_M_SUBSYSTEM:
+ case TK_M_DRIVER:
+ case TK_M_DEVLINK:
+ case TK_M_NAME:
+ case TK_M_KERNELS:
+ case TK_M_SUBSYSTEMS:
+ case TK_M_DRIVERS:
+ case TK_M_PROGRAM:
+ case TK_M_IMPORT_FILE:
+ case TK_M_IMPORT_PROG:
+ case TK_M_IMPORT_PARENT:
+ case TK_M_RESULT:
+ case TK_A_OWNER:
+ case TK_A_GROUP:
+ case TK_A_MODE:
+ case TK_A_NAME:
+ case TK_A_DEVLINK:
+ case TK_A_GOTO:
+ token->key.value_off = add_string(rule_tmp->rules, value);
+ break;
+ case TK_M_ENV:
+ case TK_M_ATTR:
+ case TK_M_ATTRS:
+ case TK_A_ATTR:
+ case TK_A_ENV:
+ token->key.value_off = add_string(rule_tmp->rules, value);
+ token->key.attr_off = add_string(rule_tmp->rules, attr);
+ break;
+ case TK_M_TEST:
+ if (data != NULL)
+ mode = *(mode_t *)data;
+ token->key.value_off = add_string(rule_tmp->rules, value);
+ token->key.mode = mode;
+ break;
+ case TK_A_IGNORE_DEVICE:
+ case TK_A_STRING_ESCAPE_NONE:
+ case TK_A_STRING_ESCAPE_REPLACE:
+ case TK_A_IGNORE_REMOVE:
+ case TK_A_LAST_RULE:
+ break;
+ case TK_A_RUN:
+ token->key.value_off = add_string(rule_tmp->rules, value);
+ token->key.ignore_error = *(int *)data;
+ break;
+ case TK_A_NUM_FAKE_PART:
+ token->key.num_fake_part = *(int *)data;
+ break;
+ case TK_A_DEVLINK_PRIO:
+ token->key.devlink_prio = *(int *)data;
+ break;
+ case TK_A_OWNER_ID:
+ token->key.uid = *(uid_t *)data;
+ break;
+ case TK_A_GROUP_ID:
+ token->key.gid = *(gid_t *)data;
+ break;
+ case TK_A_MODE_ID:
+ token->key.mode = *(mode_t *)data;
+ break;
+ case TK_A_EVENT_TIMEOUT:
+ token->key.event_timeout = *(int *)data;
+ break;
+ case TK_RULE:
+ case TK_PARENTS_MAX:
+ case TK_END:
+ case TK_UNDEF:
+ err(rule_tmp->rules->udev, "wrong type %u\n", type);
+ return -1;
+ }
+ token->type = type;
+ token->key.op = op;
+ rule_tmp->token_cur++;
+ if (rule_tmp->token_cur >= ARRAY_SIZE(rule_tmp->token)) {
+ err(rule_tmp->rules->udev, "temporary rule array too small\n");
+ return -1;
+ }
+ return 0;
+}
+
+#ifdef DEBUG
+static void dump_token(struct udev_rules *rules, struct token *token)
+{
+ enum token_type type = token->type;
+ enum key_operation op = token->key.op;
+ const char *value = &rules->buf[token->key.value_off];
+ const char *attr = &rules->buf[token->key.attr_off];
+
+ switch (type) {
+ case TK_RULE:
+ {
+ const char *tks_ptr = (char *)rules->tokens;
+ const char *tk_ptr = (char *)token;
+ unsigned int off = tk_ptr - tks_ptr;
+
+ dbg(rules->udev, "* RULE '%s', off: %u(%u), next: %u, label: '%s'\n",
+ &rules->buf[token->rule.filename_off],
+ off / (unsigned int) sizeof(struct token), off,
+ token->rule.next_rule,
+ &rules->buf[token->rule.label_off]);
+ break;
+ }
+ case TK_M_WAITFOR:
+ case TK_M_ACTION:
+ case TK_M_DEVPATH:
+ case TK_M_KERNEL:
+ case TK_M_SUBSYSTEM:
+ case TK_M_DRIVER:
+ case TK_M_DEVLINK:
+ case TK_M_NAME:
+ case TK_M_KERNELS:
+ case TK_M_SUBSYSTEMS:
+ case TK_M_DRIVERS:
+ case TK_M_PROGRAM:
+ case TK_M_IMPORT_FILE:
+ case TK_M_IMPORT_PROG:
+ case TK_M_IMPORT_PARENT:
+ case TK_M_RESULT:
+ case TK_A_NAME:
+ case TK_A_DEVLINK:
+ case TK_A_OWNER:
+ case TK_A_GROUP:
+ case TK_A_MODE:
+ case TK_A_RUN:
+ dbg(rules->udev, "%s %s '%s'\n", token_str[type], operation_str[op], value);
+ break;
+ case TK_M_ATTR:
+ case TK_M_ATTRS:
+ case TK_M_ENV:
+ case TK_A_ATTR:
+ case TK_A_ENV:
+ dbg(rules->udev, "%s %s '%s' '%s'\n", token_str[type], operation_str[op], attr, value);
+ break;
+ case TK_A_IGNORE_DEVICE:
+ case TK_A_STRING_ESCAPE_NONE:
+ case TK_A_STRING_ESCAPE_REPLACE:
+ case TK_A_LAST_RULE:
+ case TK_A_IGNORE_REMOVE:
+ dbg(rules->udev, "%s\n", token_str[type]);
+ break;
+ case TK_M_TEST:
+ dbg(rules->udev, "%s %s '%s' %#o\n", token_str[type], operation_str[op], value, token->key.mode);
+ break;
+ case TK_A_NUM_FAKE_PART:
+ dbg(rules->udev, "%s %u\n", token_str[type], token->key.num_fake_part);
+ break;
+ case TK_A_DEVLINK_PRIO:
+ dbg(rules->udev, "%s %s %u\n", token_str[type], operation_str[op], token->key.devlink_prio);
+ break;
+ case TK_A_OWNER_ID:
+ dbg(rules->udev, "%s %s %u\n", token_str[type], operation_str[op], token->key.uid);
+ break;
+ case TK_A_GROUP_ID:
+ dbg(rules->udev, "%s %s %u\n", token_str[type], operation_str[op], token->key.gid);
+ break;
+ case TK_A_MODE_ID:
+ dbg(rules->udev, "%s %s %#o\n", token_str[type], operation_str[op], token->key.mode);
+ break;
+ case TK_A_EVENT_TIMEOUT:
+ dbg(rules->udev, "%s %s %u\n", token_str[type], operation_str[op], token->key.event_timeout);
+ break;
+ case TK_A_GOTO:
+ dbg(rules->udev, "%s '%s' %u\n", token_str[type], value, token->key.rule_goto);
+ break;
+ case TK_END:
+ dbg(rules->udev, "* %s\n", token_str[type]);
+ break;
+ case TK_PARENTS_MAX:
+ case TK_UNDEF:
+ dbg(rules->udev, "unknown type %u\n", type);
+ break;
+ }
+}