Changeset 740 for vendor/current/source3/printing/pcap.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source3/printing/pcap.c
r597 r740 27 27 28 28 /* 29 * This module contains code to parse and cache printcap data, possibly30 * in concert with the CUPS/SYSV/AIX-specific code found elsewhere.31 *32 * The way this module looks at the printcap file is very simplistic.33 * Only the local printcap file is inspected (no searching of NIS34 * databases etc).35 *36 * There are assumed to be one or more printer names per record, held37 * as a set of sub-fields separated by vertical bar symbols ('|') in the38 * first field of the record. The field separator is assumed to be a colon39 * ':' and the record separator a newline.40 *41 * Lines ending with a backspace '\' are assumed to flag that the following42 * line is a continuation line so that a set of lines can be read as one43 * printcap entry.44 *45 * A line stating with a hash '#' is assumed to be a comment and is ignored46 * Comments are discarded before the record is strung together from the47 * set of continuation lines.48 *49 * Opening a pipe for "lpc status" and reading that would probably50 * be pretty effective. Code to do this already exists in the freely51 * distributable PCNFS server code.52 *53 29 * Modified to call SVID/XPG4 support if printcap name is set to "lpstat" 54 30 * in smb.conf under Solaris. … … 62 38 63 39 #include "includes.h" 64 40 #include "printing/pcap.h" 41 #include "printer_list.h" 65 42 66 43 struct pcap_cache { 67 44 char *name; 68 45 char *comment; 46 char *location; 69 47 struct pcap_cache *next; 70 48 }; 71 49 72 /* The systemwide printcap cache. */ 73 static struct pcap_cache *pcap_cache = NULL; 74 75 bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment) 50 bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment, const char *location) 76 51 { 77 52 struct pcap_cache *p; … … 82 57 p->name = SMB_STRDUP(name); 83 58 p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL; 84 85 DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s\n", 86 p->name, p->comment ? p->comment : "")); 59 p->location = (location && *location) ? SMB_STRDUP(location) : NULL; 60 61 DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s, location: %s\n", 62 p->name, p->comment ? p->comment : "", 63 p->location ? p->location : "")); 87 64 88 65 p->next = *ppcache; … … 101 78 SAFE_FREE(p->name); 102 79 SAFE_FREE(p->comment); 80 SAFE_FREE(p->location); 103 81 SAFE_FREE(p); 104 82 } … … 106 84 } 107 85 108 bool pcap_cache_add(const char *name, const char *comment) 109 { 110 return pcap_cache_add_specific(&pcap_cache, name, comment); 86 bool pcap_cache_add(const char *name, const char *comment, const char *location) 87 { 88 NTSTATUS status; 89 time_t t = time_mono(NULL); 90 91 status = printer_list_set_printer(talloc_tos(), name, comment, location, t); 92 return NT_STATUS_IS_OK(status); 111 93 } 112 94 113 95 bool pcap_cache_loaded(void) 114 96 { 115 return (pcap_cache != NULL); 116 } 117 118 void pcap_cache_replace(const struct pcap_cache *pcache) 97 NTSTATUS status; 98 time_t last; 99 100 status = printer_list_get_last_refresh(&last); 101 return NT_STATUS_IS_OK(status); 102 } 103 104 bool pcap_cache_replace(const struct pcap_cache *pcache) 119 105 { 120 106 const struct pcap_cache *p; 121 122 pcap_cache_destroy_specific(&pcap_cache); 107 NTSTATUS status; 108 109 status = printer_list_mark_reload(); 110 if (!NT_STATUS_IS_OK(status)) { 111 DEBUG(0, ("Failed to mark printer list for reload!\n")); 112 return false; 113 } 114 123 115 for (p = pcache; p; p = p->next) { 124 pcap_cache_add(p->name, p->comment); 125 } 126 } 127 128 void pcap_cache_reload(void (*post_cache_fill_fn)(void)) 116 pcap_cache_add(p->name, p->comment, p->location); 117 } 118 119 status = printer_list_clean_old(); 120 if (!NT_STATUS_IS_OK(status)) { 121 DEBUG(0, ("Failed to cleanup printer list!\n")); 122 return false; 123 } 124 125 return true; 126 } 127 128 void pcap_cache_reload(struct tevent_context *ev, 129 struct messaging_context *msg_ctx, 130 void (*post_cache_fill_fn)(struct tevent_context *, 131 struct messaging_context *)) 129 132 { 130 133 const char *pcap_name = lp_printcapname(); 131 134 bool pcap_reloaded = False; 132 struct pcap_cache *tmp_cache = NULL; 133 XFILE *pcap_file; 134 char *pcap_line; 135 NTSTATUS status; 135 136 bool post_cache_fill_fn_handled = false; 136 137 … … 143 144 } 144 145 145 tmp_cache = pcap_cache; 146 pcap_cache = NULL; 146 status = printer_list_mark_reload(); 147 if (!NT_STATUS_IS_OK(status)) { 148 DEBUG(0, ("Failed to mark printer list for reload!\n")); 149 return; 150 } 147 151 148 152 #ifdef HAVE_CUPS 149 153 if (strequal(pcap_name, "cups")) { 150 pcap_reloaded = cups_cache_reload(post_cache_fill_fn); 154 pcap_reloaded = cups_cache_reload(ev, msg_ctx, 155 post_cache_fill_fn); 151 156 /* 152 157 * cups_cache_reload() is async and calls post_cache_fill_fn() … … 179 184 #endif 180 185 181 /* handle standard printcap - moved from pcap_printer_fn() */ 182 183 if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) { 184 DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name)); 185 goto done; 186 } 187 188 for (; (pcap_line = fgets_slash(NULL, 1024, pcap_file)) != NULL; free(pcap_line)) { 189 char name[MAXPRINTERLEN+1]; 190 char comment[62]; 191 char *p, *q; 192 193 if (*pcap_line == '#' || *pcap_line == 0) 194 continue; 195 196 /* now we have a real printer line - cut at the first : */ 197 if ((p = strchr_m(pcap_line, ':')) != NULL) 198 *p = 0; 199 200 /* 201 * now find the most likely printer name and comment 202 * this is pure guesswork, but it's better than nothing 203 */ 204 for (*name = *comment = 0, p = pcap_line; p != NULL; p = q) { 205 bool has_punctuation; 206 207 if ((q = strchr_m(p, '|')) != NULL) 208 *q++ = 0; 209 210 has_punctuation = (strchr_m(p, ' ') || 211 strchr_m(p, '\t') || 212 strchr_m(p, '"') || 213 strchr_m(p, '\'') || 214 strchr_m(p, ';') || 215 strchr_m(p, ',') || 216 strchr_m(p, '(') || 217 strchr_m(p, ')')); 218 219 if (strlen(p) > strlen(comment) && has_punctuation) { 220 strlcpy(comment, p, sizeof(comment)); 221 continue; 222 } 223 224 if (strlen(p) <= MAXPRINTERLEN && *name == '\0' && !has_punctuation) { 225 if (!*comment) { 226 strlcpy(comment, name, sizeof(comment)); 227 } 228 strlcpy(name, p, sizeof(name)); 229 continue; 230 } 231 232 if (!strchr_m(comment, ' ') && 233 strlen(p) > strlen(comment)) { 234 strlcpy(comment, p, sizeof(comment)); 235 continue; 236 } 237 } 238 239 if (*name && !pcap_cache_add(name, comment)) { 240 x_fclose(pcap_file); 241 goto done; 242 } 243 } 244 245 x_fclose(pcap_file); 246 pcap_reloaded = True; 186 pcap_reloaded = std_pcap_cache_reload(pcap_name); 247 187 248 188 done: 249 189 DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error")); 250 190 251 if (pcap_reloaded) { 252 pcap_cache_destroy_specific(&tmp_cache); 253 if ((post_cache_fill_fn_handled == false) 254 && (post_cache_fill_fn != NULL)) { 255 post_cache_fill_fn(); 191 if ((pcap_reloaded) && (post_cache_fill_fn_handled == false)) { 192 /* cleanup old entries only if the operation was successful, 193 * otherwise keep around the old entries until we can 194 * successfuly reaload */ 195 status = printer_list_clean_old(); 196 if (!NT_STATUS_IS_OK(status)) { 197 DEBUG(0, ("Failed to cleanup printer list!\n")); 256 198 } 257 } else{258 pcap_cache_destroy_specific(&pcap_cache);259 pcap_cache = tmp_cache;199 if (post_cache_fill_fn != NULL) { 200 post_cache_fill_fn(ev, msg_ctx); 201 } 260 202 } 261 203 … … 266 208 bool pcap_printername_ok(const char *printername) 267 209 { 268 struct pcap_cache *p; 269 270 for (p = pcap_cache; p != NULL; p = p->next) 271 if (strequal(p->name, printername)) 272 return True; 273 274 return False; 210 NTSTATUS status; 211 212 status = printer_list_get_printer(talloc_tos(), printername, NULL, NULL, 0); 213 return NT_STATUS_IS_OK(status); 275 214 } 276 215 … … 280 219 281 220 void pcap_printer_fn_specific(const struct pcap_cache *pc, 282 void (*fn)(const char *, const char *, void *),221 void (*fn)(const char *, const char *, const char *, void *), 283 222 void *pdata) 284 223 { … … 286 225 287 226 for (p = pc; p != NULL; p = p->next) 288 fn(p->name, p->comment, p data);227 fn(p->name, p->comment, p->location, pdata); 289 228 290 229 return; 291 230 } 292 231 293 void pcap_printer_fn(void (*fn)(const char *, const char *, void *), void *pdata) 294 { 295 pcap_printer_fn_specific(pcap_cache, fn, pdata); 296 } 232 void pcap_printer_fn(void (*fn)(const char *, const char *, const char *, void *), void *pdata) 233 { 234 NTSTATUS status; 235 236 status = printer_list_run_fn(fn, pdata); 237 if (!NT_STATUS_IS_OK(status)) { 238 DEBUG(3, ("Failed to run fn for all printers!\n")); 239 } 240 return; 241 }
Note:
See TracChangeset
for help on using the changeset viewer.