• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeprint
 

tdeprint

  • tdeprint
  • cups
ipprequest.cpp
1/*
2 * This file is part of the KDE libraries
3 * Copyright (c) 2001 Michael Goffioul <tdeprint@swing.be>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License version 2 as published by the Free Software Foundation.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 **/
19
20#include "ipprequest.h"
21#include "cupsinfos.h"
22
23#include <stdlib.h>
24#include <string>
25#include <cups/language.h>
26#include <kdebug.h>
27#include <tdeglobal.h>
28#include <tdelocale.h>
29#include <tqdatetime.h>
30#include <tqregexp.h>
31#include <cups/cups.h>
32
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include <tqcstring.h>
38static TQCString cups_authstring = "";
39
40void dumpRequest(ipp_t *req, bool answer = false, const TQString& s = TQString::null)
41{
42 kdDebug(500) << "==========" << endl;
43 if (s.isEmpty())
44 kdDebug(500) << (answer ? "Answer" : "Request") << endl;
45 else
46 kdDebug(500) << s << endl;
47 kdDebug(500) << "==========" << endl;
48 if (!req)
49 {
50 kdDebug(500) << "Null request" << endl;
51 return;
52 }
53 kdDebug(500) << "State = 0x" << TQString::number(ippGetState(req), 16) << endl;
54 kdDebug(500) << "ID = 0x" << TQString::number(ippGetRequestId(req), 16) << endl;
55 if (answer)
56 {
57 kdDebug(500) << "Status = 0x" << TQString::number(ippGetStatusCode(req), 16) << endl;
58 kdDebug(500) << "Status message = " << ippErrorString(ippGetStatusCode(req)) << endl;
59 }
60 else
61 kdDebug(500) << "Operation = 0x" << TQString::number(ippGetOperation(req), 16) << endl;
62 int minorVersion;
63 int majorVersion = ippGetVersion(req, &minorVersion);
64 kdDebug(500) << "Version = " << (int)(majorVersion) << "." << (int)(minorVersion) << endl;
65 kdDebug(500) << endl;
66
67 ipp_attribute_t *attr = ippFirstAttribute(req);
68 while (attr)
69 {
70 TQString s = TQString::fromLatin1("%1 (0x%2) = ").arg(ippGetName(attr)).arg(ippGetValueTag(attr), 0, 16);
71 for (int i=0;i<ippGetCount(attr);i++)
72 {
73 switch (ippGetValueTag(attr))
74 {
75 case IPP_TAG_INTEGER:
76 case IPP_TAG_ENUM:
77 s += ("0x"+TQString::number(ippGetInteger(attr, i), 16));
78 break;
79 case IPP_TAG_BOOLEAN:
80 s += (ippGetBoolean(attr, i) ? "true" : "false");
81 break;
82 case IPP_TAG_STRING:
83 case IPP_TAG_TEXT:
84 case IPP_TAG_NAME:
85 case IPP_TAG_KEYWORD:
86 case IPP_TAG_URI:
87 case IPP_TAG_MIMETYPE:
88 case IPP_TAG_NAMELANG:
89 case IPP_TAG_TEXTLANG:
90 case IPP_TAG_CHARSET:
91 case IPP_TAG_LANGUAGE:
92 s += ippGetString(attr, i, NULL);
93 break;
94 default:
95 break;
96 }
97 if (i != (ippGetCount(attr)-1))
98 s += ", ";
99 }
100 kdDebug(500) << s << endl;
101 attr = ippNextAttribute(req);
102 }
103}
104
105TQString errorString(int status)
106{
107 TQString str;
108 switch (status)
109 {
110 case IPP_FORBIDDEN:
111 str = i18n("You don't have access to the requested resource.");
112 break;
113 case IPP_NOT_AUTHORIZED:
114 str = i18n("You are not authorized to access the requested resource.");
115 break;
116 case IPP_NOT_POSSIBLE:
117 str = i18n("The requested operation cannot be completed.");
118 break;
119 case IPP_SERVICE_UNAVAILABLE:
120 str = i18n("The requested service is currently unavailable.");
121 break;
122 case IPP_NOT_ACCEPTING:
123 str = i18n("The target printer is not accepting print jobs.");
124 break;
125 default:
126 str = TQString::fromLocal8Bit(ippErrorString((ipp_status_t)status));
127 break;
128 }
129 return str;
130}
131
132//*************************************************************************************
133
134IppRequest::IppRequest()
135{
136 request_ = 0;
137 port_ = -1;
138 host_ = TQString();
139 dump_ = 0;
140 init();
141}
142
143IppRequest::~IppRequest()
144{
145 ippDelete(request_);
146}
147
148void IppRequest::init()
149{
150 connect_ = true;
151
152 if (request_)
153 {
154 ippDelete(request_);
155 request_ = 0;
156 }
157 request_ = ippNew();
158 //kdDebug(500) << "tdeprint: IPP request, lang=" << TDEGlobal::locale()->language() << endl;
159 TQCString langstr = TDEGlobal::locale()->language().latin1();
160 cups_lang_t* lang = cupsLangGet(langstr.data());
161 // default charset to UTF-8 (ugly hack)
162 lang->encoding = CUPS_UTF8;
163 ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(lang));
164 ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, lang->language);
165 cupsLangFree(lang);
166}
167
168void IppRequest::addString_p(int group, int type, const TQString& name, const TQString& value)
169{
170 if (!name.isEmpty())
171 ippAddString(request_,(ipp_tag_t)group,(ipp_tag_t)type,name.latin1(),NULL,(value.isEmpty() ? "" : value.local8Bit().data()));
172}
173
174void IppRequest::addStringList_p(int group, int type, const TQString& name, const TQStringList& values)
175{
176 if (!name.isEmpty())
177 {
178 //> Values buffer and references offset prepare
179 const char *vlsRefs[values.count()];
180 std::string vlsBuf;
181 for(unsigned i_vl = 0; i_vl < values.count(); i_vl++)
182 {
183 vlsRefs[i_vl] = (const char*)vlsBuf.size();
184 vlsBuf += values[i_vl].local8Bit();
185 vlsBuf += (char)0;
186 }
187 //> References update to pointers
188 for(unsigned i_vl = 0; i_vl < values.count(); i_vl++)
189 vlsRefs[i_vl] = vlsBuf.data()+(intptr_t)vlsRefs[i_vl];
190 ippAddStrings(request_,(ipp_tag_t)group,(ipp_tag_t)type,name.latin1(),(int)(values.count()),NULL,(const char**)&vlsRefs);
191 }
192}
193
194void IppRequest::addInteger_p(int group, int type, const TQString& name, int value)
195{
196 if (!name.isEmpty()) ippAddInteger(request_,(ipp_tag_t)group,(ipp_tag_t)type,name.latin1(),value);
197}
198
199void IppRequest::addIntegerList_p(int group, int type, const TQString& name, const TQValueList<int>& values)
200{
201 if (!name.isEmpty())
202 {
203 ipp_attribute_t *attr = ippAddIntegers(request_,(ipp_tag_t)group,(ipp_tag_t)type,name.latin1(),(int)(values.count()),NULL);
204 int i(0);
205 for (TQValueList<int>::ConstIterator it=values.begin(); it != values.end(); ++it, i++)
206 ippSetInteger(request_, &attr, i, *it);
207 }
208}
209
210void IppRequest::addBoolean(int group, const TQString& name, bool value)
211{
212 if (!name.isEmpty()) ippAddBoolean(request_,(ipp_tag_t)group,name.latin1(),(char)value);
213}
214
215void IppRequest::addBoolean(int group, const TQString& name, const TQValueList<bool>& values)
216{
217 if (!name.isEmpty())
218 {
219 ipp_attribute_t *attr = ippAddBooleans(request_,(ipp_tag_t)group,name.latin1(),(int)(values.count()),NULL);
220 int i(0);
221 for (TQValueList<bool>::ConstIterator it=values.begin(); it != values.end(); ++it, i++)
222 ippSetBoolean(request_, &attr, i, (char)(*it));
223 }
224}
225
226void IppRequest::setOperation(int op)
227{
228 ippSetOperation(request_, (ipp_op_t)op);
229 ippSetRequestId(request_, 1); // 0 is not RFC-compliant, should be at least 1
230}
231
232int IppRequest::status()
233{
234 return (request_ ? ippGetStatusCode(request_) : (connect_ ? cupsLastError() : -2));
235}
236
237TQString IppRequest::statusMessage()
238{
239 TQString msg;
240 switch (status())
241 {
242 case -2:
243 msg = i18n("Connection to CUPS server failed. Check that the CUPS server is correctly installed and running.");
244 break;
245 case -1:
246 msg = i18n("The IPP request failed for an unknown reason.");
247 break;
248 default:
249 msg = errorString(status());
250 break;
251 }
252 return msg;
253}
254
255bool IppRequest::integerValue_p(const TQString& name, int& value, int type)
256{
257 if (!request_ || name.isEmpty()) return false;
258 ipp_attribute_t *attr = ippFindAttribute(request_, name.latin1(), (ipp_tag_t)type);
259 if (attr)
260 {
261 value = ippGetInteger(attr, 0);
262 return true;
263 }
264 else return false;
265}
266
267bool IppRequest::stringValue_p(const TQString& name, TQString& value, int type)
268{
269 if (!request_ || name.isEmpty()) return false;
270 ipp_attribute_t *attr = ippFindAttribute(request_, name.latin1(), (ipp_tag_t)type);
271 if (attr)
272 {
273 value = TQString::fromLocal8Bit(ippGetString(attr, 0, NULL));
274 return true;
275 }
276 else return false;
277}
278
279bool IppRequest::stringListValue_p(const TQString& name, TQStringList& values, int type)
280{
281 if (!request_ || name.isEmpty()) return false;
282 ipp_attribute_t *attr = ippFindAttribute(request_, name.latin1(), (ipp_tag_t)type);
283 values.clear();
284 if (attr)
285 {
286 for (int i=0;i<ippGetCount(attr);i++)
287 values.append(TQString::fromLocal8Bit(ippGetString(attr, i, NULL)));
288 return true;
289 }
290 else return false;
291}
292
293bool IppRequest::boolean(const TQString& name, bool& value)
294{
295 if (!request_ || name.isEmpty()) return false;
296 ipp_attribute_t *attr = ippFindAttribute(request_, name.latin1(), IPP_TAG_BOOLEAN);
297 if (attr)
298 {
299 value = (bool)ippGetBoolean(attr, 0);
300 return true;
301 }
302 else return false;
303}
304
305bool IppRequest::doFileRequest(const TQString& res, const TQString& filename)
306{
307 TQString myHost = host_;
308 int myPort = port_;
309 if (myHost.isEmpty()) myHost = CupsInfos::self()->host();
310 if (myPort <= 0) myPort = CupsInfos::self()->port();
311 http_t *HTTP = httpConnect2(
312 myHost.latin1(), myPort, NULL, AF_UNSPEC,
313 HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL);
314
315 connect_ = (HTTP != NULL);
316
317 if (HTTP == NULL)
318 {
319 ippDelete(request_);
320 request_ = 0;
321 return false;
322 }
323
324 httpSetAuthString( HTTP, NULL, cups_authstring.data() );
325
326 if (dump_ > 0)
327 {
328 dumpRequest(request_, false, "Request to "+myHost+":"+TQString::number(myPort));
329 }
330
331 request_ = cupsDoFileRequest(HTTP, request_, (res.isEmpty() ? "/" : res.latin1()), (filename.isEmpty() ? NULL : filename.latin1()));
332 cups_authstring = httpGetAuthString( HTTP );
333 httpClose(HTTP);
334
335 if (dump_ > 1)
336 {
337 dumpRequest(request_, true);
338 }
339
340 /* No printers found */
341 if ( request_ && ippGetStatusCode(request_) == 0x406 )
342 return true;
343
344 if (!request_ || ippGetState(request_) == IPP_ERROR || (ippGetStatusCode(request_) & 0x0F00))
345 return false;
346
347
348 return true;
349}
350
351bool IppRequest::htmlReport(int group, TQTextStream& output)
352{
353 if (!request_) return false;
354 // start table
355 output << "<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">" << endl;
356 output << "<tr><th bgcolor=\"dark blue\"><font color=\"white\">" << i18n("Attribute") << "</font></th>" << endl;
357 output << "<th bgcolor=\"dark blue\"><font color=\"white\">" << i18n("Values") << "</font></th></tr>" << endl;
358 // go to the first attribute of the specified group
359 ipp_attribute_t *attr = ippFirstAttribute(request_);
360 while (attr && ippGetGroupTag(attr) != group)
361 attr = ippNextAttribute(request_);
362 // print each attribute
363 const ipp_uchar_t *d;
364 TQCString dateStr;
365 TQDateTime dt;
366 bool bg(false);
367 while (attr && ippGetGroupTag(attr) == group)
368 {
369 output << " <tr bgcolor=\"" << (bg ? "#ffffd9" : "#ffffff") << "\">\n <td><b>" << ippGetName(attr) << "</b></td>\n <td>" << endl;
370 bg = !bg;
371 for (int i=0; i<ippGetCount(attr); i++)
372 {
373 switch (ippGetValueTag(attr))
374 {
375 case IPP_TAG_INTEGER:
376 if (ippGetName(attr) && strstr(ippGetName(attr), "time"))
377 {
378 dt.setTime_t((unsigned int)(ippGetInteger(attr, i)));
379 output << dt.toString();
380 }
381 else
382 output << ippGetInteger(attr, i);
383 break;
384 case IPP_TAG_ENUM:
385 output << "0x" << hex << ippGetInteger(attr, i) << dec;
386 break;
387 case IPP_TAG_BOOLEAN:
388 output << (ippGetBoolean(attr, i) ? i18n("True") : i18n("False"));
389 break;
390 case IPP_TAG_STRING:
391 case IPP_TAG_TEXTLANG:
392 case IPP_TAG_NAMELANG:
393 case IPP_TAG_TEXT:
394 case IPP_TAG_NAME:
395 case IPP_TAG_KEYWORD:
396 case IPP_TAG_URI:
397 case IPP_TAG_CHARSET:
398 case IPP_TAG_LANGUAGE:
399 case IPP_TAG_MIMETYPE:
400 output << ippGetString(attr, i, NULL);
401 break;
402 case IPP_TAG_RESOLUTION:
403 int xres;
404 int yres;
405 ipp_res_t units;
406 xres = ippGetResolution(attr, i, &yres, &units);
407 output << "( " << xres
408 << ", " << yres << " )";
409 break;
410 case IPP_TAG_RANGE:
411 int lowervalue;
412 int uppervalue;
413 lowervalue = ippGetRange(attr, i, &uppervalue);
414 output << "[ " << (lowervalue > 0 ? lowervalue : 1)
415 << ", " << (uppervalue > 0 ? uppervalue : 65535) << " ]";
416 break;
417 case IPP_TAG_DATE:
418 d = ippGetDate(attr, i);
419 dateStr.sprintf("%.4d-%.2d-%.2d, %.2d:%.2d:%.2d %c%.2d%.2d",
420 d[0]*256+d[1], d[2], d[3],
421 d[4], d[5], d[6],
422 d[8], d[9], d[10]);
423 output << dateStr;
424 break;
425 default:
426 continue;
427 }
428 if (i < ippGetCount(attr)-1)
429 output << "<br>";
430 }
431 output << "</td>\n </tr>" << endl;
432 attr = ippNextAttribute(request_);
433 }
434 // end table
435 output << "</table>" << endl;
436
437 return true;
438}
439
440TQMap<TQString,TQString> IppRequest::toMap(int group)
441{
442 TQMap<TQString,TQString> opts;
443 if (request_)
444 {
445 ipp_attribute_t *attr = first();
446 while (attr)
447 {
448 if (group != -1 && ippGetGroupTag(attr) != group)
449 {
450 attr = ippNextAttribute(request_);
451 continue;
452 }
453 TQString value;
454 for (int i=0; i<ippGetCount(attr); i++)
455 {
456 switch (ippGetValueTag(attr))
457 {
458 case IPP_TAG_INTEGER:
459 case IPP_TAG_ENUM:
460 value.append(TQString::number(ippGetInteger(attr, i))).append(",");
461 break;
462 case IPP_TAG_BOOLEAN:
463 value.append((ippGetBoolean(attr, i) ? "true" : "false")).append(",");
464 break;
465 case IPP_TAG_RANGE:
466 int lowervalue;
467 int uppervalue;
468 lowervalue = ippGetRange(attr, i, &uppervalue);
469 if (lowervalue > 0)
470 value.append(TQString::number(lowervalue));
471 if (lowervalue != uppervalue)
472 {
473 value.append("-");
474 if (uppervalue > 0)
475 value.append(TQString::number(uppervalue));
476 }
477 value.append(",");
478 break;
479 case IPP_TAG_STRING:
480 case IPP_TAG_TEXT:
481 case IPP_TAG_NAME:
482 case IPP_TAG_KEYWORD:
483 case IPP_TAG_URI:
484 case IPP_TAG_MIMETYPE:
485 case IPP_TAG_NAMELANG:
486 case IPP_TAG_TEXTLANG:
487 case IPP_TAG_CHARSET:
488 case IPP_TAG_LANGUAGE:
489 value.append(TQString::fromLocal8Bit(ippGetString(attr, i, NULL))).append(",");
490 break;
491 default:
492 break;
493 }
494 }
495 if (!value.isEmpty())
496 value.truncate(value.length()-1);
497 opts[TQString::fromLocal8Bit(ippGetName(attr))] = value;
498 attr = ippNextAttribute(request_);
499 }
500 }
501 return opts;
502}
503
504void IppRequest::setMap(const TQMap<TQString,TQString>& opts)
505{
506 if (!request_)
507 return;
508
509 TQRegExp re("^\"|\"$");
510 cups_option_t *options = NULL;
511 int n = 0;
512 for (TQMap<TQString,TQString>::ConstIterator it=opts.begin(); it!=opts.end(); ++it)
513 {
514 if (it.key().startsWith("kde-") || it.key().startsWith("app-"))
515 continue;
516 TQString value = it.data().stripWhiteSpace(), lovalue;
517 value.replace(re, "");
518 lovalue = value.lower();
519
520 // handles specific cases: boolean, empty strings, or option that has that boolean
521 // keyword as value (to prevent them from conversion to real boolean)
522 if (value == "true" || value == "false")
523 addBoolean(IPP_TAG_JOB, it.key(), (value == "true"));
524 else if (value.isEmpty() || lovalue == "off" || lovalue == "on"
525 || lovalue == "yes" || lovalue == "no"
526 || lovalue == "true" || lovalue == "false")
527 addName(IPP_TAG_JOB, it.key(), value);
528 else
529 n = cupsAddOption(it.key().local8Bit(), value.local8Bit(), n, &options);
530 }
531 if (n > 0)
532 cupsEncodeOptions(request_, n, options);
533 cupsFreeOptions(n, options);
534
535 // find an remove that annoying "document-format" attribute
536 ipp_attribute_t *attr = ippFindAttribute(request_, "document-format", IPP_TAG_NAME);
537 ippDeleteAttribute(request_, attr);
538}
539
540ipp_attribute_t* IppRequest::first()
541{ return (request_ ? ippFirstAttribute(request_) : NULL); }

tdeprint

Skip menu "tdeprint"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdeprint

Skip menu "tdeprint"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeprint by doxygen 1.15.0
This website is maintained by Timothy Pearson.