1 /*****************************************************************************/
7 // This application and all source files used in its construction, except
8 // where noted, are licensed under the MIT License, and have been written
11 // Copyright (c) 2002 OpenBeOS Project
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 /*****************************************************************************/
33 #include "pr_server.h"
35 // #include "PrintServerApp.h"
42 #include <kernel/fs_attr.h>
43 #include <Application.h>
46 #include <NodeMonitor.h>
49 // Implementation of Job
51 Job::Job(const BEntry
& job
, Folder
* folder
)
58 // store light weight versions of BEntry and BNode
60 job
.GetNodeRef(&fNode
);
62 fValid
= IsValidJobFile();
65 if (node
.InitCheck() != B_OK
) return;
68 // read status attribute
69 if (node
.ReadAttrString(PSRV_SPOOL_ATTR_STATUS
, &status
) != B_OK
) {
72 UpdateStatus(status
.String());
74 // Now get file name and creation time from file name
77 char name
[B_FILE_NAME_LENGTH
];
78 if (entry
.InitCheck() == B_OK
&& entry
.GetName(name
) == B_OK
) {
80 // search for last '@' in file name
81 char* p
= NULL
, *c
= name
;
82 while ((c
= strchr(c
, '@')) != NULL
) {
85 // and get time from file name
86 if (p
) fTime
= atoi(p
+1);
90 // conversion from string representation of status to JobStatus constant
91 void Job::UpdateStatus(const char* status
) {
92 if (strcmp(status
, PSRV_JOB_STATUS_WAITING
) == 0) fStatus
= kWaiting
;
93 else if (strcmp(status
, PSRV_JOB_STATUS_PROCESSING
) == 0) fStatus
= kProcessing
;
94 else if (strcmp(status
, PSRV_JOB_STATUS_FAILED
) == 0) fStatus
= kFailed
;
95 else if (strcmp(status
, PSRV_JOB_STATUS_COMPLETED
) == 0) fStatus
= kCompleted
;
96 else fStatus
= kUnknown
;
99 // Write to status attribute of node
100 void Job::UpdateStatusAttribute(const char* status
) {
102 if (node
.InitCheck() == B_OK
) {
103 node
.WriteAttr(PSRV_SPOOL_ATTR_STATUS
, B_STRING_TYPE
, 0, status
, strlen(status
)+1);
108 bool Job::HasAttribute(BNode
* n
, const char* name
) {
110 return n
->GetAttrInfo(name
, &info
) == B_OK
;
114 bool Job::IsValidJobFile() {
116 if (node
.InitCheck() != B_OK
) return false;
118 BNodeInfo
info(&node
);
121 // Is job a spool file?
122 return (info
.InitCheck() == B_OK
&&
123 info
.GetType(mimeType
) == B_OK
&&
124 strcmp(mimeType
, PSRV_SPOOL_FILETYPE
) == 0) &&
125 HasAttribute(&node
, PSRV_SPOOL_ATTR_MIMETYPE
) &&
126 HasAttribute(&node
, PSRV_SPOOL_ATTR_PAGECOUNT
) &&
127 HasAttribute(&node
, PSRV_SPOOL_ATTR_DESCRIPTION
) &&
128 HasAttribute(&node
, PSRV_SPOOL_ATTR_PRINTER
) &&
129 HasAttribute(&node
, PSRV_SPOOL_ATTR_STATUS
);
133 // Set status of object and optionally write to attribute of node
134 void Job::SetStatus(JobStatus s
, bool writeToNode
) {
136 if (!writeToNode
) return;
138 case kWaiting
: UpdateStatusAttribute(PSRV_JOB_STATUS_WAITING
); break;
139 case kProcessing
: UpdateStatusAttribute(PSRV_JOB_STATUS_PROCESSING
); break;
140 case kFailed
: UpdateStatusAttribute(PSRV_JOB_STATUS_FAILED
); break;
141 case kCompleted
: UpdateStatusAttribute(PSRV_JOB_STATUS_COMPLETED
); break;
146 // Synchronize file attribute with member variable
147 void Job::UpdateAttribute() {
148 fValid
= fValid
|| IsValidJobFile();
151 if (node
.InitCheck() == B_OK
&&
152 node
.ReadAttrString(PSRV_SPOOL_ATTR_STATUS
, &status
) == B_OK
) {
153 UpdateStatus(status
.String());
158 BEntry
entry(&fEntry
);
159 if (entry
.InitCheck() == B_OK
) entry
.Remove();
162 // Implementation of Folder
164 // BObjectList CompareFunction
165 int Folder::AscendingByTime(const Job
* a
, const Job
* b
) {
166 return a
->Time() - b
->Time();
169 bool Folder::AddJob(BEntry
& entry
, bool notify
) {
170 Job
* job
= new Job(entry
, this);
171 if (job
->InitCheck() == B_OK
) {
173 if (notify
) Notify(job
, kJobAdded
);
181 // simplified assumption that ino_t identifies job file
182 // will probabely not work in all cases with link to a file on another volume???
183 Job
* Folder::Find(node_ref
* node
) {
184 for (int i
= 0; i
< fJobs
.CountItems(); i
++) {
185 Job
* job
= fJobs
.ItemAt(i
);
186 if (job
->NodeRef() == *node
) return job
;
191 void Folder::EntryCreated(node_ref
* node
, entry_ref
* entry
) {
193 if (job
.InitCheck() == B_OK
&& Lock()) {
195 fJobs
.SortItems(AscendingByTime
);
201 void Folder::EntryRemoved(node_ref
* node
) {
202 Job
* job
= Find(node
);
204 fJobs
.RemoveItem(job
);
205 Notify(job
, kJobRemoved
);
211 void Folder::AttributeChanged(node_ref
* node
) {
212 Job
* job
= Find(node
);
214 job
->UpdateAttribute();
215 Notify(job
, kJobAttrChanged
);
220 // initial setup of job list
221 void Folder::SetupJobList() {
222 if (inherited::Folder()->InitCheck() == B_OK
) {
223 inherited::Folder()->Rewind();
226 while (inherited::Folder()->GetNextEntry(&entry
) == B_OK
) {
227 AddJob(entry
, false);
229 fJobs
.SortItems(AscendingByTime
);
233 Folder::Folder(BLocker
* locker
, BLooper
* looper
, const BDirectory
& spoolDir
)
234 : FolderWatcher(looper
, spoolDir
, true)
249 for (int i
= 0; i
< fJobs
.CountItems(); i
++) {
250 Job
* job
= fJobs
.ItemAt(i
);
256 Job
* Folder::GetNextJob() {
257 for (int i
= 0; i
< fJobs
.CountItems(); i
++) {
258 Job
* job
= fJobs
.ItemAt(i
);
259 if (job
->IsValid() && job
->IsWaiting()) {
260 job
->Acquire(); return job
;