source: trunk/third/scrollkeeper/libs/uninstall.c @ 20861

Revision 20861, 7.4 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20860, which included commits to RCS files with non-trunk default branches.
Line 
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
34struct IdTab {
35    int id;
36    char *locale;
37};
38
39
40static void remove_doc_from_content_list(xmlNodePtr, struct IdTab *, int, int);
41
42static 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
60static 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
68static 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
120static 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
155static 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
186static 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, &timestamp, 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
253void
254uninstall (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
Note: See TracBrowser for help on using the repository browser.