Coverage Report

Created: 2026-09-03 07:24

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/source3/printing/print_iprint.c
Line
Count
Source
1
/*
2
 * Support code for Novell iPrint using the Common UNIX Printing
3
 * System ("CUPS") libraries
4
 *
5
 * Copyright 1999-2003 by Michael R Sweet.
6
 * Portions Copyright 2005 by Joel J. Smith.
7
 *
8
 * This program is free software; you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation; either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "includes.h"
23
#include "printing.h"
24
#include "printing/pcap.h"
25
#include "lib/util/string_wrappers.h"
26
27
#ifdef HAVE_IPRINT
28
#include <cups/cups.h>
29
#include <cups/language.h>
30
31
0
#define OPERATION_NOVELL_LIST_PRINTERS          0x401A
32
0
#define OPERATION_NOVELL_MGMT                   0x401C
33
0
#define NOVELL_SERVER_SYSNAME     "sysname="
34
0
#define NOVELL_SERVER_SYSNAME_NETWARE   "NetWare IA32"
35
0
#define NOVELL_SERVER_VERSION_STRING    "iprintserverversion="
36
0
#define NOVELL_SERVER_VERSION_OES_SP1   33554432
37
38
#if (CUPS_VERSION_MAJOR > 1) || (CUPS_VERSION_MINOR > 5)
39
#define HAVE_CUPS_1_6 1
40
#endif
41
42
#ifndef HAVE_CUPS_1_6
43
#define ippGetCount(attr)     attr->num_values
44
#define ippGetGroupTag(attr)  attr->group_tag
45
#define ippGetName(attr)      attr->name
46
#define ippGetValueTag(attr)  attr->value_tag
47
#define ippGetStatusCode(ipp) ipp->request.status.status_code
48
#define ippGetBoolean(attr, element) attr->values[element].boolean
49
#define ippGetInteger(attr, element) attr->values[element].integer
50
#define ippGetString(attr, element, language) attr->values[element].string.text
51
52
static ipp_attribute_t *
53
ippFirstAttribute(ipp_t *ipp)
54
{
55
  if (!ipp)
56
    return (NULL);
57
  return (ipp->current = ipp->attrs);
58
}
59
60
static ipp_attribute_t *
61
ippNextAttribute(ipp_t *ipp)
62
{
63
  if (!ipp || !ipp->current)
64
    return (NULL);
65
  return (ipp->current = ipp->current->next);
66
}
67
68
static int ippSetOperation(ipp_t *ipp, ipp_op_t op)
69
{
70
    ipp->request.op.operation_id = op;
71
    return (1);
72
}
73
74
static int ippSetRequestId(ipp_t *ipp, int request_id)
75
{
76
    ipp->request.any.request_id = request_id;
77
    return (1);
78
}
79
#endif
80
81
/*
82
 * 'iprint_passwd_cb()' - The iPrint password callback...
83
 */
84
85
static const char *       /* O - Password or NULL */
86
iprint_passwd_cb(const char *prompt)  /* I - Prompt */
87
0
{
88
       /*
89
  * Always return NULL to indicate that no password is available...
90
  */
91
92
0
  return (NULL);
93
0
}
94
95
static const char *iprint_server(void)
96
0
{
97
0
  const struct loadparm_substitution *lp_sub =
98
0
    loadparm_s3_global_substitution();
99
0
  const char *server = lp_iprint_server(talloc_tos(), lp_sub);
100
101
0
  if ((server != NULL) && (strlen(server) > 0)) {
102
0
    DEBUG(10, ("iprint server explicitly set to %s\n",
103
0
         server));
104
0
    return server;
105
0
  }
106
107
0
  DEBUG(10, ("iprint server left to default %s\n", cupsServer()));
108
0
  return cupsServer();
109
0
}
110
111
/*
112
 * Pass in an already connected http_t*
113
 * Returns the server version if one can be found, multiplied by
114
 * -1 for all NetWare versions.  Returns 0 if a server version
115
 * cannot be determined
116
 */
117
118
static int iprint_get_server_version(http_t *http, char* serviceUri)
119
0
{
120
0
  ipp_t   *request = NULL, /* IPP Request */
121
0
      *response = NULL; /* IPP Response */
122
0
  ipp_attribute_t *attr;      /* Current attribute */
123
0
  cups_lang_t *language = NULL; /* Default language */
124
0
  const char  *ver;     /* server version pointer */
125
0
  char    *vertmp;    /* server version tmp pointer */
126
0
  int   serverVersion = 0;  /* server version */
127
0
  const char  *os;      /* server os */
128
0
  int   osFlag = 0;   /* 0 for NetWare, 1 for anything else */
129
0
  char    *temp;      /* pointer for string manipulation */
130
131
       /*
132
  * Build an OPERATION_NOVELL_MGMT("get-server-version") request,
133
  * which requires the following attributes:
134
  *
135
  *    attributes-charset
136
  *    attributes-natural-language
137
  *    operation-name
138
  *    service-uri
139
  */
140
141
0
  request = ippNew();
142
143
0
  ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_MGMT);
144
0
  ippSetRequestId(request, 1);
145
146
0
  language = cupsLangDefault();
147
148
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
149
0
               "attributes-charset", NULL, "utf-8");
150
151
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
152
0
               "attributes-natural-language", NULL, language->language);
153
154
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
155
0
               "service-uri", NULL, serviceUri);
156
157
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
158
0
                "operation-name", NULL, "get-server-version");
159
160
       /*
161
  * Do the request and get back a response...
162
  */
163
164
0
  if (((response = cupsDoRequest(http, request, "/ipp/")) == NULL) ||
165
0
      (ippGetStatusCode(response) >= IPP_OK_CONFLICT))
166
0
    goto out;
167
168
0
  if (((attr = ippFindAttribute(response, "server-version",
169
0
                                IPP_TAG_STRING)) != NULL)) {
170
0
    if ((ver = strstr(ippGetString(attr, 0, NULL),
171
0
                                  NOVELL_SERVER_VERSION_STRING)) != NULL) {
172
0
      ver += strlen(NOVELL_SERVER_VERSION_STRING);
173
           /*
174
      * Strangely, libcups stores a IPP_TAG_STRING (octet
175
      * string) as a null-terminated string with no length
176
      * even though it could be binary data with nulls in
177
      * it.  Luckily, in this case the value is not binary.
178
      */
179
0
      serverVersion = strtol(ver, &vertmp, 10);
180
181
      /* Check for not found, overflow or negative version */
182
0
      if ((ver == vertmp) || (serverVersion < 0))
183
0
        serverVersion = 0;
184
0
    }
185
186
0
    if ((os = strstr(ippGetString(attr, 0, NULL),
187
0
                                  NOVELL_SERVER_SYSNAME)) != NULL) {
188
0
      os += strlen(NOVELL_SERVER_SYSNAME);
189
0
      temp = discard_const_p(char, os);
190
0
      if ((temp = strchr(temp,'<')) != NULL)
191
0
        *temp = '\0';
192
0
      if (strcmp(os,NOVELL_SERVER_SYSNAME_NETWARE))
193
0
        osFlag = 1; /* 1 for non-NetWare systems */
194
0
    }
195
0
  }
196
197
0
 out:
198
0
  if (response)
199
0
    ippDelete(response);
200
201
0
  if (language)
202
0
    cupsLangFree(language);
203
204
0
  if (osFlag == 0)
205
0
    serverVersion *= -1;
206
207
0
  return serverVersion;
208
0
}
209
210
211
static int iprint_cache_add_printer(http_t *http,
212
           int reqId,
213
           const char *url,
214
           struct pcap_cache **pcache)
215
0
{
216
0
  ipp_t   *request = NULL, /* IPP Request */
217
0
      *response = NULL; /* IPP Response */
218
0
  ipp_attribute_t *attr;      /* Current attribute */
219
0
  cups_lang_t *language = NULL; /* Default language */
220
0
  const char  *name,      /* printer-name attribute */
221
0
      *info;      /* printer-info attribute */
222
0
  char    smb_enabled,    /* smb-enabled attribute */
223
0
      secure;     /* security-enabled attrib. */
224
225
0
  const char  *httpPath;  /* path portion of the printer-uri */
226
227
0
  static const char *pattrs[] = /* Requested printer attributes */
228
0
      {
229
0
        "printer-name",
230
0
        "security-enabled",
231
0
        "printer-info",
232
0
        "smb-enabled"
233
0
      };
234
235
0
  request = ippNew();
236
237
0
  ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES);
238
0
  ippSetRequestId(request, reqId);
239
240
0
  language = cupsLangDefault();
241
242
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
243
0
               "attributes-charset", NULL, "utf-8");
244
245
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
246
0
               "attributes-natural-language", NULL, language->language);
247
248
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, url);
249
250
0
  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
251
0
                "requested-attributes",
252
0
                (sizeof(pattrs) / sizeof(pattrs[0])),
253
0
                NULL, pattrs);
254
255
  /*
256
   * Do the request and get back a response...
257
   */
258
259
0
  if ((httpPath = strstr(url,"://")) == NULL ||
260
0
      (httpPath = strchr(httpPath+3,'/')) == NULL)
261
0
  {
262
0
    ippDelete(request);
263
0
    request = NULL;
264
0
    goto out;
265
0
  }
266
267
0
  if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
268
0
    ipp_status_t lastErr = cupsLastError();
269
270
         /*
271
    * Ignore printers that cannot be queried without credentials
272
    */
273
0
    if (lastErr == IPP_FORBIDDEN ||
274
0
        lastErr == IPP_NOT_AUTHENTICATED ||
275
0
        lastErr == IPP_NOT_AUTHORIZED)
276
0
      goto out;
277
278
0
    DEBUG(0,("Unable to get printer list - %s\n",
279
0
          ippErrorString(lastErr)));
280
0
    goto out;
281
0
  }
282
283
0
  for (attr = ippFirstAttribute(response); attr != NULL;) {
284
         /*
285
    * Skip leading attributes until we hit a printer...
286
    */
287
288
0
    while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
289
0
      attr = ippNextAttribute(response);
290
291
0
    if (attr == NULL)
292
0
      break;
293
294
         /*
295
    * Pull the needed attributes from this printer...
296
    */
297
298
0
    name       = NULL;
299
0
    info       = NULL;
300
0
    smb_enabled= 1;
301
0
    secure     = 0;
302
303
0
    while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) {
304
0
      if (strcmp(ippGetName(attr), "printer-name") == 0 &&
305
0
          ippGetValueTag(attr) == IPP_TAG_NAME)
306
0
        name = ippGetString(attr, 0, NULL);
307
308
0
      if (strcmp(ippGetName(attr), "printer-info") == 0 &&
309
0
          (ippGetValueTag(attr) == IPP_TAG_TEXT ||
310
0
          ippGetValueTag(attr) == IPP_TAG_TEXTLANG))
311
0
        info = ippGetString(attr, 0, NULL);
312
313
           /*
314
      * If the smb-enabled attribute is present and the
315
      * value is set to 0, don't show the printer.
316
      * If the attribute is not present, assume that the
317
      * printer should show up
318
      */
319
0
      if (!strcmp(ippGetName(attr), "smb-enabled") &&
320
0
          ((ippGetValueTag(attr) == IPP_TAG_INTEGER &&
321
0
          !ippGetInteger(attr, 0)) ||
322
0
          (ippGetValueTag(attr) == IPP_TAG_BOOLEAN &&
323
0
          !ippGetBoolean(attr, 0))))
324
0
        smb_enabled = 0;
325
326
           /*
327
      * If the security-enabled attribute is present and the
328
      * value is set to 1, don't show the printer.
329
      * If the attribute is not present, assume that the
330
      * printer should show up
331
      */
332
0
      if (!strcmp(ippGetName(attr), "security-enabled") &&
333
0
          ((ippGetValueTag(attr) == IPP_TAG_INTEGER &&
334
0
          ippGetInteger(attr, 0)) ||
335
0
          (ippGetValueTag(attr) == IPP_TAG_BOOLEAN &&
336
0
          ippGetBoolean(attr, 0))))
337
0
        secure = 1;
338
339
0
      attr = ippNextAttribute(response);
340
0
    }
341
342
         /*
343
    * See if we have everything needed...
344
    * Make sure the printer is not a secure printer
345
    * and make sure smb printing hasn't been explicitly
346
    * disabled for the printer
347
    */
348
349
0
    if (name != NULL && !secure && smb_enabled)
350
0
      pcap_cache_add_specific(pcache, name, info, NULL);
351
0
  }
352
353
0
 out:
354
0
  if (response)
355
0
    ippDelete(response);
356
0
  return(0);
357
0
}
358
359
bool iprint_cache_reload(struct pcap_cache **_pcache)
360
0
{
361
0
  http_t    *http = NULL;   /* HTTP connection to server */
362
0
  ipp_t   *request = NULL, /* IPP Request */
363
0
      *response = NULL; /* IPP Response */
364
0
  ipp_attribute_t *attr;      /* Current attribute */
365
0
  cups_lang_t *language = NULL; /* Default language */
366
0
  int   i;
367
0
  bool ret = false;
368
0
  struct pcap_cache *pcache = NULL;
369
370
0
  DEBUG(5, ("reloading iprint printcap cache\n"));
371
372
       /*
373
  * Make sure we don't ask for passwords...
374
  */
375
376
0
  cupsSetPasswordCB(iprint_passwd_cb);
377
378
       /*
379
  * Try to connect to the server...
380
  */
381
382
0
#ifdef HAVE_HTTPCONNECT2
383
0
  http = httpConnect2(iprint_server(),
384
0
          ippPort(),
385
0
          NULL,
386
0
          AF_UNSPEC,
387
0
          HTTP_ENCRYPTION_NEVER,
388
0
          1, /* blocking */
389
0
          30 * 1000, /* timeout */
390
0
          NULL);
391
#else
392
  http = httpConnect(iprint_server(), ippPort());
393
#endif
394
0
  if (http == NULL) {
395
0
    DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
396
0
       iprint_server(), strerror(errno)));
397
0
    goto out;
398
0
  }
399
400
       /*
401
  * Build a OPERATION_NOVELL_LIST_PRINTERS request, which requires the following attributes:
402
  *
403
  *    attributes-charset
404
  *    attributes-natural-language
405
  */
406
407
0
  request = ippNew();
408
409
0
  ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_LIST_PRINTERS);
410
0
  ippSetRequestId(request, 1);
411
412
0
  language = cupsLangDefault();
413
414
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
415
0
               "attributes-charset", NULL, "utf-8");
416
417
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
418
0
               "attributes-natural-language", NULL, language->language);
419
420
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
421
0
               "ipp-server", NULL, "ippSrvr");
422
423
       /*
424
  * Do the request and get back a response...
425
  */
426
427
0
  if ((response = cupsDoRequest(http, request, "/ipp")) == NULL) {
428
0
    DEBUG(0,("Unable to get printer list - %s\n",
429
0
       ippErrorString(cupsLastError())));
430
0
    goto out;
431
0
  }
432
433
0
  for (attr = ippFirstAttribute(response); attr != NULL;) {
434
         /*
435
    * Skip leading attributes until we hit a printer...
436
    */
437
438
0
    while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER)
439
0
      attr = ippNextAttribute(response);
440
441
0
    if (attr == NULL)
442
0
      break;
443
444
         /*
445
    * Pull the needed attributes from this printer...
446
    */
447
448
0
    while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER)
449
0
    {
450
0
      if (strcmp(ippGetName(attr), "printer-name") == 0 &&
451
0
          (ippGetValueTag(attr) == IPP_TAG_URI ||
452
0
           ippGetValueTag(attr) == IPP_TAG_NAME ||
453
0
           ippGetValueTag(attr) == IPP_TAG_TEXT ||
454
0
           ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
455
0
           ippGetValueTag(attr) == IPP_TAG_TEXTLANG))
456
0
      {
457
0
        for (i = 0; i<ippGetCount(attr); i++)
458
0
        {
459
0
          const char *url = ippGetString(attr, i, NULL);
460
0
          if (!url || !strlen(url))
461
0
            continue;
462
0
          iprint_cache_add_printer(http, i+2, url,
463
0
                 &pcache);
464
0
        }
465
0
      }
466
0
      attr = ippNextAttribute(response);
467
0
    }
468
0
  }
469
470
0
  ret = true;
471
0
  *_pcache = pcache;
472
473
0
 out:
474
0
  if (response)
475
0
    ippDelete(response);
476
477
0
  if (language)
478
0
    cupsLangFree(language);
479
480
0
  if (http)
481
0
    httpClose(http);
482
483
0
  return ret;
484
0
}
485
486
487
/*
488
 * 'iprint_job_delete()' - Delete a job.
489
 */
490
491
static int iprint_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
492
0
{
493
0
  int   ret = 1;    /* Return value */
494
0
  http_t    *http = NULL;   /* HTTP connection to server */
495
0
  ipp_t   *request = NULL, /* IPP Request */
496
0
      *response = NULL; /* IPP Response */
497
0
  cups_lang_t *language = NULL; /* Default language */
498
0
  char    uri[HTTP_MAX_URI];  /* printer-uri attribute */
499
0
  char    httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
500
501
502
0
  DEBUG(5,("iprint_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
503
504
       /*
505
  * Make sure we don't ask for passwords...
506
  */
507
508
0
  cupsSetPasswordCB(iprint_passwd_cb);
509
510
       /*
511
  * Try to connect to the server...
512
  */
513
514
0
#ifdef HAVE_HTTPCONNECT2
515
0
  http = httpConnect2(iprint_server(),
516
0
          ippPort(),
517
0
          NULL,
518
0
          AF_UNSPEC,
519
0
          HTTP_ENCRYPTION_NEVER,
520
0
          1, /* blocking */
521
0
          30 * 1000, /* timeout */
522
0
          NULL);
523
#else
524
  http = httpConnect(iprint_server(), ippPort());
525
#endif
526
0
  if (http == NULL) {
527
0
    DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
528
0
       iprint_server(), strerror(errno)));
529
0
    goto out;
530
0
  }
531
532
       /*
533
  * Build an IPP_CANCEL_JOB request, which uses the following
534
  * attributes:
535
  *
536
  *    attributes-charset
537
  *    attributes-natural-language
538
  *    printer-uri
539
  *    job-id
540
  *    requesting-user-name
541
  */
542
543
0
  request = ippNew();
544
545
0
  ippSetOperation(request, IPP_CANCEL_JOB);
546
0
  ippSetRequestId(request, 1);
547
548
0
  language = cupsLangDefault();
549
550
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
551
0
               "attributes-charset", NULL, "utf-8");
552
553
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
554
0
               "attributes-natural-language", NULL, language->language);
555
556
0
  slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), sharename);
557
558
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
559
560
0
  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
561
562
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
563
0
               NULL, pjob->user);
564
565
       /*
566
  * Do the request and get back a response...
567
  */
568
569
0
  slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", sharename);
570
571
0
  if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
572
0
    if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
573
0
      DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
574
0
        ippErrorString(cupsLastError())));
575
0
    } else {
576
0
      ret = 0;
577
0
    }
578
0
  } else {
579
0
    DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
580
0
      ippErrorString(cupsLastError())));
581
0
  }
582
583
0
 out:
584
0
  if (response)
585
0
    ippDelete(response);
586
587
0
  if (language)
588
0
    cupsLangFree(language);
589
590
0
  if (http)
591
0
    httpClose(http);
592
593
0
  return ret;
594
0
}
595
596
597
/*
598
 * 'iprint_job_pause()' - Pause a job.
599
 */
600
601
static int iprint_job_pause(int snum, struct printjob *pjob)
602
0
{
603
0
  int   ret = 1;    /* Return value */
604
0
  http_t    *http = NULL;   /* HTTP connection to server */
605
0
  ipp_t   *request = NULL, /* IPP Request */
606
0
      *response = NULL; /* IPP Response */
607
0
  cups_lang_t *language = NULL; /* Default language */
608
0
  char    uri[HTTP_MAX_URI];  /* printer-uri attribute */
609
0
  char    httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
610
0
  const struct loadparm_substitution *lp_sub =
611
0
    loadparm_s3_global_substitution();
612
613
614
0
  DEBUG(5,("iprint_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
615
616
       /*
617
  * Make sure we don't ask for passwords...
618
  */
619
620
0
  cupsSetPasswordCB(iprint_passwd_cb);
621
622
       /*
623
  * Try to connect to the server...
624
  */
625
626
0
#ifdef HAVE_HTTPCONNECT2
627
0
  http = httpConnect2(iprint_server(),
628
0
          ippPort(),
629
0
          NULL,
630
0
          AF_UNSPEC,
631
0
          HTTP_ENCRYPTION_NEVER,
632
0
          1, /* blocking */
633
0
          30 * 1000, /* timeout */
634
0
          NULL);
635
#else
636
  http = httpConnect(iprint_server(), ippPort());
637
#endif
638
0
  if (http == NULL) {
639
0
    DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
640
0
       iprint_server(), strerror(errno)));
641
0
    goto out;
642
0
  }
643
644
       /*
645
  * Build an IPP_HOLD_JOB request, which requires the following
646
  * attributes:
647
  *
648
  *    attributes-charset
649
  *    attributes-natural-language
650
  *    printer-uri
651
  *    job-id
652
  *    requesting-user-name
653
  */
654
655
0
  request = ippNew();
656
657
0
  ippSetOperation(request, IPP_HOLD_JOB);
658
0
  ippSetRequestId(request, 1);
659
660
0
  language = cupsLangDefault();
661
662
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
663
0
               "attributes-charset", NULL, "utf-8");
664
665
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
666
0
               "attributes-natural-language", NULL, language->language);
667
668
0
  slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
669
0
     lp_printername(talloc_tos(), lp_sub, snum));
670
671
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
672
673
0
  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
674
675
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
676
0
               NULL, pjob->user);
677
678
       /*
679
  * Do the request and get back a response...
680
  */
681
682
0
  slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s",
683
0
     lp_printername(talloc_tos(), lp_sub, snum));
684
685
0
  if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
686
0
    if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
687
0
      DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
688
0
        ippErrorString(cupsLastError())));
689
0
    } else {
690
0
      ret = 0;
691
0
    }
692
0
  } else {
693
0
    DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
694
0
      ippErrorString(cupsLastError())));
695
0
  }
696
697
0
 out:
698
0
  if (response)
699
0
    ippDelete(response);
700
701
0
  if (language)
702
0
    cupsLangFree(language);
703
704
0
  if (http)
705
0
    httpClose(http);
706
707
0
  return ret;
708
0
}
709
710
711
/*
712
 * 'iprint_job_resume()' - Resume a paused job.
713
 */
714
715
static int iprint_job_resume(int snum, struct printjob *pjob)
716
0
{
717
0
  int   ret = 1;    /* Return value */
718
0
  http_t    *http = NULL;   /* HTTP connection to server */
719
0
  ipp_t   *request = NULL, /* IPP Request */
720
0
      *response = NULL; /* IPP Response */
721
0
  cups_lang_t *language = NULL; /* Default language */
722
0
  char    uri[HTTP_MAX_URI];  /* printer-uri attribute */
723
0
  char    httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
724
0
  const struct loadparm_substitution *lp_sub =
725
0
    loadparm_s3_global_substitution();
726
727
728
0
  DEBUG(5,("iprint_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
729
730
       /*
731
  * Make sure we don't ask for passwords...
732
  */
733
734
0
  cupsSetPasswordCB(iprint_passwd_cb);
735
736
       /*
737
  * Try to connect to the server...
738
  */
739
740
0
#ifdef HAVE_HTTPCONNECT2
741
0
  http = httpConnect2(iprint_server(),
742
0
          ippPort(),
743
0
          NULL,
744
0
          AF_UNSPEC,
745
0
          HTTP_ENCRYPTION_NEVER,
746
0
          1, /* blocking */
747
0
          30 * 1000, /* timeout */
748
0
          NULL);
749
#else
750
  http = httpConnect(iprint_server(), ippPort());
751
#endif
752
0
  if (http == NULL) {
753
0
    DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
754
0
       iprint_server(), strerror(errno)));
755
0
    goto out;
756
0
  }
757
758
       /*
759
  * Build an IPP_RELEASE_JOB request, which requires the following
760
  * attributes:
761
  *
762
  *    attributes-charset
763
  *    attributes-natural-language
764
  *    printer-uri
765
  *    job-id
766
  *    requesting-user-name
767
  */
768
769
0
  request = ippNew();
770
771
0
  ippSetOperation(request, IPP_RELEASE_JOB);
772
0
  ippSetRequestId(request, 1);
773
774
0
  language = cupsLangDefault();
775
776
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
777
0
               "attributes-charset", NULL, "utf-8");
778
779
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
780
0
               "attributes-natural-language", NULL, language->language);
781
782
0
  slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
783
0
     lp_printername(talloc_tos(), lp_sub, snum));
784
785
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
786
787
0
  ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
788
789
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
790
0
               NULL, pjob->user);
791
792
       /*
793
  * Do the request and get back a response...
794
  */
795
796
0
  slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s",
797
0
     lp_printername(talloc_tos(), lp_sub, snum));
798
799
0
  if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
800
0
    if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
801
0
      DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
802
0
        ippErrorString(cupsLastError())));
803
0
    } else {
804
0
      ret = 0;
805
0
    }
806
0
  } else {
807
0
    DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
808
0
      ippErrorString(cupsLastError())));
809
0
  }
810
811
0
 out:
812
0
  if (response)
813
0
    ippDelete(response);
814
815
0
  if (language)
816
0
    cupsLangFree(language);
817
818
0
  if (http)
819
0
    httpClose(http);
820
821
0
  return ret;
822
0
}
823
824
825
/*
826
 * 'iprint_job_submit()' - Submit a job for printing.
827
 */
828
829
static int iprint_job_submit(int snum, struct printjob *pjob,
830
           enum printing_types printing_type,
831
           char *lpq_cmd)
832
0
{
833
0
  int   ret = 1;    /* Return value */
834
0
  http_t    *http = NULL;   /* HTTP connection to server */
835
0
  ipp_t   *request = NULL, /* IPP Request */
836
0
      *response = NULL; /* IPP Response */
837
0
  ipp_attribute_t *attr;    /* Current attribute */
838
0
  cups_lang_t *language = NULL; /* Default language */
839
0
  char    uri[HTTP_MAX_URI]; /* printer-uri attribute */
840
0
  const struct loadparm_substitution *lp_sub =
841
0
    loadparm_s3_global_substitution();
842
843
0
  DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
844
845
       /*
846
  * Make sure we don't ask for passwords...
847
  */
848
849
0
  cupsSetPasswordCB(iprint_passwd_cb);
850
851
       /*
852
  * Try to connect to the server...
853
  */
854
855
0
#ifdef HAVE_HTTPCONNECT2
856
0
  http = httpConnect2(iprint_server(),
857
0
          ippPort(),
858
0
          NULL,
859
0
          AF_UNSPEC,
860
0
          HTTP_ENCRYPTION_NEVER,
861
0
          1, /* blocking */
862
0
          30 * 1000, /* timeout */
863
0
          NULL);
864
#else
865
  http = httpConnect(iprint_server(), ippPort());
866
#endif
867
0
  if (http == NULL) {
868
0
    DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
869
0
       iprint_server(), strerror(errno)));
870
0
    goto out;
871
0
  }
872
873
       /*
874
  * Build an IPP_PRINT_JOB request, which requires the following
875
  * attributes:
876
  *
877
  *    attributes-charset
878
  *    attributes-natural-language
879
  *    printer-uri
880
  *    requesting-user-name
881
  *    [document-data]
882
  */
883
884
0
  request = ippNew();
885
886
0
  ippSetOperation(request, IPP_PRINT_JOB);
887
0
  ippSetRequestId(request, 1);
888
889
0
  language = cupsLangDefault();
890
891
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
892
0
               "attributes-charset", NULL, "utf-8");
893
894
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
895
0
               "attributes-natural-language", NULL, language->language);
896
897
0
  slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(),
898
0
     lp_printername(talloc_tos(), lp_sub, snum));
899
900
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
901
0
               "printer-uri", NULL, uri);
902
903
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
904
0
               NULL, pjob->user);
905
906
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
907
0
               "job-originating-host-name", NULL,
908
0
         pjob->clientmachine);
909
910
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
911
0
               pjob->jobname);
912
913
       /*
914
  * Do the request and get back a response...
915
  */
916
917
0
  slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(talloc_tos(), lp_sub, snum));
918
919
0
  if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
920
0
    if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
921
0
      DEBUG(0,("Unable to print file to %s - %s\n",
922
0
         lp_printername(talloc_tos(), lp_sub, snum),
923
0
               ippErrorString(cupsLastError())));
924
0
    } else {
925
0
      ret = 0;
926
0
    }
927
0
  } else {
928
0
    DEBUG(0,("Unable to print file to `%s' - %s\n",
929
0
       lp_printername(talloc_tos(), lp_sub, snum),
930
0
       ippErrorString(cupsLastError())));
931
0
  }
932
933
0
  if ( ret == 0 )
934
0
    unlink(pjob->filename);
935
  /* else print_job_end will do it for us */
936
937
0
  if ( ret == 0 ) {
938
939
0
    attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER);
940
0
    if (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB)
941
0
    {
942
0
      pjob->sysjob = ippGetInteger(attr, 0);
943
0
    }
944
0
  }
945
946
0
 out:
947
0
  if (response)
948
0
    ippDelete(response);
949
950
0
  if (language)
951
0
    cupsLangFree(language);
952
953
0
  if (http)
954
0
    httpClose(http);
955
956
0
  return ret;
957
0
}
958
959
/*
960
 * 'iprint_queue_get()' - Get all the jobs in the print queue.
961
 */
962
963
static int iprint_queue_get(const char *sharename,
964
          enum printing_types printing_type,
965
          char *lpq_command,
966
          print_queue_struct **q,
967
          print_status_struct *status)
968
0
{
969
0
  fstring   printername;
970
0
  http_t    *http = NULL;   /* HTTP connection to server */
971
0
  ipp_t   *request = NULL, /* IPP Request */
972
0
      *response = NULL; /* IPP Response */
973
0
  ipp_attribute_t *attr = NULL;   /* Current attribute */
974
0
  cups_lang_t *language = NULL; /* Default language */
975
0
  char    uri[HTTP_MAX_URI]; /* printer-uri attribute */
976
0
  char    serviceUri[HTTP_MAX_URI]; /* service-uri attribute */
977
0
  char    httpPath[HTTP_MAX_URI]; /* path portion of the uri */
978
0
  int   jobUseUnixTime = 0; /* Whether job times should
979
                                                 * be assumed to be Unix time */
980
0
  int   qcount = 0,   /* Number of active queue entries */
981
0
      qalloc = 0;   /* Number of queue entries allocated */
982
0
  print_queue_struct *queue = NULL, /* Queue entries */
983
0
      *temp;    /* Temporary pointer for queue */
984
0
  const char  *user_name, /* job-originating-user-name attribute */
985
0
      *job_name;  /* job-name attribute */
986
0
  int   job_id;   /* job-id attribute */
987
0
  int   job_k_octets; /* job-k-octets attribute */
988
0
  time_t    job_time; /* time-at-creation attribute */
989
0
  time_t    printer_up_time = 0;  /* printer's uptime */
990
0
  ipp_jstate_t  job_status; /* job-status attribute */
991
0
  int   job_priority; /* job-priority attribute */
992
0
  static const char *jattrs[] = /* Requested job attributes */
993
0
      {
994
0
        "job-id",
995
0
        "job-k-octets",
996
0
        "job-name",
997
0
        "job-originating-user-name",
998
0
        "job-priority",
999
0
        "job-state",
1000
0
        "time-at-creation",
1001
0
      };
1002
0
  static const char *pattrs[] = /* Requested printer attributes */
1003
0
      {
1004
0
        "printer-state",
1005
0
        "printer-state-message",
1006
0
        "printer-current-time",
1007
0
        "printer-up-time"
1008
0
      };
1009
1010
0
  *q = NULL;
1011
1012
  /* HACK ALERT!!!  The problem with support the 'printer name'
1013
     option is that we key the tdb off the sharename.  So we will
1014
     overload the lpq_command string to pass in the printername
1015
     (which is basically what we do for non-cups printers ... using
1016
     the lpq_command to get the queue listing). */
1017
1018
0
  fstrcpy( printername, lpq_command );
1019
1020
0
  DEBUG(5,("iprint_queue_get(%s, %p, %p)\n", printername, q, status));
1021
1022
       /*
1023
  * Make sure we don't ask for passwords...
1024
  */
1025
1026
0
  cupsSetPasswordCB(iprint_passwd_cb);
1027
1028
       /*
1029
  * Try to connect to the server...
1030
  */
1031
1032
0
#ifdef HAVE_HTTPCONNECT2
1033
0
  http = httpConnect2(iprint_server(),
1034
0
          ippPort(),
1035
0
          NULL,
1036
0
          AF_UNSPEC,
1037
0
          HTTP_ENCRYPTION_NEVER,
1038
0
          1, /* blocking */
1039
0
          30 * 1000, /* timeout */
1040
0
          NULL);
1041
#else
1042
  http = httpConnect(iprint_server(), ippPort());
1043
#endif
1044
0
  if (http == NULL) {
1045
0
    DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
1046
0
       iprint_server(), strerror(errno)));
1047
0
    goto out;
1048
0
  }
1049
1050
       /*
1051
  * Generate the printer URI and the service URI that goes with it...
1052
  */
1053
1054
0
  slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), printername);
1055
0
  slprintf(serviceUri, sizeof(serviceUri) - 1, "ipp://%s/ipp/", iprint_server());
1056
1057
       /*
1058
  * For Linux iPrint servers from OES SP1 on, the iPrint server
1059
  * uses Unix time for job start times unless it detects the iPrint
1060
  * client in an http User-Agent header.  (This was done to accommodate
1061
  * CUPS broken behavior.  According to RFC 2911, section 4.3.14, job
1062
  * start times are supposed to be relative to how long the printer has
1063
  * been up.)  Since libcups doesn't allow us to set that header before
1064
  * the request is sent, this ugly hack allows us to detect the server
1065
  * version and decide how to interpret the job time.
1066
  */
1067
0
  if (iprint_get_server_version(http, serviceUri) >=
1068
0
      NOVELL_SERVER_VERSION_OES_SP1)
1069
0
    jobUseUnixTime = 1;
1070
1071
0
  request = ippNew();
1072
1073
0
  ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES);
1074
0
  ippSetRequestId(request, 2);
1075
1076
0
  language = cupsLangDefault();
1077
1078
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1079
0
               "attributes-charset", NULL, "utf-8");
1080
1081
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1082
0
               "attributes-natural-language", NULL, language->language);
1083
1084
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1085
0
               "printer-uri", NULL, uri);
1086
1087
0
  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1088
0
                "requested-attributes",
1089
0
                (sizeof(pattrs) / sizeof(pattrs[0])),
1090
0
                NULL, pattrs);
1091
1092
       /*
1093
  * Do the request and get back a response...
1094
  */
1095
1096
0
  slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername);
1097
1098
0
  if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
1099
0
    DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
1100
0
       ippErrorString(cupsLastError())));
1101
0
    *q = queue;
1102
0
    goto out;
1103
0
  }
1104
1105
0
  if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
1106
0
    DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
1107
0
       ippErrorString(ippGetStatusCode(response))));
1108
0
    *q = queue;
1109
0
    goto out;
1110
0
  }
1111
1112
       /*
1113
  * Get the current printer status and convert it to the SAMBA values.
1114
  */
1115
1116
0
  if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
1117
0
    if (ippGetInteger(attr, 0) == IPP_PRINTER_STOPPED)
1118
0
      status->status = LPSTAT_STOPPED;
1119
0
    else
1120
0
      status->status = LPSTAT_OK;
1121
0
  }
1122
1123
0
  if ((attr = ippFindAttribute(response, "printer-state-message",
1124
0
                               IPP_TAG_TEXT)) != NULL)
1125
0
    fstrcpy(status->message, ippGetString(attr, 0, NULL));
1126
1127
0
  if ((attr = ippFindAttribute(response, "printer-up-time",
1128
0
                               IPP_TAG_INTEGER)) != NULL)
1129
0
    printer_up_time = ippGetInteger(attr, 0);
1130
1131
0
  ippDelete(response);
1132
0
  response = NULL;
1133
1134
       /*
1135
  * Build an IPP_GET_JOBS request, which requires the following
1136
  * attributes:
1137
  *
1138
  *    attributes-charset
1139
  *    attributes-natural-language
1140
  *    requested-attributes
1141
  *    printer-uri
1142
  */
1143
1144
0
  request = ippNew();
1145
1146
0
  ippSetOperation(request, IPP_GET_JOBS);
1147
0
  ippSetRequestId(request, 3);
1148
1149
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1150
0
               "attributes-charset", NULL, "utf-8");
1151
1152
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1153
0
               "attributes-natural-language", NULL, language->language);
1154
1155
0
  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1156
0
               "printer-uri", NULL, uri);
1157
1158
0
  ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1159
0
                "requested-attributes",
1160
0
                (sizeof(jattrs) / sizeof(jattrs[0])),
1161
0
                NULL, jattrs);
1162
1163
       /*
1164
  * Do the request and get back a response...
1165
  */
1166
1167
0
  slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername);
1168
1169
0
  if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
1170
0
    DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
1171
0
       ippErrorString(cupsLastError())));
1172
0
    goto out;
1173
0
  }
1174
1175
0
  if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) {
1176
0
    DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
1177
0
       ippErrorString(ippGetStatusCode(response))));
1178
0
    goto out;
1179
0
  }
1180
1181
       /*
1182
  * Process the jobs...
1183
  */
1184
1185
0
  qcount = 0;
1186
0
  qalloc = 0;
1187
0
  queue  = NULL;
1188
1189
0
  for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response)) {
1190
         /*
1191
    * Skip leading attributes until we hit a job...
1192
    */
1193
1194
0
    while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_JOB)
1195
0
      attr = ippNextAttribute(response);
1196
1197
0
    if (attr == NULL)
1198
0
      break;
1199
1200
         /*
1201
    * Allocate memory as needed...
1202
    */
1203
0
    if (qcount >= qalloc) {
1204
0
      qalloc += 16;
1205
1206
0
      queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);
1207
1208
0
      if (queue == NULL) {
1209
0
        DEBUG(0,("iprint_queue_get: Not enough memory!\n"));
1210
0
        qcount = 0;
1211
0
        goto out;
1212
0
      }
1213
0
    }
1214
1215
0
    temp = queue + qcount;
1216
0
    memset(temp, 0, sizeof(print_queue_struct));
1217
1218
         /*
1219
    * Pull the needed attributes from this job...
1220
    */
1221
1222
0
    job_id       = 0;
1223
0
    job_priority = 50;
1224
0
    job_status   = IPP_JOB_PENDING;
1225
0
    job_time     = 0;
1226
0
    job_k_octets = 0;
1227
0
    user_name    = NULL;
1228
0
    job_name     = NULL;
1229
1230
0
    while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) {
1231
0
      if (ippGetName(attr) == NULL) {
1232
0
        attr = ippNextAttribute(response);
1233
0
        break;
1234
0
      }
1235
1236
0
      if (strcmp(ippGetName(attr), "job-id") == 0 &&
1237
0
          ippGetValueTag(attr) == IPP_TAG_INTEGER)
1238
0
        job_id = ippGetInteger(attr, 0);
1239
1240
0
      if (strcmp(ippGetName(attr), "job-k-octets") == 0 &&
1241
0
          ippGetValueTag(attr) == IPP_TAG_INTEGER)
1242
0
        job_k_octets = ippGetInteger(attr, 0);
1243
1244
0
      if (strcmp(ippGetName(attr), "job-priority") == 0 &&
1245
0
          ippGetValueTag(attr) == IPP_TAG_INTEGER)
1246
0
        job_priority = ippGetInteger(attr, 0);
1247
1248
0
      if (strcmp(ippGetName(attr), "job-state") == 0 &&
1249
0
          ippGetValueTag(attr) == IPP_TAG_ENUM)
1250
0
        job_status = (ipp_jstate_t)ippGetInteger(attr, 0);
1251
1252
0
      if (strcmp(ippGetName(attr), "time-at-creation") == 0 &&
1253
0
          ippGetValueTag(attr) == IPP_TAG_INTEGER)
1254
0
      {
1255
             /*
1256
        * If jobs times are in Unix time, the accuracy of the job
1257
        * start time depends upon the iPrint server's time being
1258
        * set correctly.  Otherwise, the accuracy depends upon
1259
        * the Samba server's time being set correctly
1260
        */
1261
1262
0
        if (jobUseUnixTime)
1263
0
          job_time = ippGetInteger(attr, 0);
1264
0
        else
1265
0
          job_time = time(NULL) - printer_up_time + ippGetInteger(attr, 0);
1266
0
      }
1267
1268
0
      if (strcmp(ippGetName(attr), "job-name") == 0 &&
1269
0
          (ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
1270
0
           ippGetValueTag(attr) == IPP_TAG_NAME))
1271
0
        job_name = ippGetString(attr, 0, NULL);
1272
1273
0
      if (strcmp(ippGetName(attr), "job-originating-user-name") == 0 &&
1274
0
          (ippGetValueTag(attr) == IPP_TAG_NAMELANG ||
1275
0
           ippGetValueTag(attr) == IPP_TAG_NAME))
1276
0
        user_name = ippGetString(attr, 0, NULL);
1277
1278
0
      attr = ippNextAttribute(response);
1279
0
    }
1280
1281
         /*
1282
    * See if we have everything needed...
1283
    */
1284
1285
0
    if (user_name == NULL || job_name == NULL || job_id == 0) {
1286
0
      if (attr == NULL)
1287
0
        break;
1288
0
      else
1289
0
        continue;
1290
0
    }
1291
1292
0
    temp->sysjob   = job_id;
1293
0
    temp->size     = job_k_octets * 1024;
1294
0
    temp->status   = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
1295
0
                     job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
1296
0
                                 job_status == IPP_JOB_HELD ? LPQ_PAUSED :
1297
0
                                 LPQ_PRINTING;
1298
0
    temp->priority = job_priority;
1299
0
    temp->time     = job_time;
1300
0
    strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
1301
0
    strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);
1302
1303
0
    qcount ++;
1304
1305
0
    if (attr == NULL)
1306
0
      break;
1307
0
  }
1308
1309
       /*
1310
  * Return the job queue...
1311
  */
1312
1313
0
  *q = queue;
1314
1315
0
 out:
1316
0
  if (response)
1317
0
    ippDelete(response);
1318
1319
0
  if (language)
1320
0
    cupsLangFree(language);
1321
1322
0
  if (http)
1323
0
    httpClose(http);
1324
1325
0
  return qcount;
1326
0
}
1327
1328
1329
/*
1330
 * 'iprint_queue_pause()' - Pause a print queue.
1331
 */
1332
1333
static int iprint_queue_pause(int snum)
1334
0
{
1335
0
  return(-1); /* Not supported without credentials */
1336
0
}
1337
1338
1339
/*
1340
 * 'iprint_queue_resume()' - Restart a print queue.
1341
 */
1342
1343
static int iprint_queue_resume(int snum)
1344
0
{
1345
0
  return(-1); /* Not supported without credentials */
1346
0
}
1347
1348
/*******************************************************************
1349
 * iPrint printing interface definitions...
1350
 ******************************************************************/
1351
1352
struct printif  iprint_printif =
1353
{
1354
  PRINT_IPRINT,
1355
  iprint_queue_get,
1356
  iprint_queue_pause,
1357
  iprint_queue_resume,
1358
  iprint_job_delete,
1359
  iprint_job_pause,
1360
  iprint_job_resume,
1361
  iprint_job_submit,
1362
};
1363
1364
#else
1365
 /* this keeps fussy compilers happy */
1366
 void print_iprint_dummy(void);
1367
 void print_iprint_dummy(void) {}
1368
#endif /* HAVE_IPRINT */