static void cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */ { _cups_buffer_t *buffer, /* Current read/write buffer */ *next; /* Next buffer */ if (cg->last_status_message) _cupsStrFree(cg->last_status_message); for (buffer = cg->cups_buffers; buffer; buffer = next) { next = buffer->next; free(buffer); } cupsArrayDelete(cg->leg_size_lut); cupsArrayDelete(cg->ppd_size_lut); cupsArrayDelete(cg->pwg_size_lut); httpClose(cg->http); _httpFreeCredentials(cg->tls_credentials); cupsFileClose(cg->stdio_files[0]); cupsFileClose(cg->stdio_files[1]); cupsFileClose(cg->stdio_files[2]); cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings); free(cg); }
static void free_policy(cupsd_policy_t *p) /* I - Policy to free */ { cupsArrayDelete(p->job_access); cupsArrayDelete(p->job_attrs); cupsArrayDelete(p->sub_access); cupsArrayDelete(p->sub_attrs); cupsArrayDelete(p->ops); cupsdClearString(&p->name); free(p); }
int /* O - Number of conflicting options */ cupsGetConflicts( ppd_file_t *ppd, /* I - PPD file */ const char *option, /* I - Option to test */ const char *choice, /* I - Choice to test */ cups_option_t **options) /* O - Conflicting options */ { int i, /* Looping var */ num_options; /* Number of conflicting options */ cups_array_t *active; /* Active conflicts */ _ppd_cups_uiconsts_t *c; /* Current constraints */ _ppd_cups_uiconst_t *cptr; /* Current constraint */ ppd_choice_t *marked; /* Marked choice */ /* * Range check input... */ if (options) *options = NULL; if (!ppd || !option || !choice || !options) return (0); /* * Test for conflicts... */ active = ppd_test_constraints(ppd, option, choice, 0, NULL, _PPD_ALL_CONSTRAINTS); /* * Loop through all of the UI constraints and add any options that conflict... */ for (num_options = 0, c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active); c; c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active)) { for (i = c->num_constraints, cptr = c->constraints; i > 0; i --, cptr ++) if (_cups_strcasecmp(cptr->option->keyword, option)) { if (cptr->choice) num_options = cupsAddOption(cptr->option->keyword, cptr->choice->choice, num_options, options); else if ((marked = ppdFindMarkedChoice(ppd, cptr->option->keyword)) != NULL) num_options = cupsAddOption(cptr->option->keyword, marked->choice, num_options, options); } } cupsArrayDelete(active); return (num_options); }
static void free_cache(void) { snmp_cache_t *cache; /* Cached device */ for (cache = (snmp_cache_t *)cupsArrayFirst(Devices); cache; cache = (snmp_cache_t *)cupsArrayNext(Devices)) { free(cache->addrname); if (cache->uri) free(cache->uri); if (cache->id) free(cache->id); if (cache->make_and_model) free(cache->make_and_model); free(cache); } cupsArrayDelete(Devices); Devices = NULL; }
static void help_delete_node(help_node_t *n) /* I - Node */ { help_word_t *w; /* Current word */ DEBUG_printf(("2help_delete_node(n=%p)", n)); if (!n) return; if (n->filename) free(n->filename); if (n->anchor) free(n->anchor); if (n->section) free(n->section); if (n->text) free(n->text); for (w = (help_word_t *)cupsArrayFirst(n->words); w; w = (help_word_t *)cupsArrayNext(n->words)) help_delete_word(w); cupsArrayDelete(n->words); free(n); }
void cupsdDeleteAllPolicies(void) { cupsd_printer_t *printer; /* Current printer */ if (!Policies) return; /* * First clear the policy pointers for all printers... */ for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers); printer; printer = (cupsd_printer_t *)cupsArrayNext(Printers)) printer->op_policy_ptr = NULL; DefaultPolicyPtr = NULL; /* * Then free all of the policies... */ cupsArrayDelete(Policies); Policies = NULL; }
void _cupsStrFlush(void) { _cups_sp_item_t *item; /* Current item */ // DEBUG_printf(("_cupsStrFlush(cg=%p)\n", cg)); DEBUG_printf((" %d strings in array\n", cupsArrayCount(stringpool))); #ifdef HAVE_PTHREAD_H pthread_mutex_lock(&sp_mutex); #endif /* HAVE_PTHREAD_H */ for (item = (_cups_sp_item_t *)cupsArrayFirst(stringpool); item; item = (_cups_sp_item_t *)cupsArrayNext(stringpool)) { free(item->str); free(item); } cupsArrayDelete(stringpool); stringpool = NULL; #ifdef HAVE_PTHREAD_H pthread_mutex_unlock(&sp_mutex); #endif /* HAVE_PTHREAD_H */ }
int /* O - 1 if conflicting, 0 if not conflicting */ ppdInstallableConflict( ppd_file_t *ppd, /* I - PPD file */ const char *option, /* I - Option */ const char *choice) /* I - Choice */ { cups_array_t *active; /* Active conflicts */ DEBUG_printf(("2ppdInstallableConflict(ppd=%p, option=\"%s\", choice=\"%s\")", ppd, option, choice)); /* * Range check input... */ if (!ppd || !option || !choice) return (0); /* * Test constraints using the new option... */ active = ppd_test_constraints(ppd, option, choice, 0, NULL, _PPD_INSTALLABLE_CONSTRAINTS); cupsArrayDelete(active); return (active != NULL); }
void cupsdFreeStrings(cups_array_t **a) /* IO - String array */ { if (*a) { cupsArrayDelete(*a); *a = NULL; } }
int /* O - Number of conflicts found */ ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ { int i, /* Looping variable */ conflicts; /* Number of conflicts */ cups_array_t *active; /* Active conflicts */ _ppd_cups_uiconsts_t *c; /* Current constraints */ _ppd_cups_uiconst_t *cptr; /* Current constraint */ ppd_option_t *o; /* Current option */ if (!ppd) return (0); /* * Clear all conflicts... */ cupsArraySave(ppd->options); for (o = ppdFirstOption(ppd); o; o = ppdNextOption(ppd)) o->conflicted = 0; cupsArrayRestore(ppd->options); /* * Test for conflicts... */ active = ppd_test_constraints(ppd, NULL, NULL, 0, NULL, _PPD_ALL_CONSTRAINTS); conflicts = cupsArrayCount(active); /* * Loop through all of the UI constraints and flag any options * that conflict... */ for (c = (_ppd_cups_uiconsts_t *)cupsArrayFirst(active); c; c = (_ppd_cups_uiconsts_t *)cupsArrayNext(active)) { for (i = c->num_constraints, cptr = c->constraints; i > 0; i --, cptr ++) cptr->option->conflicted = 1; } cupsArrayDelete(active); /* * Return the number of conflicts found... */ return (conflicts); }
void mimeDelete(mime_t *mime) /* I - MIME database */ { mime_type_t *type; /* Current type */ mime_filter_t *filter; /* Current filter */ printf("[mime.c::mimeDelete()]called %p\n", mime); if (!mime) return; /* * Loop through filters and free them... */ for (filter = (mime_filter_t *)cupsArrayFirst(mime->filters); filter; filter = (mime_filter_t *)cupsArrayNext(mime->filters)) { mimeDeleteFilter(mime, filter); printf("[mime.c::mimeDelete()] deleting filter %p\n", filter); } /* * Loop through the file types and delete any rules... */ for (type = (mime_type_t *)cupsArrayFirst(mime->types); type; type = (mime_type_t *)cupsArrayNext(mime->types)) { printf("[mime.c::mimeDelete()] deleting type rule %p\n", type); mimeDeleteType(mime, type); } /* * Free the types and filters arrays, and then the MIME database structure. */ cupsArrayDelete(mime->types); cupsArrayDelete(mime->filters); cupsArrayDelete(mime->srcs); free(mime); }
static void free_formats(cups_array_t *fmts) /* I - Array of format strings */ { char *s; /* Current string */ for (s = (char *)cupsArrayFirst(fmts); s; s = (char *)cupsArrayNext(fmts)) free(s); cupsArrayDelete(fmts); }
static void free_array(cups_array_t *a) /* I - Array */ { char *s; /* Current string */ for (s = (char *)cupsArrayFirst(a); s; s = (char *)cupsArrayNext(a)) free(s); cupsArrayDelete(a); }
void mimeDelete(mime_t *mime) /* I - MIME database */ { mime_type_t *type; /* Current type */ mime_filter_t *filter; /* Current filter */ DEBUG_printf(("mimeDelete(mime=%p)", mime)); if (!mime) return; /* * Loop through filters and free them... */ for (filter = (mime_filter_t *)cupsArrayFirst(mime->filters); filter; filter = (mime_filter_t *)cupsArrayNext(mime->filters)) mimeDeleteFilter(mime, filter); /* * Loop through the file types and delete any rules... */ for (type = (mime_type_t *)cupsArrayFirst(mime->types); type; type = (mime_type_t *)cupsArrayNext(mime->types)) mimeDeleteType(mime, type); /* * Free the types and filters arrays, and then the MIME database structure. */ cupsArrayDelete(mime->types); cupsArrayDelete(mime->filters); cupsArrayDelete(mime->srcs); free(mime); }
void cupsdDeleteAllListeners(void) { cupsd_listener_t *lis; /* Current listening socket */ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) free(lis); cupsArrayDelete(Listeners); Listeners = NULL; }
void _ppdFreeLanguages( cups_array_t *languages) /* I - Languages array */ { char *language; /* Current language */ for (language = (char *)cupsArrayFirst(languages); language; language = (char *)cupsArrayNext(languages)) free(language); cupsArrayDelete(languages); }
static void dnssdStop(void) { cupsd_printer_t *p; /* Current printer */ /* * De-register the individual printers */ for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers)) dnssdDeregisterPrinter(p, 1, 0); /* * Shutdown the rest of the service refs... */ dnssdDeregisterInstance(&WebIFSrv, 0); # ifdef HAVE_DNSSD cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDMaster)); DNSServiceRefDeallocate(DNSSDMaster); DNSSDMaster = NULL; # else /* HAVE_AVAHI */ if (DNSSDMaster) avahi_threaded_poll_stop(DNSSDMaster); if (DNSSDClient) { avahi_client_free(DNSSDClient); DNSSDClient = NULL; } if (DNSSDMaster) { avahi_threaded_poll_free(DNSSDMaster); DNSSDMaster = NULL; } # endif /* HAVE_DNSSD */ cupsArrayDelete(DNSSDPrinters); DNSSDPrinters = NULL; DNSSDPort = 0; }
void helpDeleteIndex(help_index_t *hi) /* I - Help index */ { help_node_t *node; /* Current node */ DEBUG_printf(("helpDeleteIndex(hi=%p)", hi)); if (!hi) return; for (node = (help_node_t *)cupsArrayFirst(hi->nodes); node; node = (help_node_t *)cupsArrayNext(hi->nodes)) { if (!hi->search) help_delete_node(node); } cupsArrayDelete(hi->nodes); cupsArrayDelete(hi->sorted); free(hi); }
void cupsdDeleteAllSubscriptions(void) { cupsd_subscription_t *sub; /* Subscription */ if (!Subscriptions) return; for (sub = (cupsd_subscription_t *)cupsArrayFirst(Subscriptions); sub; sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions)) cupsdDeleteSubscription(sub, 0); cupsArrayDelete(Subscriptions); Subscriptions = NULL; }
void cupsdFreeQuotas(cupsd_printer_t *p) /* I - Printer */ { cupsd_quota_t *q; /* Current quota record */ if (!p) return; for (q = (cupsd_quota_t *)cupsArrayFirst(p->quotas); q; q = (cupsd_quota_t *)cupsArrayNext(p->quotas)) free(q); cupsArrayDelete(p->quotas); p->quotas = NULL; }
void _cupsMessageFree(cups_array_t *a) /* I - Message array */ { #if defined(__APPLE__) && defined(CUPS_BUNDLEDIR) /* * Release the cups.strings dictionary as needed... */ if (cupsArrayUserData(a)) CFRelease((CFDictionaryRef)cupsArrayUserData(a)); #endif /* __APPLE__ && CUPS_BUNDLEDIR */ /* * Free the array... */ cupsArrayDelete(a); }
static void delete_fcache(cups_array_t *filtercache)/* I - Filter cache */ { _mime_fcache_t *current; /* Current cache entry */ for (current = (_mime_fcache_t *)cupsArrayFirst(filtercache); current; current = (_mime_fcache_t *)cupsArrayNext(filtercache)) { free(current->name); if (current->path) free(current->path); free(current); } cupsArrayDelete(filtercache); }
void mimeDeleteFilter(mime_t *mime, /* I - MIME database */ mime_filter_t *filter) /* I - Filter */ { if (!mime || !filter) return; cupsArrayRemove(mime->filters, filter); free(filter); /* * Deleting a filter invalidates the source lookup cache used by * mimeFilter()... */ if (mime->srcs) { cupsArrayDelete(mime->srcs); mime->srcs = NULL; } }
void _cupsStrFlush(void) { _cups_sp_item_t *item; /* Current item */ DEBUG_printf(("4_cupsStrFlush: %d strings in array", cupsArrayCount(stringpool))); _cupsMutexLock(&sp_mutex); for (item = (_cups_sp_item_t *)cupsArrayFirst(stringpool); item; item = (_cups_sp_item_t *)cupsArrayNext(stringpool)) free(item); cupsArrayDelete(stringpool); stringpool = NULL; _cupsMutexUnlock(&sp_mutex); }
void cupsdDeleteAllListeners(void) { cupsd_listener_t *lis; /* Current listening socket */ for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) #if defined(HAVE_LAUNCHD) || defined(HAVE_SYSTEMD) if (!lis->on_demand) #endif /* HAVE_LAUNCHD || HAVE_SYSTEMD */ { cupsArrayRemove(Listeners, lis); free(lis); } if (cupsArrayCount(Listeners) == 0) { cupsArrayDelete(Listeners); Listeners = NULL; } }
void mimeDeleteFilter(mime_t *mime, /* I - MIME database */ mime_filter_t *filter) /* I - Filter */ { DEBUG_printf(("mimeDeleteFilter(mime=%p, filter=%p(%s/%s->%s/%s, cost=%d, " "maxsize=" CUPS_LLFMT "))", mime, filter, filter ? filter->src->super : "???", filter ? filter->src->type : "???", filter ? filter->dst->super : "???", filter ? filter->dst->super : "???", filter ? filter->cost : -1, filter ? CUPS_LLCAST filter->maxsize : CUPS_LLCAST -1)); if (!mime || !filter) return; #ifdef DEBUG if (!cupsArrayFind(mime->filters, filter)) DEBUG_puts("1mimeDeleteFilter: Filter not in MIME database."); #endif /* DEBUG */ cupsArrayRemove(mime->filters, filter); free(filter); /* * Deleting a filter invalidates the source lookup cache used by * mimeFilter()... */ if (mime->srcs) { DEBUG_puts("1mimeDeleteFilter: Deleting source lookup cache."); cupsArrayDelete(mime->srcs); mime->srcs = NULL; } }
void cupsdDeleteSubscription( cupsd_subscription_t *sub, /* I - Subscription object */ int update) /* I - 1 = update subscriptions.conf */ { /* * Close the pipe to the notifier as needed... */ if (sub->pipe >= 0) close(sub->pipe); /* * Remove subscription from array... */ cupsArrayRemove(Subscriptions, sub); /* * Free memory... */ cupsdClearString(&(sub->owner)); cupsdClearString(&(sub->recipient)); cupsArrayDelete(sub->events); free(sub); /* * Update the subscriptions as needed... */ if (update) cupsdMarkDirty(CUPSD_DIRTY_SUBSCRIPTIONS); }
static int /* O - 0 = success, -1 = error */ help_load_file( help_index_t *hi, /* I - Index */ const char *filename, /* I - Filename */ const char *relative, /* I - Relative path */ time_t mtime) /* I - Modification time */ { cups_file_t *fp; /* HTML file */ help_node_t *node; /* Current node */ char line[1024], /* Line from file */ temp[1024], /* Temporary word */ section[1024], /* Section */ *ptr, /* Pointer into line */ *anchor, /* Anchor name */ *text; /* Text for anchor */ off_t offset; /* File offset */ char quote; /* Quote character */ help_word_t *word; /* Current word */ int wordlen; /* Length of word */ DEBUG_printf(("2help_load_file(hi=%p, filename=\"%s\", relative=\"%s\", " "mtime=%ld)", hi, filename, relative, mtime)); if ((fp = cupsFileOpen(filename, "r")) == NULL) return (-1); node = NULL; offset = 0; strlcpy(section, "Other", sizeof(section)); while (cupsFileGets(fp, line, sizeof(line))) { /* * Look for "<TITLE>", "<A NAME", or "<!-- SECTION:" prefix... */ if (!_cups_strncasecmp(line, "<!-- SECTION:", 13)) { /* * Got section line, copy it! */ for (ptr = line + 13; isspace(*ptr & 255); ptr ++); strlcpy(section, ptr, sizeof(section)); if ((ptr = strstr(section, "-->")) != NULL) { /* * Strip comment stuff from end of line... */ for (*ptr-- = '\0'; ptr > line && isspace(*ptr & 255); *ptr-- = '\0'); if (isspace(*ptr & 255)) *ptr = '\0'; } continue; } for (ptr = line; (ptr = strchr(ptr, '<')) != NULL;) { ptr ++; if (!_cups_strncasecmp(ptr, "TITLE>", 6)) { /* * Found the title... */ anchor = NULL; ptr += 6; } else if (!_cups_strncasecmp(ptr, "A NAME=", 7)) { /* * Found an anchor... */ ptr += 7; if (*ptr == '\"' || *ptr == '\'') { /* * Get quoted anchor... */ quote = *ptr; anchor = ptr + 1; if ((ptr = strchr(anchor, quote)) != NULL) *ptr++ = '\0'; else break; } else { /* * Get unquoted anchor... */ anchor = ptr + 1; for (ptr = anchor; *ptr && *ptr != '>' && !isspace(*ptr & 255); ptr ++); if (*ptr) *ptr++ = '\0'; else break; } /* * Got the anchor, now lets find the end... */ while (*ptr && *ptr != '>') ptr ++; if (*ptr != '>') break; ptr ++; } else continue; /* * Now collect text for the link... */ text = ptr; while ((ptr = strchr(text, '<')) == NULL) { ptr = text + strlen(text); if (ptr >= (line + sizeof(line) - 2)) break; *ptr++ = ' '; if (!cupsFileGets(fp, ptr, sizeof(line) - (ptr - line) - 1)) break; } *ptr = '\0'; if (node) node->length = offset - node->offset; if (!*text) { node = NULL; break; } if ((node = helpFindNode(hi, relative, anchor)) != NULL) { /* * Node already in the index, so replace the text and other * data... */ cupsArrayRemove(hi->nodes, node); if (node->section) free(node->section); if (node->text) free(node->text); if (node->words) { for (word = (help_word_t *)cupsArrayFirst(node->words); word; word = (help_word_t *)cupsArrayNext(node->words)) help_delete_word(word); cupsArrayDelete(node->words); node->words = NULL; } node->section = section[0] ? strdup(section) : NULL; node->text = strdup(text); node->mtime = mtime; node->offset = offset; node->score = 0; } else { /* * New node... */ node = help_new_node(relative, anchor, section, text, mtime, offset, 0); } /* * Go through the text value and replace tabs and newlines with * whitespace and eliminate extra whitespace... */ for (ptr = node->text, text = node->text; *ptr;) if (isspace(*ptr & 255)) { while (isspace(*ptr & 255)) ptr ++; *text++ = ' '; } else if (text != ptr) *text++ = *ptr++; else { text ++; ptr ++; } *text = '\0'; /* * (Re)add the node to the array... */ cupsArrayAdd(hi->nodes, node); if (!anchor) node = NULL; break; } if (node) { /* * Scan this line for words... */ for (ptr = line; *ptr; ptr ++) { /* * Skip HTML stuff... */ if (*ptr == '<') { if (!strncmp(ptr, "<!--", 4)) { /* * Skip HTML comment... */ if ((text = strstr(ptr + 4, "-->")) == NULL) ptr += strlen(ptr) - 1; else ptr = text + 2; } else { /* * Skip HTML element... */ for (ptr ++; *ptr && *ptr != '>'; ptr ++) { if (*ptr == '\"' || *ptr == '\'') { for (quote = *ptr++; *ptr && *ptr != quote; ptr ++); if (!*ptr) ptr --; } } if (!*ptr) ptr --; } continue; } else if (*ptr == '&') { /* * Skip HTML entity... */ for (ptr ++; *ptr && *ptr != ';'; ptr ++); if (!*ptr) ptr --; continue; } else if (!isalnum(*ptr & 255)) continue; /* * Found the start of a word, search until we find the end... */ for (text = ptr, ptr ++; *ptr && isalnum(*ptr & 255); ptr ++); wordlen = ptr - text; memcpy(temp, text, wordlen); temp[wordlen] = '\0'; ptr --; if (wordlen > 1 && !bsearch(temp, help_common_words, (sizeof(help_common_words) / sizeof(help_common_words[0])), sizeof(help_common_words[0]), (int (*)(const void *, const void *)) _cups_strcasecmp)) help_add_word(node, temp); } } /* * Get the offset of the next line... */ offset = cupsFileTell(fp); } cupsFileClose(fp); if (node) node->length = offset - node->offset; return (0); }
help_index_t * /* O - Search index */ helpSearchIndex(help_index_t *hi, /* I - Index */ const char *query, /* I - Query string */ const char *section, /* I - Limit search to this section */ const char *filename) /* I - Limit search to this file */ { help_index_t *search; /* Search index */ help_node_t *node; /* Current node */ help_word_t *word; /* Current word */ void *sc; /* Search context */ int matches; /* Number of matches */ DEBUG_printf(("helpSearchIndex(hi=%p, query=\"%s\", filename=\"%s\")", hi, query, filename)); /* * Range check... */ if (!hi || !query) return (NULL); /* * Reset the scores of all nodes to 0... */ for (node = (help_node_t *)cupsArrayFirst(hi->nodes); node; node = (help_node_t *)cupsArrayNext(hi->nodes)) node->score = 0; /* * Find the first node to search in... */ if (filename) { node = helpFindNode(hi, filename, NULL); if (!node) return (NULL); } else node = (help_node_t *)cupsArrayFirst(hi->nodes); /* * Convert the query into a regular expression... */ sc = cgiCompileSearch(query); if (!sc) return (NULL); /* * Allocate a search index... */ search = calloc(1, sizeof(help_index_t)); if (!search) { cgiFreeSearch(sc); return (NULL); } search->nodes = cupsArrayNew((cups_array_func_t)help_sort_by_name, NULL); search->sorted = cupsArrayNew((cups_array_func_t)help_sort_by_score, NULL); if (!search->nodes || !search->sorted) { cupsArrayDelete(search->nodes); cupsArrayDelete(search->sorted); free(search); cgiFreeSearch(sc); return (NULL); } search->search = 1; /* * Check each node in the index, adding matching nodes to the * search index... */ for (; node; node = (help_node_t *)cupsArrayNext(hi->nodes)) if (section && strcmp(node->section, section)) continue; else if (filename && strcmp(node->filename, filename)) continue; else { matches = cgiDoSearch(sc, node->text); for (word = (help_word_t *)cupsArrayFirst(node->words); word; word = (help_word_t *)cupsArrayNext(node->words)) if (cgiDoSearch(sc, word->text) > 0) matches += word->count; if (matches > 0) { /* * Found a match, add the node to the search index... */ node->score = matches; cupsArrayAdd(search->nodes, node); cupsArrayAdd(search->sorted, node); } } /* * Free the search context... */ cgiFreeSearch(sc); /* * Return the results... */ return (search); }
help_index_t * /* O - Index pointer or NULL */ helpLoadIndex(const char *hifile, /* I - Index filename */ const char *directory) /* I - Directory that is indexed */ { help_index_t *hi; /* Help index */ cups_file_t *fp; /* Current file */ char line[2048], /* Line from file */ *ptr, /* Pointer into line */ *filename, /* Filename in line */ *anchor, /* Anchor in line */ *sectptr, /* Section pointer in line */ section[1024], /* Section name */ *text; /* Text in line */ time_t mtime; /* Modification time */ off_t offset; /* Offset into file */ size_t length; /* Length in bytes */ int update; /* Update? */ help_node_t *node; /* Current node */ help_word_t *word; /* Current word */ DEBUG_printf(("helpLoadIndex(hifile=\"%s\", directory=\"%s\")", hifile, directory)); /* * Create a new, empty index. */ if ((hi = (help_index_t *)calloc(1, sizeof(help_index_t))) == NULL) return (NULL); hi->nodes = cupsArrayNew((cups_array_func_t)help_sort_by_name, NULL); hi->sorted = cupsArrayNew((cups_array_func_t)help_sort_by_score, NULL); if (!hi->nodes || !hi->sorted) { cupsArrayDelete(hi->nodes); cupsArrayDelete(hi->sorted); free(hi); return (NULL); } /* * Try loading the existing index file... */ if ((fp = cupsFileOpen(hifile, "r")) != NULL) { /* * Lock the file and then read the first line... */ cupsFileLock(fp, 1); if (cupsFileGets(fp, line, sizeof(line)) && !strcmp(line, "HELPV2")) { /* * Got a valid header line, now read the data lines... */ node = NULL; while (cupsFileGets(fp, line, sizeof(line))) { /* * Each line looks like one of the following: * * filename mtime offset length "section" "text" * filename#anchor offset length "text" * SP count word */ if (line[0] == ' ') { /* * Read a word in the current node... */ if (!node || (ptr = strrchr(line, ' ')) == NULL) continue; if ((word = help_add_word(node, ptr + 1)) != NULL) word->count = atoi(line + 1); } else { /* * Add a node... */ filename = line; if ((ptr = strchr(line, ' ')) == NULL) break; while (isspace(*ptr & 255)) *ptr++ = '\0'; if ((anchor = strrchr(filename, '#')) != NULL) { *anchor++ = '\0'; mtime = 0; } else mtime = strtol(ptr, &ptr, 10); offset = strtoll(ptr, &ptr, 10); length = strtoll(ptr, &ptr, 10); while (isspace(*ptr & 255)) ptr ++; if (!anchor) { /* * Get section... */ if (*ptr != '\"') break; ptr ++; sectptr = ptr; while (*ptr && *ptr != '\"') ptr ++; if (*ptr != '\"') break; *ptr++ = '\0'; strlcpy(section, sectptr, sizeof(section)); while (isspace(*ptr & 255)) ptr ++; } if (*ptr != '\"') break; ptr ++; text = ptr; while (*ptr && *ptr != '\"') ptr ++; if (*ptr != '\"') break; *ptr++ = '\0'; if ((node = help_new_node(filename, anchor, section, text, mtime, offset, length)) == NULL) break; node->score = -1; cupsArrayAdd(hi->nodes, node); } } } cupsFileClose(fp); } /* * Scan for new/updated files... */ update = help_load_directory(hi, directory, NULL); /* * Remove any files that are no longer installed... */ for (node = (help_node_t *)cupsArrayFirst(hi->nodes); node; node = (help_node_t *)cupsArrayNext(hi->nodes)) if (node->score < 0) { /* * Delete this node... */ cupsArrayRemove(hi->nodes, node); help_delete_node(node); } /* * Add nodes to the sorted array... */ for (node = (help_node_t *)cupsArrayFirst(hi->nodes); node; node = (help_node_t *)cupsArrayNext(hi->nodes)) cupsArrayAdd(hi->sorted, node); /* * Save the index if we updated it... */ if (update) helpSaveIndex(hi, hifile); /* * Return the index... */ return (hi); }