OSDN Git Service

Fix bugs of uninitialized variables.
[ffftp/ffftp.git] / cache.c
1 /*=============================================================================\r
2 *\r
3 *                                                               ファイル一覧キャッシュ\r
4 *\r
5 ===============================================================================\r
6 / Copyright (C) 1997-2007 Sota. All rights reserved.\r
7 /\r
8 / Redistribution and use in source and binary forms, with or without \r
9 / modification, are permitted provided that the following conditions \r
10 / are met:\r
11 /\r
12 /  1. Redistributions of source code must retain the above copyright \r
13 /     notice, this list of conditions and the following disclaimer.\r
14 /  2. Redistributions in binary form must reproduce the above copyright \r
15 /     notice, this list of conditions and the following disclaimer in the \r
16 /     documentation and/or other materials provided with the distribution.\r
17 /\r
18 / THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR \r
19 / IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES \r
20 / OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
21 / IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, \r
22 / INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, \r
23 / BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
24 / USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
25 / ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
26 / (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF \r
27 / THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
28 /============================================================================*/\r
29 \r
30 #define STRICT\r
31 // IPv6対応\r
32 #include <winsock2.h>\r
33 #include <windows.h>\r
34 #include <stdio.h>\r
35 #include <stdlib.h>\r
36 #include <string.h>\r
37 #include <time.h>\r
38 #include <mbstring.h>\r
39 #include <malloc.h>\r
40 #include <windowsx.h>\r
41 #include <commctrl.h>\r
42 \r
43 #include <stdarg.h>\r
44 \r
45 #include "common.h"\r
46 #include "resource.h"\r
47 \r
48 \r
49 \r
50 \r
51 static BOOL CALLBACK CountPrevFfftpWindowsProc(HWND hWnd, LPARAM lParam);\r
52 \r
53 \r
54 \r
55 /*===== キャッシュデータのストラクチャ =====*/\r
56 \r
57 typedef struct {\r
58         time_t Time;                                            /* リストに登録した時間 */\r
59         char HostAdrs[HOST_ADRS_LEN+1];         /* ホストのアドレス */\r
60         char UserName[USER_NAME_LEN+1];         /* ユーザ名 */\r
61         char Path[FMAX_PATH+1];                         /* パス名 */\r
62 } CACHELIST;\r
63 \r
64 /*===== ローカルなワーク =====*/\r
65 \r
66 static CACHELIST *RemoteCache = NULL;   /* キャッシュデータ */\r
67 static int TmpCacheEntry = 0;                   /* キャッシュされているデータの数 */\r
68 static int LastNum;                                             /* 現在表示しているデータの番号 */\r
69 static int ProgNum;                                             /* FFFTPの起動番号 */\r
70 \r
71 \r
72 /*----- ファイル一覧キャッシュを作成する --------------------------------------\r
73 *\r
74 *       Parameter\r
75 *               int Num : キャッシュ可能個数\r
76 *\r
77 *       Return Value\r
78 *               int ステータス\r
79 *                       FFFTP_SUCCESS/FFFTP_FAIL\r
80 *----------------------------------------------------------------------------*/\r
81 \r
82 int MakeCacheBuf(int Num)\r
83 {\r
84         int Sts;\r
85         int i;\r
86 \r
87         Sts = FFFTP_SUCCESS;\r
88         if(Num > 0)\r
89         {\r
90                 Sts = FFFTP_FAIL;\r
91                 if((RemoteCache = malloc(sizeof(CACHELIST) * Num)) != NULL)\r
92                 {\r
93                         TmpCacheEntry = Num;\r
94                         for(i = 0; i < TmpCacheEntry; i++)\r
95                                 ClearCache(i);\r
96                         Sts = FFFTP_SUCCESS;\r
97                 }\r
98         }\r
99         return(Sts);\r
100 }\r
101 \r
102 \r
103 /*----- ファイル一覧キャッシュを削除する --------------------------------------\r
104 *\r
105 *       Parameter\r
106 *               なし\r
107 *\r
108 *       Return Value\r
109 *               なし\r
110 *----------------------------------------------------------------------------*/\r
111 \r
112 void DeleteCacheBuf(void)\r
113 {\r
114         if(RemoteCache != NULL)\r
115                 free(RemoteCache);\r
116         RemoteCache = NULL;\r
117         TmpCacheEntry = 0;\r
118         return;\r
119 }\r
120 \r
121 \r
122 /*----- パスがキャッシュされているかどうかを返す ------------------------------\r
123 *\r
124 *       Parameter\r
125 *               char *Path : パス名\r
126 *\r
127 *       Return Value\r
128 *               int キャッシュデータの番号\r
129 *                       -1 = キャッシュされていない\r
130 *----------------------------------------------------------------------------*/\r
131 \r
132 int AskCached(char *Path)\r
133 {\r
134         int Ret;\r
135         int i;\r
136         CACHELIST *Pos;\r
137 \r
138         Ret = -1;\r
139         if(TmpCacheEntry > 0)\r
140         {\r
141                 Pos = RemoteCache;\r
142                 for(i = 0; i < TmpCacheEntry; i++)\r
143                 {\r
144                         if((_stricmp(AskHostAdrs(), Pos->HostAdrs) == 0) &&\r
145                            (strcmp(AskHostUserName(), Pos->UserName) == 0) &&\r
146                            (strcmp(Path, Pos->Path) == 0))\r
147                         {\r
148                                 time(&(Pos->Time));             /* Refresh */\r
149                                 Ret = i;\r
150 //                              DoPrintf("Filelist cache found. (%d)", Ret);\r
151                                 break;\r
152                         }\r
153                         Pos++;\r
154                 }\r
155         }\r
156         return(Ret);\r
157 }\r
158 \r
159 \r
160 /*----- 未使用のキャッシュデータ番号を返す ------------------------------------\r
161 *\r
162 *       Parameter\r
163 *               なし\r
164 *\r
165 *       Return Value\r
166 *               int 未使用のキャッシュデータ番号\r
167 *\r
168 *       Note\r
169 *               未使用の物が無い時は、一番古いものに上書きする\r
170 *----------------------------------------------------------------------------*/\r
171 \r
172 int AskFreeCache(void)\r
173 {\r
174         int Ret;\r
175         int i;\r
176         time_t Oldest;\r
177         CACHELIST *Pos;\r
178 \r
179         Ret = 0;\r
180         if(TmpCacheEntry > 0)\r
181         {\r
182                 Oldest = 0;\r
183                 Ret = -1;\r
184                 Pos = RemoteCache;\r
185                 for(i = 0; i < TmpCacheEntry; i++)\r
186                 {\r
187                         if(strlen(Pos->Path) == 0)\r
188                         {\r
189                                 Ret = i;\r
190                                 break;\r
191                         }\r
192                         else\r
193                         {\r
194                                 if((Ret == -1) || (Pos->Time < Oldest))\r
195                                 {\r
196                                         Oldest = Pos->Time;\r
197                                         Ret = i;\r
198                                 }\r
199                         }\r
200                         Pos++;\r
201                 }\r
202         }\r
203 //      DoPrintf("Set filelist cache. (%d)", Ret);\r
204         return(Ret);\r
205 }\r
206 \r
207 \r
208 /*----- キャッシュデータをセットする ------------------------------------------\r
209 *\r
210 *       Parameter\r
211 *               int Num : キャッシュデータ番号\r
212 *               char *Path : パス名\r
213 *\r
214 *       Return Value\r
215 *               なし\r
216 *\r
217 *       Note\r
218 *               現在接続中のホスト名を使用する\r
219 *----------------------------------------------------------------------------*/\r
220 \r
221 void SetCache(int Num, char *Path)\r
222 {\r
223         if(TmpCacheEntry > 0)\r
224         {\r
225                 strcpy((RemoteCache + Num)->HostAdrs, AskHostAdrs());\r
226                 strcpy((RemoteCache + Num)->UserName, AskHostUserName());\r
227                 strcpy((RemoteCache + Num)->Path, Path);\r
228                 time(&((RemoteCache + Num)->Time));\r
229         }\r
230         return;\r
231 }\r
232 \r
233 \r
234 /*----- キャッシュデータをクリアする ------------------------------------------\r
235 *\r
236 *       Parameter\r
237 *               int Num : キャッシュデータ番号\r
238 *\r
239 *       Return Value\r
240 *               なし\r
241 *----------------------------------------------------------------------------*/\r
242 \r
243 void ClearCache(int Num)\r
244 {\r
245         if(TmpCacheEntry > 0)\r
246         {\r
247                 strcpy((RemoteCache + Num)->HostAdrs, "");\r
248                 strcpy((RemoteCache + Num)->UserName, "");\r
249                 strcpy((RemoteCache + Num)->Path, "");\r
250                 (RemoteCache + Num)->Time = 0;\r
251         }\r
252         return;\r
253 }\r
254 \r
255 \r
256 /*----- 現在表示中のキャッシュデータ番号を返す --------------------------------\r
257 *\r
258 *       Parameter\r
259 *               なし\r
260 *\r
261 *       Return Value\r
262 *               int キャッシュデータ番号\r
263 *----------------------------------------------------------------------------*/\r
264 \r
265 int AskCurrentFileListNum(void)\r
266 {\r
267         return(LastNum);\r
268 }\r
269 \r
270 \r
271 /*----- 現在表示中のキャッシュデータ番号をセットする --------------------------\r
272 *\r
273 *       Parameter\r
274 *               int Num : キャッシュデータ番号\r
275 *\r
276 *       Return Value\r
277 *               なし\r
278 *----------------------------------------------------------------------------*/\r
279 \r
280 void SetCurrentFileListNum(int Num)\r
281 {\r
282         LastNum = Num;\r
283 }\r
284 \r
285 \r
286 /*----- キャッシュデータを保存する --------------------------------------------\r
287 *\r
288 *       Parameter\r
289 *               なし\r
290 *\r
291 *       Return Value\r
292 *               なし\r
293 *\r
294 *       Note\r
295 *               キャッシュデータそのものはファイルになっているので、ここではインデック\r
296 *               スファイルを作成する。\r
297 *               また、不要なファイルは削除する。\r
298 *----------------------------------------------------------------------------*/\r
299 \r
300 void SaveCache(void)\r
301 {\r
302         char Buf[FMAX_PATH+1];\r
303         FILE *fd;\r
304         CACHELIST *Pos;\r
305         int i;\r
306 \r
307         if(ProgNum == 0)        /* 最初のインスタンスだけがキャッシュを保存できる */\r
308         {\r
309                 if(TmpCacheEntry > 0)\r
310                 {\r
311                         strcpy(Buf, AskTmpFilePath());\r
312                         SetYenTail(Buf);\r
313                         strcat(Buf, "_ffftp.idx");\r
314                         if((fd = fopen(Buf, "wt"))!=NULL)\r
315                         {\r
316                                 Pos = RemoteCache;\r
317                                 for(i = 0; i < TmpCacheEntry; i++)\r
318                                 {\r
319                                         if(strlen(Pos->Path) != 0)\r
320                                                 fprintf(fd, "%s %s %s %ld\n", Pos->HostAdrs, Pos->UserName, Pos->Path, Pos->Time);\r
321                                         Pos++;\r
322                                 }\r
323                                 fclose(fd);\r
324                         }\r
325                 }\r
326         }\r
327         else\r
328                 DeleteCache();\r
329 \r
330         MakeCacheFileName(998, Buf);\r
331         _unlink(Buf);\r
332 \r
333         MakeCacheFileName(999, Buf);\r
334         _unlink(Buf);\r
335 \r
336         return;\r
337 }\r
338 \r
339 \r
340 /*----- キャッシュデータを読み込む --------------------------------------------\r
341 *\r
342 *       Parameter\r
343 *               なし\r
344 *\r
345 *       Return Value\r
346 *               なし\r
347 *----------------------------------------------------------------------------*/\r
348 \r
349 void LoadCache(void)\r
350 {\r
351         char Buf[FMAX_PATH+1];\r
352         FILE *fd;\r
353         CACHELIST *Pos;\r
354         int Num;\r
355 \r
356         if(ProgNum == 0)        /* 最初のインスタンスだけがキャッシュを保存できる */\r
357         {\r
358                 if(TmpCacheEntry > 0)\r
359                 {\r
360                         strcpy(Buf, AskTmpFilePath());\r
361                         SetYenTail(Buf);\r
362                         strcat(Buf, "_ffftp.idx");\r
363                         if((fd = fopen(Buf, "rt"))!=NULL)\r
364                         {\r
365                                 Pos = RemoteCache;\r
366                                 Num = 0;\r
367                                 while(Num < TmpCacheEntry)\r
368                                 {\r
369                                         if(fgets(Buf, FMAX_PATH, fd) == NULL)\r
370                                                 break;\r
371 \r
372                                         if(sscanf(Buf, "%s %s %s %ld\n", Pos->HostAdrs, Pos->UserName, Pos->Path, &(Pos->Time)) == 4)\r
373                                         {\r
374                                                 Pos++;\r
375                                                 Num++;\r
376                                         }\r
377                                         else\r
378                                                 ClearCache(Num);\r
379                                 }\r
380                                 fclose(fd);\r
381                         }\r
382                 }\r
383         }\r
384         return;\r
385 }\r
386 \r
387 \r
388 /*----- キャッシュデータを全て削除する ----------------------------------------\r
389 *\r
390 *       Parameter\r
391 *               なし\r
392 *\r
393 *       Return Value\r
394 *               なし\r
395 *----------------------------------------------------------------------------*/\r
396 \r
397 void DeleteCache(void)\r
398 {\r
399         char Buf[FMAX_PATH+1];\r
400         int i;\r
401 \r
402         if(ProgNum == 0)\r
403         {\r
404                 strcpy(Buf, AskTmpFilePath());\r
405                 SetYenTail(Buf);\r
406                 strcat(Buf, "_ffftp.idx");\r
407                 _unlink(Buf);\r
408         }\r
409 \r
410         for(i = 0; i <= TmpCacheEntry; i++)\r
411         {\r
412                 MakeCacheFileName(i, Buf);\r
413                 _unlink(Buf);\r
414         }\r
415 \r
416         MakeCacheFileName(998, Buf);\r
417         _unlink(Buf);\r
418 \r
419         MakeCacheFileName(999, Buf);\r
420         _unlink(Buf);\r
421 \r
422         return;\r
423 }\r
424 \r
425 \r
426 /*----- キャッシュのファイル名を作成する --------------------------------------\r
427 *\r
428 *       Parameter\r
429 *               int Num : キャッシュデータ番号\r
430 *               char *Buf : ファイル名を格納するバッファ\r
431 *\r
432 *       Return Value\r
433 *               なし\r
434 *----------------------------------------------------------------------------*/\r
435 \r
436 void MakeCacheFileName(int Num, char *Buf)\r
437 {\r
438         char Prog[10];\r
439         char *Pos;\r
440 \r
441         strcpy(Buf, AskTmpFilePath());\r
442         SetYenTail(Buf);\r
443         Pos = strchr(Buf, NUL);\r
444 \r
445         strcpy(Prog, "");\r
446         if(ProgNum > 0)\r
447                 sprintf(Prog, ".%d", ProgNum);\r
448 \r
449         sprintf(Pos, "_ffftp.%03d%s", Num, Prog);\r
450         return;\r
451 }\r
452 \r
453 \r
454 /*----- 起動しているFFFTPの数を数える ------------------------------------------\r
455 *\r
456 *       Parameter\r
457 *               なし\r
458 *\r
459 *       Return Value\r
460 *               なし\r
461 *\r
462 *       Note\r
463 *               個数はProgNumに格納する\r
464 *----------------------------------------------------------------------------*/\r
465 \r
466 void CountPrevFfftpWindows(void)\r
467 {\r
468         ProgNum = 0;\r
469         EnumWindows(CountPrevFfftpWindowsProc, 0);\r
470         return;\r
471 }\r
472 \r
473 \r
474 /*----- 起動しているFFFTPの数を数えるコールバック-------------------------------\r
475 *\r
476 *       Parameter\r
477 *               HWND hWnd : ウインドウハンドル\r
478 *               LPARAM lParam : パラメータ\r
479 *\r
480 *       Return Value\r
481 *               BOOL TRUE/FALSE\r
482 *----------------------------------------------------------------------------*/\r
483 \r
484 static BOOL CALLBACK CountPrevFfftpWindowsProc(HWND hWnd, LPARAM lParam)\r
485 {\r
486         char Buf[FMAX_PATH+1];\r
487 \r
488         if(GetClassName(hWnd, Buf, FMAX_PATH) > 0)\r
489         {\r
490                 if(strcmp(Buf, "FFFTPWin") == 0)\r
491                         ProgNum++;\r
492         }\r
493         return(TRUE);\r
494 }\r
495 \r
496 \r
497 \r