~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/printing/print_iprint.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

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