File indexing completed on 2025-01-05 05:09:30
0001 /* 0002 SPDX-FileCopyrightText: 2010-2018 Daniel Nicoletti <dantti12@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "KCupsRequest.h" 0008 0009 #include "kcupslib_log.h" 0010 0011 #include <KLocalizedString> 0012 0013 #include <cups/adminutil.h> 0014 #include <cups/ppd.h> 0015 0016 #define CUPS_DATADIR QLatin1String("/usr/share/cups") 0017 0018 KCupsRequest::KCupsRequest(KCupsConnection *connection) 0019 : m_connection(connection) 0020 { 0021 // If no connection was specified use default one 0022 if (m_connection == nullptr) { 0023 m_connection = KCupsConnection::global(); 0024 } 0025 connect(this, &KCupsRequest::finished, &m_loop, &QEventLoop::quit); 0026 } 0027 0028 QString KCupsRequest::serverError() const 0029 { 0030 switch (error()) { 0031 case IPP_SERVICE_UNAVAILABLE: 0032 return i18n("Print service is unavailable"); 0033 case IPP_NOT_FOUND: 0034 return i18n("Not found"); 0035 default: // In this case we don't want to map all enums 0036 qCWarning(LIBKCUPS) << "status unrecognised: " << error(); 0037 return QString::fromUtf8(ippErrorString(error())); 0038 } 0039 } 0040 0041 void KCupsRequest::getPPDS(const QString &make) 0042 { 0043 if (m_connection->readyToStart()) { 0044 KIppRequest request(CUPS_GET_PPDS, QLatin1String("/")); 0045 if (!make.isEmpty()) { 0046 request.addString(IPP_TAG_PRINTER, IPP_TAG_TEXT, KCUPS_PPD_MAKE_AND_MODEL, make); 0047 } 0048 0049 m_ppds = m_connection->request(request, IPP_TAG_PRINTER); 0050 0051 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0052 setFinished(); 0053 } else { 0054 invokeMethod("getPPDS", make); 0055 } 0056 } 0057 0058 static void choose_device_cb(const char *device_class, /* I - Class */ 0059 const char *device_id, /* I - 1284 device ID */ 0060 const char *device_info, /* I - Description */ 0061 const char *device_make_and_model, /* I - Make and model */ 0062 const char *device_uri, /* I - Device URI */ 0063 const char *device_location, /* I - Location */ 0064 void *user_data) /* I - Result object */ 0065 { 0066 /* 0067 * Add the device to the array... 0068 */ 0069 auto request = static_cast<KCupsRequest *>(user_data); 0070 QMetaObject::invokeMethod(request, 0071 "device", 0072 Qt::QueuedConnection, 0073 Q_ARG(QString, QString::fromUtf8(device_class)), 0074 Q_ARG(QString, QString::fromUtf8(device_id)), 0075 Q_ARG(QString, QString::fromUtf8(device_info)), 0076 Q_ARG(QString, QString::fromUtf8(device_make_and_model)), 0077 Q_ARG(QString, QString::fromUtf8(device_uri)), 0078 Q_ARG(QString, QString::fromUtf8(device_location))); 0079 } 0080 0081 void KCupsRequest::getDevices(int timeout) 0082 { 0083 getDevices(timeout, QStringList(), QStringList()); 0084 } 0085 0086 void KCupsRequest::getDevices(int timeout, QStringList includeSchemes, QStringList excludeSchemes) 0087 { 0088 if (m_connection->readyToStart()) { 0089 do { 0090 const char *include; 0091 if (includeSchemes.isEmpty()) { 0092 include = CUPS_INCLUDE_ALL; 0093 } else { 0094 include = qUtf8Printable(includeSchemes.join(QLatin1String(","))); 0095 } 0096 0097 const char *exclude; 0098 if (excludeSchemes.isEmpty()) { 0099 exclude = CUPS_EXCLUDE_NONE; 0100 } else { 0101 exclude = qUtf8Printable(excludeSchemes.join(QLatin1String(","))); 0102 } 0103 0104 // Scan for devices for "timeout" seconds 0105 cupsGetDevices(CUPS_HTTP_DEFAULT, timeout, include, exclude, (cups_device_cb_t)choose_device_cb, this); 0106 } while (m_connection->retry("/admin/", CUPS_GET_DEVICES)); 0107 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0108 setFinished(true); 0109 } else { 0110 invokeMethod("getDevices", timeout, includeSchemes, excludeSchemes); 0111 } 0112 } 0113 0114 // THIS function can get the default server dest through the 0115 // "printer-is-default" attribute BUT it does not get user 0116 // defined default printer, see cupsGetDefault() on www.cups.org for details 0117 0118 void KCupsRequest::getPrinters(QStringList attributes, int mask) 0119 { 0120 if (m_connection->readyToStart()) { 0121 KIppRequest request(CUPS_GET_PRINTERS, QLatin1String("/")); 0122 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_ENUM, KCUPS_PRINTER_TYPE, CUPS_PRINTER_LOCAL); 0123 if (!attributes.isEmpty()) { 0124 request.addStringList(IPP_TAG_OPERATION, IPP_TAG_KEYWORD, KCUPS_REQUESTED_ATTRIBUTES, attributes); 0125 } 0126 if (mask != -1) { 0127 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_ENUM, KCUPS_PRINTER_TYPE_MASK, mask); 0128 } 0129 0130 const ReturnArguments ret = m_connection->request(request, IPP_TAG_PRINTER); 0131 0132 for (const QVariantMap &arguments : ret) { 0133 m_printers << KCupsPrinter(arguments); 0134 } 0135 0136 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0137 setFinished(); 0138 } else { 0139 invokeMethod("getPrinters", QVariant::fromValue(attributes), mask); 0140 } 0141 } 0142 0143 void KCupsRequest::getPrinterAttributes(const QString &printerName, bool isClass, QStringList attributes) 0144 { 0145 if (m_connection->readyToStart()) { 0146 KIppRequest request(IPP_GET_PRINTER_ATTRIBUTES, QLatin1String("/")); 0147 0148 request.addPrinterUri(printerName, isClass); 0149 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_ENUM, QLatin1String(KCUPS_PRINTER_TYPE), CUPS_PRINTER_LOCAL); 0150 request.addStringList(IPP_TAG_OPERATION, IPP_TAG_KEYWORD, QLatin1String(KCUPS_REQUESTED_ATTRIBUTES), attributes); 0151 0152 const ReturnArguments ret = m_connection->request(request, IPP_TAG_PRINTER); 0153 0154 for (const QVariantMap &arguments : ret) { 0155 // Inject the printer name back to the arguments hash 0156 QVariantMap args = arguments; 0157 args[KCUPS_PRINTER_NAME] = printerName; 0158 m_printers << KCupsPrinter(args); 0159 } 0160 0161 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0162 setFinished(); 0163 } else { 0164 invokeMethod("getPrinterAttributes", printerName, isClass, QVariant::fromValue(attributes)); 0165 } 0166 } 0167 0168 void KCupsRequest::getJobs(const QString &printerName, bool myJobs, int whichJobs, QStringList attributes) 0169 { 0170 if (m_connection->readyToStart()) { 0171 KIppRequest request(IPP_GET_JOBS, QLatin1String("/")); 0172 0173 // printer-uri makes the Name of the Job and owner came blank lol 0174 request.addPrinterUri(printerName, false); 0175 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_ENUM, KCUPS_PRINTER_TYPE, CUPS_PRINTER_LOCAL); 0176 request.addStringList(IPP_TAG_OPERATION, IPP_TAG_KEYWORD, KCUPS_REQUESTED_ATTRIBUTES, attributes); 0177 0178 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_ENUM, KCUPS_MY_JOBS, myJobs); 0179 0180 if (whichJobs == CUPS_WHICHJOBS_COMPLETED) { 0181 request.addString(IPP_TAG_OPERATION, IPP_TAG_KEYWORD, KCUPS_WHICH_JOBS, QLatin1String("completed")); 0182 } else if (whichJobs == CUPS_WHICHJOBS_ALL) { 0183 request.addString(IPP_TAG_OPERATION, IPP_TAG_KEYWORD, KCUPS_WHICH_JOBS, QLatin1String("all")); 0184 } 0185 0186 const ReturnArguments ret = m_connection->request(request, IPP_TAG_JOB); 0187 0188 for (const QVariantMap &arguments : ret) { 0189 m_jobs << KCupsJob(arguments); 0190 } 0191 0192 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0193 setFinished(); 0194 } else { 0195 invokeMethod("getJobs", printerName, myJobs, whichJobs, QVariant::fromValue(attributes)); 0196 } 0197 } 0198 0199 void KCupsRequest::getJobAttributes(int jobId, const QString &printerUri, QStringList attributes) 0200 { 0201 if (m_connection->readyToStart()) { 0202 KIppRequest request(IPP_GET_JOB_ATTRIBUTES, QLatin1String("/")); 0203 0204 request.addString(IPP_TAG_OPERATION, IPP_TAG_URI, KCUPS_PRINTER_URI, printerUri); 0205 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_ENUM, KCUPS_PRINTER_TYPE, CUPS_PRINTER_LOCAL); 0206 request.addStringList(IPP_TAG_OPERATION, IPP_TAG_KEYWORD, KCUPS_REQUESTED_ATTRIBUTES, attributes); 0207 0208 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_INTEGER, KCUPS_JOB_ID, jobId); 0209 0210 const ReturnArguments ret = m_connection->request(request, IPP_TAG_PRINTER); 0211 0212 for (const QVariantMap &arguments : ret) { 0213 m_jobs << KCupsJob(arguments); 0214 } 0215 0216 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0217 setFinished(); 0218 } else { 0219 invokeMethod("getJobAttributes", jobId, printerUri, QVariant::fromValue(attributes)); 0220 } 0221 } 0222 0223 void KCupsRequest::getServerSettings() 0224 { 0225 if (m_connection->readyToStart()) { 0226 do { 0227 int num_settings; 0228 cups_option_t *settings; 0229 QVariantMap arguments; 0230 int ret = cupsAdminGetServerSettings(CUPS_HTTP_DEFAULT, &num_settings, &settings); 0231 for (int i = 0; i < num_settings; ++i) { 0232 QString name = QString::fromUtf8(settings[i].name); 0233 QString value = QString::fromUtf8(settings[i].value); 0234 arguments[name] = value; 0235 } 0236 cupsFreeOptions(num_settings, settings); 0237 if (ret) { 0238 setError(HTTP_OK, IPP_OK, QString()); 0239 } else { 0240 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0241 } 0242 0243 m_server = KCupsServer(arguments); 0244 } while (m_connection->retry("/admin/", -1)); 0245 setFinished(); 0246 } else { 0247 invokeMethod("getServerSettings"); 0248 } 0249 } 0250 0251 void KCupsRequest::getPrinterPPD(const QString &printerName) 0252 { 0253 if (m_connection->readyToStart()) { 0254 do { 0255 const char *filename; 0256 filename = cupsGetPPD2(CUPS_HTTP_DEFAULT, qUtf8Printable(printerName)); 0257 qCDebug(LIBKCUPS) << filename; 0258 m_ppdFile = QString::fromUtf8(filename); 0259 qCDebug(LIBKCUPS) << m_ppdFile; 0260 } while (m_connection->retry("/", CUPS_GET_PPD)); 0261 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0262 setFinished(); 0263 } else { 0264 invokeMethod("getPrinterPPD", printerName); 0265 } 0266 } 0267 0268 void KCupsRequest::setServerSettings(const KCupsServer &server) 0269 { 0270 if (m_connection->readyToStart()) { 0271 do { 0272 QVariantMap args = server.arguments(); 0273 int num_settings = 0; 0274 cups_option_t *settings; 0275 0276 QVariantMap::const_iterator i = args.constBegin(); 0277 while (i != args.constEnd()) { 0278 num_settings = cupsAddOption(qUtf8Printable(i.key()), qUtf8Printable(i.value().toString()), num_settings, &settings); 0279 ++i; 0280 } 0281 0282 cupsAdminSetServerSettings(CUPS_HTTP_DEFAULT, num_settings, settings); 0283 cupsFreeOptions(num_settings, settings); 0284 } while (m_connection->retry("/admin/", -1)); 0285 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0286 setFinished(); 0287 } else { 0288 invokeMethod("setServerSettings", QVariant::fromValue(server)); 0289 } 0290 } 0291 0292 void KCupsRequest::addOrModifyPrinter(const QString &printerName, const QVariantMap &attributes, const QString &filename) 0293 { 0294 KIppRequest request(CUPS_ADD_MODIFY_PRINTER, QLatin1String("/admin/"), filename); 0295 request.addPrinterUri(printerName); 0296 request.addVariantValues(attributes); 0297 0298 process(request); 0299 } 0300 0301 void KCupsRequest::addOrModifyClass(const QString &printerName, const QVariantMap &attributes) 0302 { 0303 KIppRequest request(CUPS_ADD_MODIFY_CLASS, QLatin1String("/admin/")); 0304 request.addPrinterUri(printerName, true); 0305 request.addVariantValues(attributes); 0306 0307 process(request); 0308 } 0309 0310 void KCupsRequest::setShared(const QString &printerName, bool isClass, bool shared) 0311 { 0312 KIppRequest request(isClass ? CUPS_ADD_MODIFY_CLASS : CUPS_ADD_MODIFY_PRINTER, QLatin1String("/admin/")); 0313 request.addPrinterUri(printerName, isClass); 0314 request.addBoolean(IPP_TAG_OPERATION, KCUPS_PRINTER_IS_SHARED, shared); 0315 0316 process(request); 0317 } 0318 0319 void KCupsRequest::pausePrinter(const QString &printerName) 0320 { 0321 KIppRequest request(IPP_PAUSE_PRINTER, QLatin1String("/admin/")); 0322 request.addPrinterUri(printerName); 0323 0324 process(request); 0325 } 0326 0327 void KCupsRequest::resumePrinter(const QString &printerName) 0328 { 0329 KIppRequest request(IPP_RESUME_PRINTER, QLatin1String("/admin/")); 0330 request.addPrinterUri(printerName); 0331 0332 process(request); 0333 } 0334 0335 void KCupsRequest::rejectJobs(const QString &printerName) 0336 { 0337 KIppRequest request(CUPS_REJECT_JOBS, QLatin1String("/admin/")); 0338 request.addPrinterUri(printerName); 0339 0340 process(request); 0341 } 0342 0343 void KCupsRequest::acceptJobs(const QString &printerName) 0344 { 0345 KIppRequest request(CUPS_ACCEPT_JOBS, QLatin1String("/admin/")); 0346 request.addPrinterUri(printerName); 0347 0348 process(request); 0349 } 0350 0351 void KCupsRequest::setDefaultPrinter(const QString &printerName) 0352 { 0353 KIppRequest request(CUPS_SET_DEFAULT, QLatin1String("/admin/")); 0354 request.addPrinterUri(printerName); 0355 0356 process(request); 0357 } 0358 0359 void KCupsRequest::deletePrinter(const QString &printerName) 0360 { 0361 KIppRequest request(CUPS_DELETE_PRINTER, QLatin1String("/admin/")); 0362 request.addPrinterUri(printerName); 0363 0364 process(request); 0365 } 0366 0367 void KCupsRequest::printTestPage(const QString &printerName, bool isClass) 0368 { 0369 QString resource; /* POST resource path */ 0370 QString filename; /* Test page filename */ 0371 QString datadir; /* CUPS_DATADIR env var */ 0372 0373 /* 0374 * Locate the test page file... 0375 */ 0376 datadir = QString::fromUtf8(qgetenv("CUPS_DATADIR")); 0377 if (datadir.isEmpty()) { 0378 datadir = CUPS_DATADIR; 0379 } 0380 filename = datadir % QLatin1String("/data/testprint"); 0381 0382 /* 0383 * Point to the printer/class... 0384 */ 0385 if (isClass) { 0386 resource = QLatin1String("/classes/") + printerName; 0387 } else { 0388 resource = QLatin1String("/printers/") + printerName; 0389 } 0390 0391 KIppRequest request(IPP_PRINT_JOB, resource, filename); 0392 request.addPrinterUri(printerName); 0393 request.addString(IPP_TAG_OPERATION, IPP_TAG_NAME, KCUPS_JOB_NAME, i18n("Test Page")); 0394 0395 process(request); 0396 } 0397 0398 void KCupsRequest::printCommand(const QString &printerName, const QString &command, const QString &title) 0399 { 0400 if (m_connection->readyToStart()) { 0401 do { 0402 int job_id; /* Command file job */ 0403 char command_file[1024]; /* Command "file" */ 0404 http_status_t status; /* Document status */ 0405 cups_option_t hold_option; /* job-hold-until option */ 0406 0407 /* 0408 * Create the CUPS command file... 0409 */ 0410 snprintf(command_file, sizeof(command_file), "#CUPS-COMMAND\n%s\n", command.toUtf8().constData()); 0411 0412 /* 0413 * Send the command file job... 0414 */ 0415 hold_option.name = const_cast<char *>("job-hold-until"); 0416 hold_option.value = const_cast<char *>("no-hold"); 0417 0418 if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, qUtf8Printable(printerName), qUtf8Printable(title), 1, &hold_option)) < 1) { 0419 qCWarning(LIBKCUPS) << "Unable to send command to printer driver!"; 0420 0421 setError(HTTP_OK, IPP_NOT_POSSIBLE, i18n("Unable to send command to printer driver!")); 0422 setFinished(); 0423 return; 0424 } 0425 0426 status = cupsStartDocument(CUPS_HTTP_DEFAULT, qUtf8Printable(printerName), job_id, nullptr, CUPS_FORMAT_COMMAND, 1); 0427 if (status == HTTP_CONTINUE) { 0428 status = cupsWriteRequestData(CUPS_HTTP_DEFAULT, command_file, strlen(command_file)); 0429 } 0430 0431 if (status == HTTP_CONTINUE) { 0432 cupsFinishDocument(CUPS_HTTP_DEFAULT, qUtf8Printable(printerName)); 0433 } 0434 0435 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0436 if (httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError() >= IPP_REDIRECTION_OTHER_SITE) { 0437 qCWarning(LIBKCUPS) << "Unable to send command to printer driver!"; 0438 0439 cupsCancelJob(qUtf8Printable(printerName), job_id); 0440 setFinished(); 0441 return; // Return to avoid a new try 0442 } 0443 } while (m_connection->retry("/", IPP_CREATE_JOB)); 0444 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0445 setFinished(); 0446 } else { 0447 invokeMethod("printCommand", printerName, command, title); 0448 } 0449 } 0450 0451 void KCupsRequest::cancelJob(const QString &printerName, int jobId) 0452 { 0453 KIppRequest request(IPP_CANCEL_JOB, QLatin1String("/jobs/")); 0454 request.addPrinterUri(printerName); 0455 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_INTEGER, KCUPS_JOB_ID, jobId); 0456 0457 process(request); 0458 } 0459 0460 void KCupsRequest::holdJob(const QString &printerName, int jobId) 0461 { 0462 KIppRequest request(IPP_HOLD_JOB, QLatin1String("/jobs/")); 0463 request.addPrinterUri(printerName); 0464 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_INTEGER, KCUPS_JOB_ID, jobId); 0465 0466 process(request); 0467 } 0468 0469 void KCupsRequest::releaseJob(const QString &printerName, int jobId) 0470 { 0471 KIppRequest request(IPP_RELEASE_JOB, QLatin1String("/jobs/")); 0472 request.addPrinterUri(printerName); 0473 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_INTEGER, KCUPS_JOB_ID, jobId); 0474 0475 process(request); 0476 } 0477 0478 void KCupsRequest::restartJob(const QString &printerName, int jobId) 0479 { 0480 KIppRequest request(IPP_RESTART_JOB, QLatin1String("/jobs/")); 0481 request.addPrinterUri(printerName); 0482 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_INTEGER, KCUPS_JOB_ID, jobId); 0483 0484 process(request); 0485 } 0486 0487 void KCupsRequest::moveJob(const QString &fromPrinterName, int jobId, const QString &toPrinterName) 0488 { 0489 if (jobId < -1 || fromPrinterName.isEmpty() || toPrinterName.isEmpty() || jobId == 0) { 0490 qCWarning(LIBKCUPS) << "Internal error, invalid input data" << jobId << fromPrinterName << toPrinterName; 0491 setFinished(); 0492 return; 0493 } 0494 0495 KIppRequest request(CUPS_MOVE_JOB, QLatin1String("/jobs/")); 0496 request.addPrinterUri(fromPrinterName); 0497 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_INTEGER, KCUPS_JOB_ID, jobId); 0498 0499 QString toPrinterUri = KIppRequest::assembleUrif(toPrinterName, false); 0500 request.addString(IPP_TAG_OPERATION, IPP_TAG_URI, KCUPS_JOB_PRINTER_URI, toPrinterUri); 0501 0502 process(request); 0503 } 0504 0505 void KCupsRequest::authenticateJob(const QString &printerName, const QStringList authInfo, int jobId) 0506 { 0507 KIppRequest request(IPP_OP_CUPS_AUTHENTICATE_JOB, QLatin1String("/jobs/")); 0508 request.addPrinterUri(printerName); 0509 request.addInteger(IPP_TAG_OPERATION, IPP_TAG_INTEGER, KCUPS_JOB_ID, jobId); 0510 request.addStringList(IPP_TAG_OPERATION, IPP_TAG_TEXT, KCUPS_AUTH_INFO, authInfo); 0511 0512 process(request); 0513 } 0514 0515 void KCupsRequest::invokeMethod(const char *method, 0516 const QVariant &arg1, 0517 const QVariant &arg2, 0518 const QVariant &arg3, 0519 const QVariant &arg4, 0520 const QVariant &arg5, 0521 const QVariant &arg6, 0522 const QVariant &arg7, 0523 const QVariant &arg8) 0524 { 0525 m_error = IPP_OK; 0526 m_errorMsg.clear(); 0527 m_printers.clear(); 0528 m_jobs.clear(); 0529 m_ppds.clear(); 0530 m_ppdFile.clear(); 0531 0532 // If this fails we get into a infinite loop 0533 // Do not use global()->thread() which point 0534 // to the KCupsConnection parent thread 0535 moveToThread(m_connection); 0536 0537 m_finished = !QMetaObject::invokeMethod(this, 0538 method, 0539 Qt::QueuedConnection, 0540 QGenericArgument(arg1.typeName(), arg1.data()), 0541 QGenericArgument(arg2.typeName(), arg2.data()), 0542 QGenericArgument(arg3.typeName(), arg3.data()), 0543 QGenericArgument(arg4.typeName(), arg4.data()), 0544 QGenericArgument(arg5.typeName(), arg5.data()), 0545 QGenericArgument(arg6.typeName(), arg6.data()), 0546 QGenericArgument(arg7.typeName(), arg7.data()), 0547 QGenericArgument(arg8.typeName(), arg8.data())); 0548 if (m_finished) { 0549 setError(HTTP_ERROR, IPP_BAD_REQUEST, i18n("Failed to invoke method: %1", QLatin1String(method))); 0550 setFinished(); 0551 } 0552 } 0553 0554 void KCupsRequest::process(const KIppRequest &request) 0555 { 0556 if (m_connection->readyToStart()) { 0557 m_connection->request(request); 0558 0559 setError(httpGetStatus(CUPS_HTTP_DEFAULT), cupsLastError(), QString::fromUtf8(cupsLastErrorString())); 0560 setFinished(); 0561 } else { 0562 invokeMethod("process", QVariant::fromValue(request)); 0563 } 0564 } 0565 0566 ReturnArguments KCupsRequest::ppds() const 0567 { 0568 return m_ppds; 0569 } 0570 0571 KCupsServer KCupsRequest::serverSettings() const 0572 { 0573 return m_server; 0574 } 0575 0576 QString KCupsRequest::printerPPD() const 0577 { 0578 return m_ppdFile; 0579 } 0580 0581 KCupsPrinters KCupsRequest::printers() const 0582 { 0583 return m_printers; 0584 } 0585 0586 KCupsJobs KCupsRequest::jobs() const 0587 { 0588 return m_jobs; 0589 } 0590 0591 void KCupsRequest::waitTillFinished() 0592 { 0593 if (m_finished) { 0594 return; 0595 } 0596 0597 m_loop.exec(); 0598 } 0599 0600 bool KCupsRequest::hasError() const 0601 { 0602 return m_error; 0603 } 0604 0605 ipp_status_t KCupsRequest::error() const 0606 { 0607 return m_error; 0608 } 0609 0610 http_status_t KCupsRequest::httpStatus() const 0611 { 0612 return m_httpStatus; 0613 } 0614 0615 QString KCupsRequest::errorMsg() const 0616 { 0617 return m_errorMsg; 0618 } 0619 0620 KCupsConnection *KCupsRequest::connection() const 0621 { 0622 return m_connection; 0623 } 0624 0625 void KCupsRequest::setError(http_status_t httpStatus, ipp_status_t error, const QString &errorMsg) 0626 { 0627 m_httpStatus = httpStatus; 0628 m_error = error; 0629 m_errorMsg = errorMsg; 0630 } 0631 0632 void KCupsRequest::setFinished(bool delayed) 0633 { 0634 m_finished = true; 0635 if (delayed) { 0636 QTimer::singleShot(0, this, [this]() { 0637 Q_EMIT finished(this); 0638 }); 0639 } else { 0640 Q_EMIT finished(this); 0641 } 0642 } 0643 0644 #include "moc_KCupsRequest.cpp"