1 /***************************************************************************/
2 /*                                                                         */
3 /* Fast Webpage Exchanger - an FTP client for updating webpages            */
4 /* Copyright (C) 1999-2000 Yuuki NINOMIYA <gm@debian.or.jp>                */
5 /*                                                                         */
6 /* This program is free software; you can redistribute it and/or modify    */
7 /* it under the terms of the GNU General Public License as published by    */
8 /* the Free Software Foundation; either version 2, or (at your option)     */
9 /* any later version.                                                      */
10 /*                                                                         */
11 /* This program is distributed in the hope that it will be useful,         */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of          */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           */
14 /* GNU General Public License for more details.                            */
15 /*                                                                         */
16 /* You should have received a copy of the GNU General Public License       */
17 /* along with this program; if not, write to the                           */
18 /* Free Software Foundation, Inc., 59 Temple Place - Suite 330,            */
19 /* Boston, MA 02111-1307, USA.                                             */
20 /*                                                                         */
21 /***************************************************************************/
22 
23 #ifdef HAVE_CONFIG_H
24 #  include "config.h"
25 #endif
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include "intl.h"
31 #include "strlib.h"
32 #include "variable.h"
33 #include "proto.h"
34 
35 
36 static Cache_dir *cache_dir;
37 static int max_cache_dir;
38 
39 /* --------------------------------------------------
40  NAME       load_cache
41  FUNCTION   load cache of time stamp
42  OUTPUT     none
43 -------------------------------------------------- */
load_cache(void)44 void load_cache(void)
45 {
46 	char *temp;
47 	FILE *fp;
48 	char *read_temp;
49 	Cache *cache;
50 	int max_cache_file;
51 	char *date,*time,*name;
52 	int i;
53 
54 
55 	cache_dir=NULL;
56 	max_cache_file=max_cache_dir=0;
57 	is_cache_existent=0;
58 
59 	temp=str_concat(getenv("HOME"),"/.weex/weex.cache.",cfgSectionNumberToName(host_number),NULL);
60 
61 	if(rebuild_cache){
62 		fprintf(stderr,_("Rebuilding cache file `%s'.\n"),temp);
63 		free(temp);
64 		return;
65 	}
66 
67 	fp=fopen(temp,"r");
68 	if(fp==NULL){
69 		fprintf(stderr,_("Cache file `%s' does not exist."),temp);
70 		if(!opt_test){
71 			 fprintf(stderr,_(" Creating a new one.\n"));
72 		}else{
73 			 fprintf(stderr,"\n");
74 		}
75 		free(temp);
76 		return;
77 	}
78 
79 	for(i=0;(read_temp=str_fgets(fp))!=NULL;i++){
80 		date=strtok(read_temp," ");
81 		time=strtok(NULL," ");
82 		if(date==NULL || time==NULL){
83 			fprintf(stderr,_("Cache file `%s' is broken at line %d.\n"),temp,i+1);
84 			exit(1);
85 		}
86 
87 		name=time+strlen(time)+1;
88 		if(name==NULL || (i==0 && strcmp(date,"00000000")!=0)){
89 			fprintf(stderr,_("Cache file `%s' is broken at line %d.\n"),temp,i+1);
90 			exit(1);
91 		}
92 		if(strcmp(date,"00000000")==0){	/* directory */
93 			cache_dir=str_realloc(cache_dir,(max_cache_dir+1)*sizeof(*cache_dir));
94 			cache_dir[max_cache_dir].name=str_dup(name);
95 			cache_dir[max_cache_dir].ptr=NULL;
96 			if(max_cache_dir>0){
97 				cache_dir[max_cache_dir-1].max_file=max_cache_file;
98 			}
99 			max_cache_dir++;
100 			max_cache_file=0;
101 		}else{	/* file */
102 			cache_dir[max_cache_dir-1].ptr=str_realloc(cache_dir[max_cache_dir-1].ptr,(max_cache_file+1)*sizeof(*cache_dir[max_cache_dir-1].ptr));
103 			cache=cache_dir[max_cache_dir-1].ptr;
104 
105 			cache[max_cache_file].name=str_dup(name);
106 			cache[max_cache_file].date=atol(date);
107 			cache[max_cache_file].time=atol(time);
108 			max_cache_file++;
109 		}
110 		free(read_temp);
111 	}
112 	if(max_cache_dir>0){
113 		cache_dir[max_cache_dir-1].max_file=max_cache_file;
114 	}
115 	fclose(fp);
116 	free(temp);
117 	is_cache_existent=1;
118 }
119 
120 
121 /* --------------------------------------------------
122  NAME       find_cache
123  FUNCTION   find the file in the cache
124  INPUT      cache_dir_num ... the number of directory in a cache
125             file_name ... file name
126  OUTPUT     pointer to cached file data
127             return NULL if not found
128 -------------------------------------------------- */
find_cache(char * file_name)129 Cache *find_cache(char *file_name)
130 {
131 	int i;
132 	int cache_dir_num;
133 	Cache *cache;
134 
135 	cache_dir_num=find_cache_dir(current_dir[REMOTE]);
136 	if(cache_dir_num<0){	/* no such a directory */
137 		return(NULL);
138 	}
139 
140 	cache=cache_dir[cache_dir_num].ptr;
141 	if(cache==NULL){	/* no files in the directory */
142 		return(NULL);
143 	}
144 
145 	for(i=0;i<cache_dir[cache_dir_num].max_file;i++){
146 		if(cache[i].name!=NULL && strcmp(cache[i].name,file_name)==0){
147 			return(cache+i);
148 		}
149 	}
150 
151 	return(NULL);
152 }
153 
154 
155 /* --------------------------------------------------
156  NAME       get_cache
157  FUNCTION   get cached date and time
158  INPUT      file_name ... file name
159             date ... stored date
160             time ... stored time
161  OUTPUT     return 0 if successful, -1 otherwise
162 -------------------------------------------------- */
get_cache(char * file_name,long * date,long * time)163 int get_cache(char *file_name,long *date,long *time)
164 {
165 	Cache *cache;
166 
167 	cache=find_cache(file_name);
168 	if(cache!=NULL){
169 		*date=(*cache).date;
170 		*time=(*cache).time;
171 		return(0);
172 	}
173 	return(-1);
174 }
175 
176 
177 /* --------------------------------------------------
178  NAME       update_cache
179  FUNCTION   update file data of cache
180  INPUT      file_name ... file name
181             date ... date
182             time ... time
183  OUTPUT     none
184 -------------------------------------------------- */
update_cache(char * file_name,long date,long time)185 void update_cache(char *file_name,long date,long time)
186 {
187 	Cache *cache;
188 	int cache_dir_num;
189 	int max_cache_file;
190 
191 	cache=find_cache(file_name);
192 	if(cache!=NULL){
193 		(*cache).date=date;
194 		(*cache).time=time;
195 		return;
196 	}
197 
198 	cache_dir_num=find_cache_dir(current_dir[REMOTE]);
199 	if(cache_dir_num<0){
200 		fprintf(stderr,_("Internal error: cache facility is broken.\n"));
201 		exit(1);
202 	}
203 	max_cache_file=cache_dir[cache_dir_num].max_file;
204 	cache_dir[cache_dir_num].ptr=str_realloc(cache_dir[cache_dir_num].ptr,(max_cache_file+1)*sizeof(*cache_dir[cache_dir_num].ptr));
205 	cache=cache_dir[cache_dir_num].ptr;
206 	cache[max_cache_file].name=str_dup(file_name);
207 	cache[max_cache_file].date=date;
208 	cache[max_cache_file].time=time;
209 	cache_dir[cache_dir_num].max_file++;
210 }
211 
212 /* --------------------------------------------------
213  NAME       del_cache
214  FUNCTION   delete file data from cache
215  INPUT      file_name ... file name
216  OUTPUT     none
217 -------------------------------------------------- */
del_cache(char * file_name)218 void del_cache(char *file_name)
219 {
220 	Cache *cache;
221 
222 	cache=find_cache(file_name);
223 	if(cache!=NULL){
224 		free((*cache).name);
225 		(*cache).name=NULL;
226 	}
227 }
228 
229 
del_cache_dir(char * dir_name)230 void del_cache_dir(char *dir_name)
231 {
232 	int cache_dir_num;
233 	char *temp;
234 
235 	temp=str_concat(current_dir[REMOTE],dir_name,"/",NULL);
236 	cache_dir_num=find_cache_dir(temp);
237 	free(temp);
238 
239 	if(cache_dir_num>=0){
240 		free(cache_dir[cache_dir_num].name);
241 		cache_dir[cache_dir_num].name=NULL;
242 	}
243 }
244 
245 
update_cache_directory(char * dir)246 void update_cache_directory(char *dir)
247 {
248 	if(find_cache_dir(dir)<0){
249 		cache_dir=str_realloc(cache_dir,sizeof(*cache_dir)*(max_cache_dir+1));
250 		cache_dir[max_cache_dir].name=str_dup(dir);
251 		cache_dir[max_cache_dir].max_file=0;
252 		cache_dir[max_cache_dir].ptr=NULL;
253 		max_cache_dir++;
254 	}
255 }
256 
257 
find_cache_dir(char * name)258 int find_cache_dir(char *name)
259 {
260 	int i;
261 
262 	for(i=0;i<max_cache_dir;i++){
263 		if(cache_dir[i].name!=NULL && strcmp(cache_dir[i].name,name)==0){
264 			return(i);
265 		}
266 	}
267 	return(-1);
268 }
269 
270 
271 /* --------------------------------------------------
272  NAME       save_cache
273  FUNCTION   save cache of time stamp
274  OUTPUT     none
275 -------------------------------------------------- */
save_cache(void)276 void save_cache(void)
277 {
278 	char *temp;
279 	FILE *fp;
280 	Cache *cache;
281 	int i,j;
282 	/* don't free the cache because of frequent cache saves */
283 	int freecache = 0;
284 
285 	temp=str_concat(getenv("HOME"),"/.weex/weex.cache.",cfgSectionNumberToName(host_number),NULL);
286 	fp=fopen(temp,"w");
287 	if(fp==NULL){
288 		fprintf(stderr,_("Cannot create cache file `%s'.\n"),temp);
289 		exit(1);
290 	}
291 
292 	for(i=0;i<max_cache_dir;i++){
293 		if(cache_dir[i].name==NULL){	/* deleted directory */
294 			continue;
295 		}
296 		fprintf(fp,"00000000 000000 %s\n",cache_dir[i].name);
297 
298 		if(cache_dir[i].ptr!=NULL){
299 			cache=cache_dir[i].ptr;
300 			for(j=0;j<cache_dir[i].max_file;j++){
301 				if(cache[j].name==NULL){	/* deleted file */
302 					continue;
303 				}
304 				fprintf(fp,"%08ld %06ld %s\n",cache[j].date,cache[j].time,cache[j].name);
305 				if (freecache) free(cache[j].name);
306 			}
307 			if (freecache) free(cache);
308 		}
309 		if (freecache) free(cache_dir[i].name);
310 	}
311 
312 	fclose(fp);
313 	free(temp);
314 	if (freecache) free(cache_dir);
315 }
316 
317 
get_remote_file_data_from_cache(FileData ** remote_data)318 int get_remote_file_data_from_cache(FileData **remote_data)
319 {
320 	int cache_dir_num;
321 	Cache *cache;
322 	int i;
323 	int cache_max_file;
324 
325 	update_cache_directory(current_dir[REMOTE]);
326 
327 	if(!is_cache_existent){
328 		return(get_remote_file_data(remote_data));
329 	}
330 	cache_dir_num=find_cache_dir(current_dir[REMOTE]);
331 
332 	cache_max_file=cache_dir[cache_dir_num].max_file;
333 
334 	*remote_data=str_malloc(sizeof(**remote_data)*cache_max_file);
335 	cache=cache_dir[cache_dir_num].ptr;
336 	for(i=0;i<cache_max_file;i++){
337 		(*remote_data)[i].date=cache[i].date;
338 		(*remote_data)[i].time=cache[i].time;
339 		(*remote_data)[i].isdir=(cache[i].date==99999999);
340 		(*remote_data)[i].name=str_dup(cache[i].name);
341 	}
342 	return(cache_max_file);
343 }
344 
345