Bug 3830: Spanish netshell update and more by Javier Remacha
[reactos.git] / rosapps / applications / packmgr / lib / download.cpp
1 ////////////////////////////////////////////////////////
2 //
3 // download.cpp
4 //
5 // Stuff related to downloading
6 //
7 //
8 // Maarten Bosma, 09.01.2004
9 // maarten.paul@bosma.de
10 //
11 ////////////////////////////////////////////////////////
12
13 #include "package.hpp"
14 #include "expat.h"
15 #include "log.h"
16 #include <string>
17 #include <urlmon.h>
18
19 HRESULT WINAPI URLDownloadToFileA(
20 LPUNKNOWN pCaller,
21 LPCSTR szURL,
22 LPCSTR szFileName,
23 DWORD dwReserved,
24 LPBINDSTATUSCALLBACK lpfnCB
25 );
26
27 int FindCount (string What, string Where, int start = 0, int end = -1);
28
29
30 // Download a file
31 char* PML_Download (pTree tree, const char* url, const char* server = "tree", const char* filename = "packmgr.xml")
32 {
33 UINT i;
34 static char downl [MAX_PATH]; // the full url
35 static char path [MAX_PATH]; // the full resulting Path
36
37 // It goes to the temp folder when no other path is entered (or even compleatly no filename)
38 // If server == "tree" it will be downloaded from the server speficied in option.xml
39 // File:// links are possible too
40
41 // get temp dir
42 if(!filename)
43 GetTempPathA (200, path);
44
45 else if(!strstr(filename, "\\"))
46 GetTempPathA (200, path);
47
48 else
49 strcpy(path, "");
50
51
52 // create the local file name
53 if(filename)
54 {
55 strcat(path, filename);
56 DeleteFileA (path);
57 }
58 else
59 GetTempFileNameA (path, "pml", 1, path);
60
61 // get the url
62 if (!server)
63 strcpy(downl, "");
64
65 else if(!strcmp(server, "tree"))
66 {
67 char* ret;
68 for (i=0; i<tree->sources.size(); i++)
69 {
70 ret = PML_Download(tree, url, tree->sources[i], filename);
71 if(ret)
72 return ret;
73 }
74 return NULL;
75 }
76
77 else
78 strcpy(downl, server);
79
80 strcat(downl, url);
81
82 // is this a file link ?
83 if (strstr(downl, "file://") || strstr(downl, "File://"))
84 {
85 if(!filename)
86 {
87 return &downl[7];
88 }
89
90 else
91 {
92 CopyFileA(filename, &downl[7], FALSE);
93 return (char*)filename;
94 }
95 }
96
97
98 // download the file
99 if(URLDownloadToFileA (NULL, downl, path, 0, NULL) != S_OK)
100 {
101 Log("! ERROR: Unable to download ");
102 LogAdd(downl);
103
104 return NULL;
105 }
106
107 return path;
108 }
109
110 // Download and prozess a xml file
111 int PML_XmlDownload (pTree tree, const char* url, void* usrdata,
112 XML_StartElementHandler start, XML_EndElementHandler end, XML_CharacterDataHandler text)
113 {
114 int done = 0;
115 char buffer[255];
116 char* filename = 0;
117
118 // logging
119 Log("* prozess the xml file: ");
120 LogAdd(url);
121
122 // download the file
123 if(strstr(url, "file://"))
124 filename = PML_Download(tree, url, NULL, NULL);
125
126 else
127 filename = PML_Download(tree, url);
128
129
130 if(!filename)
131 {
132 Log("! ERROR: Could not download the xml file");
133 return ERR_DOWNL;
134 }
135
136 // open the file
137 FILE* file = fopen(filename, "r");
138 if(!file)
139 {
140 Log("! ERROR: Could not open the xml file ");
141 LogAdd(filename);
142 return ERR_GENERIC;
143 }
144
145 // parse the xml file
146 XML_Parser parser = XML_ParserCreate(NULL);
147 XML_SetUserData (parser, usrdata);
148 XML_SetElementHandler(parser, start, end);
149 XML_SetCharacterDataHandler(parser, text);
150
151 while (!done)
152 {
153 size_t len = fread (buffer, 1, sizeof(buffer), file);
154 done = len < sizeof(buffer);
155
156 buffer[len] = 0;
157 if(!XML_Parse(parser, buffer, len, done))
158 {
159 Log("! ERROR: Could not parse the xml file");
160 return ERR_GENERIC;
161 }
162 }
163
164 XML_ParserFree(parser);
165 fclose(file);
166
167 return ERR_OK;
168 }
169