+ auto_seen = 1;
+
+ /*
+ * Parse the 'auto' line creating policy statements for the 'auto'
+ * policy.
+ *
+ * The default is 'yes' but the 'auto' line might over-ride that.
+ * Words in the line are processed in order with the first
+ * match winning.
+ * word can be:
+ * +version - that version can be assembled
+ * -version - that version cannot be auto-assembled
+ * yes or +all - any other version can be assembled
+ * no or -all - no other version can be assembled.
+ * homehost - any array associated by 'homehost' to this
+ * host can be assembled.
+ *
+ * Thus:
+ * +ddf -0.90 homehost -all
+ * will auto-assemble any ddf array, no 0.90 array, and
+ * any other array (imsm, 1.x) if and only if it is identified
+ * as belonging to this host.
+ *
+ * We translate that to policy by creating 'auto=yes' when we see
+ * a '+version' line, 'auto=no' if we see '-version' before 'homehost',
+ * or 'auto=homehost' if we see '-version' after 'homehost'.
+ * When we see yes, no, +all or -all we stop and any version that hasn't
+ * been seen gets an appropriate auto= entry.
+ */
+
+ /*
+ * If environment variable MDADM_CONF_AUTO is defined, then
+ * it is prepended to the auto line. This allow a script
+ * to easily disable some metadata types.
+ */
+ w = getenv("MDADM_CONF_AUTO");
+ if (w && *w) {
+ char *l = xstrdup(w);
+ char *head = line;
+ w = strtok(l, " \t");
+ while (w) {
+ char *nw = dl_strdup(w);
+ dl_insert(head, nw);
+ head = nw;
+ w = strtok(NULL, " \t");
+ }
+ free(l);
+ }
+
+ for (super_cnt = 0; superlist[super_cnt]; super_cnt++)
+ ;
+ seen = xcalloc(super_cnt, 1);
+
+ for (w = dl_next(line); w != line; w = dl_next(w)) {
+ char *val;
+
+ if (strcasecmp(w, "yes") == 0) {
+ dflt = auto_yes;
+ break;
+ }
+ if (strcasecmp(w, "no") == 0) {
+ if (homehost)
+ dflt = auto_homehost;
+ else
+ dflt = auto_no;
+ break;
+ }
+ if (strcasecmp(w, "homehost") == 0) {
+ homehost = 1;
+ continue;
+ }
+ if (w[0] == '+')
+ val = auto_yes;
+ else if (w[0] == '-') {
+ if (homehost)
+ val = auto_homehost;
+ else
+ val = auto_no;
+ } else
+ continue;
+
+ if (strcasecmp(w + 1, "all") == 0) {
+ dflt = val;
+ break;
+ }
+ for (i = 0; superlist[i]; i++) {
+ const char *version = superlist[i]->name;
+ if (strcasecmp(w + 1, version) == 0)
+ break;
+ /* 1 matches 1.x, 0 matches 0.90 */
+ if (version[1] == '.' && strlen(w + 1) == 1 &&
+ w[1] == version[0])
+ break;
+ /* 1.anything matches 1.x */
+ if (strcmp(version, "1.x") == 0 &&
+ strncmp(w + 1, "1.", 2) == 0)
+ break;
+ }
+ if (superlist[i] == NULL)
+ /* ignore this word */
+ continue;
+ if (seen[i])
+ /* already know about this metadata */
+ continue;
+ policy_add(rule_policy, pol_auto, val, pol_metadata,
+ superlist[i]->name, NULL);
+ seen[i] = 1;