/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these libraries and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* $TOG: Queue.C /main/4 1998/07/24 16:17:58 mgreess $ */ /* * * (c) Copyright 1993, 1994 Hewlett-Packard Company * * (c) Copyright 1993, 1994 International Business Machines Corp. * * (c) Copyright 1993, 1994 Sun Microsystems, Inc. * * (c) Copyright 1993, 1994 Novell, Inc. * */ #include "Queue.h" #include "PrintJob.h" #include "ParseJobs.h" #include extern "C" { #include
} #ifdef aix const char *GET_ATTRS = "lsque -cq%s |awk -F: 'NR == 2 {print $2,$6,$9}' OFS=:"; const char *GET_QUEUE_STATUS = "LANG=C enq -As -P%s | " "egrep 'READY|RUNNING' > /dev/null"; const char *GET_DEVICE_STATUS = "LANG=C enq -As -P%s | " "egrep 'READY|RUNNING' > /dev/null"; const char *START_QUEUE_CMD = "enq -U -P%s"; const char *STOP_QUEUE_CMD = "enq -D -P%s"; #else const char *GET_ATTRS = "LANG=C lpstat -v %s 2>&1 | nawk '" "BEGIN { device=\"\"; rhost=\"\"; rp=\"\" } " "/device for/ { device = $4 } " "/system for/ { rhost = $4; x = match($7, /\\)/); " " if (x == 0) " " rp = substr($3, 1, match($3, /:/) - 1); " " else " " rp = substr($7, 1, x - 1) } " "END { print device,rhost,rp }' OFS=:"; const char *GET_QUEUE_STATUS = "LANG=C lpstat -a%s | awk '" "{if ($2 == \"not\") {exit 1} else {exit 0}}'"; const char *GET_DEVICE_STATUS = "LANG=C lpstat -p%s | " "awk '/disabled/ {exit 1}'"; const char *START_QUEUE_CMD = "/usr/sbin/accept %s"; const char *STOP_QUEUE_CMD = "/usr/sbin/reject %s"; const char *START_PRINTING_CMD = "enable %s"; const char *STOP_PRINTING_CMD = "disable %s"; #endif // Object Class Name const char *QUEUE = "Queue"; // Actions const char *START_QUEUE = "StartQueue"; const char *STOP_QUEUE = "StopQueue"; #ifndef aix const char *START_PRINTING = "StartPrinting"; const char *STOP_PRINTING = "StopPrinting"; #endif // Attributes const char *ICON_NAME = "IconName"; const char *PRINTER_QUEUE = "PrinterQueue"; const char *QUEUE_DEVICE = "QueueDevice"; Queue::Queue(BaseObj *parent, char *_name) : BaseObj(parent, _name) { if (getenv("DO_ADMIN")) { AddAction(&Queue::Start, START_QUEUE, MESSAGE(StartChoiceL), MESSAGE(StartMnemonicL)); AddAction(&Queue::Stop, STOP_QUEUE, MESSAGE(StopChoiceL), MESSAGE(StopMnemonicL)); #ifndef aix AddAction(&Queue::StartPrint, START_PRINTING, MESSAGE(EnableChoiceL), MESSAGE(EnableMnemonicL)); AddAction(&Queue::StopPrint, STOP_PRINTING, MESSAGE(DisableChoiceL), MESSAGE(DisableMnemonicL)); #endif } #ifdef aix local_devices = NULL; n_devices = 0; #endif remote_server = NULL; remote_printer = NULL; is_remote = false; _loaded_attributes = false; char *Help = NULL, *ContextualHelp = NULL, *Listing = NULL; Characteristics Mask = EDITABLE_AFTER_CREATE; ValueList ValueListType = NO_LIST; // AddAttribute(ICON_NAME, MESSAGE(IconNameL), // Help, ContextualHelp, Mask, ValueListType, Listing); Mask = OPTIONAL; AddAttribute(PRINTER_QUEUE, MESSAGE(PrintQueueL), Help, ContextualHelp, Mask, ValueListType, Listing); AddAttribute(QUEUE_DEVICE, MESSAGE(DeviceL), Help, ContextualHelp, Mask, ValueListType, Listing); } Queue::~Queue() { #ifdef aix int i; for (i = 0; i < n_devices; i++) delete local_devices[i]; delete local_devices; #endif delete remote_server; delete remote_printer; } void Queue::LoadAttributes(int /*n_attrs*/, Attribute **attrs) { char *command = new char[500]; sprintf(command, GET_ATTRS, Name()); char *output; RunCommand(command, &output); delete [] command; char *s = output, *s1; char *dollar[3]; int i; for (i = 0; i < 3; i++) { if (s1 = strchr(s, ':')) *s1++ = '\0'; else if (s1 = strchr(s, '\n')) *s1++ = '\0'; dollar[i] = s; s = s1; } i = 0; attrs[i]->Value = strdup(Name()); attrs[i]->DisplayValue = strdup(Name()); i++; if (_loaded_attributes == false) { if (*dollar[2]) // It's a remote printer { #ifdef aix n_devices = 1; local_devices = new char *[1]; local_devices[0] = new char[strlen(Name()) + strlen(dollar[0]) + 2]; sprintf(local_devices[0], "%s:%s", Name(), dollar[0]); #endif is_remote = true; char *new_value = new char [strlen(MESSAGE(PrinterOnServerL)) + strlen(dollar[1]) + strlen(dollar[2])]; remote_server = strdup(dollar[1]); remote_printer = strdup(dollar[2]); sprintf(new_value, MESSAGE(PrinterOnServerL), remote_printer, remote_server); attrs[i]->Value = strdup(new_value); attrs[i]->DisplayValue = strdup(new_value); delete [] new_value; } else // It's a local printer { #ifdef aix if (strchr(dollar[0], ',')) // AIX can have multiple devices per queue { DeleteAttribute(QUEUE_DEVICE); char *device = new char [strlen(MESSAGE(DeviceNL)) + 4]; s = dollar[0]; while (s && *s) { if (s1 = strchr(s, ',')) s1++; s = s1; n_devices++; } local_devices = new char *[n_devices]; n_devices = 0; s = dollar[0]; while (s && *s) { sprintf(device, MESSAGE(DeviceNL), n_devices + 1); AddAttribute(QUEUE_DEVICE, device, NULL, NULL, OPTIONAL, NO_LIST, NULL); if (s1 = strchr(s, ',')) *s1++ = '\0'; _attributes[i]->Value = strdup(s); _attributes[i]->DisplayValue = strdup(s); local_devices[n_devices] = new char[strlen(Name()) + strlen(s)+2]; sprintf(local_devices[n_devices], "%s:%s", Name(), s); i++; s = s1; n_devices++; } delete [] device; } else #endif { #ifdef aix n_devices = 1; local_devices = new char *[1]; local_devices[0] = new char[strlen(Name()) + strlen(dollar[0]) + 2]; sprintf(local_devices[0], "%s:%s", Name(), dollar[0]); #endif attrs[i]->Value = strdup(dollar[0]); attrs[i]->DisplayValue = strdup(dollar[0]); } } _loaded_attributes = true; } delete output; } #ifdef aix char *Queue::Device(int index) { if (_loaded_attributes == false) ReadAttributes(); if (index >= 0 && index <= n_devices) return local_devices[index]; else return NULL; } int Queue::NumberDevices() { if (_loaded_attributes == false) ReadAttributes(); return n_devices; } #endif int Queue::Start(BaseObj *obj, char **output, BaseObj * /*requestor*/) { Queue *queue = (Queue *)obj; int rc; char *command = new char[100]; #ifdef aix if (queue->n_devices > 1) { sprintf(command, START_QUEUE_CMD, "$d"); int i, len; len = 30 + strlen(command) + queue->n_devices; for (i = 0; i < queue->n_devices; i++) len += strlen(queue->local_devices[i]); char *cmd = new char[len]; strcpy(cmd, "for d in"); for (i = 0; i < queue->n_devices; i++) { strcat(cmd, " "); strcat(cmd, queue->local_devices[i]); } strcat(cmd, " ; do "); strcat(cmd, command); strcat(cmd, "; done"); rc = queue->RunCommand(cmd, NULL, output); delete [] cmd; } else #endif { sprintf(command, START_QUEUE_CMD, queue->Name()); rc = queue->RunCommand(command, NULL, output); } delete [] command; return rc; } int Queue::Stop(BaseObj *obj, char **output, BaseObj * /*requestor*/) { Queue *queue = (Queue *)obj; char *command = new char[100]; int rc; #ifdef aix if (queue->n_devices > 1) { sprintf(command, STOP_QUEUE_CMD, "$d"); int i, len; len = 30 + strlen(command) + queue->n_devices; for (i = 0; i < queue->n_devices; i++) len += strlen(queue->local_devices[i]); char *cmd = new char[len]; strcpy(cmd, "for d in"); for (i = 0; i < queue->n_devices; i++) { strcat(cmd, " "); strcat(cmd, queue->local_devices[i]); } strcat(cmd, " ; do "); strcat(cmd, command); strcat(cmd, "; done"); rc = queue->RunCommand(cmd, NULL, output); delete [] cmd; } else #endif { snprintf(command, 100, STOP_QUEUE_CMD, queue->Name()); rc = queue->RunCommand(command, NULL, output); } delete [] command; return rc; } #ifndef aix int Queue::StartPrint(BaseObj *obj, char **output, BaseObj * /*requestor*/) { Queue *queue = (Queue *)obj; char *command = new char[100]; int rc; sprintf(command, STOP_PRINTING_CMD, queue->Name()); rc = queue->RunCommand(command, NULL, output); delete [] command; return rc; } int Queue::StopPrint(BaseObj *obj, char **output, BaseObj * /*requestor*/) { Queue *queue = (Queue *)obj; char *command = new char[100]; int rc; sprintf(command, STOP_PRINTING_CMD, queue->Name()); rc = queue->RunCommand(command, NULL, output); delete [] command; return rc; } #endif void Queue::InitChildren() { if (_loaded_attributes == false) ReadAttributes(); ProcessJobs(); } void Queue::ProcessJobs(char *jobs) { char *job_list; int n_jobs; // Get remote jobs first if (is_remote) { int rc; if (jobs) rc = ParseRemotePrintJobs(remote_printer, jobs, &job_list, &n_jobs); else rc = RemotePrintJobs(remote_server, remote_printer, &job_list, &n_jobs); remote_up = rc ? true : false; ParseOutput(job_list, n_jobs); #ifdef sun return; #endif } // Get local jobs next #ifdef aix if (is_remote) LocalPrintJobs(local_devices[0], &job_list, &n_jobs); else LocalPrintJobs((char*)Name(), &job_list, &n_jobs); #else LocalPrintJobs((char*)Name(), &job_list, &n_jobs); #endif ParseOutput(job_list, n_jobs); } void Queue::ParseOutput(char *job_list, int n_jobs) { int i; char *printer = DtStrtok(job_list, "|"); for (i = 0; i < n_jobs; i++) { char *JobName = DtStrtok(NULL, "|"); char *JobNumber = DtStrtok(NULL, "|"); char *Owner = DtStrtok(NULL, "|"); char *Date = DtStrtok(NULL, "|"); char *Time = DtStrtok(NULL, "|"); char *tmp = DtStrtok(NULL, "\n"); char *Size = new char [strlen(tmp) + strlen(MESSAGE(BytesL)) + 2]; sprintf(Size, "%s %s", tmp, MESSAGE(BytesL)); new PrintJob(this, JobName, JobNumber, Owner, Date, Time, Size); delete [] Size; printer = DtStrtok(NULL, "|"); } } void Queue::ParseRemoteStatus(char *output) { SetInitChildren(); DeleteChildren(); if (_loaded_attributes == false) ReadAttributes(); ProcessJobs(output); } boolean Queue::IsRemote() { if (_loaded_attributes == false) ReadAttributes(); return is_remote; } const char *Queue::RemotePrinter() { if (_loaded_attributes == false) ReadAttributes(); return remote_printer; } const char *Queue::Server() { if (_loaded_attributes == false) ReadAttributes(); return remote_server; }