nwqueue: implement change queue job entry
All checks were successful
Source release / source-package (push) Successful in 47s
All checks were successful
Source release / source-package (push) Successful in 47s
Implement the Queue Change Job Entry endpoint for both the old NCP 17/6d and newer NCP 17/7b variants. Parse the queue job structure, look up the selected job by its job number, and update the mutable job metadata fields while preserving server-managed state such as client identity, entry time, job number, queue position, file name/handle and servicing information. Allow the job creator to update the standard user-changeable fields and allow SUPERVISOR or Q_OPERATORS members to update the operator hold flag as well. Return the documented queue/job/right/servicing completion codes for missing queues, missing jobs, insufficient rights and jobs already being serviced. This only updates NetWare queue metadata. It does not change the existing Q_UNIX_PRINT/lp backend behavior and adds no CUPS dependency.
This commit is contained in:
@@ -617,11 +617,101 @@ int nw_get_queue_job_file_size(uint32 q_id, int job_id)
|
||||
return(result);
|
||||
}
|
||||
|
||||
int nw_change_queue_job_entry(uint32 q_id, uint8 *qjstruct)
|
||||
static int is_queue_operator(NWE_QUEUE *q, uint32 user_id)
|
||||
{
|
||||
/* TODO */
|
||||
int result;
|
||||
if (user_id == 1) /* SUPERVISOR */
|
||||
return(1);
|
||||
if (!q)
|
||||
return(0);
|
||||
result = nw_is_member_in_set(q->id, "Q_OPERATORS", user_id);
|
||||
return(result == 0);
|
||||
}
|
||||
|
||||
return(-0xfb);
|
||||
static int change_queue_job_entry_old(INT_QUEUE_JOB *qj, QUEUE_JOB_OLD *job,
|
||||
int operator)
|
||||
{
|
||||
int old_flags = qj->job_control_flags;
|
||||
int new_flags = (old_flags & 0x20) | (job->job_control_flags & 0x58);
|
||||
|
||||
if (operator)
|
||||
new_flags |= (job->job_control_flags & 0x80);
|
||||
else
|
||||
new_flags |= (old_flags & 0x80);
|
||||
|
||||
qj->target_id = GET_BE32(job->target_id);
|
||||
qj->execute_time = get_time_field(job->target_execute_time);
|
||||
qj->job_typ = GET_BE16(job->job_typ);
|
||||
qj->job_control_flags = new_flags;
|
||||
memcpy(qj->job_description, job->job_description,
|
||||
sizeof(qj->job_description));
|
||||
memcpy(qj->client_area, job->client_area, sizeof(qj->client_area));
|
||||
|
||||
return(old_flags);
|
||||
}
|
||||
|
||||
static int change_queue_job_entry(INT_QUEUE_JOB *qj, QUEUE_JOB *job,
|
||||
int operator)
|
||||
{
|
||||
int old_flags = qj->job_control_flags;
|
||||
int request_flags = GET_16(job->job_control_flags);
|
||||
int new_flags = (old_flags & 0x20) | (request_flags & 0x58);
|
||||
|
||||
if (operator)
|
||||
new_flags |= (request_flags & 0x80);
|
||||
else
|
||||
new_flags |= (old_flags & 0x80);
|
||||
|
||||
qj->target_id = GET_BE32(job->target_id);
|
||||
qj->execute_time = get_time_field(job->target_execute_time);
|
||||
qj->job_typ = GET_BE16(job->job_typ);
|
||||
qj->job_control_flags = new_flags;
|
||||
memcpy(qj->job_description, job->job_description,
|
||||
sizeof(qj->job_description));
|
||||
memcpy(qj->client_area, job->client_area, sizeof(qj->client_area));
|
||||
|
||||
return(old_flags);
|
||||
}
|
||||
|
||||
int nw_change_queue_job_entry(uint32 user_id, uint32 q_id,
|
||||
uint8 *qjstruct, int old_call)
|
||||
{
|
||||
int result=-0xd1; /* no queue */
|
||||
NWE_QUEUE *q=find_queue(q_id);
|
||||
|
||||
if (q) {
|
||||
int job_id = old_call
|
||||
? GET_BE16(((QUEUE_JOB_OLD*)qjstruct)->job_id)
|
||||
: GET_BE16(((QUEUE_JOB*)qjstruct)->job_id);
|
||||
INT_QUEUE_JOB *qj=find_queue_job(q, job_id);
|
||||
|
||||
result=-0xd5; /* no queue job */
|
||||
if (qj) {
|
||||
int operator = is_queue_operator(q, user_id);
|
||||
int creator = (user_id == qj->client_id);
|
||||
|
||||
result=-0xd6; /* no job right */
|
||||
if (operator || creator) {
|
||||
int old_flags;
|
||||
|
||||
if (qj->server_station || qj->server_id)
|
||||
return(-0xd7); /* queue servicing */
|
||||
|
||||
old_flags = old_call
|
||||
? change_queue_job_entry_old(qj, (QUEUE_JOB_OLD*)qjstruct,
|
||||
operator)
|
||||
: change_queue_job_entry(qj, (QUEUE_JOB*)qjstruct,
|
||||
operator);
|
||||
q->changed++;
|
||||
XDPRINTF((2, 0,
|
||||
"Change Queue Job Entry q=0x%x, job=%d, user=0x%x, flags 0x%x->0x%x",
|
||||
q_id, job_id, user_id, old_flags, qj->job_control_flags));
|
||||
result=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
static int remove_queue_job_file(NWE_QUEUE *q, INT_QUEUE_JOB *qj)
|
||||
|
||||
Reference in New Issue
Block a user