OSDN Git Service

89909d34b66359020dc0ff9ba0b648a6a74c574d
[handbrake-jp/handbrake-jp-git.git] / libhb / update.c
1 /* $Id: update.c,v 1.7 2005/03/26 23:04:14 titer Exp $
2
3    This file is part of the HandBrake source code.
4    Homepage: <http://handbrake.fr/>.
5    It may be used under the terms of the GNU General Public License. */
6
7 #include "hb.h"
8
9 static void UpdateFunc( void * );
10
11 typedef struct
12 {
13     int  * build;
14     char * version;
15
16 } hb_update_t;
17
18 hb_thread_t * hb_update_init( int * build, char * version )
19 {
20     hb_update_t * data = calloc( sizeof( hb_update_t ), 1 );
21     data->build   = build;
22     data->version = version;
23
24     return hb_thread_init( "update", UpdateFunc, data,
25                            HB_NORMAL_PRIORITY );
26 }
27
28
29 static void UpdateFunc( void * _data )
30 {
31
32     hb_update_t * data = (hb_update_t *) _data;
33
34     char*       p;
35     char* const url  = HB_PROJECT_URL_APPCAST;
36     char* const urlz = url + strlen( HB_PROJECT_URL_APPCAST ); /* marks null-term */
37     char        url_host[64];
38     char        url_path[128];
39     char        query[256];
40
41         hb_net_t * net;
42     int        ret;
43     char       buf[4096];
44     char     * cur, * end;
45     int        size;
46     int        i_vers;
47     char       s_vers[32]; /* must be no larger than hb_handle_s.version */
48     int        i;
49
50     /* Setup hb_query and hb_query_two with the correct appcast file */
51     hb_log( "Using %s", url );
52
53     /* extract host part */
54     cur = strstr( HB_PROJECT_URL_APPCAST, "//" );
55     if( !cur || cur+2 > urlz )
56         goto error;
57     cur += 2;
58
59     end = strstr( cur, "/" );
60     if( !end || end > urlz )
61         goto error;
62
63     memset( url_host, 0, sizeof(url_host) );
64     strncpy( url_host, cur, (end-cur) );
65
66     /* extract path part */
67     memset( url_path, 0, sizeof(url_path) );
68     strncpy( url_path, end, (urlz-end) );
69
70     if( !strlen( url_path ))
71         goto error;
72
73     memset( query, 0, sizeof(query) );
74     snprintf( query, sizeof(query), "GET %s HTTP/1.0\r\nHost: %s\r\n\r\n", url_path, url_host );
75
76     /* Grab the data from the web server */
77     if( !( net = hb_net_open( url_host, 80 ) ) )
78     {
79         goto error;
80     }
81
82     if( hb_net_send( net, query ) < 0 )
83     {
84         hb_log("Error: Unable to connect to server");
85         hb_net_close( &net );
86         goto error;
87     }
88
89     size = 0;
90     memset( buf, 0, 4096 );
91     for( ;; )
92     {
93         ret = hb_net_recv( net, &buf[size], sizeof( buf ) - size );
94         if( ret < 1 )
95         {
96             hb_net_close( &net );
97             break;
98         }
99         size += ret;
100     }
101
102     cur = buf;
103     end = &buf[sizeof( buf )];
104         
105     /* Make sure we got it */
106     cur += 9;
107     if( size < 15 || strncmp( cur, "200 OK", 6 ) )
108     {
109         hb_log("Error: We did not get a 200 OK from the server. \n");
110         goto error;
111     }
112     cur += 6;
113
114     /* Find the end of the headers and the beginning of the content */
115     for( ; &cur[3] < end; cur++ )
116     {
117         if( cur[0] == '\r' && cur[1] == '\n' &&
118             cur[2] == '\r' && cur[3] == '\n' )
119         {
120             cur += 4;
121             break;
122         }
123     }
124
125     if( cur >= end )
126     {
127         hb_log("Error: Found the end of the buffer before the end of the HTTP header information! \n");
128         goto error;
129     }
130         
131     /*
132      * Find the <cli> tag
133      * Scan though each character of the buffer until we find that the first 4 characters of "cur" are "<cli"
134      */
135     for(i=0 ; &cur[3] < end; i++, cur++ )
136     {
137         if( cur[0] == 'c' && cur[1] == 'l' && cur[2] == 'i' && cur[3] == '>' )
138         {
139             cur += 1;
140             break;
141         }
142                  
143         /* If the CLI tag has not been found in the first 768 characters, or the end is reached, something bad happened.*/
144         if (( i > 768) || ( cur >= end ))
145                 {
146             hb_log("Error: Did not find the <cli> tag in the expected maximum amount of characters into the file. \n");
147             goto error;
148                 }
149     }
150          
151     if( cur >= end )
152     {
153         goto error;
154     }
155         
156     /*
157      * Ok, The above code didn't position cur, it only found <cli so we need to shift cur along 3 places.
158      * After which, the next 10 characters are the build number
159      */
160     cur += 3;
161         
162     if( cur >= end )
163     {
164         hb_log("Error: Unexpected end of buffer! Could not find the build information. \n");
165         goto error;
166     }
167         
168     /* Stable HB_PROJECT_BUILD */
169     i_vers = strtol( cur, &cur, 10 );
170
171     if( cur >= end )
172     {
173         hb_log("Error: Unexpected end of buffer! \n");
174         goto error;
175     }
176         
177     /*
178      * The Version number is 2 places after the build, so shift cur, 2 places.
179      * Get all the characters in cur until the point where " is found.
180      */
181     cur += 2;
182         
183     if( cur >= end )
184     {
185         hb_log("Error: Unexpected end of buffer! Could not get version number. \n");
186         goto error;
187     }
188     memset( s_vers, 0, sizeof( s_vers ) );
189     for( i = 0;   i < sizeof( s_vers ) - 1 && cur < end && *cur != '"'; i++, cur++ )
190     {
191         s_vers[i] = *cur;
192                 
193         /* If the CLI tag has not been found in the first 768 characters, or the end is reached, something bad happened.*/
194         if (( cur >= end ))
195         {
196             hb_log("Error: Version number too long, or end of buffer reached. \n");
197             goto error;
198         }
199     }
200
201     if( cur >= end )
202     {
203         goto error;
204     }
205
206     /* Print the version information */
207     hb_log( "latest: %s, build %d", s_vers, i_vers );
208
209     /* Return the build information */
210     if( i_vers > HB_PROJECT_BUILD )
211     {
212         memcpy( data->version, s_vers, sizeof(s_vers) );
213         *(data->build) = i_vers;
214     }
215
216 error:
217     free( data );
218     return;
219 }