~ubuntu-branches/ubuntu/natty/migration-assistant/natty

« back to all changes in this revision

Viewing changes to utils.c

  • Committer: Bazaar Package Importer
  • Author(s): Evan Dandrea
  • Date: 2006-08-01 00:50:33 UTC
  • Revision ID: james.westby@ubuntu.com-20060801005033-3tm4t07u4t7zi7vv
Tags: 0.1
Initial release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <libgen.h>
 
2
#include <dirent.h>
 
3
#include <sys/stat.h>
 
4
#include <sys/types.h>
 
5
#include <fcntl.h>
 
6
#include <stdlib.h>
 
7
#include <string.h>
 
8
 
 
9
// For gconf utils
 
10
#include <stdio.h>
 
11
#include <libxml/parser.h>
 
12
#include <libxml/tree.h>
 
13
 
 
14
// for copyfile and rcopy
 
15
#include <sys/mman.h>
 
16
#include <unistd.h>
 
17
 
 
18
#include "utils.h"
 
19
 
 
20
// Modified from Advanced Programming in the Unix Environment.
 
21
// A generic error(const char*, ...) would be nice.
 
22
void copyfile(const char* from, const char* to) {
 
23
    int         fdin, fdout;
 
24
    void        *src, *dst;
 
25
    struct stat statbuf;
 
26
    const int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
 
27
 
 
28
    create_file(to);
 
29
 
 
30
    if ((fdin = open(from, O_RDONLY)) < 0) {
 
31
        printf("can't open %s for reading\n", from);
 
32
        exit(EXIT_FAILURE);
 
33
    }
 
34
 
 
35
    if ((fdout = open(to, O_RDWR | O_CREAT | O_TRUNC, mode)) < 0) {
 
36
        printf("can't creat %s for writing\n", to);
 
37
        exit(EXIT_FAILURE);
 
38
    }
 
39
 
 
40
    if (fstat(fdin, &statbuf) < 0) {  /* need size of input file */
 
41
        puts("fstat error");
 
42
        exit(EXIT_FAILURE);
 
43
    }
 
44
 
 
45
    /* set size of output file */
 
46
    if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1) {
 
47
        puts("lseek error");
 
48
        exit(EXIT_FAILURE);
 
49
    }
 
50
    if (write(fdout, "", 1) != 1) {
 
51
        puts("write error");
 
52
        exit(EXIT_FAILURE);
 
53
    }
 
54
 
 
55
    if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED,
 
56
      fdin, 0)) == MAP_FAILED) {
 
57
        puts("mmap error for input");
 
58
        exit(EXIT_FAILURE);
 
59
    }
 
60
 
 
61
    if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE,
 
62
      MAP_SHARED, fdout, 0)) == MAP_FAILED) {
 
63
        puts("mmap error for output");
 
64
        exit(EXIT_FAILURE);
 
65
    }
 
66
 
 
67
    memcpy(dst, src, statbuf.st_size); /* does the file copy */
 
68
}
 
69
 
 
70
void rcopy(const char* from, const char* to) {
 
71
    struct dirent *de;
 
72
    DIR *d;
 
73
    char* fpn, *tpn;
 
74
 
 
75
    d = opendir(from);
 
76
    if(!d) {
 
77
        printf("could not open dir, %s\n", from);
 
78
        exit(EXIT_FAILURE);
 
79
    }
 
80
 
 
81
    mkdir(to, 0755);
 
82
 
 
83
    while((de = readdir(d)) != NULL) {
 
84
        if(strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
 
85
            continue;
 
86
 
 
87
        asprintf(&fpn, "%s/%s", from, de->d_name);
 
88
        asprintf(&tpn, "%s/%s", to, de->d_name);
 
89
 
 
90
        if(de->d_type == DT_REG) {
 
91
            copyfile(fpn, tpn);
 
92
        } else if(de->d_type == DT_DIR) {
 
93
            mkdir(tpn, 0755); // I think we can axe this.  See above.
 
94
            rcopy(fpn, tpn);
 
95
        }
 
96
        free(fpn);
 
97
        free(tpn);
 
98
    }
 
99
    closedir(d);
 
100
}
 
101
 
 
102
/* taken from partconf/partconf.c */
 
103
void makedirs(const char *dir)
 
104
{
 
105
    DIR *d;
 
106
    char *dirtmp, *basedir;
 
107
 
 
108
    if ((d = opendir(dir)) != NULL) {
 
109
        closedir(d);
 
110
        return;
 
111
    }
 
112
    if (mkdir(dir, 0755) < 0) {
 
113
        dirtmp = strdup(dir);
 
114
        basedir = dirname(dirtmp);
 
115
        makedirs(basedir);
 
116
        free(dirtmp);
 
117
        mkdir(dir, 0755);
 
118
    }
 
119
}
 
120
 
 
121
void create_file(const char* file) {
 
122
    FILE* fp;
 
123
    char* tmp;
 
124
    char* filename;
 
125
 
 
126
    if((fp = fopen(file, "r")) != NULL) {
 
127
        fclose(fp);
 
128
        return;
 
129
    }
 
130
 
 
131
    tmp = strdup(file);
 
132
    filename = dirname(tmp);
 
133
    makedirs(filename);
 
134
    free(tmp);
 
135
 
 
136
    creat(file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
137
}
 
138
void add_wallpaper (const char* path) {
 
139
    xmlDoc* doc = NULL;
 
140
    xmlNode* root, *wallpaper, *ptr = NULL;
 
141
    char* file, *name;
 
142
    const int opts = XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_RECOVER;
 
143
 
 
144
    name = strdup(path);
 
145
    name = basename(name);
 
146
 
 
147
    asprintf(&file, "%s/home/%s/.gnome2/backgrounds.xml", to_location, to_user);
 
148
    create_file(file);
 
149
    doc = xmlReadFile(file, NULL, opts);
 
150
    root = xmlDocGetRootElement(doc);
 
151
 
 
152
    if(!root) {
 
153
        // FIXME: set DTD.
 
154
        root = xmlNewNode(NULL, (xmlChar*) "wallpapers");
 
155
        xmlDocSetRootElement(doc, root);
 
156
    } else {
 
157
        wallpaper = root->children;
 
158
        while(wallpaper != NULL) {
 
159
            ptr = wallpaper->children;
 
160
            while(ptr != NULL) {
 
161
                if((xmlStrcmp(ptr->name, (xmlChar*) "filename") == 0) &&
 
162
                        (xmlStrcmp(ptr->children->content, (xmlChar*) path) == 0)) {
 
163
                    return; // Already set.
 
164
                }
 
165
                ptr = ptr->next;
 
166
            }
 
167
            wallpaper = wallpaper->next;
 
168
        }
 
169
 
 
170
    }
 
171
    
 
172
    wallpaper = xmlNewChild(root, NULL, (xmlChar*) "wallpaper", NULL);
 
173
    xmlNewProp(wallpaper, (xmlChar*) "deleted", (xmlChar*) "false");
 
174
    xmlNewTextChild(wallpaper, NULL, (xmlChar*) "name", (xmlChar*) name);
 
175
    xmlNewTextChild(wallpaper, NULL, (xmlChar*) "filename", (xmlChar*) path);
 
176
    xmlNewTextChild(wallpaper, NULL, (xmlChar*) "options", (xmlChar*) "scaled");
 
177
    free(name);
 
178
 
 
179
    xmlSaveFormatFile(file, doc, 1);
 
180
    free(file);
 
181
}
 
182
// yikes, get rid of this.
 
183
void makegconfdirs(const char *dir)
 
184
{
 
185
    DIR *d;
 
186
    char *dirtmp, *basedir, *gconf;
 
187
 
 
188
    if ((d = opendir(dir)) != NULL) {
 
189
        closedir(d);
 
190
        return;
 
191
    }
 
192
    if (mkdir(dir, 0755) < 0) {
 
193
        dirtmp = strdup(dir);
 
194
        basedir = dirname(dirtmp);
 
195
        makegconfdirs(basedir);
 
196
        free(dirtmp);
 
197
 
 
198
        mkdir(dir, 0755);
 
199
        
 
200
    }
 
201
    dirtmp = strdup(dir);
 
202
    basedir = basename(dirtmp);
 
203
    if(strcmp(basedir,".gconf") != 0) {
 
204
        asprintf(&gconf, "%s/%%gconf.xml", dir);
 
205
        creat(gconf, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
206
        free(gconf);
 
207
    }
 
208
    free(dirtmp);
 
209
}
 
210
 
 
211
 
 
212
void set_gconf_key (const char* path, const char* name, gconf_type type, const char* value) {
 
213
    char* file, *gconf;
 
214
    xmlDoc* doc = NULL;
 
215
    xmlNode* root, *entry = NULL;
 
216
    const int opts = XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_RECOVER;
 
217
 
 
218
    asprintf(&gconf, "%s/home/%s/.gconf/%s", to_location, to_user, path);
 
219
    asprintf(&file, "%s/%%gconf.xml", gconf);
 
220
 
 
221
    makegconfdirs(gconf);
 
222
    free(gconf);
 
223
    create_file(file);
 
224
 
 
225
    doc = xmlReadFile(file, NULL, opts);
 
226
    root = xmlDocGetRootElement(doc);
 
227
    if(!root) {
 
228
        root = xmlNewNode(NULL, (xmlChar*) "gconf");
 
229
        xmlDocSetRootElement(doc, root);
 
230
        entry = xmlNewChild(root, NULL, (xmlChar*) "entry", NULL);
 
231
        xmlNewProp(entry, (xmlChar*) "name", (xmlChar*) name);
 
232
    } else {
 
233
        entry = root->children;
 
234
        while(entry != NULL) {
 
235
            if(xmlStrcmp(xmlGetProp(entry, (xmlChar*) "name"),(xmlChar*) name) == 0)
 
236
                break;
 
237
            entry = entry->next;
 
238
        }
 
239
        if(!entry) {
 
240
            entry = xmlNewChild(root, NULL, (xmlChar*) "entry", NULL);
 
241
            xmlNewProp(entry, (xmlChar*) "name", (xmlChar*) name);
 
242
        }
 
243
    }
 
244
 
 
245
 
 
246
    if(type == GCONF_STRING) {
 
247
 
 
248
        xmlSetProp(entry, (xmlChar*) "type", (xmlChar*) "string");
 
249
        if(entry->children == NULL)
 
250
            xmlNewTextChild(entry, NULL, (xmlChar*) "stringvalue", (xmlChar*) value);
 
251
        else
 
252
            xmlNodeSetContent(entry->children, (xmlChar*) value);
 
253
 
 
254
    } else if (type == GCONF_BOOLEAN) {
 
255
 
 
256
        xmlSetProp(entry, (xmlChar*) "type", (xmlChar*) "bool");
 
257
        xmlSetProp(entry, (xmlChar*) "value", (xmlChar*) value);
 
258
 
 
259
    } else if (type == GCONF_LIST_STRING) {
 
260
        xmlNode* li, *sv = NULL;
 
261
        xmlSetProp(entry, (xmlChar*) "type", (xmlChar*) "list");
 
262
        xmlSetProp(entry, (xmlChar*) "ltype", (xmlChar*) "string");
 
263
 
 
264
        if(entry->children == NULL)
 
265
            li = xmlNewChild(entry, NULL, (xmlChar*) "li", NULL);
 
266
        else
 
267
            li = entry->children;
 
268
 
 
269
        xmlSetProp(li, (xmlChar*) "type", (xmlChar*) "string");
 
270
        sv = li->children;
 
271
        while(sv != NULL) {
 
272
            // Already exists.
 
273
            if(xmlStrcmp(sv->children->content, (xmlChar*) value) == 0)
 
274
                return;
 
275
            sv = sv->next;
 
276
        }
 
277
        xmlNewTextChild(li, NULL, (xmlChar*) "stringvalue", (xmlChar*) value);
 
278
    }
 
279
 
 
280
    xmlSaveFormatFile(file, doc, 1);
 
281
 
 
282
}