~ubuntu-branches/ubuntu/precise/migration-assistant/precise

1 by Evan Dandrea
Initial release.
1
#include <libxml/parser.h>
2
#include <libxml/tree.h>
3
#include <stdio.h>
4
#include <string.h>
5
6
#include <sys/types.h>
3 by Evan Dandrea
* Added tests for empty passwords, reserved usernames, bad usernames and
7
#include <sys/stat.h>
1 by Evan Dandrea
Initial release.
8
#include <dirent.h>
9
10
#include "gaim-import.h"
11
#include "registry.h"
12
#include "utils.h"
13
14
xmlDoc* gaim_new_accounts_file(void) {
15
    static xmlDoc* doc = NULL;
16
    xmlNode* node = NULL;
17
    char* accounts_file;
18
    int opts = XML_PARSE_NOBLANKS | XML_PARSE_NOERROR | XML_PARSE_RECOVER;
19
20
    if(!doc) {
21
	asprintf(&accounts_file, "%s/%s/%s/%s", to_location,
22
	    "home", to_user,
23
	    ".gaim/accounts.xml");
24
25
	create_file(accounts_file);
26
	doc = xmlReadFile(accounts_file, NULL, opts);
27
	free(accounts_file);
28
	
29
	node = xmlDocGetRootElement(doc);
30
	if(!node) {
31
	    node = xmlNewNode(NULL, (xmlChar*) "accounts");
32
	    xmlNewProp(node, (xmlChar*) "version", (xmlChar*) "1.0");
33
	    xmlDocSetRootElement(doc, node);
34
	}
35
    }
36
    return doc;
37
}
38
39
void gaim_save_accounts_file(void) {
40
    xmlDoc* doc = gaim_new_accounts_file();
41
    char* accounts_file;
42
    asprintf(&accounts_file, "%s/%s/%s/%s", to_location,
43
	    "home", to_user,
44
	    ".gaim/accounts.xml");
45
    xmlSaveFormatFile(accounts_file, doc, 1);
46
}
47
48
int gaim_account_exists(xmlNode* node) {
49
    xmlNode* ptr = NULL;
50
    xmlDoc* doc = NULL;
51
    xmlChar* username = NULL;
52
    xmlChar* protocol = NULL;
53
54
    node = node->children;
55
56
    while(node != NULL) {
57
       if(xmlStrcmp(node->name, (xmlChar*) "name") == 0)
58
	   username = node->children->content;
59
       else if(xmlStrcmp(node->name, (xmlChar*) "protocol") == 0)
60
	   protocol = node->children->content;
61
62
       node = node->next;
63
    }
64
65
    doc = gaim_new_accounts_file();
66
    node = xmlDocGetRootElement(doc);
67
68
    node = node->children;
69
    int found = 0;
70
71
    // For each account.
72
    while(node) {
73
       if(node->type == XML_ELEMENT_NODE &&
74
	(xmlStrcmp(node->name, (xmlChar*) "account") == 0)) {
75
76
	   ptr = node->children;
77
78
	   // For each account property.
79
	   while(ptr != NULL) {
80
	       if(xmlStrcmp(ptr->name, (xmlChar*) "name") == 0) {
81
		   if(xmlStrcmp(ptr->children->content,
82
			       (xmlChar*) username) == 0) {
83
		       found++;
84
		   }
85
	       }
86
	       if(xmlStrcmp(ptr->name, (xmlChar*) "protocol") == 0) {
87
		   if(xmlStrcmp(ptr->children->content,
88
			       (xmlChar*) protocol) == 0) {
89
		       found++;
90
		   }
91
	       }
92
	       ptr = ptr->next;
93
	   }
94
95
	   if(found == 2) return 1;
96
	   found = 0;
97
       }
98
       node = node->next;
99
    }
100
    return 0;
101
}
102
103
void gaim_add_account(xmlNode* node) {
104
    xmlDoc* doc = gaim_new_accounts_file();
105
    xmlNode* top = xmlDocGetRootElement(doc);
106
    xmlAddChild(top, node);
107
}
108
109
void gaim_import_gaim(void) {
110
    xmlDoc* doc = NULL;
111
    xmlNode* node, *node_copy = NULL;
112
    char* accounts_file;
113
6 by Evan Dandrea
* Added proper support for the Windows registry's use of UTF-16 strings.
114
    char* filename, *path;
115
    char* appdata = NULL;
116
1 by Evan Dandrea
Initial release.
117
    if(os_type == LINUX)
118
	asprintf(&accounts_file, "%s/%s/%s/%s", from_location,
119
		"home", from_user,
120
		".gaim/accounts.xml");
6 by Evan Dandrea
* Added proper support for the Windows registry's use of UTF-16 strings.
121
    else if(os_type == WINDOWSXP) {
122
        asprintf(&filename, "%s/%s/%s/%s", from_location,
123
	        "Documents and Settings", from_user, "NTUSER.DAT");
124
        appdata = findkey(filename, "\\Software\\Microsoft\\Windows\\"
125
            "CurrentVersion\\Explorer\\Shell Folders\\Local AppData");
126
        free(filename);
127
        if(!appdata) {
128
            printf("Couldn't find %s\n", appdata);
129
            return;
130
        }
131
        path = reformat_path(appdata);
132
        free(appdata);
133
	    asprintf(&accounts_file, "%s/%s/%s", from_location, path,
134
    		"/.gaim/accounts.xml");
135
        free(path);
136
    }
1 by Evan Dandrea
Initial release.
137
    
138
    if(!accounts_file) return;
139
140
    doc = xmlReadFile(accounts_file, NULL, XML_PARSE_NOBLANKS);
141
    free(accounts_file);
3 by Evan Dandrea
* Added tests for empty passwords, reserved usernames, bad usernames and
142
    if(!doc) return;
1 by Evan Dandrea
Initial release.
143
    node = xmlDocGetRootElement(doc);
144
145
    node = node->children;
146
147
    while(node) {
148
       if(node->type == XML_ELEMENT_NODE &&
149
	(xmlStrcmp(node->name, (xmlChar*) "account") == 0)) {
150
151
	   if(!gaim_account_exists(node)) {
152
		node_copy = xmlCopyNode(node, 1);
153
		gaim_add_account(node_copy);
154
	   }
155
       }
156
       node = node->next;
157
    }
158
    gaim_save_accounts_file();
159
}
160
161
void gaim_import_other(const char* proto, const char* username,
162
	const char* password) {
163
    
164
    xmlNode *account, *name, *protocol;
165
    account = xmlNewNode(NULL, (xmlChar*) "account");
166
    
167
    // protocol must come before name in the accounts file otherwise Gaim will
168
    // have a bad time.
169
    protocol = xmlNewChild(account, NULL, (xmlChar*) "protocol", (xmlChar*) proto);
170
    name = xmlNewChild(account, NULL, (xmlChar*) "name", (xmlChar*) username);
171
    
172
    if(!gaim_account_exists(account))
173
	gaim_add_account(account);
174
}
175
176
void gaim_import_yahoo(void) {
177
    char* username;
178
    char* filename;
179
180
    asprintf(&filename, "%s/%s/%s/%s", from_location,
181
	    "Documents and Settings", from_user, "NTUSER.DAT");
182
    username = findkey(filename,
183
	    "\\Software\\Yahoo\\pager\\Yahoo! User ID");
184
    free(filename);
185
186
    if(username) {
187
	gaim_import_other("prpl-yahoo", username, NULL);
188
	free(username);
189
	gaim_save_accounts_file();
190
    } else {
191
	puts("could not get yahoo ID from registry.");
192
	exit(EXIT_FAILURE);
193
    }
194
}
195
196
// FIXME: This is a terrible test.  If the user has an AIM account with the
197
// same username as the one they use for Windows, the test will fail.
198
void gaim_import_aimtriton(void) {
199
    DIR *dir, *dir2;
200
    struct dirent *entry, *entry2;
3 by Evan Dandrea
* Added tests for empty passwords, reserved usernames, bad usernames and
201
    struct stat buf;
6 by Evan Dandrea
* Added proper support for the Windows registry's use of UTF-16 strings.
202
    char* dirname, *uprofile, *filename, *cls, *path;
203
    char* appdata = NULL;
204
205
    asprintf(&filename, "%s/%s/%s/%s", from_location,
206
	    "Documents and Settings", from_user, "NTUSER.DAT");
207
    appdata = findkey(filename, "\\Software\\Microsoft\\Windows\\"
208
        "CurrentVersion\\Explorer\\Shell Folders\\Local AppData");
209
    free(filename);
210
    if(!appdata) {
211
        printf("Couldn't find %s\n", appdata);
212
        return;
213
    }
214
    path = reformat_path(appdata);
215
    free(appdata);
216
    asprintf(&dirname, "%s/%s/%s", from_location, path, "AOL/UserProfiles");
217
    free(path);
218
1 by Evan Dandrea
Initial release.
219
    dir = opendir(dirname);
3 by Evan Dandrea
* Added tests for empty passwords, reserved usernames, bad usernames and
220
    if(!dir) {
6 by Evan Dandrea
* Added proper support for the Windows registry's use of UTF-16 strings.
221
	    printf("Could not open AIM profile root directory: %s\n", dirname);
3 by Evan Dandrea
* Added tests for empty passwords, reserved usernames, bad usernames and
222
	    free(dirname);
223
	    return;
6 by Evan Dandrea
* Added proper support for the Windows registry's use of UTF-16 strings.
224
    }
225
226
    while((entry = readdir(dir)) != NULL) {
227
        if(entry->d_type != DT_DIR)
228
            continue;
229
            
230
        if(strcmp(entry->d_name,"All Users") == 0 ||
231
            (strcmp(entry->d_name,".") == 0 ||
232
             strcmp(entry->d_name,"..") == 0)) {
233
            continue;
234
        }
235
236
        asprintf(&uprofile, "%s/%s", dirname, entry->d_name);
237
        dir2 = opendir(uprofile);
238
        if(!dir2) {
239
            printf("Could not open user's AIM profile directory: %s\n", uprofile);
240
            free(uprofile);
241
            return;
242
        }
243
244
        while((entry2 = readdir(dir2)) != NULL) {
245
            if((strcmp(entry2->d_name,from_user) != 0) &&
246
                ((strcmp(entry2->d_name,".") != 0) &&
247
                 (strcmp(entry2->d_name,"..") != 0))) {
248
            asprintf(&cls, "%s/%s/cls", uprofile, entry2->d_name);
249
            
250
            if(stat(cls, &buf) == 0)
251
                gaim_import_other("prpl-oscar", entry2->d_name, NULL);
252
253
            free(cls);
254
            }
255
        }
256
        closedir(dir2);
257
        free(uprofile);
258
259
    }
260
    free(dirname);
1 by Evan Dandrea
Initial release.
261
    closedir(dir);
262
    gaim_save_accounts_file();
263
}