Changeset 597 for vendor/current/source3/printing
- Timestamp:
- Jul 2, 2011, 4:01:14 PM (14 years ago)
- Location:
- vendor/current/source3/printing
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/printing/load.c
r587 r597 54 54 55 55 /*************************************************************************** 56 load automatic printer services 56 load automatic printer services from pre-populated pcap cache 57 57 ***************************************************************************/ 58 58 void load_printers(void) 59 59 { 60 if (!pcap_cache_loaded())61 pcap_cache_reload();62 63 60 add_auto_printers(); 64 61 -
vendor/current/source3/printing/nt_printing.c
r594 r597 92 92 {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c}, 93 93 {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc}, 94 {"A0",0x1,0xcd528,0x122488,0x0,0x0,0xcd528,0x122488},95 {"A1",0x1,0x91050,0xcd528,0x0,0x0,0x91050,0xcd528},96 94 {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0}, 97 95 {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828}, -
vendor/current/source3/printing/pcap.c
r414 r597 126 126 } 127 127 128 void pcap_cache_reload(void )128 void pcap_cache_reload(void (*post_cache_fill_fn)(void)) 129 129 { 130 130 const char *pcap_name = lp_printcapname(); … … 133 133 XFILE *pcap_file; 134 134 char *pcap_line; 135 bool post_cache_fill_fn_handled = false; 135 136 136 137 DEBUG(3, ("reloading printcap cache\n")); … … 147 148 #ifdef HAVE_CUPS 148 149 if (strequal(pcap_name, "cups")) { 149 pcap_reloaded = cups_cache_reload(); 150 pcap_reloaded = cups_cache_reload(post_cache_fill_fn); 151 /* 152 * cups_cache_reload() is async and calls post_cache_fill_fn() 153 * on successful completion 154 */ 155 post_cache_fill_fn_handled = true; 150 156 goto done; 151 157 } … … 204 210 has_punctuation = (strchr_m(p, ' ') || 205 211 strchr_m(p, '\t') || 212 strchr_m(p, '"') || 213 strchr_m(p, '\'') || 214 strchr_m(p, ';') || 215 strchr_m(p, ',') || 206 216 strchr_m(p, '(') || 207 217 strchr_m(p, ')')); … … 212 222 } 213 223 214 if (strlen(p) <= MAXPRINTERLEN && 215 strlen(p) > strlen(name) && !has_punctuation) { 224 if (strlen(p) <= MAXPRINTERLEN && *name == '\0' && !has_punctuation) { 216 225 if (!*comment) { 217 226 strlcpy(comment, name, sizeof(comment)); … … 228 237 } 229 238 230 comment[60] = 0;231 name[MAXPRINTERLEN] = 0;232 233 239 if (*name && !pcap_cache_add(name, comment)) { 234 240 x_fclose(pcap_file); … … 243 249 DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error")); 244 250 245 if (pcap_reloaded) 251 if (pcap_reloaded) { 246 252 pcap_cache_destroy_specific(&tmp_cache); 247 else { 253 if ((post_cache_fill_fn_handled == false) 254 && (post_cache_fill_fn != NULL)) { 255 post_cache_fill_fn(); 256 } 257 } else { 248 258 pcap_cache_destroy_specific(&pcap_cache); 249 259 pcap_cache = tmp_cache; -
vendor/current/source3/printing/print_cups.c
r478 r597 25 25 #include "includes.h" 26 26 #include "printing.h" 27 #include "librpc/gen_ndr/ndr_printcap.h" 27 28 28 29 #ifdef HAVE_CUPS … … 112 113 } 113 114 114 static void send_pcap_info(const char *name, const char *info, void *pd) 115 { 116 int fd = *(int *)pd; 117 size_t namelen = name ? strlen(name)+1 : 0; 118 size_t infolen = info ? strlen(info)+1 : 0; 119 120 DEBUG(11,("send_pcap_info: writing namelen %u\n", (unsigned int)namelen)); 121 if (sys_write(fd, &namelen, sizeof(namelen)) != sizeof(namelen)) { 122 DEBUG(10,("send_pcap_info: namelen write failed %s\n", 123 strerror(errno))); 124 return; 125 } 126 DEBUG(11,("send_pcap_info: writing infolen %u\n", (unsigned int)infolen)); 127 if (sys_write(fd, &infolen, sizeof(infolen)) != sizeof(infolen)) { 128 DEBUG(10,("send_pcap_info: infolen write failed %s\n", 129 strerror(errno))); 130 return; 131 } 132 if (namelen) { 133 DEBUG(11,("send_pcap_info: writing name %s\n", name)); 134 if (sys_write(fd, name, namelen) != namelen) { 135 DEBUG(10,("send_pcap_info: name write failed %s\n", 136 strerror(errno))); 137 return; 138 } 139 } 140 if (infolen) { 141 DEBUG(11,("send_pcap_info: writing info %s\n", info)); 142 if (sys_write(fd, info, infolen) != infolen) { 143 DEBUG(10,("send_pcap_info: info write failed %s\n", 144 strerror(errno))); 145 return; 146 } 147 } 115 static bool send_pcap_blob(DATA_BLOB *pcap_blob, int fd) 116 { 117 size_t ret; 118 119 ret = sys_write(fd, &pcap_blob->length, sizeof(pcap_blob->length)); 120 if (ret != sizeof(pcap_blob->length)) { 121 return false; 122 } 123 124 ret = sys_write(fd, pcap_blob->data, pcap_blob->length); 125 if (ret != pcap_blob->length) { 126 return false; 127 } 128 129 DEBUG(10, ("successfully sent blob of len %ld\n", (int64_t)ret)); 130 return true; 148 131 } 149 132 133 static bool recv_pcap_blob(TALLOC_CTX *mem_ctx, int fd, DATA_BLOB *pcap_blob) 134 { 135 size_t blob_len; 136 size_t ret; 137 138 ret = sys_read(fd, &blob_len, sizeof(blob_len)); 139 if (ret != sizeof(blob_len)) { 140 return false; 141 } 142 143 *pcap_blob = data_blob_talloc_named(mem_ctx, NULL, blob_len, 144 "cups pcap"); 145 if (pcap_blob->length != blob_len) { 146 return false; 147 } 148 ret = sys_read(fd, pcap_blob->data, blob_len); 149 if (ret != blob_len) { 150 talloc_free(pcap_blob->data); 151 return false; 152 } 153 154 DEBUG(10, ("successfully recvd blob of len %ld\n", (int64_t)ret)); 155 return true; 156 } 157 158 static bool process_cups_printers_response(TALLOC_CTX *mem_ctx, 159 ipp_t *response, 160 struct pcap_data *pcap_data) 161 { 162 ipp_attribute_t *attr; 163 char *name; 164 char *info; 165 struct pcap_printer *printer; 166 bool ret_ok = false; 167 168 for (attr = response->attrs; attr != NULL;) { 169 /* 170 * Skip leading attributes until we hit a printer... 171 */ 172 173 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) 174 attr = attr->next; 175 176 if (attr == NULL) 177 break; 178 179 /* 180 * Pull the needed attributes from this printer... 181 */ 182 183 name = NULL; 184 info = NULL; 185 186 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { 187 size_t size; 188 if (strcmp(attr->name, "printer-name") == 0 && 189 attr->value_tag == IPP_TAG_NAME) { 190 if (!pull_utf8_talloc(mem_ctx, 191 &name, 192 attr->values[0].string.text, 193 &size)) { 194 goto err_out; 195 } 196 } 197 198 if (strcmp(attr->name, "printer-info") == 0 && 199 attr->value_tag == IPP_TAG_TEXT) { 200 if (!pull_utf8_talloc(mem_ctx, 201 &info, 202 attr->values[0].string.text, 203 &size)) { 204 goto err_out; 205 } 206 } 207 208 attr = attr->next; 209 } 210 211 /* 212 * See if we have everything needed... 213 */ 214 215 if (name == NULL) 216 break; 217 218 if (pcap_data->count == 0) { 219 printer = talloc_array(mem_ctx, struct pcap_printer, 1); 220 } else { 221 printer = talloc_realloc(mem_ctx, pcap_data->printers, 222 struct pcap_printer, 223 pcap_data->count + 1); 224 } 225 if (printer == NULL) { 226 goto err_out; 227 } 228 pcap_data->printers = printer; 229 pcap_data->printers[pcap_data->count].name = name; 230 pcap_data->printers[pcap_data->count].info = info; 231 pcap_data->count++; 232 } 233 234 ret_ok = true; 235 err_out: 236 return ret_ok; 237 } 238 239 /* 240 * request printer list from cups, send result back to up parent via fd. 241 * returns true if the (possibly failed) result was successfuly sent to parent. 242 */ 150 243 static bool cups_cache_reload_async(int fd) 151 244 { 152 245 TALLOC_CTX *frame = talloc_stackframe(); 153 struct pcap_ cache *tmp_pcap_cache = NULL;246 struct pcap_data pcap_data; 154 247 http_t *http = NULL; /* HTTP connection to server */ 155 248 ipp_t *request = NULL, /* IPP Request */ 156 249 *response = NULL; /* IPP Response */ 157 ipp_attribute_t *attr; /* Current attribute */158 250 cups_lang_t *language = NULL; /* Default language */ 159 char *name, /* printer-name attribute */160 *info; /* printer-info attribute */161 251 static const char *requested[] =/* Requested attributes */ 162 252 { … … 165 255 }; 166 256 bool ret = False; 167 size_t size; 257 enum ndr_err_code ndr_ret; 258 DATA_BLOB pcap_blob; 259 260 ZERO_STRUCT(pcap_data); 261 pcap_data.status = NT_STATUS_UNSUCCESSFUL; 168 262 169 263 DEBUG(5, ("reloading cups printcap cache\n")); … … 174 268 175 269 cupsSetPasswordCB(cups_passwd_cb); 176 177 /*178 * Try to connect to the server...179 */180 270 181 271 if ((http = cups_connect(frame)) == NULL) { … … 210 300 NULL, requested); 211 301 212 /*213 * Do the request and get back a response...214 */215 216 302 if ((response = cupsDoRequest(http, request, "/")) == NULL) { 217 303 DEBUG(0,("Unable to get printer list - %s\n", … … 220 306 } 221 307 222 for (attr = response->attrs; attr != NULL;) { 223 /* 224 * Skip leading attributes until we hit a printer... 225 */ 226 227 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) 228 attr = attr->next; 229 230 if (attr == NULL) 231 break; 232 233 /* 234 * Pull the needed attributes from this printer... 235 */ 236 237 name = NULL; 238 info = NULL; 239 240 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { 241 if (strcmp(attr->name, "printer-name") == 0 && 242 attr->value_tag == IPP_TAG_NAME) { 243 if (!pull_utf8_talloc(frame, 244 &name, 245 attr->values[0].string.text, 246 &size)) { 247 goto out; 248 } 249 } 250 251 if (strcmp(attr->name, "printer-info") == 0 && 252 attr->value_tag == IPP_TAG_TEXT) { 253 if (!pull_utf8_talloc(frame, 254 &info, 255 attr->values[0].string.text, 256 &size)) { 257 goto out; 258 } 259 } 260 261 attr = attr->next; 262 } 263 264 /* 265 * See if we have everything needed... 266 */ 267 268 if (name == NULL) 269 break; 270 271 if (!pcap_cache_add_specific(&tmp_pcap_cache, name, info)) { 272 goto out; 273 } 308 ret = process_cups_printers_response(frame, response, &pcap_data); 309 if (!ret) { 310 DEBUG(0,("failed to process cups response\n")); 311 goto out; 274 312 } 275 313 … … 302 340 NULL, requested); 303 341 304 /*305 * Do the request and get back a response...306 */307 308 342 if ((response = cupsDoRequest(http, request, "/")) == NULL) { 309 343 DEBUG(0,("Unable to get printer list - %s\n", … … 312 346 } 313 347 314 for (attr = response->attrs; attr != NULL;) { 315 /* 316 * Skip leading attributes until we hit a printer... 317 */ 318 319 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) 320 attr = attr->next; 321 322 if (attr == NULL) 323 break; 324 325 /* 326 * Pull the needed attributes from this printer... 327 */ 328 329 name = NULL; 330 info = NULL; 331 332 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { 333 if (strcmp(attr->name, "printer-name") == 0 && 334 attr->value_tag == IPP_TAG_NAME) { 335 if (!pull_utf8_talloc(frame, 336 &name, 337 attr->values[0].string.text, 338 &size)) { 339 goto out; 340 } 341 } 342 343 if (strcmp(attr->name, "printer-info") == 0 && 344 attr->value_tag == IPP_TAG_TEXT) { 345 if (!pull_utf8_talloc(frame, 346 &info, 347 attr->values[0].string.text, 348 &size)) { 349 goto out; 350 } 351 } 352 353 attr = attr->next; 354 } 355 356 /* 357 * See if we have everything needed... 358 */ 359 360 if (name == NULL) 361 break; 362 363 if (!pcap_cache_add_specific(&tmp_pcap_cache, name, info)) { 364 goto out; 365 } 366 } 367 368 ret = True; 369 348 ret = process_cups_printers_response(frame, response, &pcap_data); 349 if (!ret) { 350 DEBUG(0,("failed to process cups response\n")); 351 goto out; 352 } 353 354 pcap_data.status = NT_STATUS_OK; 370 355 out: 371 356 if (response) … … 378 363 httpClose(http); 379 364 380 /* Send all the entries up the pipe. */ 381 if (tmp_pcap_cache) { 382 pcap_printer_fn_specific(tmp_pcap_cache, 383 send_pcap_info, 384 (void *)&fd); 385 386 pcap_cache_destroy_specific(&tmp_pcap_cache); 387 } 365 ret = false; 366 ndr_ret = ndr_push_struct_blob(&pcap_blob, frame, NULL, &pcap_data, 367 (ndr_push_flags_fn_t)ndr_push_pcap_data); 368 if (ndr_ret == NDR_ERR_SUCCESS) { 369 ret = send_pcap_blob(&pcap_blob, fd); 370 } 371 388 372 TALLOC_FREE(frame); 389 373 return ret; … … 446 430 } 447 431 432 struct cups_async_cb_args { 433 int pipe_fd; 434 void (*post_cache_fill_fn)(void); 435 }; 436 448 437 static void cups_async_callback(struct event_context *event_ctx, 449 438 struct fd_event *event, … … 452 441 { 453 442 TALLOC_CTX *frame = talloc_stackframe(); 454 int fd = *(int*)p;443 struct cups_async_cb_args *cb_args = (struct cups_async_cb_args *)p; 455 444 struct pcap_cache *tmp_pcap_cache = NULL; 445 bool ret_ok; 446 struct pcap_data pcap_data; 447 DATA_BLOB pcap_blob; 448 enum ndr_err_code ndr_ret; 449 int i; 456 450 457 451 DEBUG(5,("cups_async_callback: callback received for printer data. " 458 "fd = %d\n", fd)); 459 460 while (1) { 461 char *name = NULL, *info = NULL; 462 size_t namelen = 0, infolen = 0; 463 ssize_t ret = -1; 464 465 ret = sys_read(fd, &namelen, sizeof(namelen)); 466 if (ret == 0) { 467 /* EOF */ 452 "fd = %d\n", cb_args->pipe_fd)); 453 454 ret_ok = recv_pcap_blob(frame, cb_args->pipe_fd, &pcap_blob); 455 if (!ret_ok) { 456 DEBUG(0,("failed to recv pcap blob\n")); 457 goto err_out; 458 } 459 460 ndr_ret = ndr_pull_struct_blob(&pcap_blob, frame, NULL, &pcap_data, 461 (ndr_pull_flags_fn_t)ndr_pull_pcap_data); 462 if (ndr_ret != NDR_ERR_SUCCESS) { 463 goto err_out; 464 } 465 466 if (!NT_STATUS_IS_OK(pcap_data.status)) { 467 DEBUG(0,("failed to retrieve printer list: %s\n", 468 nt_errstr(pcap_data.status))); 469 goto err_out; 470 } 471 472 for (i = 0; i < pcap_data.count; i++) { 473 ret_ok = pcap_cache_add_specific(&tmp_pcap_cache, 474 pcap_data.printers[i].name, 475 pcap_data.printers[i].info); 476 if (!ret_ok) { 477 DEBUG(0, ("failed to add to tmp pcap cache\n")); 468 478 break; 469 479 } 470 if (ret != sizeof(namelen)) { 471 DEBUG(10,("cups_async_callback: namelen read failed %d %s\n", 472 errno, strerror(errno))); 473 break; 474 } 475 476 DEBUG(11,("cups_async_callback: read namelen %u\n", 477 (unsigned int)namelen)); 478 479 ret = sys_read(fd, &infolen, sizeof(infolen)); 480 if (ret == 0) { 481 /* EOF */ 482 break; 483 } 484 if (ret != sizeof(infolen)) { 485 DEBUG(10,("cups_async_callback: infolen read failed %s\n", 486 strerror(errno))); 487 break; 488 } 489 490 DEBUG(11,("cups_async_callback: read infolen %u\n", 491 (unsigned int)infolen)); 492 493 if (namelen) { 494 name = TALLOC_ARRAY(frame, char, namelen); 495 if (!name) { 496 break; 497 } 498 ret = sys_read(fd, name, namelen); 499 if (ret == 0) { 500 /* EOF */ 501 break; 502 } 503 if (ret != namelen) { 504 DEBUG(10,("cups_async_callback: name read failed %s\n", 505 strerror(errno))); 506 break; 507 } 508 DEBUG(11,("cups_async_callback: read name %s\n", 509 name)); 510 } else { 511 name = NULL; 512 } 513 if (infolen) { 514 info = TALLOC_ARRAY(frame, char, infolen); 515 if (!info) { 516 break; 517 } 518 ret = sys_read(fd, info, infolen); 519 if (ret == 0) { 520 /* EOF */ 521 break; 522 } 523 if (ret != infolen) { 524 DEBUG(10,("cups_async_callback: info read failed %s\n", 525 strerror(errno))); 526 break; 527 } 528 DEBUG(11,("cups_async_callback: read info %s\n", 529 info)); 530 } else { 531 info = NULL; 532 } 533 534 /* Add to our local pcap cache. */ 535 pcap_cache_add_specific(&tmp_pcap_cache, name, info); 536 TALLOC_FREE(name); 537 TALLOC_FREE(info); 538 } 539 540 TALLOC_FREE(frame); 541 if (tmp_pcap_cache) { 542 /* We got a namelist, replace our local cache. */ 480 } 481 482 if (!ret_ok) { 483 DEBUG(0,("failed to read a new printer list\n")); 484 pcap_cache_destroy_specific(&tmp_pcap_cache); 485 } else { 486 /* We got a possibly empty namelist, replace our local cache. */ 543 487 pcap_cache_destroy_specific(&local_pcap_copy); 544 488 local_pcap_copy = tmp_pcap_cache; … … 546 490 /* And the systemwide pcap cache. */ 547 491 pcap_cache_replace(local_pcap_copy); 548 } else { 549 DEBUG(2,("cups_async_callback: failed to read a new " 550 "printer list\n")); 551 } 552 close(fd); 553 TALLOC_FREE(p); 492 493 /* Caller may have requested post cache fill callback */ 494 if (cb_args->post_cache_fill_fn) { 495 cb_args->post_cache_fill_fn(); 496 } 497 } 498 err_out: 499 TALLOC_FREE(frame); 500 close(cb_args->pipe_fd); 501 TALLOC_FREE(cb_args); 554 502 TALLOC_FREE(cache_fd_event); 555 503 } 556 504 557 bool cups_cache_reload(void) 558 { 559 int *p_pipe_fd = TALLOC_P(NULL, int); 560 561 if (!p_pipe_fd) { 505 bool cups_cache_reload(void (*post_cache_fill_fn)(void)) 506 { 507 struct cups_async_cb_args *cb_args; 508 int *p_pipe_fd; 509 510 cb_args = TALLOC_P(NULL, struct cups_async_cb_args); 511 if (!cb_args) { 562 512 return false; 563 513 } 564 514 cb_args->post_cache_fill_fn = post_cache_fill_fn; 515 p_pipe_fd = &cb_args->pipe_fd; 565 516 *p_pipe_fd = -1; 566 517 567 518 /* Set up an async refresh. */ 568 519 if (!cups_pcap_load_async(p_pipe_fd)) { 520 talloc_free(cb_args); 569 521 return false; 570 522 } … … 579 531 NULL, 580 532 EVENT_FD_READ, 581 (void *) p_pipe_fd);533 (void *)cb_args); 582 534 if (!local_pcap_copy) { 583 535 return false; … … 596 548 EVENT_FD_READ, 597 549 cups_async_callback, 598 (void *) p_pipe_fd);550 (void *)cb_args); 599 551 if (!cache_fd_event) { 600 552 close(*p_pipe_fd); 601 TALLOC_FREE(p_pipe_fd);553 talloc_free(cb_args); 602 554 return false; 603 555 } … … 1641 1593 cups_lang_t *language = NULL; /* Default language */ 1642 1594 char uri[HTTP_MAX_URI]; 1643 char *server = NULL;1644 1595 char *sharename = NULL; 1645 1596 char *name = NULL; … … 1682 1633 "attributes-natural-language", NULL, language->language); 1683 1634 1684 if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) {1685 if (!push_utf8_talloc(frame, &server, lp_cups_server(), &size)) {1686 goto out;1687 }1688 } else {1689 server = talloc_strdup(frame,cupsServer());1690 }1691 if (server) {1692 goto out;1693 }1694 1635 if (!push_utf8_talloc(frame, &sharename, printer->sharename, &size)) { 1695 1636 goto out; 1696 1637 } 1697 slprintf(uri, sizeof(uri) - 1, "ipp:// %s/printers/%s",1698 s erver, sharename);1638 slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", 1639 sharename); 1699 1640 1700 1641 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, … … 1797 1738 ippDelete(response); 1798 1739 1799 if (request) {1800 ippDelete(request);1801 }1802 1803 1740 if (language) 1804 1741 cupsLangFree(language);
Note:
See TracChangeset
for help on using the changeset viewer.