20 #include "ipprequest.h"
21 #include "cupsinfos.h"
25 #include <cups/language.h>
27 #include <tdeglobal.h>
28 #include <tdelocale.h>
29 #include <tqdatetime.h>
31 #include <cups/cups.h>
37 #ifdef HAVE_CUPS_NO_PWD_CACHE
38 #include <tqcstring.h>
39 static TQCString cups_authstring =
"";
42 void dumpRequest(ipp_t *req,
bool answer =
false,
const TQString& s = TQString::null)
44 kdDebug(500) <<
"==========" << endl;
46 kdDebug(500) << (answer ?
"Answer" :
"Request") << endl;
48 kdDebug(500) << s << endl;
49 kdDebug(500) <<
"==========" << endl;
52 kdDebug(500) <<
"Null request" << endl;
56 kdDebug(500) <<
"State = 0x" << TQString::number(ippGetState(req), 16) << endl;
57 kdDebug(500) <<
"ID = 0x" << TQString::number(ippGetRequestId(req), 16) << endl;
60 kdDebug(500) <<
"Status = 0x" << TQString::number(ippGetStatusCode(req), 16) << endl;
61 kdDebug(500) <<
"Status message = " << ippErrorString(ippGetStatusCode(req)) << endl;
64 kdDebug(500) <<
"Operation = 0x" << TQString::number(ippGetOperation(req), 16) << endl;
66 int majorVersion = ippGetVersion(req, &minorVersion);
67 kdDebug(500) <<
"Version = " << (int)(majorVersion) <<
"." << (int)(minorVersion) << endl;
70 ipp_attribute_t *attr = ippFirstAttribute(req);
73 TQString s = TQString::fromLatin1(
"%1 (0x%2) = ").arg(ippGetName(attr)).arg(ippGetValueTag(attr), 0, 16);
74 for (
int i=0;i<ippGetCount(attr);i++)
76 switch (ippGetValueTag(attr))
80 s += (
"0x"+TQString::number(ippGetInteger(attr, i), 16));
83 s += (ippGetBoolean(attr, i) ?
"true" :
"false");
90 case IPP_TAG_MIMETYPE:
91 case IPP_TAG_NAMELANG:
92 case IPP_TAG_TEXTLANG:
94 case IPP_TAG_LANGUAGE:
95 s += ippGetString(attr, i, NULL);
100 if (i != (ippGetCount(attr)-1))
103 kdDebug(500) << s << endl;
104 attr = ippNextAttribute(req);
107 kdDebug(500) <<
"State = 0x" << TQString::number(req->state, 16) << endl;
108 kdDebug(500) <<
"ID = 0x" << TQString::number(req->request.status.request_id, 16) << endl;
111 kdDebug(500) <<
"Status = 0x" << TQString::number(req->request.status.status_code, 16) << endl;
112 kdDebug(500) <<
"Status message = " << ippErrorString(req->request.status.status_code) << endl;
115 kdDebug(500) <<
"Operation = 0x" << TQString::number(req->request.op.operation_id, 16) << endl;
116 kdDebug(500) <<
"Version = " << (int)(req->request.status.version[0]) <<
"." << (int)(req->request.status.version[1]) << endl;
117 kdDebug(500) << endl;
119 ipp_attribute_t *attr = req->attrs;
122 TQString s = TQString::fromLatin1(
"%1 (0x%2) = ").arg(attr->name).arg(attr->value_tag, 0, 16);
123 for (
int i=0;i<attr->num_values;i++)
125 switch (attr->value_tag)
127 case IPP_TAG_INTEGER:
129 s += (
"0x"+TQString::number(attr->values[i].integer, 16));
131 case IPP_TAG_BOOLEAN:
132 s += (attr->values[i].boolean ?
"true" :
"false");
137 case IPP_TAG_KEYWORD:
139 case IPP_TAG_MIMETYPE:
140 case IPP_TAG_NAMELANG:
141 case IPP_TAG_TEXTLANG:
142 case IPP_TAG_CHARSET:
143 case IPP_TAG_LANGUAGE:
144 s += attr->values[i].string.text;
149 if (i != (attr->num_values-1))
152 kdDebug(500) << s << endl;
158 TQString errorString(
int status)
164 str = i18n(
"You don't have access to the requested resource.");
166 case IPP_NOT_AUTHORIZED:
167 str = i18n(
"You are not authorized to access the requested resource.");
169 case IPP_NOT_POSSIBLE:
170 str = i18n(
"The requested operation cannot be completed.");
172 case IPP_SERVICE_UNAVAILABLE:
173 str = i18n(
"The requested service is currently unavailable.");
175 case IPP_NOT_ACCEPTING:
176 str = i18n(
"The target printer is not accepting print jobs.");
179 str = TQString::fromLocal8Bit(ippErrorString((ipp_status_t)status));
187 IppRequest::IppRequest()
196 IppRequest::~IppRequest()
201 void IppRequest::init()
212 TQCString langstr = TDEGlobal::locale()->language().latin1();
213 cups_lang_t* lang = cupsLangGet(langstr.data());
215 lang->encoding = CUPS_UTF8;
216 ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(lang));
217 ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, lang->language);
221 void IppRequest::addString_p(
int group,
int type,
const TQString& name,
const TQString& value)
224 ippAddString(request_,(ipp_tag_t)group,(ipp_tag_t)type,name.latin1(),NULL,(value.isEmpty() ?
"" : value.local8Bit().data()));
227 void IppRequest::addStringList_p(
int group,
int type,
const TQString& name,
const TQStringList& values)
232 const char *vlsRefs[values.count()];
234 for(
unsigned i_vl = 0; i_vl < values.count(); i_vl++)
236 vlsRefs[i_vl] = (
const char*)vlsBuf.size();
237 vlsBuf += values[i_vl].local8Bit();
241 for(
unsigned i_vl = 0; i_vl < values.count(); i_vl++)
242 vlsRefs[i_vl] = vlsBuf.data()+(intptr_t)vlsRefs[i_vl];
243 ippAddStrings(request_,(ipp_tag_t)group,(ipp_tag_t)type,name.latin1(),(
int)(values.count()),NULL,(
const char**)&vlsRefs);
247 void IppRequest::addInteger_p(
int group,
int type,
const TQString& name,
int value)
249 if (!name.isEmpty()) ippAddInteger(request_,(ipp_tag_t)group,(ipp_tag_t)type,name.latin1(),value);
252 void IppRequest::addIntegerList_p(
int group,
int type,
const TQString& name,
const TQValueList<int>& values)
256 ipp_attribute_t *attr = ippAddIntegers(request_,(ipp_tag_t)group,(ipp_tag_t)type,name.latin1(),(
int)(values.count()),NULL);
258 for (TQValueList<int>::ConstIterator it=values.begin(); it != values.end(); ++it, i++)
260 ippSetInteger(request_, &attr, i, *it);
262 attr->values[i].integer = *it;
267 void IppRequest::addBoolean(
int group,
const TQString& name,
bool value)
269 if (!name.isEmpty()) ippAddBoolean(request_,(ipp_tag_t)group,name.latin1(),(
char)value);
272 void IppRequest::addBoolean(
int group,
const TQString& name,
const TQValueList<bool>& values)
276 ipp_attribute_t *attr = ippAddBooleans(request_,(ipp_tag_t)group,name.latin1(),(
int)(values.count()),NULL);
278 for (TQValueList<bool>::ConstIterator it=values.begin(); it != values.end(); ++it, i++)
280 ippSetBoolean(request_, &attr, i, (
char)(*it));
282 attr->values[i].boolean = (char)(*it);
287 void IppRequest::setOperation(
int op)
290 ippSetOperation(request_, (ipp_op_t)op);
291 ippSetRequestId(request_, 1);
293 request_->request.op.operation_id = (ipp_op_t)op;
294 request_->request.op.request_id = 1;
298 int IppRequest::status()
301 return (request_ ? ippGetStatusCode(request_) : (connect_ ? cupsLastError() : -2));
303 return (request_ ? request_->request.status.status_code : (connect_ ? cupsLastError() : -2));
307 TQString IppRequest::statusMessage()
313 msg = i18n(
"Connection to CUPS server failed. Check that the CUPS server is correctly installed and running.");
316 msg = i18n(
"The IPP request failed for an unknown reason.");
319 msg = errorString(status());
325 bool IppRequest::integerValue_p(
const TQString& name,
int& value,
int type)
327 if (!request_ || name.isEmpty())
return false;
328 ipp_attribute_t *attr = ippFindAttribute(request_, name.latin1(), (ipp_tag_t)type);
332 value = ippGetInteger(attr, 0);
334 value = attr->values[0].integer;
341 bool IppRequest::stringValue_p(
const TQString& name, TQString& value,
int type)
343 if (!request_ || name.isEmpty())
return false;
344 ipp_attribute_t *attr = ippFindAttribute(request_, name.latin1(), (ipp_tag_t)type);
348 value = TQString::fromLocal8Bit(ippGetString(attr, 0, NULL));
350 value = TQString::fromLocal8Bit(attr->values[0].string.text);
357 bool IppRequest::stringListValue_p(
const TQString& name, TQStringList& values,
int type)
359 if (!request_ || name.isEmpty())
return false;
360 ipp_attribute_t *attr = ippFindAttribute(request_, name.latin1(), (ipp_tag_t)type);
365 for (
int i=0;i<ippGetCount(attr);i++)
366 values.append(TQString::fromLocal8Bit(ippGetString(attr, i, NULL)));
368 for (
int i=0;i<attr->num_values;i++)
369 values.append(TQString::fromLocal8Bit(attr->values[i].string.text));
376 bool IppRequest::boolean(
const TQString& name,
bool& value)
378 if (!request_ || name.isEmpty())
return false;
379 ipp_attribute_t *attr = ippFindAttribute(request_, name.latin1(), IPP_TAG_BOOLEAN);
383 value = (bool)ippGetBoolean(attr, 0);
385 value = (bool)attr->values[0].boolean;
392 bool IppRequest::doFileRequest(
const TQString& res,
const TQString& filename)
394 TQString myHost = host_;
396 if (myHost.isEmpty()) myHost = CupsInfos::self()->host();
397 if (myPort <= 0) myPort = CupsInfos::self()->port();
398 http_t *HTTP = httpConnect(myHost.latin1(),myPort);
400 connect_ = (HTTP != NULL);
409 #ifdef HAVE_CUPS_NO_PWD_CACHE
410 #if CUPS_VERSION_MAJOR < 1 || (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR < 2)
411 strncpy( HTTP->authstring, cups_authstring.data(), HTTP_MAX_VALUE );
413 httpSetAuthString( HTTP, NULL, cups_authstring.data() );
419 dumpRequest(request_,
false,
"Request to "+myHost+
":"+TQString::number(myPort));
422 request_ = cupsDoFileRequest(HTTP, request_, (res.isEmpty() ?
"/" : res.latin1()), (filename.isEmpty() ? NULL : filename.latin1()));
423 #ifdef HAVE_CUPS_NO_PWD_CACHE
424 #if CUPS_VERSION_MAJOR < 1 || (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR < 2)
425 cups_authstring = HTTP->authstring;
427 cups_authstring = httpGetAuthString( HTTP );
434 dumpRequest(request_,
true);
439 if ( request_ && ippGetStatusCode(request_) == 0x406 )
441 if ( request_ && request_->request.status.status_code == 0x406 )
446 if (!request_ || ippGetState(request_) == IPP_ERROR || (ippGetStatusCode(request_) & 0x0F00))
448 if (!request_ || request_->state == IPP_ERROR || (request_->request.status.status_code & 0x0F00))
456 bool IppRequest::htmlReport(
int group, TQTextStream& output)
458 if (!request_)
return false;
460 output <<
"<table border=\"1\" cellspacing=\"0\" cellpadding=\"0\">" << endl;
461 output <<
"<tr><th bgcolor=\"dark blue\"><font color=\"white\">" << i18n(
"Attribute") <<
"</font></th>" << endl;
462 output <<
"<th bgcolor=\"dark blue\"><font color=\"white\">" << i18n(
"Values") <<
"</font></th></tr>" << endl;
465 ipp_attribute_t *attr = ippFirstAttribute(request_);
466 while (attr && ippGetGroupTag(attr) != group)
467 attr = ippNextAttribute(request_);
469 ipp_attribute_t *attr = request_->attrs;
470 while (attr && attr->group_tag != group)
474 const ipp_uchar_t *d;
479 while (attr && ippGetGroupTag(attr) == group)
481 output <<
" <tr bgcolor=\"" << (bg ?
"#ffffd9" :
"#ffffff") <<
"\">\n <td><b>" << ippGetName(attr) <<
"</b></td>\n <td>" << endl;
483 for (
int i=0; i<ippGetCount(attr); i++)
485 switch (ippGetValueTag(attr))
487 case IPP_TAG_INTEGER:
488 if (ippGetName(attr) && strstr(ippGetName(attr),
"time"))
490 dt.setTime_t((
unsigned int)(ippGetInteger(attr, i)));
491 output << dt.toString();
494 output << ippGetInteger(attr, i);
497 output <<
"0x" << hex << ippGetInteger(attr, i) << dec;
499 case IPP_TAG_BOOLEAN:
500 output << (ippGetBoolean(attr, i) ? i18n(
"True") : i18n(
"False"));
503 case IPP_TAG_TEXTLANG:
504 case IPP_TAG_NAMELANG:
507 case IPP_TAG_KEYWORD:
509 case IPP_TAG_CHARSET:
510 case IPP_TAG_LANGUAGE:
511 case IPP_TAG_MIMETYPE:
512 output << ippGetString(attr, i, NULL);
514 case IPP_TAG_RESOLUTION:
518 xres = ippGetResolution(attr, i, &yres, &units);
519 output <<
"( " << xres
520 <<
", " << yres <<
" )";
525 lowervalue = ippGetRange(attr, i, &uppervalue);
526 output <<
"[ " << (lowervalue > 0 ? lowervalue : 1)
527 <<
", " << (uppervalue > 0 ? uppervalue : 65535) <<
" ]";
530 d = ippGetDate(attr, i);
531 dateStr.sprintf(
"%.4d-%.2d-%.2d, %.2d:%.2d:%.2d %c%.2d%.2d",
532 d[0]*256+d[1], d[2], d[3],
540 if (i < ippGetCount(attr)-1)
543 output <<
"</td>\n </tr>" << endl;
544 attr = ippNextAttribute(request_);
546 while (attr && attr->group_tag == group)
548 output <<
" <tr bgcolor=\"" << (bg ?
"#ffffd9" :
"#ffffff") <<
"\">\n <td><b>" << attr->name <<
"</b></td>\n <td>" << endl;
550 for (
int i=0; i<attr->num_values; i++)
552 switch (attr->value_tag)
554 case IPP_TAG_INTEGER:
555 if (attr->name && strstr(attr->name,
"time"))
557 dt.setTime_t((
unsigned int)(attr->values[i].integer));
558 output << dt.toString();
561 output << attr->values[i].integer;
564 output <<
"0x" << hex << attr->values[i].integer << dec;
566 case IPP_TAG_BOOLEAN:
567 output << (attr->values[i].boolean ? i18n(
"True") : i18n(
"False"));
570 case IPP_TAG_TEXTLANG:
571 case IPP_TAG_NAMELANG:
574 case IPP_TAG_KEYWORD:
576 case IPP_TAG_CHARSET:
577 case IPP_TAG_LANGUAGE:
578 case IPP_TAG_MIMETYPE:
579 output << attr->values[i].string.text;
581 case IPP_TAG_RESOLUTION:
582 output <<
"( " << attr->values[i].resolution.xres
583 <<
", " << attr->values[i].resolution.yres <<
" )";
586 output <<
"[ " << (attr->values[i].range.lower > 0 ? attr->values[i].range.lower : 1)
587 <<
", " << (attr->values[i].range.upper > 0 ? attr->values[i].range.upper : 65535) <<
" ]";
590 d = attr->values[i].date;
591 dateStr.sprintf(
"%.4d-%.2d-%.2d, %.2d:%.2d:%.2d %c%.2d%.2d",
592 d[0]*256+d[1], d[2], d[3],
600 if (i < attr->num_values-1)
603 output <<
"</td>\n </tr>" << endl;
608 output <<
"</table>" << endl;
613 TQMap<TQString,TQString> IppRequest::toMap(
int group)
615 TQMap<TQString,TQString> opts;
618 ipp_attribute_t *attr = first();
622 if (group != -1 && ippGetGroupTag(attr) != group)
624 attr = ippNextAttribute(request_);
628 for (
int i=0; i<ippGetCount(attr); i++)
630 switch (ippGetValueTag(attr))
632 case IPP_TAG_INTEGER:
634 value.append(TQString::number(ippGetInteger(attr, i))).append(
",");
636 case IPP_TAG_BOOLEAN:
637 value.append((ippGetBoolean(attr, i) ?
"true" :
"false")).append(
",");
642 lowervalue = ippGetRange(attr, i, &uppervalue);
644 value.append(TQString::number(lowervalue));
645 if (lowervalue != uppervalue)
649 value.append(TQString::number(uppervalue));
656 case IPP_TAG_KEYWORD:
658 case IPP_TAG_MIMETYPE:
659 case IPP_TAG_NAMELANG:
660 case IPP_TAG_TEXTLANG:
661 case IPP_TAG_CHARSET:
662 case IPP_TAG_LANGUAGE:
663 value.append(TQString::fromLocal8Bit(ippGetString(attr, i, NULL))).append(
",");
669 if (!value.isEmpty())
670 value.truncate(value.length()-1);
671 opts[TQString::fromLocal8Bit(ippGetName(attr))] = value;
672 attr = ippNextAttribute(request_);
674 if (group != -1 && attr->group_tag != group)
680 for (
int i=0; i<attr->num_values; i++)
682 switch (attr->value_tag)
684 case IPP_TAG_INTEGER:
686 value.append(TQString::number(attr->values[i].integer)).append(
",");
688 case IPP_TAG_BOOLEAN:
689 value.append((attr->values[i].boolean ?
"true" :
"false")).append(
",");
692 if (attr->values[i].range.lower > 0)
693 value.append(TQString::number(attr->values[i].range.lower));
694 if (attr->values[i].range.lower != attr->values[i].range.upper)
697 if (attr->values[i].range.upper > 0)
698 value.append(TQString::number(attr->values[i].range.upper));
705 case IPP_TAG_KEYWORD:
707 case IPP_TAG_MIMETYPE:
708 case IPP_TAG_NAMELANG:
709 case IPP_TAG_TEXTLANG:
710 case IPP_TAG_CHARSET:
711 case IPP_TAG_LANGUAGE:
712 value.append(TQString::fromLocal8Bit(attr->values[i].string.text)).append(
",");
718 if (!value.isEmpty())
719 value.truncate(value.length()-1);
720 opts[TQString::fromLocal8Bit(attr->name)] = value;
728 void IppRequest::setMap(
const TQMap<TQString,TQString>& opts)
733 TQRegExp re(
"^\"|\"$");
734 cups_option_t *options = NULL;
736 for (TQMap<TQString,TQString>::ConstIterator it=opts.begin(); it!=opts.end(); ++it)
738 if (it.key().startsWith(
"kde-") || it.key().startsWith(
"app-"))
740 TQString value = it.data().stripWhiteSpace(), lovalue;
741 value.replace(re,
"");
742 lovalue = value.lower();
746 if (value ==
"true" || value ==
"false")
747 addBoolean(IPP_TAG_JOB, it.key(), (value ==
"true"));
748 else if (value.isEmpty() || lovalue ==
"off" || lovalue ==
"on"
749 || lovalue ==
"yes" || lovalue ==
"no"
750 || lovalue ==
"true" || lovalue ==
"false")
751 addName(IPP_TAG_JOB, it.key(), value);
753 n = cupsAddOption(it.key().local8Bit(), value.local8Bit(), n, &options);
756 cupsEncodeOptions(request_, n, options);
757 cupsFreeOptions(n, options);
760 #if CUPS_VERSION_MAJOR > 1 || (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2)
761 ipp_attribute_t *attr = ippFindAttribute(request_,
"document-format", IPP_TAG_NAME);
762 ippDeleteAttribute(request_, attr);
765 ipp_attribute_t *attr = request_->attrs;
768 if (attr->next && strcmp(attr->next->name,
"document-format") == 0)
770 ipp_attribute_t *attr2 = attr->next;
771 attr->next = attr2->next;
772 _ipp_free_attr(attr2);
781 ipp_attribute_t* IppRequest::first()
782 {
return (request_ ? ippFirstAttribute(request_) : NULL); }
784 ipp_attribute_t* IppRequest::first()
785 {
return (request_ ? request_->attrs : NULL); }