• 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>
38 static TQCString cups_authstring = "";
39 
40 void 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 
105 TQString 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 
134 IppRequest::IppRequest()
135 {
136  request_ = 0;
137  port_ = -1;
138  host_ = TQString();
139  dump_ = 0;
140  init();
141 }
142 
143 IppRequest::~IppRequest()
144 {
145  ippDelete(request_);
146 }
147 
148 void 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 
168 void 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 
174 void 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 
194 void 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 
199 void 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 
210 void 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 
215 void 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 
226 void 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 
232 int IppRequest::status()
233 {
234  return (request_ ? ippGetStatusCode(request_) : (connect_ ? cupsLastError() : -2));
235 }
236 
237 TQString 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 
255 bool 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 
267 bool 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 
279 bool 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 
293 bool 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 
305 bool 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 
351 bool 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 
440 TQMap<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 
504 void 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 
540 ipp_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.9.1
This website is maintained by Timothy Pearson.