Coverage Report

Created: 2026-02-14 07:07

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