1 | /* copyright (C) 2000 Sun Microsystems, Inc.*/ |
---|
2 | |
---|
3 | /* |
---|
4 | * This library is free software; you can redistribute it and/or |
---|
5 | * modify it under the terms of the GNU Lesser General Public |
---|
6 | * License as published by the Free Software Foundation; either |
---|
7 | * version 2.1 of the License, or (at your option) any later version. |
---|
8 | * |
---|
9 | * This library is distributed in the hope that it will be useful, |
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
12 | * Lesser General Public License for more details. |
---|
13 | * |
---|
14 | * You should have received a copy of the GNU Lesser General Public |
---|
15 | * License along with this library; if not, write to the Free Software |
---|
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
17 | */ |
---|
18 | |
---|
19 | #include <config.h> |
---|
20 | #include <libxml/tree.h> |
---|
21 | #include <libxml/parser.h> |
---|
22 | #include <stdlib.h> |
---|
23 | #include <string.h> |
---|
24 | #include <unistd.h> |
---|
25 | #include <sys/stat.h> |
---|
26 | #include <libintl.h> |
---|
27 | #include <locale.h> |
---|
28 | #include <scrollkeeper.h> |
---|
29 | |
---|
30 | #define _(String) gettext (String) |
---|
31 | |
---|
32 | #define PATHLEN 256 |
---|
33 | |
---|
34 | struct IdTab { |
---|
35 | int id; |
---|
36 | char *locale; |
---|
37 | }; |
---|
38 | |
---|
39 | |
---|
40 | static void remove_doc_from_content_list(xmlNodePtr, struct IdTab *, int, int); |
---|
41 | |
---|
42 | static void remove_tocs_and_index(struct IdTab *tab, int num, char *scrollkeeper_dir) |
---|
43 | { |
---|
44 | char toc_dir[PATHLEN], toc_file[PATHLEN], index_dir[PATHLEN], index_file[PATHLEN]; |
---|
45 | int i; |
---|
46 | |
---|
47 | snprintf(toc_dir, PATHLEN, "%s/TOC", scrollkeeper_dir); |
---|
48 | snprintf(index_dir, PATHLEN, "%s/index", scrollkeeper_dir); |
---|
49 | |
---|
50 | for(i = 0; i < num; i++) |
---|
51 | { |
---|
52 | snprintf(toc_file, PATHLEN, "%s/%d", toc_dir, tab[i].id); |
---|
53 | snprintf(index_file, PATHLEN, "%s/%d", index_dir, tab[i].id); |
---|
54 | unlink(toc_file); |
---|
55 | unlink(index_file); |
---|
56 | } |
---|
57 | |
---|
58 | } |
---|
59 | |
---|
60 | static int compare(const void *elem1, const void *elem2) |
---|
61 | { |
---|
62 | struct IdTab *el1 = (struct IdTab *)elem1; |
---|
63 | struct IdTab *el2 = (struct IdTab *)elem2; |
---|
64 | |
---|
65 | return strcmp(el1->locale, el2->locale); |
---|
66 | } |
---|
67 | |
---|
68 | static void remove_docs_from_content_list(struct IdTab *id_tab, int id_num, char *scrollkeeper_dir, char outputprefs) |
---|
69 | { |
---|
70 | int start, end; |
---|
71 | char cl_filename[PATHLEN], cl_ext_filename[PATHLEN]; |
---|
72 | xmlDocPtr cl_doc, cl_ext_doc; |
---|
73 | |
---|
74 | if (id_tab == NULL) |
---|
75 | return; |
---|
76 | |
---|
77 | end = 0; |
---|
78 | |
---|
79 | while (1) |
---|
80 | { |
---|
81 | start = end; |
---|
82 | |
---|
83 | while (start < id_num && end < id_num && |
---|
84 | !strcmp(id_tab[start].locale, id_tab[end].locale)) |
---|
85 | end++; |
---|
86 | |
---|
87 | if (start >= id_num) |
---|
88 | break; |
---|
89 | |
---|
90 | snprintf(cl_filename, PATHLEN, "%s/%s/scrollkeeper_cl.xml", scrollkeeper_dir, id_tab[start].locale); |
---|
91 | snprintf(cl_ext_filename, PATHLEN, "%s/%s/scrollkeeper_extended_cl.xml", scrollkeeper_dir, |
---|
92 | id_tab[start].locale); |
---|
93 | |
---|
94 | cl_doc = xmlParseFile(cl_filename); |
---|
95 | if (cl_doc == NULL) |
---|
96 | { |
---|
97 | sk_message(outputprefs, SKOUT_VERBOSE, SKOUT_QUIET,"(remove_docs_from_content_list)", _("wrong content list file %s\n"), cl_filename); |
---|
98 | continue; |
---|
99 | } |
---|
100 | |
---|
101 | cl_ext_doc = xmlParseFile(cl_ext_filename); |
---|
102 | if (cl_ext_doc == NULL) |
---|
103 | { |
---|
104 | sk_message(outputprefs, SKOUT_VERBOSE, SKOUT_QUIET, "(remove_docs_from_content_list)",_("wrong extended content list file %s\n"), cl_ext_filename); |
---|
105 | continue; |
---|
106 | } |
---|
107 | |
---|
108 | |
---|
109 | remove_doc_from_content_list(cl_doc->children, id_tab, start, end); |
---|
110 | remove_doc_from_content_list(cl_ext_doc->children, id_tab, start, end); |
---|
111 | |
---|
112 | xmlSaveFile(cl_filename, cl_doc); |
---|
113 | xmlFreeDoc(cl_doc); |
---|
114 | xmlSaveFile(cl_ext_filename, cl_ext_doc); |
---|
115 | xmlFreeDoc(cl_ext_doc); |
---|
116 | |
---|
117 | } |
---|
118 | } |
---|
119 | |
---|
120 | static void remove_doc_from_content_list(xmlNodePtr cl_node, struct IdTab *id_tab, |
---|
121 | int start, int end) |
---|
122 | { |
---|
123 | xmlNodePtr node, next; |
---|
124 | char *str_id; |
---|
125 | int id, i; |
---|
126 | |
---|
127 | if (cl_node == NULL) |
---|
128 | return; |
---|
129 | |
---|
130 | for(node = cl_node; node != NULL; node = next) |
---|
131 | { |
---|
132 | next = node->next; |
---|
133 | |
---|
134 | if (node->type == XML_ELEMENT_NODE && |
---|
135 | !xmlStrcmp(node->name, (xmlChar *)"doc")) |
---|
136 | { |
---|
137 | str_id = (char *)xmlGetProp(node, (xmlChar *)"docid"); |
---|
138 | id = atoi(str_id); |
---|
139 | xmlFree(str_id); |
---|
140 | |
---|
141 | for(i = start; id_tab[i].id != id && i < end; i++) |
---|
142 | ; |
---|
143 | |
---|
144 | if (i < end && id_tab[i].id == id) |
---|
145 | { |
---|
146 | xmlUnlinkNode(node); |
---|
147 | xmlFreeNode((void *)node); |
---|
148 | } |
---|
149 | } |
---|
150 | else |
---|
151 | remove_doc_from_content_list(node->children, id_tab, start, end); |
---|
152 | } |
---|
153 | } |
---|
154 | |
---|
155 | static int get_next_doc_info(FILE *fid, char *omf_name, int *id, |
---|
156 | char *doc_name, long *timestamp, |
---|
157 | char *locale) |
---|
158 | { |
---|
159 | char line[2056], *token, sep[5]; |
---|
160 | int ret; |
---|
161 | |
---|
162 | fgets(line, 2056, fid); |
---|
163 | if ((ret = feof(fid))) { |
---|
164 | return (!ret); |
---|
165 | } |
---|
166 | |
---|
167 | sep[0] = ' '; |
---|
168 | sep[1] = '\n'; |
---|
169 | sep[2] = '\t'; |
---|
170 | sep[3] = '\0'; |
---|
171 | |
---|
172 | token = strtok(line, sep); |
---|
173 | snprintf(omf_name, PATHLEN, "%s", token); |
---|
174 | token = strtok(NULL, sep); |
---|
175 | *id = atoi(token); |
---|
176 | token = strtok(NULL, sep); |
---|
177 | snprintf(doc_name, PATHLEN, "%s", token); |
---|
178 | token = strtok(NULL, sep); |
---|
179 | *timestamp = atol(token); |
---|
180 | token = strtok(NULL, sep); |
---|
181 | snprintf(locale, 32, "%s", token); |
---|
182 | |
---|
183 | return (!ret); |
---|
184 | } |
---|
185 | |
---|
186 | static void remove_doc_from_scrollkeeper_docs(char *omf_name, |
---|
187 | struct IdTab **id_tab, int *id_num, |
---|
188 | char *scrollkeeper_dir, char outputprefs) |
---|
189 | { |
---|
190 | int id, count; |
---|
191 | struct IdTab *l_id_tab = NULL; |
---|
192 | FILE *fid, *tmp_fid; |
---|
193 | char l_omf_name[PATHLEN], doc_name[PATHLEN], tmp[PATHLEN], locale[32]; |
---|
194 | char scrollkeeper_docs[PATHLEN]; |
---|
195 | long timestamp; |
---|
196 | |
---|
197 | snprintf(scrollkeeper_docs, PATHLEN, "%s/scrollkeeper_docs", scrollkeeper_dir); |
---|
198 | |
---|
199 | fid = fopen(scrollkeeper_docs, "r"); |
---|
200 | if (fid == NULL) |
---|
201 | { |
---|
202 | sk_message(outputprefs, SKOUT_DEFAULT, SKOUT_QUIET, "(remove_doc_from_scrollkeeper_docs)", _("%s missing\n"), scrollkeeper_docs); |
---|
203 | return; |
---|
204 | } |
---|
205 | |
---|
206 | snprintf(tmp, PATHLEN, "%s.tmp", scrollkeeper_docs); |
---|
207 | |
---|
208 | tmp_fid = fopen(tmp, "w"); |
---|
209 | if (tmp_fid == NULL) |
---|
210 | { |
---|
211 | sk_message(outputprefs, SKOUT_DEFAULT, SKOUT_QUIET, "(remove_doc_from_scrollkeeper_docs)", _("cannot create temporary file %s\n"), tmp); |
---|
212 | return; |
---|
213 | } |
---|
214 | |
---|
215 | count = 0; |
---|
216 | |
---|
217 | while (get_next_doc_info(fid, l_omf_name, &id, doc_name, ×tamp, locale)) |
---|
218 | { |
---|
219 | if (strcmp(omf_name, l_omf_name)) |
---|
220 | fprintf(tmp_fid, "%s\t%d\t%s\t%ld\t%s\n", l_omf_name, id, doc_name, |
---|
221 | timestamp, locale); |
---|
222 | else |
---|
223 | { |
---|
224 | if (l_id_tab == NULL) |
---|
225 | { |
---|
226 | count = 0; |
---|
227 | l_id_tab = (struct IdTab *)calloc(2, sizeof(struct IdTab)); |
---|
228 | l_id_tab[count].id = id; |
---|
229 | l_id_tab[count].locale = strdup(locale); |
---|
230 | count++; |
---|
231 | } |
---|
232 | else |
---|
233 | { |
---|
234 | l_id_tab = (struct IdTab *)realloc( |
---|
235 | l_id_tab, (count + 2)*sizeof(struct IdTab)); |
---|
236 | l_id_tab[count].id = id; |
---|
237 | l_id_tab[count].locale = strdup(locale); |
---|
238 | count++; |
---|
239 | } |
---|
240 | } |
---|
241 | } |
---|
242 | |
---|
243 | fclose(fid); |
---|
244 | fclose(tmp_fid); |
---|
245 | |
---|
246 | unlink(scrollkeeper_docs); |
---|
247 | rename(tmp, scrollkeeper_docs); |
---|
248 | |
---|
249 | *id_tab = l_id_tab; |
---|
250 | *id_num = count; |
---|
251 | } |
---|
252 | |
---|
253 | void |
---|
254 | uninstall (char *omf_name, char *scrollkeeper_dir, char outputprefs) |
---|
255 | { |
---|
256 | struct IdTab *removed_id_tab; |
---|
257 | int removed_id_num = 0, i; |
---|
258 | |
---|
259 | removed_id_tab = NULL; |
---|
260 | remove_doc_from_scrollkeeper_docs(omf_name, &removed_id_tab, &removed_id_num, scrollkeeper_dir, outputprefs); |
---|
261 | |
---|
262 | if (removed_id_tab == NULL) |
---|
263 | return; |
---|
264 | |
---|
265 | qsort((void *)removed_id_tab, removed_id_num, |
---|
266 | sizeof(struct IdTab), compare); |
---|
267 | remove_docs_from_content_list(removed_id_tab, removed_id_num, scrollkeeper_dir, outputprefs); |
---|
268 | |
---|
269 | remove_tocs_and_index(removed_id_tab, removed_id_num, scrollkeeper_dir); |
---|
270 | |
---|
271 | for(i = 0; i < removed_id_num; i++) |
---|
272 | free((void *)removed_id_tab[i].locale); |
---|
273 | |
---|
274 | free((void *)removed_id_tab); |
---|
275 | |
---|
276 | } |
---|
277 | |
---|