+
+static int /* O - 1 to continue, 0 to cancel */
+timeout_cb(http_t *http, /* I - Connection to server (unused) */
+ void *user_data) /* I - User data (unused) */
+{
+ (void)http;
+ (void)user_data;
+
+ return (!job_canceled);
+}
+
+
+/*
+ * 'update_reasons()' - Update the printer-state-reasons values.
+ */
+
+static void
+update_reasons(ipp_attribute_t *attr, /* I - printer-state-reasons or NULL */
+ const char *s) /* I - STATE: string or NULL */
+{
+ char op; /* Add (+), remove (-), replace (\0) */
+ cups_array_t *new_reasons; /* New reasons array */
+ char *reason, /* Current reason */
+ add[2048], /* Reasons added string */
+ *addptr, /* Pointer into add string */
+ rem[2048], /* Reasons removed string */
+ *remptr; /* Pointer into remove string */
+ const char *addprefix, /* Current add string prefix */
+ *remprefix; /* Current remove string prefix */
+
+
+ fprintf(stderr, "DEBUG: update_reasons(attr=%d(%s%s), s=\"%s\")\n",
+ attr ? attr->num_values : 0, attr ? attr->values[0].string.text : "",
+ attr && attr->num_values > 1 ? ",..." : "", s ? s : "(null)");
+
+ /*
+ * Create an array of new reason keyword strings...
+ */
+
+ if (attr)
+ {
+ int i; /* Looping var */
+
+ new_reasons = cupsArrayNew((cups_array_func_t)strcmp, NULL);
+ op = '\0';
+
+ for (i = 0; i < attr->num_values; i ++)
+ {
+ reason = attr->values[i].string.text;
+
+ if (strcmp(reason, "none") &&
+ strcmp(reason, "none-report") &&
+ strcmp(reason, "paused") &&
+ strncmp(reason, "spool-area-full", 15) &&
+ strcmp(reason, "com.apple.print.recoverable-warning") &&
+ strncmp(reason, "cups-", 5))
+ cupsArrayAdd(new_reasons, reason);
+ }
+ }
+ else if (s)
+ {
+ if (*s == '+' || *s == '-')
+ op = *s++;
+ else
+ op = '\0';
+
+ new_reasons = _cupsArrayNewStrings(s, ',');
+ }
+ else
+ return;
+
+ /*
+ * Compute the changes...
+ */
+
+ add[0] = '\0';
+ addprefix = "STATE: +";
+ addptr = add;
+ rem[0] = '\0';
+ remprefix = "STATE: -";
+ remptr = rem;
+
+ fprintf(stderr, "DEBUG2: op='%c', new_reasons=%d, state_reasons=%d\n",
+ op ? op : ' ', cupsArrayCount(new_reasons),
+ cupsArrayCount(state_reasons));
+
+ _cupsMutexLock(&report_mutex);
+
+ if (op == '+')
+ {
+ /*
+ * Add reasons...
+ */
+
+ for (reason = (char *)cupsArrayFirst(new_reasons);
+ reason;
+ reason = (char *)cupsArrayNext(new_reasons))
+ {
+ if (!cupsArrayFind(state_reasons, reason))
+ {
+ if (!strncmp(reason, "cups-remote-", 12))
+ {
+ /*
+ * If we are setting cups-remote-xxx, remove all other cups-remote-xxx
+ * keywords...
+ */
+
+ char *temp; /* Current reason in state_reasons */
+
+ cupsArraySave(state_reasons);
+
+ for (temp = (char *)cupsArrayFirst(state_reasons);
+ temp;
+ temp = (char *)cupsArrayNext(state_reasons))
+ if (!strncmp(temp, "cups-remote-", 12))
+ {
+ snprintf(remptr, sizeof(rem) - (size_t)(remptr - rem), "%s%s", remprefix, temp);
+ remptr += strlen(remptr);
+ remprefix = ",";
+
+ cupsArrayRemove(state_reasons, temp);
+ break;
+ }
+
+ cupsArrayRestore(state_reasons);
+ }
+
+ cupsArrayAdd(state_reasons, reason);
+
+ snprintf(addptr, sizeof(add) - (size_t)(addptr - add), "%s%s", addprefix, reason);
+ addptr += strlen(addptr);
+ addprefix = ",";
+ }
+ }
+ }
+ else if (op == '-')
+ {
+ /*
+ * Remove reasons...
+ */
+
+ for (reason = (char *)cupsArrayFirst(new_reasons);
+ reason;
+ reason = (char *)cupsArrayNext(new_reasons))
+ {
+ if (cupsArrayFind(state_reasons, reason))
+ {
+ snprintf(remptr, sizeof(rem) - (size_t)(remptr - rem), "%s%s", remprefix, reason);
+ remptr += strlen(remptr);
+ remprefix = ",";
+
+ cupsArrayRemove(state_reasons, reason);
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Replace reasons...
+ */
+
+ for (reason = (char *)cupsArrayFirst(state_reasons);
+ reason;
+ reason = (char *)cupsArrayNext(state_reasons))
+ {
+ if (strncmp(reason, "cups-", 5) && !cupsArrayFind(new_reasons, reason))
+ {
+ snprintf(remptr, sizeof(rem) - (size_t)(remptr - rem), "%s%s", remprefix, reason);
+ remptr += strlen(remptr);
+ remprefix = ",";
+
+ cupsArrayRemove(state_reasons, reason);
+ }
+ }
+
+ for (reason = (char *)cupsArrayFirst(new_reasons);
+ reason;
+ reason = (char *)cupsArrayNext(new_reasons))
+ {
+ if (!cupsArrayFind(state_reasons, reason))
+ {
+ cupsArrayAdd(state_reasons, reason);
+
+ snprintf(addptr, sizeof(add) - (size_t)(addptr - add), "%s%s", addprefix, reason);
+ addptr += strlen(addptr);
+ addprefix = ",";
+ }
+ }
+ }
+
+ _cupsMutexUnlock(&report_mutex);
+
+ /*
+ * Report changes and return...
+ */
+
+ if (add[0] && rem[0])
+ fprintf(stderr, "%s\n%s\n", add, rem);
+ else if (add[0])
+ fprintf(stderr, "%s\n", add);
+ else if (rem[0])
+ fprintf(stderr, "%s\n", rem);
+}