@@ -29,17 +29,155 @@ int ROOT_LINK_OFFSET = 0;
2929 */
3030static pthread_mutex_t link_lock ;
3131
32+ /**
33+ * \brief create a new Link
34+ */
35+ static Link * Link_new (const char * linkname , LinkType type )
36+ {
37+ Link * link = CALLOC (1 , sizeof (Link ));
38+
39+ strncpy (link -> linkname , linkname , MAX_FILENAME_LEN );
40+ link -> type = type ;
41+
42+ /*
43+ * remove the '/' from linkname if it exists
44+ */
45+ char * c =
46+ & (link -> linkname [strnlen (link -> linkname , MAX_FILENAME_LEN ) - 1 ]);
47+ if (* c == '/' ) {
48+ * c = '\0' ;
49+ }
50+
51+ return link ;
52+ }
53+
54+ static CURL * Link_to_curl (Link * link )
55+ {
56+ CURL * curl = curl_easy_init ();
57+ if (!curl ) {
58+ lprintf (fatal , "curl_easy_init() failed!\n" );
59+ }
60+ /*
61+ * set up some basic curl stuff
62+ */
63+ curl_easy_setopt (curl , CURLOPT_USERAGENT , CONFIG .user_agent );
64+ curl_easy_setopt (curl , CURLOPT_FOLLOWLOCATION , 1 );
65+ /*
66+ * for following directories without the '/'
67+ */
68+ curl_easy_setopt (curl , CURLOPT_MAXREDIRS , 2 );
69+ curl_easy_setopt (curl , CURLOPT_URL , link -> f_url );
70+ curl_easy_setopt (curl , CURLOPT_TCP_KEEPALIVE , 1 );
71+ curl_easy_setopt (curl , CURLOPT_CONNECTTIMEOUT , 15 );
72+ curl_easy_setopt (curl , CURLOPT_SHARE , CURL_SHARE );
73+ curl_easy_setopt (curl , CURLOPT_WRITEFUNCTION , write_memory_callback );
74+ if (CONFIG .insecure_tls ) {
75+ curl_easy_setopt (curl , CURLOPT_SSL_VERIFYPEER , 0 );
76+ }
77+ // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
78+
79+ if (CONFIG .http_username ) {
80+ curl_easy_setopt (curl , CURLOPT_USERNAME , CONFIG .http_username );
81+ }
82+
83+ if (CONFIG .http_password ) {
84+ curl_easy_setopt (curl , CURLOPT_PASSWORD , CONFIG .http_password );
85+ }
86+
87+ if (CONFIG .proxy ) {
88+ curl_easy_setopt (curl , CURLOPT_PROXY , CONFIG .proxy );
89+ }
90+
91+ if (CONFIG .proxy_username ) {
92+ curl_easy_setopt (curl , CURLOPT_PROXYUSERNAME ,
93+ CONFIG .proxy_username );
94+ }
95+
96+ if (CONFIG .proxy_password ) {
97+ curl_easy_setopt (curl , CURLOPT_PROXYPASSWORD ,
98+ CONFIG .proxy_password );
99+ }
100+
101+ return curl ;
102+ }
103+
104+ static void Link_req_file_stat (Link * this_link )
105+ {
106+ CURL * curl = Link_to_curl (this_link );
107+ curl_easy_setopt (curl , CURLOPT_NOBODY , 1 );
108+ curl_easy_setopt (curl , CURLOPT_FILETIME , 1L );
109+
110+ /*
111+ * We need to put the variable on the heap, because otherwise the
112+ * variable gets popped from the stack as the function returns.
113+ *
114+ * It gets freed in curl_multi_perform_once();
115+ */
116+ TransferStruct * transfer = CALLOC (1 , sizeof (TransferStruct ));
117+
118+ transfer -> link = this_link ;
119+ transfer -> type = FILESTAT ;
120+ curl_easy_setopt (curl , CURLOPT_PRIVATE , transfer );
121+
122+ transfer_nonblocking (curl );
123+ }
124+
125+ /**
126+ * \brief Fill in the uninitialised entries in a link table
127+ * \details Try and get the stats for each link in the link table. This will get
128+ * repeated until the uninitialised entry count drop to zero.
129+ */
130+ static void LinkTable_uninitialised_fill (LinkTable * linktbl )
131+ {
132+ int u ;
133+ char s [STATUS_LEN ];
134+ lprintf (debug , "LinkTable_uninitialised_fill(): ... " );
135+ do {
136+ u = 0 ;
137+ for (int i = 0 ; i < linktbl -> num ; i ++ ) {
138+ Link * this_link = linktbl -> links [i ];
139+ if (this_link -> type == LINK_UNINITIALISED_FILE ) {
140+ Link_req_file_stat (linktbl -> links [i ]);
141+ u ++ ;
142+ }
143+ }
144+ /*
145+ * Block until the gaps are filled
146+ */
147+ int n = curl_multi_perform_once ();
148+ int i = 0 ;
149+ int j = 0 ;
150+ while ((i = curl_multi_perform_once ())) {
151+ if (CONFIG .log_type & debug ) {
152+ if (j ) {
153+ erase_string (stderr , STATUS_LEN , s );
154+ }
155+ snprintf (s , STATUS_LEN , "%d / %d" , n - i , n );
156+ fprintf (stderr , "%s" , s );
157+ j ++ ;
158+ }
159+ }
160+ }
161+ while (u );
162+ if (CONFIG .log_type & debug ) {
163+ erase_string (stderr , STATUS_LEN , s );
164+ fprintf (stderr , "... Done!\n" );
165+ }
166+ }
167+
32168/**
33169 * \brief Create the root linktable for single file mode
34170 */
35171static LinkTable * single_LinkTable_new (const char * url )
36172{
37- char * ptr = strrchr (url , '/' );
38- int dir_len = ptr - url ;
39- char * dir_name = CALLOC (dir_len + 1 , sizeof (char ));
40-
41- free (dir_name );
42- return NULL ;
173+ char * ptr = strrchr (url , '/' ) + 1 ;
174+ LinkTable * linktbl = LinkTable_alloc (url );
175+ Link * link = Link_new (ptr , LINK_UNINITIALISED_FILE );
176+ strncpy (link -> f_url , url , MAX_FILENAME_LEN );
177+ LinkTable_add (linktbl , link );
178+ LinkTable_uninitialised_fill (linktbl );
179+ LinkTable_print (linktbl );
180+ return linktbl ;
43181}
44182
45183LinkTable * LinkSystem_init (const char * raw_url )
@@ -79,6 +217,8 @@ LinkTable *LinkSystem_init(const char *raw_url)
79217 */
80218 if (CONFIG .mode == NORMAL ) {
81219 ROOT_LINK_TBL = LinkTable_new (url );
220+ } else if (CONFIG .mode == SINGLE ) {
221+ ROOT_LINK_TBL = single_LinkTable_new (url );
82222 } else if (CONFIG .mode == SONIC ) {
83223 sonic_config_init (url , CONFIG .sonic_username ,
84224 CONFIG .sonic_password );
@@ -105,28 +245,6 @@ void LinkTable_add(LinkTable * linktbl, Link * link)
105245 linktbl -> links [linktbl -> num - 1 ] = link ;
106246}
107247
108- /**
109- * \brief create a new Link
110- */
111- static Link * Link_new (const char * linkname , LinkType type )
112- {
113- Link * link = CALLOC (1 , sizeof (Link ));
114-
115- strncpy (link -> linkname , linkname , MAX_FILENAME_LEN );
116- link -> type = type ;
117-
118- /*
119- * remove the '/' from linkname if it exists
120- */
121- char * c =
122- & (link -> linkname [strnlen (link -> linkname , MAX_FILENAME_LEN ) - 1 ]);
123- if (* c == '/' ) {
124- * c = '\0' ;
125- }
126-
127- return link ;
128- }
129-
130248static LinkType linkname_to_LinkType (const char * linkname )
131249{
132250 /*
@@ -219,77 +337,6 @@ static void HTML_to_LinkTable(GumboNode * node, LinkTable * linktbl)
219337 return ;
220338}
221339
222- static CURL * Link_to_curl (Link * link )
223- {
224- CURL * curl = curl_easy_init ();
225- if (!curl ) {
226- lprintf (fatal , "curl_easy_init() failed!\n" );
227- }
228- /*
229- * set up some basic curl stuff
230- */
231- curl_easy_setopt (curl , CURLOPT_USERAGENT , CONFIG .user_agent );
232- curl_easy_setopt (curl , CURLOPT_FOLLOWLOCATION , 1 );
233- /*
234- * for following directories without the '/'
235- */
236- curl_easy_setopt (curl , CURLOPT_MAXREDIRS , 2 );
237- curl_easy_setopt (curl , CURLOPT_URL , link -> f_url );
238- curl_easy_setopt (curl , CURLOPT_TCP_KEEPALIVE , 1 );
239- curl_easy_setopt (curl , CURLOPT_CONNECTTIMEOUT , 15 );
240- curl_easy_setopt (curl , CURLOPT_SHARE , CURL_SHARE );
241- curl_easy_setopt (curl , CURLOPT_WRITEFUNCTION , write_memory_callback );
242- if (CONFIG .insecure_tls ) {
243- curl_easy_setopt (curl , CURLOPT_SSL_VERIFYPEER , 0 );
244- }
245- // curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
246-
247- if (CONFIG .http_username ) {
248- curl_easy_setopt (curl , CURLOPT_USERNAME , CONFIG .http_username );
249- }
250-
251- if (CONFIG .http_password ) {
252- curl_easy_setopt (curl , CURLOPT_PASSWORD , CONFIG .http_password );
253- }
254-
255- if (CONFIG .proxy ) {
256- curl_easy_setopt (curl , CURLOPT_PROXY , CONFIG .proxy );
257- }
258-
259- if (CONFIG .proxy_username ) {
260- curl_easy_setopt (curl , CURLOPT_PROXYUSERNAME ,
261- CONFIG .proxy_username );
262- }
263-
264- if (CONFIG .proxy_password ) {
265- curl_easy_setopt (curl , CURLOPT_PROXYPASSWORD ,
266- CONFIG .proxy_password );
267- }
268-
269- return curl ;
270- }
271-
272- static void Link_req_file_stat (Link * this_link )
273- {
274- CURL * curl = Link_to_curl (this_link );
275- curl_easy_setopt (curl , CURLOPT_NOBODY , 1 );
276- curl_easy_setopt (curl , CURLOPT_FILETIME , 1L );
277-
278- /*
279- * We need to put the variable on the heap, because otherwise the
280- * variable gets popped from the stack as the function returns.
281- *
282- * It gets freed in curl_multi_perform_once();
283- */
284- TransferStruct * transfer = CALLOC (1 , sizeof (TransferStruct ));
285-
286- transfer -> link = this_link ;
287- transfer -> type = FILESTAT ;
288- curl_easy_setopt (curl , CURLOPT_PRIVATE , transfer );
289-
290- transfer_nonblocking (curl );
291- }
292-
293340void Link_set_file_stat (Link * this_link , CURL * curl )
294341{
295342 long http_resp ;
@@ -315,49 +362,6 @@ void Link_set_file_stat(Link * this_link, CURL * curl)
315362 }
316363}
317364
318- /**
319- * \brief Fill in the uninitialised entries in a link table
320- * \details Try and get the stats for each link in the link table. This will get
321- * repeated until the uninitialised entry count drop to zero.
322- */
323- static void LinkTable_uninitialised_fill (LinkTable * linktbl )
324- {
325- int u ;
326- char s [STATUS_LEN ];
327- lprintf (debug , "LinkTable_uninitialised_fill(): ... " );
328- do {
329- u = 0 ;
330- for (int i = 0 ; i < linktbl -> num ; i ++ ) {
331- Link * this_link = linktbl -> links [i ];
332- if (this_link -> type == LINK_UNINITIALISED_FILE ) {
333- Link_req_file_stat (linktbl -> links [i ]);
334- u ++ ;
335- }
336- }
337- /*
338- * Block until the gaps are filled
339- */
340- int n = curl_multi_perform_once ();
341- int i = 0 ;
342- int j = 0 ;
343- while ((i = curl_multi_perform_once ())) {
344- if (CONFIG .log_type & debug ) {
345- if (j ) {
346- erase_string (stderr , STATUS_LEN , s );
347- }
348- snprintf (s , STATUS_LEN , "%d / %d" , n - i , n );
349- fprintf (stderr , "%s" , s );
350- j ++ ;
351- }
352- }
353- }
354- while (u );
355- if (CONFIG .log_type & debug ) {
356- erase_string (stderr , STATUS_LEN , s );
357- fprintf (stderr , "... Done!\n" );
358- }
359- }
360-
361365static void LinkTable_fill (LinkTable * linktbl )
362366{
363367 Link * head_link = linktbl -> links [0 ];
0 commit comments