# include <sys/vfs.h>
#endif /* HAVE_SYS_VFS_H */
+#ifdef HAVE_PTHREAD_H
+typedef pthread_cond_t _cups_cond_t;
+# define _CUPS_COND_INITIALIZER PTHREAD_COND_INITIALIZER
+# define _cupsCondBroadcast(c) pthread_cond_broadcast(c)
+# define _cupsCondDeinit(c) pthread_cond_destroy(c)
+# define _cupsCondInit(c) pthread_cond_init((c), NULL)
+# define _cupsCondWait(c,m) pthread_cond_wait((c),(m))
+# define _cupsMutexDeinit(m) pthread_mutex_destroy(m)
+# define _cupsRWDeinit(rw) pthread_rwlock_destroy(rw)
+#else
+typedef char _cups_cond_t;
+# define _CUPS_COND_INITIALIZER 0
+# define _cupsCondBroadcast(c)
+# define _cupsCondDeinit(c)
+# define _cupsCondInit(c) *(c)=0
+# define _cupsCondWait(c,m) 0
+# define _cupsMutexDeinit(m)
+# define _cupsRWDeinit(rw)
+#endif /* HAVE_PTHREAD_H */
+
/*
* Constants...
# define _IPP_OP_UPDATE_DOCUMENT_STATUS (ipp_op_t)0x0047
# define _IPP_OP_UPDATE_JOB_STATUS (ipp_op_t)0x0048
# define _IPP_OP_UPDATE_OUTPUT_DEVICE_ATTRIBUTES (ipp_op_t)0x0049
+# define _IPP_OP_UNREGISTER_OUTPUT_DEVICE (ipp_op_t)0x204b
/* New IPP status code from IPP INFRA */
# define _IPP_STATUS_ERROR_NOT_FETCHABLE (ipp_status_t)0x0420
# define _IPP_NOTIFY_LEASE_DURATION_MAX 67108863
/* But a value of 0 means "never expires"... */
# define _IPP_NOTIFY_LEASE_DURATION_FOREVER 0
+/* Default duration is 1 day */
+# define _IPP_NOTIFY_LEASE_DURATION_DEFAULT 86400
+
/*
* Event mask enumeration...
_IPP_EVENT_ALL = 0x001fffff /* Everything */
};
typedef unsigned int _ipp_event_t; /* Bitfield for notify-events */
+#define _IPP_EVENT_DEFAULT _IPP_EVENT_JOB_COMPLETED
+#define _IPP_EVENT_DEFAULT_STRING "job-completed"
static const char * const _ipp_events[] =
{ /* Strings for bits */
"document-completed",
char uri[1024], /* Request URI */
*options; /* URI options */
http_addr_t addr; /* Client address */
- char hostname[256]; /* Client hostname */
+ char hostname[256], /* Client hostname */
+ username[32]; /* Client authenticated username */
_ipp_printer_t *printer; /* Printer */
_ipp_job_t *job; /* Current job, if any */
+ int fetch_compression,
+ /* Compress file? */
+ fetch_file; /* File to fetch */
} _ipp_client_t;
static void copy_printer_state_reasons(ipp_t *ipp, ipp_tag_t group_tag, _ipp_printer_t *printer);
static void copy_subscription_attributes(_ipp_client_t *client, _ipp_subscription_t *sub, cups_array_t *ra);
static _ipp_client_t *create_client(_ipp_printer_t *printer, int sock);
+static _ipp_device_t *create_device(_ipp_client_t *client);
static _ipp_job_t *create_job(_ipp_client_t *client);
-static void create_job_filename(_ipp_printer_t *printer, _ipp_job_t *job, char *fname, size_t fnamesize);
+static void create_job_filename(_ipp_printer_t *printer, _ipp_job_t *job, const char *format, char *fname, size_t fnamesize);
static int create_listener(int family, int port);
-static _ipp_subscription_t *create_subscription(_ipp_printer_t *printer, _ipp_job_t *job, int lease, const char *username, ipp_attribute_t *events, ipp_attribute_t *notify_attrs, ipp_attribute_t *userdata);
+static _ipp_subscription_t *create_subscription(_ipp_printer_t *printer, _ipp_job_t *job, int interval, int lease, const char *username, ipp_attribute_t *notify_events, ipp_attribute_t *notify_attributes, ipp_attribute_t *notify_user_data);
static _ipp_printer_t *create_printer(const char *servername, int port, const char *name, const char *directory, const char *proxy_user, const char *proxy_pass);
static void debug_attributes(const char *title, ipp_t *ipp,
int response);
static void delete_client(_ipp_client_t *client);
+static void delete_device(_ipp_device_t *device);
static void delete_job(_ipp_job_t *job);
static void delete_printer(_ipp_printer_t *printer);
static void delete_subscription(_ipp_subscription_t *sub);
static int filter_cb(_ipp_filter_t *filter, ipp_t *dst, ipp_attribute_t *attr);
-static _ipp_job_t *find_job(_ipp_client_t *client);
+static _ipp_device_t *find_device(_ipp_client_t *client);
+static _ipp_job_t *find_job(_ipp_client_t *client, int job_id);
+static _ipp_subscription_t *find_subscription(_ipp_client_t *client, int sub_id);
static _ipp_jreason_t get_job_state_reasons_bits(ipp_attribute_t *attr);
static _ipp_event_t get_notify_events_bits(ipp_attribute_t *attr);
static const char *get_notify_subscribed_event(_ipp_event_t event);
static void ipp_renew_subscription(_ipp_client_t *client);
static void ipp_send_document(_ipp_client_t *client);
static void ipp_send_uri(_ipp_client_t *client);
+static void ipp_unregister_output_device(_ipp_client_t *client);
static void ipp_update_active_jobs(_ipp_client_t *client);
static void ipp_update_document_status(_ipp_client_t *client);
static void ipp_update_job_status(_ipp_client_t *client);
static void ipp_update_output_device_attributes(_ipp_client_t *client);
static void ipp_validate_document(_ipp_client_t *client);
static void ipp_validate_job(_ipp_client_t *client);
-static int parse_options(_ipp_client_t *client, cups_option_t **options);
+//static int parse_options(_ipp_client_t *client, cups_option_t **options);
static void *process_client(_ipp_client_t *client);
static int process_http(_ipp_client_t *client);
static int process_ipp(_ipp_client_t *client);
ipp_attribute_t *attr);
static void run_printer(_ipp_printer_t *printer);
static char *time_string(time_t tv, char *buffer, size_t bufsize);
+static void update_device_attributes_no_lock(_ipp_printer_t *printer);
+static void update_device_state_no_lock(_ipp_printer_t *printer);
static void usage(int status) __attribute__((noreturn));
static int valid_doc_attributes(_ipp_client_t *client);
static int valid_job_attributes(_ipp_client_t *client);
static int KeepFiles = 0,
Verbosity = 0;
-static pthread_mutex_t SubscriptionMutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t SubscriptionCondition = PTHREAD_COND_INITIALIZER;
+static _cups_mutex_t SubscriptionMutex = _CUPS_MUTEX_INITIALIZER;
+static _cups_cond_t SubscriptionCondition = _CUPS_COND_INITIALIZER;
/*
delete_printer(printer);
- /* TODO: Silence compiler warnings until everything is implemented */
- add_event(NULL, NULL, _IPP_EVENT_NONE, "");
- check_jobs(printer);
- copy_subscription_attributes(NULL, NULL, NULL);
- create_subscription(NULL);
- delete_subscription(NULL);
- get_job_state_reasons_bits(NULL);
- get_printer_state_reasons_bits(NULL);
- parse_options(NULL, NULL);
-
return (0);
}
char text[1024]; /* notify-text value */
va_list ap; /* Argument pointer */
+
va_start(ap, message);
vsnprintf(text, sizeof(text), message, ap);
va_end(ap);
}
_cupsRWUnlock(&sub->rwlock);
- pthread_cond_broadcast(&SubscriptionCondition);
+ _cupsCondBroadcast(&SubscriptionCondition);
}
}
}
else
{
int i, /* Looping var */
- num_reasons; /* Number of reasons */
+ num_reasons = 0;/* Number of reasons */
_ipp_jreason_t reason; /* Current reason */
const char *reasons[32]; /* Reason strings */
return (NULL);
}
- client->printer = printer;
+ client->printer = printer;
+ client->fetch_file = -1;
/*
* Accept the client and get the remote address...
}
+/*
+ * 'create_device()' - Create an output device tracking object.
+ */
+
+static _ipp_device_t * /* O - Device */
+create_device(_ipp_client_t *client) /* I - Client */
+{
+ _ipp_device_t *device; /* Device */
+ ipp_attribute_t *uuid; /* output-device-uuid */
+
+
+ if ((uuid = ippFindAttribute(client->request, "output-device-uuid", IPP_TAG_URI)) == NULL)
+ return (NULL);
+
+ if ((device = calloc(1, sizeof(_ipp_device_t))) == NULL)
+ return (NULL);
+
+ _cupsRWInit(&device->rwlock);
+
+ device->uuid = strdup(ippGetString(uuid, 0, NULL));
+ device->state = IPP_PSTATE_STOPPED;
+
+ _cupsRWLockWrite(&client->printer->rwlock);
+ cupsArrayAdd(client->printer->devices, device);
+ _cupsRWUnlock(&client->printer->rwlock);
+
+ return (device);
+}
+
+
/*
* 'create_job()' - Create a new job object from a Print-Job or Create-Job
* request.
static void create_job_filename(
_ipp_printer_t *printer, /* I - Printer */
_ipp_job_t *job, /* I - Job */
+ const char *format, /* I - Format or NULL */
char *fname, /* I - Filename buffer */
size_t fnamesize) /* I - Size of filename buffer */
{
* Figure out the extension...
*/
- if (!strcasecmp(job->format, "image/jpeg"))
+ if (!format)
+ format = job->format;
+
+ if (!strcasecmp(format, "image/jpeg"))
ext = "jpg";
- else if (!strcasecmp(job->format, "image/png"))
+ else if (!strcasecmp(format, "image/png"))
ext = "png";
- else if (!strcasecmp(job->format, "image/pwg-raster"))
+ else if (!strcasecmp(format, "image/pwg-raster"))
ext = "ras";
- else if (!strcasecmp(job->format, "image/urf"))
+ else if (!strcasecmp(format, "image/urf"))
ext = "urf";
- else if (!strcasecmp(job->format, "application/pdf"))
+ else if (!strcasecmp(format, "application/pdf"))
ext = "pdf";
- else if (!strcasecmp(job->format, "application/postscript"))
+ else if (!strcasecmp(format, "application/postscript"))
ext = "ps";
else
ext = "prn";
_IPP_OP_UPDATE_ACTIVE_JOBS,
_IPP_OP_UPDATE_DOCUMENT_STATUS,
_IPP_OP_UPDATE_JOB_STATUS,
- _IPP_OP_UPDATE_OUTPUT_DEVICE_ATTRIBUTES
+ _IPP_OP_UPDATE_OUTPUT_DEVICE_ATTRIBUTES,
+ _IPP_OP_UNREGISTER_OUTPUT_DEVICE
};
static const char * const charsets[] =/* charset-supported values */
{
printer->state_time = printer->start_time;
printer->jobs = cupsArrayNew3((cups_array_func_t)compare_jobs, NULL, NULL, 0, NULL, (cups_afree_func_t)delete_job);
printer->active_jobs = cupsArrayNew((cups_array_func_t)compare_active_jobs, NULL);
- printer->completed_jobs = cupsArrayNew((cups_array_func_t)compare_active_jobs, NULL);
+ printer->completed_jobs = cupsArrayNew((cups_array_func_t)compare_completed_jobs, NULL);
printer->next_job_id = 1;
httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
create_subscription(
_ipp_printer_t *printer, /* I - Printer */
_ipp_job_t *job, /* I - Job, if any */
+ int interval, /* I - Interval for progress events */
int lease, /* I - Lease duration */
const char *username, /* I - User creating the subscription */
- ipp_attribute_t *events, /* I - Events to monitor */
- ipp_attribute_t *notify_attrs, /* I - Attributes to report */
- ipp_attribute_t *userdata) /* I - User data, if any */
+ ipp_attribute_t *notify_events, /* I - Events to monitor */
+ ipp_attribute_t *notify_attributes, /* I - Attributes to report */
+ ipp_attribute_t *notify_user_data) /* I - User data, if any */
{
_ipp_subscription_t *sub; /* Subscription */
ipp_attribute_t *attr; /* Subscription attribute */
_cupsRWLockWrite(&(printer->rwlock));
- sub->id = printer->next_sub_id ++;
- sub->mask = get_notify_events_bits(events);
- sub->printer = printer;
- sub->job = job;
- sub->lease = lease;
- sub->expire = time(NULL) + sub->lease;
- sub->attrs = ippNew();
+ sub->id = printer->next_sub_id ++;
+ sub->mask = notify_events ? get_notify_events_bits(notify_events) : _IPP_EVENT_DEFAULT;
+ sub->printer = printer;
+ sub->job = job;
+ sub->interval = interval;
+ sub->lease = lease;
+ sub->attrs = ippNew();
+
+ if (lease)
+ sub->expire = time(NULL) + sub->lease;
+ else
+ sub->expire = INT_MAX;
- _cupsMutexInit(&(sub->mutex));
- pthread_cond_init(&(sub->cond), NULL);
+ _cupsRWInit(&(sub->rwlock));
/*
* Add subscription description attributes and add to the subscriptions
attr = ippAddString(sub->attrs, IPP_TAG_SUBSCRIPTION, IPP_TAG_NAME, "notify-subscriber-user-name", NULL, username);
sub->username = ippGetString(attr, 0, NULL);
- ippCopyAttribute(sub->attrs, events, 0);
+ if (notify_events)
+ ippCopyAttribute(sub->attrs, notify_events, 0);
+ else
+ ippAddString(sub->attrs, IPP_TAG_SUBSCRIPTION, IPP_CONST_TAG(IPP_TAG_KEYWORD), "notify-events", NULL, _IPP_EVENT_DEFAULT_STRING);
ippAddString(sub->attrs, IPP_TAG_SUBSCRIPTION, IPP_CONST_TAG(IPP_TAG_KEYWORD), "notify-pull-method", NULL, "ippget");
- if (notify_attrs)
- ippCopyAttribute(sub->attrs, notify_attrs, 0);
+ if (notify_attributes)
+ ippCopyAttribute(sub->attrs, notify_attributes, 0);
- if (userdata)
- ippCopyAttribute(sub->attrs, userdata, 0);
+ if (notify_user_data)
+ ippCopyAttribute(sub->attrs, notify_user_data, 0);
sub->events = cupsArrayNew3(NULL, NULL, NULL, 0, NULL, (cups_afree_func_t)ippDelete);
}
+/*
+ * 'delete_device()' - Remove a device from a printer.
+ *
+ * Note: Caller is responsible for locking the printer object.
+ */
+
+static void
+delete_device(_ipp_device_t *device) /* I - Device */
+{
+ /*
+ * Free memory used for the device...
+ */
+
+ _cupsRWDeinit(&device->rwlock);
+
+ if (device->name)
+ free(device->name);
+
+ free(device->uuid);
+
+ ippDelete(device->attrs);
+
+ free(device);
+}
+
+
/*
* 'delete_job()' - Remove from the printer and free all memory used by a job
* object.
free(job->filename);
}
- pthread_rwlock_destroy(&job->rwlock);
+ _cupsRWDeinit(&job->rwlock);
free(job);
}
if (printer->proxy_pass)
free(printer->proxy_pass);
+
ippDelete(printer->attrs);
ippDelete(printer->dev_attrs);
cupsArrayDelete(printer->jobs);
cupsArrayDelete(printer->subscriptions);
- pthread_rwlock_destroy(&printer->rwlock);
+ _cupsRWDeinit(&printer->rwlock);
free(printer);
}
{
sub->pending_delete = 1;
- pthread_cond_broadcast(&SubscriptionCondition);
+ _cupsCondBroadcast(&SubscriptionCondition);
_cupsRWLockWrite(&sub->rwlock);
ippDelete(sub->attrs);
cupsArrayDelete(sub->events);
- pthread_rwlock_destroy(&sub->rwlock);
+ _cupsRWDeinit(&sub->rwlock);
free(sub);
}
}
+/*
+ * 'find_device()' - Find a device.
+ */
+
+static _ipp_device_t * /* I - Device */
+find_device(_ipp_client_t *client) /* I - Client */
+{
+ ipp_attribute_t *uuid; /* output-device-uuid */
+ _ipp_device_t key, /* Search key */
+ *device; /* Matching device */
+
+
+ if ((uuid = ippFindAttribute(client->request, "output-device-uuid", IPP_TAG_URI)) == NULL)
+ return (NULL);
+
+ key.uuid = (char *)ippGetString(uuid, 0, NULL);
+
+ _cupsRWLockRead(&client->printer->rwlock);
+ device = (_ipp_device_t *)cupsArrayFind(client->printer->devices, &key);
+ _cupsRWUnlock(&client->printer->rwlock);
+
+ return (device);
+}
+
+
/*
* 'find_job()' - Find a job specified in a request.
*/
static _ipp_job_t * /* O - Job or NULL */
-find_job(_ipp_client_t *client) /* I - Client */
+find_job(_ipp_client_t *client, /* I - Client */
+ int job_id) /* I - Job ID to find or 0 to lookup */
{
ipp_attribute_t *attr; /* job-id or job-uri attribute */
_ipp_job_t key, /* Job search key */
*job; /* Matching job, if any */
- if ((attr = ippFindAttribute(client->request, "job-uri", IPP_TAG_URI)) != NULL)
+ if (job_id > 0)
+ {
+ key.id = job_id;
+ }
+ else if ((attr = ippFindAttribute(client->request, "job-uri", IPP_TAG_URI)) != NULL)
{
const char *uri = ippGetString(attr, 0, NULL);
return (NULL);
}
else if ((attr = ippFindAttribute(client->request, "job-id", IPP_TAG_INTEGER)) != NULL)
+ {
key.id = ippGetInteger(attr, 0);
+ }
_cupsRWLockRead(&(client->printer->rwlock));
job = (_ipp_job_t *)cupsArrayFind(client->printer->jobs, &key);
}
+/*
+ * 'find_subscription()' - Find a subcription.
+ */
+
+static _ipp_subscription_t * /* O - Subscription */
+find_subscription(_ipp_client_t *client,/* I - Client */
+ int sub_id) /* I - Subscription ID or 0 */
+{
+ ipp_attribute_t *notify_subscription_id;
+ /* notify-subscription-id */
+ _ipp_subscription_t key, /* Search key */
+ *sub; /* Matching subscription */
+
+
+ if (sub_id > 0)
+ key.id = sub_id;
+ else if ((notify_subscription_id = ippFindAttribute(client->request, "notify-subscription-id", IPP_TAG_INTEGER)) == NULL)
+ return (NULL);
+ else
+ key.id = ippGetInteger(notify_subscription_id, 0);
+
+ _cupsRWLockRead(&client->printer->rwlock);
+ sub = (_ipp_subscription_t *)cupsArrayFind(client->printer->subscriptions, &key);
+ _cupsRWUnlock(&client->printer->rwlock);
+
+ return (sub);
+}
+
+
/*
* 'get_job_state_reasons_bits()' - Get the bits associates with "job-state-reasons" values.
*/
ipp_acknowledge_document(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ _ipp_device_t *device; /* Device */
+ _ipp_job_t *job; /* Job */
+ ipp_attribute_t *attr; /* Attribute */
+
+
+ if ((device = find_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Device was not found.");
+ return;
+ }
+
+ if ((job = find_job(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job was not found.");
+ return;
+ }
+
+ if (!job->dev_uuid || strcmp(job->dev_uuid, device->uuid))
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Job not assigned to device.");
+ return;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "document-number", IPP_TAG_ZERO)) == NULL || ippGetGroupTag(attr) != IPP_TAG_OPERATION || ippGetValueTag(attr) != IPP_TAG_INTEGER || ippGetCount(attr) != 1 || ippGetInteger(attr, 0) != 1)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, attr ? "Bad document-number attribute." : "Missing document-number attribute.");
+ return;
+ }
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
}
ipp_acknowledge_job(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ _ipp_device_t *device; /* Device */
+ _ipp_job_t *job; /* Job */
+
+
+ if ((device = find_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Device was not found.");
+ return;
+ }
+
+ if ((job = find_job(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job was not found.");
+ return;
+ }
+
+ if (job->dev_uuid && strcmp(job->dev_uuid, device->uuid))
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_AUTHORIZED, "Job not assigned to device.");
+ return;
+ }
+
+ if (!(job->state_reasons & _IPP_JREASON_JOB_FETCHABLE))
+ {
+ respond_ipp(client, _IPP_STATUS_ERROR_NOT_FETCHABLE, "Job not fetchable.");
+ return;
+ }
+
+ if (!job->dev_uuid)
+ job->dev_uuid = strdup(device->uuid);
+
+ job->state_reasons &= (_ipp_jreason_t)~_IPP_JREASON_JOB_FETCHABLE;
+
+ add_event(client->printer, job, _IPP_EVENT_JOB_STATE_CHANGED, "Job acknowledged.");
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
}
* Get the job...
*/
- if ((job = find_job(client)) == NULL)
+ if ((job = find_job(client, 0)) == NULL)
{
respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job does not exist.");
return;
_cupsRWUnlock(&(client->printer->rwlock));
+ add_event(client->printer, job, _IPP_EVENT_JOB_COMPLETED, NULL);
+
respond_ipp(client, IPP_STATUS_OK, NULL);
break;
}
ipp_cancel_subscription(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ ipp_attribute_t *sub_ids, /* notify-subscription-ids */
+ *seq_nums, /* notify-sequence-numbers */
+ *notify_wait; /* Wait for events? */
+ int i, /* Looping var */
+ count; /* Number of IDs */
+ _ipp_subscription_t *sub; /* Current subscription */
+
+
+ if ((sub_ids = ippFindAttribute(client->request, "notify-subscription-ids", IPP_TAG_INTEGER)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "Missing notify-subscription-ids attribute.");
+ return;
+ }
+
+ count = ippGetCount(sub_ids);
+ seq_nums = ippFindAttribute(client->request, "notify-sequence-numbers", IPP_TAG_INTEGER);
+ notify_wait = ippFindAttribute(client->request, "notify-wait", IPP_TAG_BOOLEAN);
+
+ if (seq_nums && count != ippGetCount(seq_nums))
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "The notify-subscription-ids and notify-sequence-numbers attributes are different lengths.");
+ return;
+ }
+
+ if ((sub = find_subscription(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Subscription was not found.");
+ return;
+ }
+
+ _cupsRWLockWrite(&client->printer->rwlock);
+ delete_subscription(sub);
+ _cupsRWUnlock(&client->printer->rwlock);
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
}
* Get the job...
*/
- if ((job = find_job(client)) == NULL)
+ if ((job = find_job(client, 0)) == NULL)
{
respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job does not exist.");
return;
if ((job = create_job(client)) == NULL)
{
- respond_ipp(client, IPP_STATUS_ERROR_BUSY,
- "Currently printing another job.");
+ respond_ipp(client, IPP_STATUS_ERROR_TOO_MANY_JOBS, "Too many jobs are queued.");
return;
}
copy_job_attributes(client, job, ra);
cupsArrayDelete(ra);
+
+ /*
+ * Add any subscriptions...
+ */
+
+ client->job = job;
+ ipp_create_xxx_subscriptions(client);
}
ipp_create_xxx_subscriptions(
_ipp_client_t *client)
{
+ _ipp_subscription_t *sub; /* Subscription */
ipp_attribute_t *attr; /* Subscription attribute */
- _ipp_job_t *job = NULL; /* Job */
- const char *user; /* Username */
- int lease = -1; /* notify-lease-duration */
- _ipp_event_t events = _IPP_EVENT_NONE;
- /* notify-events */
+ const char *username; /* requesting-user-name or
+ authenticated username */
+ int num_subs = 0, /* Number of subscriptions */
+ ok_subs = 0; /* Number of good subscriptions */
- if (ippGetOperation(client->request) == IPP_OP_CREATE_JOB_SUBSCRIPTIONS)
- {
- if ((job = find_job(client)) == NULL)
- {
- respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job not found.");
- return;
- }
- }
-
/*
- * See if we have the required subscription attributes...
+ * For the Create-xxx-Subscriptions operations, queue up a successful-ok
+ * response...
*/
- if ((attr = ippFindAttribute(client->request, "notify-pull-method", IPP_TAG_ZERO)) == NULL ||
- ippGetGroupTag(attr) != IPP_TAG_SUBSCRIPTION || ippGetValueTag(attr) != IPP_TAG_KEYWORD ||
- strcmp(ippGetString(attr, 0, NULL), "ippget"))
- {
- // TODO: Return an error?
- return (NULL);
- }
-
- if ((attr = ippFindAttribute(client->request, "notify-events", IPP_TAG_ZERO)) == NULL ||
- ippGetGroupTag(attr) != IPP_TAG_SUBSCRIPTION || ippGetValueTag(attr) != IPP_TAG_KEYWORD)
- {
- // TODO: Return an error?
- return (NULL);
- }
+ if (ippGetOperation(client->request) == IPP_OP_CREATE_JOB_SUBSCRIPTIONS || ippGetOperation(client->request) == IPP_OP_CREATE_PRINTER_SUBSCRIPTIONS)
+ respond_ipp(client, IPP_STATUS_OK, NULL);
/*
- * Get the requesting-user-name and other attributes...
+ * Get the authenticated user name, if any...
*/
- if ((attr = ippFindAttribute(client->request, "requesting-user-name", IPP_TAG_NAME)) != NULL)
- sub->username = ippGetString(attr, 0, NULL);
+ if (client->username[0])
+ username = client->username;
+ else if ((attr = ippFindAttribute(client->request, "requesting-user-name", IPP_TAG_NAME)) != NULL && ippGetGroupTag(attr) == IPP_TAG_OPERATION && ippGetCount(attr) == 1)
+ username = ippGetString(attr, 0, NULL);
else
- sub->username = "anonymous";
+ username = "guest";
- if ((attr = ippFindAttribute(client->request, "notify-lease-duration", IPP_TAG_INTEGER)) != NULL)
- sub->lease = ippGetInteger(attr, 0);
- else
- sub->lease = 86400;
+ /*
+ * Skip past the initial attributes to the first subscription group.
+ */
-get_notify_events_bits(attr)
+ attr = ippFirstAttribute(client->request);
+ while (attr && ippGetGroupTag(attr) != IPP_TAG_SUBSCRIPTION)
+ attr = ippNextAttribute(client->request);
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ while (attr)
+ {
+ _ipp_job_t *job = NULL; /* Job */
+ const char *attrname, /* Attribute name */
+ *pullmethod = NULL;
+ /* notify-pull-method */
+ ipp_attribute_t *notify_attributes = NULL,
+ /* notify-attributes */
+ *notify_events = NULL,
+ /* notify-events */
+ *notify_user_data = NULL;
+ /* notify-user-data */
+ int interval = 0, /* notify-time-interval */
+ lease = _IPP_NOTIFY_LEASE_DURATION_DEFAULT;
+ /* notify-lease-duration */
+ ipp_status_t status = IPP_STATUS_OK;
+ /* notify-status-code */
+
+ num_subs ++;
+
+ while (attr)
+ {
+ if ((attrname = ippGetName(attr)) == NULL)
+ break;
+
+ if (!strcmp(attrname, "notify-recipient-uri"))
+ {
+ /*
+ * Push notifications not supported.
+ */
+
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ else if (!strcmp(attrname, "notify-pull-method"))
+ {
+ pullmethod = ippGetString(attr, 0, NULL);
+
+ if (ippGetValueTag(attr) != IPP_TAG_KEYWORD || ippGetCount(attr) != 1 || !pullmethod || strcmp(pullmethod, "ippget"))
+ {
+ ippCopyAttribute(client->response, attr, 0);
+ pullmethod = NULL;
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ }
+ }
+ else if (!strcmp(attrname, "notify-attributes"))
+ {
+ if (ippGetValueTag(attr) != IPP_TAG_KEYWORD)
+ {
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+
+ notify_attributes = attr;
+ }
+ else if (!strcmp(attrname, "notify-charset"))
+ {
+ if (ippGetValueTag(attr) != IPP_TAG_CHARSET || ippGetCount(attr) != 1 ||
+ (strcmp(ippGetString(attr, 0, NULL), "us-ascii") && strcmp(ippGetString(attr, 0, NULL), "utf-8")))
+ {
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ }
+ else if (!strcmp(attrname, "notify-natural-language"))
+ {
+ if (ippGetValueTag(attr) != IPP_TAG_LANGUAGE || ippGetCount(attr) != 1 || strcmp(ippGetString(attr, 0, NULL), "en"))
+ {
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ }
+ else if (!strcmp(attrname, "notify-user-data"))
+ {
+ int datalen; /* Length of data */
+
+ if (ippGetValueTag(attr) != IPP_TAG_STRING || ippGetCount(attr) != 1 || !ippGetOctetString(attr, 0, &datalen) || datalen > 63)
+ {
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ else
+ notify_user_data = attr;
+ }
+ else if (!strcmp(attrname, "notify-events"))
+ {
+ if (ippGetValueTag(attr) != IPP_TAG_KEYWORD)
+ {
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ else
+ notify_events = attr;
+ }
+ else if (!strcmp(attrname, "notify-lease-duration"))
+ {
+ if (ippGetValueTag(attr) != IPP_TAG_INTEGER || ippGetCount(attr) != 1 || ippGetInteger(attr, 0) < 0)
+ {
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ else
+ lease = ippGetInteger(attr, 0);
+ }
+ else if (!strcmp(attrname, "notify-time-interval"))
+ {
+ if (ippGetValueTag(attr) != IPP_TAG_INTEGER || ippGetCount(attr) != 1 || ippGetInteger(attr, 0) < 0)
+ {
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ else
+ interval = ippGetInteger(attr, 0);
+ }
+ else if (!strcmp(attrname, "notify-job-id"))
+ {
+ if (ippGetOperation(client->request) != IPP_OP_CREATE_JOB_SUBSCRIPTIONS || ippGetValueTag(attr) != IPP_TAG_INTEGER || ippGetInteger(attr, 0) < 1)
+ {
+ status = IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ else if ((job = find_job(client, ippGetInteger(attr, 0))) == NULL)
+ {
+ status = IPP_STATUS_ERROR_NOT_FOUND;
+ ippCopyAttribute(client->response, attr, 0);
+ }
+ }
+
+ attr = ippNextAttribute(client->request);
+ }
+
+ if (status)
+ {
+ ippAddInteger(client->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, "notify-status-code", status);
+ }
+ else if (!pullmethod)
+ {
+ ippAddInteger(client->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, "notify-status-code", IPP_STATUS_ERROR_BAD_REQUEST);
+ }
+ else
+ {
+ switch (ippGetOperation(client->request))
+ {
+ case IPP_OP_PRINT_JOB :
+ case IPP_OP_PRINT_URI :
+ case IPP_OP_CREATE_JOB :
+ job = client->job;
+ break;
+
+ default :
+ break;
+ }
+
+ if ((sub = create_subscription(client->printer, job, interval, lease, username, notify_events, notify_attributes, notify_user_data)) == NULL)
+ {
+ ippAddInteger(client->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER, "notify-subscription-id", sub->id);
+ ok_subs ++;
+ }
+ else
+ ippAddInteger(client->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM, "notify-status-code", IPP_STATUS_ERROR_INTERNAL);
+ }
+ }
+
+ if (ok_subs == 0)
+ ippSetStatusCode(client->response, IPP_STATUS_ERROR_IGNORED_ALL_SUBSCRIPTIONS);
+ else if (ok_subs != num_subs)
+ ippSetStatusCode(client->response, IPP_STATUS_OK_IGNORED_SUBSCRIPTIONS);
}
ipp_fetch_document(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
-}
+ _ipp_device_t *device; /* Device */
+ _ipp_job_t *job; /* Job */
+ ipp_attribute_t *attr; /* Attribute */
+ int compression; /* compression */
+ char filename[1024]; /* Job filename */
+ const char *format; /* document-format */
+
+
+ if ((device = find_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Device was not found.");
+ return;
+ }
+
+ if ((job = find_job(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job was not found.");
+ return;
+ }
+
+ if (!job->dev_uuid || strcmp(job->dev_uuid, device->uuid))
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Job not assigned to device.");
+ return;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "document-number", IPP_TAG_ZERO)) == NULL || ippGetGroupTag(attr) != IPP_TAG_OPERATION || ippGetValueTag(attr) != IPP_TAG_INTEGER || ippGetCount(attr) != 1 || ippGetInteger(attr, 0) != 1)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, attr ? "Bad document-number attribute." : "Missing document-number attribute.");
+ return;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "compression-accepted", IPP_TAG_KEYWORD)) != NULL)
+ compression = !strcmp(ippGetString(attr, 0, NULL), "gzip");
+ else
+ compression = 0;
+
+ if ((attr = ippFindAttribute(client->request, "document-format-accepted", IPP_TAG_MIMETYPE)) != NULL)
+ {
+ int i, /* Looping var */
+ count = ippGetCount(attr); /* Number of values */
+
+
+ for (i = 0; i < count; i ++)
+ {
+ format = ippGetString(attr, i, NULL);
+
+ create_job_filename(client->printer, job, NULL, filename, sizeof(filename));
+
+ if (!access(filename, R_OK))
+ break;
+ }
+
+ if (i >= count)
+ {
+ respond_ipp(client, _IPP_STATUS_ERROR_NOT_FETCHABLE, "Document not available in requested format.");
+ return;
+ }
+ }
+ else if ((attr = ippFindAttribute(job->attrs, "document-format", IPP_TAG_MIMETYPE)) != NULL)
+ format = ippGetString(attr, 0, NULL);
+ else
+ {
+ respond_ipp(client, _IPP_STATUS_ERROR_NOT_FETCHABLE, "Document format unknown.");
+ return;
+ }
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
+ ippAddString(client->response, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, format);
+ ippAddString(client->response, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "compression", NULL, compression ? "gzip" : "none");
+
+ client->fetch_file = open(filename, O_RDONLY);
+}
/*
static void
ipp_fetch_job(_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ _ipp_device_t *device; /* Device */
+ _ipp_job_t *job; /* Job */
+
+
+ if ((device = find_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Device was not found.");
+ return;
+ }
+
+ if ((job = find_job(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job was not found.");
+ return;
+ }
+
+ if (job->dev_uuid && strcmp(job->dev_uuid, device->uuid))
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Job not assigned to device.");
+ return;
+ }
+
+ if (!(job->state_reasons & _IPP_JREASON_JOB_FETCHABLE))
+ {
+ respond_ipp(client, _IPP_STATUS_ERROR_NOT_FETCHABLE, "Job not fetchable.");
+ return;
+ }
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
+ copy_attributes(client->response, job->attrs, NULL, IPP_TAG_JOB, 0);
}
cups_array_t *ra; /* requested-attributes */
- if ((job = find_job(client)) == NULL)
+ if ((job = find_job(client, 0)) == NULL)
{
respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job not found.");
return;
ipp_get_notifications(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ _ipp_subscription_t *sub; /* Subscription */
+
+
+ if ((sub = find_subscription(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Subscription was not found.");
+ return;
+ }
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
}
ipp_get_printer_supported_values(
_ipp_client_t *client) /* I - Client */
{
- /* TODO: Do something */
+ cups_array_t *ra = ippCreateRequestedArray(client->request);
+ /* Requested attributes */
+
respond_ipp(client, IPP_STATUS_OK, NULL);
+
+ copy_attributes(client->response, client->printer->attrs, ra, IPP_TAG_PRINTER, 1);
+
+ cupsArrayDelete(ra);
}
ipp_get_subscription_attributes(
_ipp_client_t *client) /* I - Client */
{
- /* TODO: Do something */
+ _ipp_subscription_t *sub; /* Subscription */
+ cups_array_t *ra = ippCreateRequestedArray(client->request);
+ /* Requested attributes */
- respond_ipp(client, IPP_STATUS_OK, NULL);
+
+ if ((sub = find_subscription(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Subscription was not found.");
+ }
+ else
+ {
+ respond_ipp(client, IPP_STATUS_OK, NULL);
+ copy_subscription_attributes(client, sub, ra);
+ }
+
+ cupsArrayDelete(ra);
}
ipp_get_subscriptions(
_ipp_client_t *client) /* I - Client */
{
- /* TODO: Do something */
+ _ipp_subscription_t *sub; /* Current subscription */
+ cups_array_t *ra = ippCreateRequestedArray(client->request);
+ /* Requested attributes */
+ int first = 1; /* First time? */
+
respond_ipp(client, IPP_STATUS_OK, NULL);
+ _cupsRWLockRead(&client->printer->rwlock);
+ for (sub = (_ipp_subscription_t *)cupsArrayFirst(client->printer->subscriptions);
+ sub;
+ sub = (_ipp_subscription_t *)cupsArrayNext(client->printer->subscriptions))
+ {
+ if (!first)
+ ippAddSeparator(client->response);
+
+ copy_subscription_attributes(client, sub, ra);
+ first = 0;
+ }
+
+ cupsArrayDelete(ra);
}
* Create a file for the request data...
*/
- create_job_filename(client->printer, job, filename, sizeof(filename));
+ create_job_filename(client->printer, job, NULL, filename, sizeof(filename));
if (Verbosity)
fprintf(stderr, "Creating job file \"%s\", format \"%s\".\n", filename, job->format);
copy_job_attributes(client, job, ra);
cupsArrayDelete(ra);
+
+ /*
+ * Process any pending subscriptions...
+ */
+
+ client->job = job;
+ ipp_create_xxx_subscriptions(client);
}
copy_job_attributes(client, job, ra);
cupsArrayDelete(ra);
+
+ /*
+ * Process any pending subscriptions...
+ */
+
+ client->job = job;
+ ipp_create_xxx_subscriptions(client);
}
ipp_renew_subscription(
_ipp_client_t *client) /* I - Client */
{
- /* TODO: Do something */
+ _ipp_subscription_t *sub; /* Subscription */
+ ipp_attribute_t *attr; /* notify-lease-duration */
+ int lease; /* Lease duration in seconds */
+
+
+ if ((sub = find_subscription(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Subscription was not found.");
+ return;
+ }
+
+ if (sub->job)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Per-job subscriptions cannot be renewed.");
+ return;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "notify-lease-duration", IPP_TAG_ZERO)) != NULL)
+ {
+ if (ippGetGroupTag(attr) != IPP_TAG_SUBSCRIPTION || ippGetValueTag(attr) != IPP_TAG_INTEGER || ippGetCount(attr) != 1 || ippGetInteger(attr, 0) < 0)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES, "Bad notify-lease-duration.");
+ return;
+ }
+
+ lease = ippGetInteger(attr, 0);
+ }
+ else
+ lease = _IPP_NOTIFY_LEASE_DURATION_DEFAULT;
+
+ sub->lease = lease;
+
+ if (lease)
+ sub->expire = time(NULL) + sub->lease;
+ else
+ sub->expire = INT_MAX;
respond_ipp(client, IPP_STATUS_OK, NULL);
}
* Get the job...
*/
- if ((job = find_job(client)) == NULL)
+ if ((job = find_job(client, 0)) == NULL)
{
respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job does not exist.");
httpFlush(client->http);
* Create a file for the request data...
*/
- create_job_filename(client->printer, job, filename, sizeof(filename));
+ create_job_filename(client->printer, job, NULL, filename, sizeof(filename));
if (Verbosity)
fprintf(stderr, "Creating job file \"%s\", format \"%s\".\n", filename, job->format);
_cupsRWUnlock(&(client->printer->rwlock));
/*
- * Process the job...
+ * Process the job, if possible...
*/
-#if 0
- if (!_cupsThreadCreate((_cups_thread_func_t)process_job, job))
- {
- job->state = IPP_JSTATE_ABORTED;
- respond_ipp(client, IPP_STATUS_ERROR_INTERNAL, "Unable to process job.");
- return;
- }
-
-#else
- process_job(job);
-#endif /* 0 */
-
+ check_jobs(client->printer);
+
/*
* Return the job info...
*/
* Get the job...
*/
- if ((job = find_job(client)) == NULL)
+ if ((job = find_job(client, 0)) == NULL)
{
respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job does not exist.");
httpFlush(client->http);
_cupsRWUnlock(&(client->printer->rwlock));
/*
- * Process the job...
+ * Process the job, if possible...
*/
-#if 0
- if (!_cupsThreadCreate((_cups_thread_func_t)process_job, job))
- {
- job->state = IPP_JSTATE_ABORTED;
- respond_ipp(client, IPP_STATUS_ERROR_INTERNAL, "Unable to process job.");
- return;
- }
-
-#else
- process_job(job);
-#endif /* 0 */
-
+ check_jobs(client->printer);
+
/*
* Return the job info...
*/
}
+/*
+ * 'ipp_unregister_output_device()' - Unregister an output device.
+ */
+
+static void
+ipp_unregister_output_device(
+ _ipp_client_t *client) /* I - Client */
+{
+ _ipp_device_t *device; /* Device */
+
+
+ /*
+ * Find the device...
+ */
+
+ if ((device = find_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Output device not found.");
+ return;
+ }
+
+ /*
+ * Remove the device from the printer...
+ */
+
+ _cupsRWLockWrite(&client->printer->rwlock);
+
+ cupsArrayRemove(client->printer->devices, device);
+
+ update_device_attributes_no_lock(client->printer);
+ update_device_state_no_lock(client->printer);
+
+ _cupsRWUnlock(&client->printer->rwlock);
+
+ /*
+ * Delete the device...
+ */
+
+ delete_device(device);
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
+}
+
+
/*
* 'ipp_update_active_jobs()' - Update the list of active jobs.
*/
ipp_update_active_jobs(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ _ipp_device_t *device; /* Output device */
+ _ipp_job_t *job; /* Job */
+ ipp_attribute_t *job_ids, /* job-ids */
+ *job_states; /* output-device-job-states */
+ int i, /* Looping var */
+ count, /* Number of values */
+ num_different = 0,
+ /* Number of jobs with different states */
+ different[1000],/* Jobs with different states */
+ num_unsupported = 0,
+ /* Number of unsupported job-ids */
+ unsupported[1000];
+ /* Unsupported job-ids */
+ ipp_jstate_t states[1000]; /* Different job state values */
+
+
+ /*
+ * Process the job-ids and output-device-job-states values...
+ */
+
+ if ((device = find_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Device was not found.");
+ return;
+ }
+
+ if ((job_ids = ippFindAttribute(client->request, "job-ids", IPP_TAG_ZERO)) == NULL || ippGetGroupTag(job_ids) != IPP_TAG_OPERATION || ippGetValueTag(job_ids) != IPP_TAG_INTEGER)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, job_ids ? "Bad job-ids attribute." : "Missing required job-ids attribute.");
+ return;
+ }
+
+ if ((job_states = ippFindAttribute(client->request, "output-device-job-states", IPP_TAG_ZERO)) == NULL || ippGetGroupTag(job_states) != IPP_TAG_OPERATION || ippGetValueTag(job_states) != IPP_TAG_ENUM)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, job_ids ? "Bad output-device-job-states attribute." : "Missing required output-device-job-states attribute.");
+ return;
+ }
+
+ count = ippGetCount(job_ids);
+ if (count != ippGetCount(job_states))
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, "The job-ids and output-device-job-states attributes do not have the same number of values.");
+ return;
+ }
+
+ for (i = 0; i < count; i ++)
+ {
+ if ((job = find_job(client, ippGetInteger(job_ids, i))) == NULL || !job->dev_uuid || strcmp(job->dev_uuid, device->uuid))
+ {
+ if (num_unsupported < 1000)
+ unsupported[num_unsupported ++] = ippGetInteger(job_ids, i);
+ }
+ else
+ {
+ ipp_jstate_t state = (ipp_jstate_t)ippGetInteger(job_states, i);
+
+ if (job->state >= IPP_JSTATE_STOPPED && state != job->state)
+ {
+ if (num_different < 1000)
+ {
+ different[num_different] = job->id;
+ states[num_different ++] = job->state;
+ }
+ }
+ else
+ job->dev_state = state;
+ }
+ }
+
+ /*
+ * Then look for jobs assigned to the device but not listed...
+ */
+
+ for (job = (_ipp_job_t *)cupsArrayFirst(client->printer->jobs);
+ job && num_different < 1000;
+ job = (_ipp_job_t *)cupsArrayNext(client->printer->jobs))
+ {
+ if (job->dev_uuid && !strcmp(job->dev_uuid, device->uuid) && !ippContainsInteger(job_ids, job->id))
+ {
+ different[num_different] = job->id;
+ states[num_different ++] = job->state;
+ }
+ }
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
+
+ if (num_different > 0)
+ {
+ ippAddIntegers(client->response, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-ids", num_different, different);
+ ippAddIntegers(client->response, IPP_TAG_OPERATION, IPP_TAG_ENUM, "output-device-job-states", num_different, (int *)states);
+ }
+
+ if (num_unsupported > 0)
+ {
+ ippAddIntegers(client->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_INTEGER, "job-ids", num_unsupported, unsupported);
+ }
}
ipp_update_document_status(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ _ipp_device_t *device; /* Device */
+ _ipp_job_t *job; /* Job */
+ ipp_attribute_t *attr; /* Attribute */
+
+
+ if ((device = find_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Device was not found.");
+ return;
+ }
+
+ if ((job = find_job(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job was not found.");
+ return;
+ }
+
+ if (!job->dev_uuid || strcmp(job->dev_uuid, device->uuid))
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Job not assigned to device.");
+ return;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "document-number", IPP_TAG_ZERO)) == NULL || ippGetGroupTag(attr) != IPP_TAG_OPERATION || ippGetValueTag(attr) != IPP_TAG_INTEGER || ippGetCount(attr) != 1 || ippGetInteger(attr, 0) != 1)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_BAD_REQUEST, attr ? "Bad document-number attribute." : "Missing document-number attribute.");
+ return;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "impressions-completed", IPP_TAG_INTEGER)) != NULL)
+ {
+ job->impcompleted = ippGetInteger(attr, 0);
+ add_event(client->printer, job, _IPP_EVENT_JOB_PROGRESS, NULL);
+ }
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
}
ipp_update_job_status(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ _ipp_device_t *device; /* Device */
+ _ipp_job_t *job; /* Job */
+ ipp_attribute_t *attr; /* Attribute */
+ _ipp_event_t events = _IPP_EVENT_NONE;
+ /* Event(s) */
+
+
+ if ((device = find_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Device was not found.");
+ return;
+ }
+
+ if ((job = find_job(client, 0)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_FOUND, "Job was not found.");
+ return;
+ }
+
+ if (!job->dev_uuid || strcmp(job->dev_uuid, device->uuid))
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Job not assigned to device.");
+ return;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "job-impressions-completed", IPP_TAG_INTEGER)) != NULL)
+ {
+ job->impcompleted = ippGetInteger(attr, 0);
+ events |= _IPP_EVENT_JOB_PROGRESS;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "output-device-job-state", IPP_TAG_ENUM)) != NULL)
+ {
+ job->dev_state = (ipp_jstate_t)ippGetInteger(attr, 0);
+ events |= _IPP_EVENT_JOB_STATE_CHANGED;
+ }
+
+ if ((attr = ippFindAttribute(client->request, "output-device-job-state-reasons", IPP_TAG_KEYWORD)) != NULL)
+ {
+ job->dev_state_reasons = get_job_state_reasons_bits(attr);
+ events |= _IPP_EVENT_JOB_STATE_CHANGED;
+ }
+
+ if (events)
+ add_event(client->printer, job, events, NULL);
+
+ respond_ipp(client, IPP_STATUS_OK, NULL);
}
ipp_update_output_device_attributes(
_ipp_client_t *client) /* I - Client */
{
- // TODO: Implement this!
- respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Need to implement this.");
+ _ipp_device_t *device; /* Device */
+ ipp_attribute_t *attr, /* Current attribute */
+ *dev_attr; /* Device attribute */
+ _ipp_event_t events = _IPP_EVENT_NONE;
+ /* Config/state changed? */
+
+
+ if ((device = find_device(client)) == NULL)
+ {
+ if ((device = create_device(client)) == NULL)
+ {
+ respond_ipp(client, IPP_STATUS_ERROR_NOT_POSSIBLE, "Unable to add output device.");
+ return;
+ }
+ }
+
+ _cupsRWLockWrite(&device->rwlock);
+
+ attr = ippFirstAttribute(client->request);
+ while (attr && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
+ attr = ippNextAttribute(client->request);
+
+ for (; attr; attr = ippNextAttribute(client->request))
+ {
+ const char *attrname = ippGetName(attr),
+ /* Attribute name */
+ *dotptr; /* Pointer to dot in name */
+
+ /*
+ * Skip attributes we don't care about...
+ */
+
+ if (!attrname)
+ continue;
+
+ if (strncmp(attrname, "copies", 6) && strncmp(attrname, "document-format", 15) && strncmp(attrname, "finishings", 10) && strncmp(attrname, "media", 5) && strncmp(attrname, "print-", 6) && strncmp(attrname, "sides", 5) && strncmp(attrname, "printer-alert", 13) && strncmp(attrname, "printer-input", 13) && strncmp(attrname, "printer-output", 14) && strncmp(attrname, "printer-resolution", 18) && strncmp(attrname, "pwg-raster", 10) && strncmp(attrname, "urf-", 4))
+ continue;
+
+ if (strncmp(attrname, "printer-alert", 13) || strncmp(attrname, "printer-state", 13))
+ events |= _IPP_EVENT_PRINTER_CONFIG_CHANGED;
+ else
+ events |= _IPP_EVENT_PRINTER_STATE_CHANGED;
+
+ if (!strcmp(attrname, "media-col-ready") || !strcmp(attrname, "media-ready"))
+ events |= _IPP_EVENT_PRINTER_MEDIA_CHANGED;
+
+ if (!strcmp(attrname, "finishings-col-ready") || !strcmp(attrname, "finishings-ready"))
+ events |= _IPP_EVENT_PRINTER_FINISHINGS_CHANGED;
+
+ if ((dotptr = strrchr(attrname, '.')) != NULL && isdigit(dotptr[1] & 255))
+ {
+#if 0
+ /*
+ * Sparse representation: name.NNN or name.NNN-NNN
+ */
+
+ char temp[256], /* Temporary name string */
+ *tempptr; /* Pointer into temporary string */
+ int low, high; /* Low and high numbers in range */
+
+ low = (int)strtol(dotptr + 1, (char **)&dotptr, 10);
+ if (dotptr && *dotptr == '-')
+ high = (int)strtol(dotptr + 1, NULL, 10);
+ else
+ high = low;
+
+ strlcpy(temp, attrname, sizeof(temp));
+ if ((tempptr = strrchr(temp, '.')) != NULL)
+ *tempptr = '\0';
+
+ if ((dev_attr = ippFindAttribute(device->attrs, temp, IPP_TAG_ZERO)) != NULL)
+ {
+ }
+ else
+#endif /* 0 */
+ respond_unsupported(client, attr);
+ }
+ else
+ {
+ /*
+ * Regular representation - replace or delete current attribute,
+ * if any...
+ */
+
+ if ((dev_attr = ippFindAttribute(device->attrs, attrname, IPP_TAG_ZERO)) != NULL)
+ ippDeleteAttribute(device->attrs, dev_attr);
+
+ if (ippGetValueTag(attr) != IPP_TAG_DELETEATTR)
+ ippCopyAttribute(device->attrs, attr, 0);
+ }
+ }
+
+ _cupsRWUnlock(&device->rwlock);
+
+ if (events)
+ {
+ _cupsRWLockWrite(&client->printer->rwlock);
+ if (events & _IPP_EVENT_PRINTER_CONFIG_CHANGED)
+ update_device_attributes_no_lock(client->printer);
+ if (events & _IPP_EVENT_PRINTER_STATE_CHANGED)
+ update_device_state_no_lock(client->printer);
+ _cupsRWUnlock(&client->printer->rwlock);
+
+ add_event(client->printer, NULL, events, NULL);
+ }
}
}
+#if 0
/*
* 'parse_options()' - Parse URL options into CUPS options.
*
return (num_options);
}
+#endif /* 0 */
/*
ipp_update_output_device_attributes(client);
break;
+ case _IPP_OP_UNREGISTER_OUTPUT_DEVICE :
+ ipp_unregister_output_device(client);
+ break;
+
default :
respond_ipp(client, IPP_STATUS_ERROR_OPERATION_NOT_SUPPORTED,
"Operation not supported.");
httpFlush(client->http); /* Flush trailing (junk) data */
return (respond_http(client, HTTP_STATUS_OK, NULL, "application/ipp",
- ippLength(client->response)));
+ client->fetch_file >= 0 ? 0 : ippLength(client->response)));
}
if (ippWrite(client->http, client->response) != IPP_STATE_DATA)
return (0);
+
+ if (client->fetch_file >= 0)
+ {
+ ssize_t bytes; /* Bytes read */
+ char buffer[32768]; /* Buffer */
+
+ if (client->fetch_compression)
+ httpSetField(client->http, HTTP_FIELD_CONTENT_ENCODING, "gzip");
+
+ while ((bytes = read(client->fetch_file, buffer, sizeof(buffer))) > 0)
+ httpWrite2(client->http, buffer, (size_t)bytes);
+
+ httpWrite2(client->http, "", 0);
+ close(client->fetch_file);
+ client->fetch_file = -1;
+ }
}
return (1);
}
+/*
+ * 'update_device_attributes_no_lock()' - Update the composite device attributes.
+ *
+ * Note: Caller MUST lock the printer object for writing before using.
+ */
+
+static void
+update_device_attributes_no_lock(
+ _ipp_printer_t *printer) /* I - Printer */
+{
+ _ipp_device_t *device; /* Current device */
+ ipp_t *dev_attrs; /* Device attributes */
+
+
+ /* TODO: Support multiple output devices, icons, etc... */
+ device = (_ipp_device_t *)cupsArrayFirst(printer->devices);
+ dev_attrs = ippNew();
+
+ if (device)
+ copy_attributes(dev_attrs, device->attrs, NULL, IPP_TAG_PRINTER, 0);
+
+ ippDelete(printer->dev_attrs);
+ printer->dev_attrs = dev_attrs;
+
+ printer->config_time = time(NULL);
+}
+
+
+/*
+ * 'update_device_status_no_lock()' - Update the composite device state.
+ *
+ * Note: Caller MUST lock the printer object for writing before using.
+ */
+
+static void
+update_device_state_no_lock(
+ _ipp_printer_t *printer) /* I - Printer */
+{
+ _ipp_device_t *device; /* Current device */
+ ipp_attribute_t *attr; /* Current attribute */
+
+
+ /* TODO: Support multiple output devices, icons, etc... */
+ device = (_ipp_device_t *)cupsArrayFirst(printer->devices);
+
+ if ((attr = ippFindAttribute(device->attrs, "printer-state", IPP_TAG_ENUM)) != NULL)
+ printer->dev_state = (ipp_pstate_t)ippGetInteger(attr, 0);
+ else
+ printer->dev_state = IPP_PSTATE_STOPPED;
+
+ if ((attr = ippFindAttribute(device->attrs, "printer-state-reasons", IPP_TAG_KEYWORD)) != NULL)
+ printer->dev_reasons = get_printer_state_reasons_bits(attr);
+ else
+ printer->dev_reasons = _IPP_PREASON_PAUSED;
+
+ printer->state_time = time(NULL);
+}
+
+
/*
* 'usage()' - Show program usage.
*/
buildPhases = (
);
dependencies = (
+ 274EE2861A03EEEE003213D1 /* PBXTargetDependency */,
+ 274EE2881A03EEEE003213D1 /* PBXTargetDependency */,
726AD704135E8AA1002C930D /* PBXTargetDependency */,
2767FC5419267469000F61D3 /* PBXTargetDependency */,
273BF6DE1333B6370022CAAB /* PBXTargetDependency */,
buildPhases = (
);
dependencies = (
+ 274EE2821A03EEE0003213D1 /* PBXTargetDependency */,
+ 274EE2841A03EEE0003213D1 /* PBXTargetDependency */,
274FF5E313332D4300317ECB /* PBXTargetDependency */,
72BEA8D819AFA8BB0085F0F3 /* PBXTargetDependency */,
72F75A711336FACD004BB496 /* PBXTargetDependency */,
270CCDBA135E3D0900007BE2 /* libcupsmime.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220FAC13330B2200FCA411 /* libcupsmime.dylib */; };
270CCDBC135E3D3E00007BE2 /* testmime.c in Sources */ = {isa = PBXBuildFile; fileRef = 270CCDBB135E3D3E00007BE2 /* testmime.c */; };
273BF6C71333B5370022CAAB /* testcups.c in Sources */ = {isa = PBXBuildFile; fileRef = 273BF6C61333B5370022CAAB /* testcups.c */; };
+ 274EE2611A03EDCA003213D1 /* libcups_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 72A4332F155844CF002E172D /* libcups_static.a */; };
+ 274EE2621A03EDCA003213D1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC591926750C000F61D3 /* CoreFoundation.framework */; };
+ 274EE2631A03EDCA003213D1 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5B1926750C000F61D3 /* libresolv.dylib */; };
+ 274EE2641A03EDCA003213D1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5C1926750C000F61D3 /* libz.dylib */; };
+ 274EE2651A03EDCA003213D1 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5D1926750C000F61D3 /* Security.framework */; };
+ 274EE2661A03EDCA003213D1 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5E1926750C000F61D3 /* SystemConfiguration.framework */; };
+ 274EE2721A03EDCB003213D1 /* libcups_static.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 72A4332F155844CF002E172D /* libcups_static.a */; };
+ 274EE2731A03EDCB003213D1 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC591926750C000F61D3 /* CoreFoundation.framework */; };
+ 274EE2741A03EDCB003213D1 /* libresolv.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5B1926750C000F61D3 /* libresolv.dylib */; };
+ 274EE2751A03EDCB003213D1 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5C1926750C000F61D3 /* libz.dylib */; };
+ 274EE2761A03EDCB003213D1 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5D1926750C000F61D3 /* Security.framework */; };
+ 274EE2771A03EDCB003213D1 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2767FC5E1926750C000F61D3 /* SystemConfiguration.framework */; };
+ 274EE27E1A03EE0B003213D1 /* ippinfra.c in Sources */ = {isa = PBXBuildFile; fileRef = 274EE27D1A03EE0B003213D1 /* ippinfra.c */; };
+ 274EE2801A03EE41003213D1 /* ippproxy.c in Sources */ = {isa = PBXBuildFile; fileRef = 274EE27F1A03EE41003213D1 /* ippproxy.c */; };
274FF5D913332CC700317ECB /* cups-driverd.cxx in Sources */ = {isa = PBXBuildFile; fileRef = 274FF5D613332CC700317ECB /* cups-driverd.cxx */; };
274FF5DA13332CC700317ECB /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = 274FF5D713332CC700317ECB /* util.c */; };
274FF5DD13332D0600317ECB /* libcups.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 72220EAE1333047D00FCA411 /* libcups.dylib */; };
remoteGlobalIDString = 273BF6BC1333B5000022CAAB;
remoteInfo = testcups;
};
+ 274EE25D1A03EDCA003213D1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 274FF6891333B1C400317ECB;
+ remoteInfo = libcups_static;
+ };
+ 274EE26E1A03EDCB003213D1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 274FF6891333B1C400317ECB;
+ remoteInfo = libcups_static;
+ };
+ 274EE2811A03EEE0003213D1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 274EE25B1A03EDCA003213D1;
+ remoteInfo = ippinfra;
+ };
+ 274EE2831A03EEE0003213D1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 274EE26C1A03EDCB003213D1;
+ remoteInfo = ippproxy;
+ };
+ 274EE2851A03EEEE003213D1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 274EE25B1A03EDCA003213D1;
+ remoteInfo = ippinfra;
+ };
+ 274EE2871A03EEEE003213D1 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 274EE26C1A03EDCB003213D1;
+ remoteInfo = ippproxy;
+ };
274FF5DB13332CF900317ECB /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 72BF96371333042100B1EAD7 /* Project object */;
);
runOnlyForDeploymentPostprocessing = 1;
};
+ 274EE2671A03EDCA003213D1 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ 274EE2781A03EDCB003213D1 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
274FF5CA13332B1F00317ECB /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
2732E092137A3F5200FAFEF6 /* lpstat.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = lpstat.c; path = ../systemv/lpstat.c; sourceTree = "<group>"; };
273BF6BD1333B5000022CAAB /* testcups */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = testcups; sourceTree = BUILT_PRODUCTS_DIR; };
273BF6C61333B5370022CAAB /* testcups.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = testcups.c; path = ../cups/testcups.c; sourceTree = "<group>"; };
+ 274EE26B1A03EDCA003213D1 /* ippserver copy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "ippserver copy"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 274EE27C1A03EDCB003213D1 /* ippserver copy copy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "ippserver copy copy"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 274EE27D1A03EE0B003213D1 /* ippinfra.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ippinfra.c; path = ../test/ippinfra.c; sourceTree = "<group>"; };
+ 274EE27F1A03EE41003213D1 /* ippproxy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ippproxy.c; path = ../test/ippproxy.c; sourceTree = "<group>"; };
274FF5CC13332B1F00317ECB /* cups-driverd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "cups-driverd"; sourceTree = BUILT_PRODUCTS_DIR; };
274FF5D613332CC700317ECB /* cups-driverd.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "cups-driverd.cxx"; path = "../scheduler/cups-driverd.cxx"; sourceTree = "<group>"; };
274FF5D713332CC700317ECB /* util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = util.c; path = ../scheduler/util.c; sourceTree = "<group>"; };
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 274EE2601A03EDCA003213D1 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 274EE2611A03EDCA003213D1 /* libcups_static.a in Frameworks */,
+ 274EE2621A03EDCA003213D1 /* CoreFoundation.framework in Frameworks */,
+ 274EE2631A03EDCA003213D1 /* libresolv.dylib in Frameworks */,
+ 274EE2641A03EDCA003213D1 /* libz.dylib in Frameworks */,
+ 274EE2651A03EDCA003213D1 /* Security.framework in Frameworks */,
+ 274EE2661A03EDCA003213D1 /* SystemConfiguration.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 274EE2711A03EDCB003213D1 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 274EE2721A03EDCB003213D1 /* libcups_static.a in Frameworks */,
+ 274EE2731A03EDCB003213D1 /* CoreFoundation.framework in Frameworks */,
+ 274EE2741A03EDCB003213D1 /* libresolv.dylib in Frameworks */,
+ 274EE2751A03EDCB003213D1 /* libz.dylib in Frameworks */,
+ 274EE2761A03EDCB003213D1 /* Security.framework in Frameworks */,
+ 274EE2771A03EDCB003213D1 /* SystemConfiguration.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
274FF5C913332B1F00317ECB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
274FF67313333B0A00317ECB /* commands */ = {
isa = PBXGroup;
children = (
+ 274EE27F1A03EE41003213D1 /* ippproxy.c */,
+ 274EE27D1A03EE0B003213D1 /* ippinfra.c */,
2732E089137A3F5200FAFEF6 /* cancel.c */,
2732E08A137A3F5200FAFEF6 /* cupsaccept.c */,
276684101337FA7C000D33D0 /* cupsaddsmb.c */,
72A4332F155844CF002E172D /* libcups_static.a */,
72CF95F118A19134000FCAE4 /* ipptool copy */,
2767FC5019266A0D000F61D3 /* testdest */,
+ 274EE26B1A03EDCA003213D1 /* ippserver copy */,
+ 274EE27C1A03EDCB003213D1 /* ippserver copy copy */,
);
name = Products;
sourceTree = "<group>";
productReference = 273BF6BD1333B5000022CAAB /* testcups */;
productType = "com.apple.product-type.tool";
};
+ 274EE25B1A03EDCA003213D1 /* ippinfra */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 274EE2681A03EDCA003213D1 /* Build configuration list for PBXNativeTarget "ippinfra" */;
+ buildPhases = (
+ 274EE25E1A03EDCA003213D1 /* Sources */,
+ 274EE2601A03EDCA003213D1 /* Frameworks */,
+ 274EE2671A03EDCA003213D1 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 274EE25C1A03EDCA003213D1 /* PBXTargetDependency */,
+ );
+ name = ippinfra;
+ productName = ippserver;
+ productReference = 274EE26B1A03EDCA003213D1 /* ippserver copy */;
+ productType = "com.apple.product-type.tool";
+ };
+ 274EE26C1A03EDCB003213D1 /* ippproxy */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 274EE2791A03EDCB003213D1 /* Build configuration list for PBXNativeTarget "ippproxy" */;
+ buildPhases = (
+ 274EE26F1A03EDCB003213D1 /* Sources */,
+ 274EE2711A03EDCB003213D1 /* Frameworks */,
+ 274EE2781A03EDCB003213D1 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 274EE26D1A03EDCB003213D1 /* PBXTargetDependency */,
+ );
+ name = ippproxy;
+ productName = ippserver;
+ productReference = 274EE27C1A03EDCB003213D1 /* ippserver copy copy */;
+ productType = "com.apple.product-type.tool";
+ };
274FF5CB13332B1F00317ECB /* cups-driverd */ = {
isa = PBXNativeTarget;
buildConfigurationList = 274FF5D213332B1F00317ECB /* Build configuration list for PBXNativeTarget "cups-driverd" */;
724379461333FEA9009631B9 /* dnssd */,
724378FC1333E43E009631B9 /* ipp */,
72CF95E618A19134000FCAE4 /* ippfind */,
+ 274EE25B1A03EDCA003213D1 /* ippinfra */,
+ 274EE26C1A03EDCB003213D1 /* ippproxy */,
726AD6F6135E88F0002C930D /* ippserver */,
276683EF1337F78E000D33D0 /* ipptool */,
724379171333E532009631B9 /* lpd */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ 274EE25E1A03EDCA003213D1 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 274EE27E1A03EE0B003213D1 /* ippinfra.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 274EE26F1A03EDCB003213D1 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 274EE2801A03EE41003213D1 /* ippproxy.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
274FF5C813332B1F00317ECB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
target = 273BF6BC1333B5000022CAAB /* testcups */;
targetProxy = 273BF6DD1333B6370022CAAB /* PBXContainerItemProxy */;
};
+ 274EE25C1A03EDCA003213D1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 274FF6891333B1C400317ECB /* libcups_static */;
+ targetProxy = 274EE25D1A03EDCA003213D1 /* PBXContainerItemProxy */;
+ };
+ 274EE26D1A03EDCB003213D1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 274FF6891333B1C400317ECB /* libcups_static */;
+ targetProxy = 274EE26E1A03EDCB003213D1 /* PBXContainerItemProxy */;
+ };
+ 274EE2821A03EEE0003213D1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 274EE25B1A03EDCA003213D1 /* ippinfra */;
+ targetProxy = 274EE2811A03EEE0003213D1 /* PBXContainerItemProxy */;
+ };
+ 274EE2841A03EEE0003213D1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 274EE26C1A03EDCB003213D1 /* ippproxy */;
+ targetProxy = 274EE2831A03EEE0003213D1 /* PBXContainerItemProxy */;
+ };
+ 274EE2861A03EEEE003213D1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 274EE25B1A03EDCA003213D1 /* ippinfra */;
+ targetProxy = 274EE2851A03EEEE003213D1 /* PBXContainerItemProxy */;
+ };
+ 274EE2881A03EEEE003213D1 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 274EE26C1A03EDCB003213D1 /* ippproxy */;
+ targetProxy = 274EE2871A03EEEE003213D1 /* PBXContainerItemProxy */;
+ };
274FF5DC13332CF900317ECB /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 72220EAD1333047D00FCA411 /* libcups */;
};
name = Release;
};
+ 274EE2691A03EDCA003213D1 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "ippserver copy";
+ };
+ name = Debug;
+ };
+ 274EE26A1A03EDCA003213D1 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "ippserver copy";
+ };
+ name = Release;
+ };
+ 274EE27A1A03EDCB003213D1 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "ippserver copy copy";
+ };
+ name = Debug;
+ };
+ 274EE27B1A03EDCB003213D1 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "ippserver copy copy";
+ };
+ name = Release;
+ };
274FF5D313332B1F00317ECB /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ 274EE2681A03EDCA003213D1 /* Build configuration list for PBXNativeTarget "ippinfra" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 274EE2691A03EDCA003213D1 /* Debug */,
+ 274EE26A1A03EDCA003213D1 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 274EE2791A03EDCB003213D1 /* Build configuration list for PBXNativeTarget "ippproxy" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 274EE27A1A03EDCB003213D1 /* Debug */,
+ 274EE27B1A03EDCB003213D1 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
274FF5D213332B1F00317ECB /* Build configuration list for PBXNativeTarget "cups-driverd" */ = {
isa = XCConfigurationList;
buildConfigurations = (