source: trunk/dll/avl.c@ 1625

Last change on this file since 1625 was 1625, checked in by Gregg Young, 14 years ago

Fix arc container view for .tar.gz files when using tar 1.15+ as the archiver. Ticket 473

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 37.1 KB
Line 
1
2/***********************************************************************
3
4 $Id: avl.c 1625 2011-08-26 21:36:20Z gyoung $
5
6 archiver.bb2 search, load, save and date parse
7
8 Copyright (c) 1993, 1998 M. Kimes
9 Copyright (c) 2004, 2008 Steven H.Levine
10
11 01 Aug 04 SHL Rework lstrip/rstrip usage
12 13 Aug 05 SHL Beautify with indent
13 13 Aug 05 SHL find_type: correct no sig exists bypass logic
14 13 Aug 05 SHL SBoxDlgProc: avoid dereferencing NULL signature
15 18 Aug 05 SHL Comments
16 31 Dec 05 SHL indent -i2
17 08 Dec 05 SHL load_archivers: allow empty startlist
18 30 Dec 05 SHL load_archivers: use get_archiver_line?(), clean nits
19 29 May 06 SHL SBoxDlgProc: support move, add, delete
20 30 May 06 SHL load_archivers: add reload support
21 16 Jun 06 SHL load_archivers: support signatures containing 0s
22 26 Jun 06 SHL load_archivers: remember where comments are
23 14 Jul 06 SHL Use Runtime_Error
24 29 Jul 06 SHL Use xfgets, xfgets_bstripcr
25 15 Aug 06 SHL Use Runtime_Error more
26 01 Nov 06 SHL Turn off leftover debug code
27 06 Apr 07 GKY Work around PM DragInfo and DrgFreeDISH limit
28 19 Apr 07 SHL Use FreeDragInfoData
29 19 Apr 07 SHL Add more drag/drop error checking
30 20 Aug 07 GKY Move #pragma alloc_text to end for OpenWatcom compat
31 25 Aug 07 SHL load_archivers: add missing close on error path
32 29 Feb 08 GKY Use xfree where appropriate
33 22 Jun 08 GKY Added free_archivers for fortify checking
34 19 Jul 08 GKY ifdef Fortify free_archivers
35 29 Nov 08 GKY Add ini entry for LastArchiver so the previous archiver is selected in the
36 Select archive dialog if no default is provided.
37 29 Nov 08 GKY Remove or replace with a mutex semaphore DosEnterCriSec where appropriate.
38 11 Jan 08 GKY Replace "ARCHIVER.BB2" in string file with global set at compile in init.c
39 08 Mar 09 GKY Additional strings move to PCSZs in init.c
40 23 Oct 10 GKY Changes to populate and utilize a HELPTABLE for context specific help
41 21 Nov 10 GKY Check if archiver.bb2 has been changed on disk before editing
42 13 Aug 11 GKY Change to Doxygen comment format
43 26 Aug 11 GKY Add the code to correctly format the date time strings for tar.gz archives
44 viewed using tar 1.15+
45
46***********************************************************************/
47
48#include <stdlib.h>
49#include <string.h>
50#include <ctype.h>
51#include <share.h>
52#include <sys/stat.h>
53
54#define INCL_DOS
55#define INCL_WIN
56#define INCL_WINSTDDRAG
57#define INCL_LONGLONG
58
59#include "fm3dll.h"
60#include "fm3dll2.h" // #define's for UM_*, control id's, etc.
61#include "notebook.h" // Data declaration(s)
62#include "init.h" // Data declaration(s)
63#include "valid.h" // Data declaration(s)
64#include "mainwnd.h" // Data declaration(s)
65#include "fm3dlg.h"
66#include "fm3str.h"
67#include "avl.h"
68#include "strutil.h" // GetPString
69#include "errutil.h" // Runtime_Error
70#include "avv.h" // ArcReviewDlgProc, rewrite_archiverbb2
71#include "droplist.h" // DropHelp, FullDrgName
72#include "misc.h" // DrawTargetEmphasis
73#include "draglist.h" // FreeDragInfoData
74#include "chklist.h" // PosOverOkay
75#include "literal.h" // literal
76#include "wrappers.h" // xfgets
77#include "strips.h" // bstrip
78#include "srchpath.h" // searchpath
79#include "stristr.h" // stristr
80#include "delims.h" // to_delim
81#include "fortify.h"
82
83// Data definitions
84static PSZ pszSrcFile = __FILE__;
85static void fill_listbox(HWND hwnd, BOOL fShowAll, SHORT sOldSelect);
86
87#pragma data_seg(GLOBAL1)
88ARC_TYPE *arcsighead;
89UINT arcsigs_header_lines; // Header comments line count in archiver.bb2
90UINT arcsigs_trailer_line_num; // Trailer comments start line number (1..n)
91BOOL arcsigsloaded;
92BOOL arcsigsmodified;
93static struct stat Archiverbb2Stats;
94
95#define ARCHIVER_LINE_BYTES 256
96
97//=== quick_find_type() ===
98ARC_TYPE *quick_find_type(CHAR * filespec, ARC_TYPE * topsig)
99{
100 ARC_TYPE *info, *found = NULL;
101 CHAR *p;
102
103 if (!arcsigsloaded)
104 load_archivers();
105 p = strrchr(filespec, '.');
106 if (p) {
107 p++;
108 info = (topsig) ? topsig : arcsighead;
109 while (info) {
110 if (info->ext && *(info->ext) && !stricmp(p, info->ext)) {
111 found = find_type(filespec, topsig);
112 break;
113 }
114 info = info->next;
115 }
116 }
117 return found;
118}
119
120//=== fill_listbox() fill or refill listbox from current archiver definitions ===
121
122static VOID fill_listbox(HWND hwnd, BOOL fShowAll, SHORT sOldSelect)
123{
124 ARC_TYPE *pat;
125 BOOL found = FALSE;
126 SHORT sSelect;
127
128 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_DELETEALL, MPVOID, MPVOID);
129
130 for (pat = arcsighead; pat; pat = pat->next) {
131 /**
132 * this inner loop tests for a dup signature entry and assures
133 * that only the entry at the top of the list gets used for
134 * conversion; editing any is okay
135 */
136 if (!fShowAll) {
137 ARC_TYPE *pat2;
138 BOOL isDup = FALSE;
139
140 for (pat2 = arcsighead;
141 pat2 && pat->siglen && pat2 != pat && !isDup; pat2 = pat2->next) {
142 isDup = pat2->siglen == pat->siglen &&
143 !memcmp(pat2->signature, pat->signature, pat->siglen);
144 } // for
145 if (isDup)
146 continue;
147 }
148
149 // If caller is editing archivers or entry useful to caller, show in listbox
150 if (fShowAll || (pat->id && pat->extract && pat->create)) {
151 sSelect = (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
152 MPFROM2SHORT(LIT_END, 0),
153 MPFROMP(pat->id ? pat->id : "?"));
154 if (!found && *szDefArc && pat->id && !strcmp(szDefArc, pat->id)) {
155 // Highlight default
156 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
157 MPFROMSHORT(sSelect), MPFROMSHORT(TRUE));
158 found = TRUE;
159 }
160 }
161 else {
162 // Complain about odd entry
163 if (!pat->id || !*pat->id) {
164 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
165 MPFROM2SHORT(LIT_END, 0),
166 MPFROMP(GetPString(IDS_UNKNOWNUNUSABLETEXT)));
167 }
168 else {
169 CHAR s[81];
170
171 sprintf(s, "%0.12s %s", pat->id, GetPString(IDS_UNUSABLETEXT));
172 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
173 MPFROM2SHORT(LIT_END, 0), MPFROMP(s));
174 }
175 }
176 } // while scanning
177
178 // Try to reselect last selection unless user wants default selection
179 if (sOldSelect == LIT_NONE) {
180 ULONG size = sizeof(SHORT);
181
182 PrfQueryProfileData(fmprof, appname, "LastArchiver", &sOldSelect, &size);
183 }
184 if (sOldSelect != LIT_NONE && !found) {
185 SHORT sItemCount =
186 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
187 MPVOID, MPVOID);
188
189 if (sOldSelect >= sItemCount)
190 sOldSelect = sItemCount - 1;
191 if (sOldSelect >= 0) {
192 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
193 MPFROMSHORT(sOldSelect), MPFROMSHORT(TRUE));
194 }
195 }
196
197 if (found)
198 PosOverOkay(hwnd);
199}
200
201ARC_TYPE *find_type(CHAR * filespec, ARC_TYPE * topsig)
202{
203 HFILE handle;
204 ULONG action;
205 ULONG len;
206 ULONG l;
207 ARC_TYPE *info;
208 CHAR *p;
209 CHAR buffer[4096]; // 06 Oct 07 SHL Protect against NTFS defect
210
211 if (!arcsigsloaded)
212 load_archivers();
213 if (!topsig)
214 topsig = arcsighead;
215 DosError(FERR_DISABLEHARDERR);
216 if (DosOpen(filespec,
217 &handle,
218 &action,
219 0,
220 0,
221 OPEN_ACTION_FAIL_IF_NEW |
222 OPEN_ACTION_OPEN_IF_EXISTS,
223 OPEN_FLAGS_FAIL_ON_ERROR |
224 OPEN_FLAGS_NOINHERIT |
225 OPEN_FLAGS_RANDOMSEQUENTIAL |
226 OPEN_SHARE_DENYNONE | OPEN_ACCESS_READONLY, 0))
227 return NULL;
228 // Scan signatures
229 for (info = topsig; info; info = info->next) {
230 if (info->siglen == 0) {
231 // No signature -- check extension
232 p = strrchr(filespec, '.');
233 if (p) {
234 p++;
235 if (info->ext && *(info->ext) && !stricmp(p, info->ext))
236 break; // Matched
237
238 }
239 continue; // Next sig
240
241 }
242 // Try signature match
243 l = info->siglen;
244 l = min(l, 79);
245 if (!DosChgFilePtr(handle,
246 abs(info->file_offset),
247 (info->file_offset >= 0) ? FILE_BEGIN : FILE_END,
248 &len)) {
249 if (!DosRead(handle, buffer, l, &len) && len == l) {
250 if (!memcmp(info->signature, buffer, l))
251 break; // Matched
252
253 }
254 }
255 } // for
256
257 DosClose(handle); // Either way, we're done for now
258 return info; // Return signature, if any
259}
260
261# ifdef FORTIFY
262
263VOID free_archivers(VOID)
264{
265 ARC_TYPE *pat, *next;
266
267 pat = arcsighead;
268 while (pat) {
269 next = pat->next;
270 xfree(pat->id, pszSrcFile, __LINE__);
271 xfree(pat->ext, pszSrcFile, __LINE__);
272 xfree(pat->list, pszSrcFile, __LINE__);
273 xfree(pat->extract, pszSrcFile, __LINE__);
274 xfree(pat->create, pszSrcFile, __LINE__);
275 xfree(pat->move, pszSrcFile, __LINE__);
276 xfree(pat->delete, pszSrcFile, __LINE__);
277 xfree(pat->signature, pszSrcFile, __LINE__);
278 xfree(pat->startlist, pszSrcFile, __LINE__);
279 xfree(pat->endlist, pszSrcFile, __LINE__);
280 xfree(pat->exwdirs, pszSrcFile, __LINE__);
281 xfree(pat->test, pszSrcFile, __LINE__);
282 xfree(pat->createrecurse, pszSrcFile, __LINE__);
283 xfree(pat->createwdirs, pszSrcFile, __LINE__);
284 xfree(pat->movewdirs, pszSrcFile, __LINE__);
285 xfree(pat, pszSrcFile, __LINE__);
286 pat = next;
287 }
288 arcsighead = NULL;
289}
290
291//=== free_arc_type() free allocated ARC_TYPE ===
292
293# endif
294
295VOID free_arc_type(ARC_TYPE * pat)
296{
297 if (pat) {
298 xfree(pat->id, pszSrcFile, __LINE__);
299 xfree(pat->ext, pszSrcFile, __LINE__);
300 xfree(pat->list, pszSrcFile, __LINE__);
301 xfree(pat->extract, pszSrcFile, __LINE__);
302 xfree(pat->create, pszSrcFile, __LINE__);
303 xfree(pat->move, pszSrcFile, __LINE__);
304 xfree(pat->delete, pszSrcFile, __LINE__);
305 xfree(pat->signature, pszSrcFile, __LINE__);
306 xfree(pat->startlist, pszSrcFile, __LINE__);
307 xfree(pat->endlist, pszSrcFile, __LINE__);
308 xfree(pat->exwdirs, pszSrcFile, __LINE__);
309 xfree(pat->test, pszSrcFile, __LINE__);
310 xfree(pat->createrecurse, pszSrcFile, __LINE__);
311 xfree(pat->createwdirs, pszSrcFile, __LINE__);
312 xfree(pat->movewdirs, pszSrcFile, __LINE__);
313 free(pat);
314 }
315}
316
317static UINT cur_line_num; // Input file line counter
318
319//=== get_line_strip_comments() read line, strip comments and whitespace ===
320
321static PSZ get_line_strip_comments(PSZ pszIn, FILE * fp)
322{
323 PSZ psz = xfgets(pszIn, ARCHIVER_LINE_BYTES, fp, pszSrcFile, __LINE__);
324 PSZ psz2;
325
326 if (psz) {
327 cur_line_num++;
328 psz2 = strchr(pszIn, ';');
329 if (psz2)
330 *psz2 = 0; // Chop comment
331 bstripcr(pszIn); // Strip leading white and trailing white and CR/LF
332
333 }
334 return psz;
335}
336
337//=== get_line_strip_white() read line, strip whitespace ===
338
339static PSZ get_line_strip_white(PSZ pszIn, FILE * fp)
340{
341 PSZ psz =
342 xfgets_bstripcr(pszIn, ARCHIVER_LINE_BYTES, fp, pszSrcFile, __LINE__);
343
344 if (psz)
345 cur_line_num++;
346
347 return psz;
348}
349
350//=== load_archivers() load or reload archive definitions from archiver.bb2 ===
351
352INT load_archivers(VOID)
353{
354 FILE *fp;
355 CHAR sz[ARCHIVER_LINE_BYTES + 1];
356 CHAR *psz;
357 ARC_TYPE *pat = NULL;
358 ARC_TYPE *patLast = NULL;
359 UINT lines_per_arcsig = LINES_PER_ARCSIG;
360 UINT per_sig_comment_line_num = 0;
361 INT i;
362 CHAR *moder = "r";
363
364 // Free current signatures
365 if (arcsighead) {
366 for (pat = arcsighead; pat;) {
367 patLast = pat;
368 pat = pat->next;
369 free_arc_type(patLast);
370 }
371 arcsighead = NULL;
372 }
373
374 arcsigsmodified = FALSE;
375 arcsigs_header_lines = 0;
376 arcsigs_trailer_line_num = 0;
377
378 //DosEnterCritSec(); //GKY 11-29-08
379 DosRequestMutexSem(hmtxFM2Globals, SEM_INDEFINITE_WAIT);
380 psz = searchpath(PCSZ_ARCHIVERBB2);
381 if (!psz || !*psz) {
382 DosReleaseMutexSem(hmtxFM2Globals);
383 //DosExitCritSec();
384 return -1;
385 }
386 stat(psz, &Archiverbb2Stats);
387 fp = xfsopen(psz, moder, SH_DENYWR, pszSrcFile, __LINE__, TRUE);
388 DosReleaseMutexSem(hmtxFM2Globals);
389 //DosExitCritSec();
390 if (!fp)
391 return -2;
392 strcpy(archiverbb2, psz); // Remember full path
393
394 cur_line_num = 0;
395
396 // Line 1 must contain number of lines per signature definition
397 if (!get_line_strip_comments(sz, fp)) {
398 fclose(fp);
399 return -3;
400 }
401 if (*sz)
402 lines_per_arcsig = atoi(sz);
403 if (!*sz || lines_per_arcsig < LINES_PER_ARCSIG) {
404 fclose(fp); // 25 Aug 07 SHL
405 return -3;
406 }
407
408 // Parse rest of file
409 // 1st non-blank line starts definition
410 // Need to determine header size and start of trailer
411
412 while (!feof(fp)) {
413 // If reading header
414 if (!arcsigs_header_lines) {
415 // Reading header - find header size and start of signtures
416 if (!get_line_strip_white(sz, fp))
417 break; // Unexpected EOF
418 if (stristr(sz, "-- Current Archivers --")) {
419 arcsigs_header_lines = cur_line_num;
420 continue;
421 }
422 if (!*sz || *sz == ';')
423 continue; // Header comment or blank line
424 else {
425 // Not a comment, must be start of signatures
426 PSZ psz2 = strchr(sz, ';');
427
428 if (psz2) {
429 *psz2 = 0; // Chop trailing comment
430 bstripcr(sz); // Strip leading white and trailing white and CR/LF
431 }
432 arcsigs_header_lines = cur_line_num - 1;
433 }
434 }
435 else {
436 // Reading defintiions
437 if (!get_line_strip_comments(sz, fp))
438 break; // EOF
439 }
440
441 // fixme to avoid allocating empty fields
442
443 // Remember start of per sig comments for next definition
444 if (per_sig_comment_line_num == 0)
445 per_sig_comment_line_num = cur_line_num;
446
447 if (*sz) {
448 // At start of defintion
449
450 pat = xmallocz(sizeof(ARC_TYPE), pszSrcFile, __LINE__);
451 if (!pat)
452 break;
453 pat->id = xstrdup(sz, pszSrcFile, __LINE__);
454
455 pat->comment_line_num = per_sig_comment_line_num;
456 pat->defn_line_num = cur_line_num;
457
458 if (!get_line_strip_comments(sz, fp)) // line 2 - extension
459 break;
460 if (*sz)
461 pat->ext = xstrdup(sz, pszSrcFile, __LINE__);
462 else
463 pat->ext = NULL;
464 if (!get_line_strip_comments(sz, fp)) // line 3 - offset to signature
465 break;
466 pat->file_offset = atol(sz);
467 if (!get_line_strip_comments(sz, fp)) // line 4 - list command
468 break;
469 if (*sz)
470 pat->list = xstrdup(sz, pszSrcFile, __LINE__);
471 else
472 pat->list = NULL;
473 if (!pat->list)
474 break; // Must have list command - fixme to complain
475 if (!get_line_strip_comments(sz, fp)) // line 5
476 break;
477 if (*sz)
478 pat->extract = xstrdup(sz, pszSrcFile, __LINE__);
479 else
480 pat->extract = NULL;
481 if (!get_line_strip_comments(sz, fp)) // line 6
482 break;
483 if (*sz)
484 pat->exwdirs = xstrdup(sz, pszSrcFile, __LINE__);
485 else
486 pat->exwdirs = NULL;
487 if (!get_line_strip_comments(sz, fp)) // line 7
488 break;
489 if (*sz)
490 pat->test = xstrdup(sz, pszSrcFile, __LINE__);
491 else
492 pat->test = NULL;
493 if (!get_line_strip_comments(sz, fp)) // line 8
494 break;
495 if (*sz)
496 pat->create = xstrdup(sz, pszSrcFile, __LINE__);
497 else
498 pat->create = NULL;
499 if (!get_line_strip_comments(sz, fp)) // line 9
500 break;
501 if (*sz)
502 pat->createwdirs = xstrdup(sz, pszSrcFile, __LINE__);
503 else
504 pat->createwdirs = NULL;
505 if (!get_line_strip_comments(sz, fp)) // line 10
506 break;
507 if (*sz)
508 pat->createrecurse = xstrdup(sz, pszSrcFile, __LINE__);
509 else
510 pat->createrecurse = NULL;
511 if (!get_line_strip_comments(sz, fp)) // line 11
512 break;
513 if (*sz)
514 pat->move = xstrdup(sz, pszSrcFile, __LINE__);
515 else
516 pat->move = NULL;
517 if (!get_line_strip_comments(sz, fp)) // line 12
518 break;
519 if (*sz)
520 pat->movewdirs = xstrdup(sz, pszSrcFile, __LINE__);
521 else
522 pat->movewdirs = NULL;
523 if (!get_line_strip_comments(sz, fp)) // line 13
524 break;
525 if (*sz)
526 pat->delete = xstrdup(sz, pszSrcFile, __LINE__);
527 else
528 pat->delete = NULL;
529 if (!get_line_strip_white(sz, fp)) // line 14
530 break;
531 i = literal(sz); // Translate \ escapes
532 if (i) {
533 pat->siglen = i;
534 pat->signature = xmalloc(i, pszSrcFile, __LINE__);
535 if (!pat->signature)
536 break;
537 memcpy(pat->signature, sz, i); // signature may not be a string
538 }
539 else {
540 pat->siglen = 0;
541 pat->signature = NULL;
542 }
543 if (!get_line_strip_white(sz, fp)) // line 15
544 break;
545 if (*sz)
546 pat->startlist = xstrdup(sz, pszSrcFile, __LINE__);
547 else
548 pat->startlist = NULL;
549 if (!get_line_strip_white(sz, fp)) // line 16
550 break;
551 if (*sz)
552 pat->endlist = xstrdup(sz, pszSrcFile, __LINE__);
553 else
554 pat->endlist = NULL;
555 if (!get_line_strip_comments(sz, fp)) // line 17
556 break;
557 pat->osizepos = atoi(sz);
558 if (!get_line_strip_comments(sz, fp)) // line 18
559 break;
560 pat->nsizepos = atoi(sz);
561 if (!get_line_strip_comments(sz, fp)) // line 19
562 break;
563 pat->fdpos = atoi(sz);
564 psz = strchr(sz, ',');
565 if (psz) {
566 psz++;
567 pat->datetype = atoi(psz);
568 }
569 if (!get_line_strip_comments(sz, fp)) // line 20
570 break;
571 pat->fdflds = atoi(sz);
572 if (!get_line_strip_comments(sz, fp)) // line 21
573 break;
574 pat->fnpos = atoi(sz);
575 psz = strchr(sz, ',');
576 if (psz) {
577 psz++;
578 pat->nameislast = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
579 psz = strchr(psz, ',');
580 if (psz) {
581 psz++;
582 pat->nameisnext = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
583 psz = strchr(psz, ',');
584 if (psz) {
585 psz++;
586 pat->nameisfirst = (BOOL) (*psz && atol(psz) == 0) ? FALSE : TRUE;
587 }
588 }
589 }
590 // Ignore unknown lines - must be newer file format
591 for (i = LINES_PER_ARCSIG; i < lines_per_arcsig; i++) {
592 if (!get_line_strip_comments(sz, fp))
593 break; // Unexpected EOF - fixme to complain
594 }
595
596 // Add to list, assume next and prev already NULL
597 if (!arcsighead)
598 arcsighead = patLast = pat;
599 else {
600 patLast->next = pat;
601 pat->prev = patLast;
602 patLast = pat;
603 }
604 pat = NULL; // Done with this defintion
605
606 arcsigs_trailer_line_num = cur_line_num + 1; // In case this is last defintion
607 per_sig_comment_line_num = 0;
608 } // if got definition
609
610 } // while more lines
611
612 fclose(fp);
613
614 free_arc_type(pat); // In case partial definition in progress
615
616 if (!arcsighead)
617 return -4;
618
619 arcsigsloaded = TRUE;
620
621 return 0;
622}
623
624#define TEST_DRAG 0 // fixme to be gone or to work
625
626static MRESULT EXPENTRY SDlgListboxSubclassProc(HWND hwnd, ULONG msg,
627 MPARAM mp1, MPARAM mp2)
628{
629 PFNWP pfnOldProc = (PFNWP) WinQueryWindowPtr(hwnd, QWL_USER);
630
631 PDRAGITEM pDItem;
632 PDRAGINFO pDInfo;
633 BOOL ok;
634
635 static BOOL emphasized = FALSE;
636 static PSZ DRMDRF_LBOX = "<DRM_LBOX,DRF_UNKNOWN>";
637 static PSZ DRM_LBOX = "DRM_LBOX";
638
639 switch (msg) {
640 case WM_BEGINDRAG:
641 {
642 LONG cur_ndx;
643 DRAGITEM ditem;
644 DRAGIMAGE dimage;
645 HWND hwndDrop;
646
647 // fprintf(stderr, "SDlgListboxSubclassProc: BEGINDRAG\n");
648 cur_ndx = WinQueryLboxSelectedItem(hwnd);
649
650 if (cur_ndx != LIT_NONE) {
651 pDInfo = DrgAllocDraginfo(1);
652 if (pDInfo) {
653 pDInfo->usOperation = DO_DEFAULT;
654 pDInfo->hwndSource = hwnd;
655
656 memset(&ditem, 0, sizeof(DRAGITEM));
657 ditem.hwndItem = hwnd;
658 ditem.ulItemID = 1;
659 ditem.hstrType = DrgAddStrHandle(DRT_UNKNOWN);
660 ditem.hstrRMF = DrgAddStrHandle(DRMDRF_LBOX);
661 ditem.hstrContainerName = DrgAddStrHandle(NullStr);
662 ditem.hstrSourceName = DrgAddStrHandle(NullStr);
663 ditem.hstrTargetName = DrgAddStrHandle(NullStr);
664 ditem.fsSupportedOps = DO_MOVEABLE;
665
666 memset(&dimage, 0, sizeof(DRAGIMAGE));
667 dimage.cb = sizeof(DRAGIMAGE);
668 dimage.hImage = hptrFile;
669 dimage.cptl = 0;
670 dimage.fl = DRG_ICON;
671 dimage.sizlStretch.cx = 32;
672 dimage.sizlStretch.cy = 32;
673 dimage.cxOffset = -16;
674 dimage.cyOffset = 0;
675 DrgSetDragitem(pDInfo, &ditem, sizeof(DRAGITEM), 0); // Index of DRAGITEM
676 hwndDrop = DrgDrag(hwnd, pDInfo, &dimage, 1, // One DRAGIMAGE
677 VK_ENDDRAG, NULL);
678 if (!hwndDrop)
679 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__, "DrgDrag");
680
681 DrgFreeDraginfo(pDInfo);
682 }
683 }
684 break;
685 }
686
687 case DM_DRAGOVER:
688 ok = FALSE;
689 if (!emphasized) {
690 POINTL ptl;
691 POINTL ptl2;
692
693 emphasized = TRUE;
694 ptl.x = SHORT1FROMMP(mp2);
695 ptl.y = SHORT2FROMMP(mp2);
696 ptl2 = ptl;
697 WinMapWindowPoints(HWND_DESKTOP, hwnd, &ptl2, 1);
698 // fprintf(stderr, "DRAGOVER mapped x y %d %d to %d %d\n", ptl.x, ptl.y, ptl2.x, ptl2.y);
699 WinPostMsg(hwnd, WM_BUTTON1CLICK,
700 MPFROM2SHORT((SHORT) ptl2.x, (SHORT) ptl2.y),
701 MPFROM2SHORT(HT_NORMAL, KC_NONE));
702 // fprintf(stderr, "DRAGOVER posted 0x%x WM_BUTTON1CLICK x y %d %d\n", hwnd, ptl2.x, ptl2.y);
703 }
704 pDInfo = (PDRAGINFO) mp1; // Get DRAGINFO pointer
705 if (pDInfo) {
706 if (!DrgAccessDraginfo(pDInfo)) {
707 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
708 PCSZ_DRGACCESSDRAGINFO);
709 }
710 else {
711 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
712 // Check valid rendering mechanisms and data format
713 ok = DrgVerifyRMF(pDItem, DRM_LBOX, NULL);
714 DrgFreeDraginfo(pDInfo);
715 }
716 }
717 return ok ? MRFROM2SHORT(DOR_DROP, DO_MOVE) :
718 MRFROM2SHORT(DOR_NEVERDROP, 0);
719
720 case DM_DRAGLEAVE:
721 if (emphasized) {
722 emphasized = FALSE;
723 // fixme to draw listbox item emphasized
724 // DrawTargetEmphasis(hwnd, emphasized);
725 // fprintf(stderr, "DRAGLEAVE\n");
726 fflush(stderr);
727 }
728 return 0;
729
730 case DM_DROPHELP:
731 DropHelp(mp1, mp2, hwnd, "fixme to give some help");
732 return 0;
733
734 case DM_DROP:
735 ok = FALSE;
736 if (emphasized) {
737 emphasized = FALSE;
738 // DrawTargetEmphasis(hwnd, emphasized);
739 }
740 pDInfo = (PDRAGINFO) mp1; // Get DRAGINFO pointer
741 if (pDInfo) {
742 if (!DrgAccessDraginfo(pDInfo)) {
743 Win_Error(HWND_DESKTOP, HWND_DESKTOP, pszSrcFile, __LINE__,
744 PCSZ_DRGACCESSDRAGINFO);
745 }
746 else {
747 pDItem = DrgQueryDragitemPtr(pDInfo, 0);
748 if (!pDItem)
749 Win_Error(hwnd, hwnd, pszSrcFile, __LINE__, "DM_DROP");
750 // Check valid rendering mechanisms and data
751 ok = DrgVerifyRMF(pDItem, DRM_LBOX, NULL)
752 && ~pDItem->fsControl & DC_PREPARE;
753 if (ok) {
754 // note: targetfail is returned to source for all items
755 DrgSendTransferMsg(pDInfo->hwndSource, DM_ENDCONVERSATION,
756 MPFROMLONG(pDItem->ulItemID),
757 MPFROMLONG(DMFL_TARGETSUCCESSFUL));
758 }
759 FreeDragInfoData(hwnd, pDInfo);
760 }
761 }
762 return 0;
763 } // switch
764 return pfnOldProc ? pfnOldProc(hwnd, msg, mp1, mp2) :
765 WinDefWindowProc(hwnd, msg, mp1, mp2);
766}
767
768//=== SBoxDlgProc() Select archiver to use or edit, supports list reorder too ===
769
770static PSZ pszCantFindMsg = "Can't find item %d";
771
772MRESULT EXPENTRY SBoxDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
773{
774 ARC_TYPE **ppatReturn; // Where to return selected archiver
775 ARC_TYPE *pat;
776 SHORT sSelect;
777 SHORT sItemCount;
778 CHAR szItemText[256];
779 CHAR szPCItemText[256]; // Parent or child item text
780 SHORT i;
781 BOOL fShowAll;
782
783 static SHORT sLastSelect = LIT_NONE;
784
785 switch (msg) {
786 case WM_INITDLG:
787 if (!arcsigsloaded)
788 load_archivers();
789 else {
790 struct stat Buffer;
791
792 stat(searchpath(PCSZ_ARCHIVERBB2), &Buffer);
793 if (Archiverbb2Stats.st_size != Buffer.st_size ||
794 Archiverbb2Stats.st_mtime != Buffer.st_mtime)
795 if (saymsg(MB_YESNO,
796 hwnd,
797 GetPString(IDS_ADCHANGESONDISKTEXT),
798 GetPString(IDS_ADRELOADMEMTEXT)) == MBID_YES)
799 load_archivers();
800 }
801 if (!(ARC_TYPE **) mp2) {
802 Runtime_Error(pszSrcFile, __LINE__, NULL);
803 WinDismissDlg(hwnd, 0);
804 break;
805 }
806 /** Passed arg points to where to return selected archiver definition
807 * On input arg value controls selection list content
808 * If non-NULL, dup names are suppressed
809 * If NULL, all definitions are shown
810 */
811 ppatReturn = (ARC_TYPE **) mp2;
812 fShowAll = *ppatReturn == NULL;
813 if (*ppatReturn)
814 *ppatReturn = arcsighead; // Preset to first
815 WinSetWindowPtr(hwnd, QWL_USER, (PVOID) ppatReturn);
816 fill_listbox(hwnd, fShowAll, sLastSelect);
817
818#ifdef TEST_DRAG // fixme
819 {
820 HWND hwnd2 = WinWindowFromID(hwnd, ASEL_LISTBOX);
821 PFNWP pfn = WinSubclassWindow(hwnd2,
822 SDlgListboxSubclassProc);
823
824 WinSetWindowPtr(hwnd2, QWL_USER, (PVOID) pfn);
825 }
826#endif // TEST_DRAG fixme
827
828 break;
829
830 case WM_HELP:
831 if (hwndHelp)
832 WinSendMsg(hwndHelp,
833 HM_DISPLAY_HELP,
834 MPFROMSHORT(1), MPFROMSHORT(HM_RESOURCEID));
835 break;
836
837 case WM_COMMAND:
838 ppatReturn = (ARC_TYPE **) WinQueryWindowPtr(hwnd, QWL_USER);
839 switch (SHORT1FROMMP(mp1)) {
840 case DID_OK:
841 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
842 ASEL_LISTBOX,
843 LM_QUERYSELECTION,
844 MPFROMSHORT(LIT_FIRST), MPVOID);
845 if (sSelect == LIT_NONE) {
846 Runtime_Error(pszSrcFile, __LINE__, "list empty");
847 return 0;
848 }
849 pat = arcsighead;
850 if (*ppatReturn) {
851 // If dups hidden, find archiver with matching id
852 *szItemText = 0;
853 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
854 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
855 if (!*szItemText)
856 pat = NULL;
857 else {
858 for (; pat; pat = pat->next) {
859 if (pat->id && !strcmp(szItemText, pat->id))
860 break; // Found it
861 }
862 }
863 }
864 else {
865 // If dups not hidden, lookup by count
866 for (i = 0; pat && i < sSelect; i++, pat = pat->next) ; // Scan
867 }
868 if (pat && (!*ppatReturn || (pat->id && pat->extract && pat->create))) {
869 *ppatReturn = pat;
870 }
871 else {
872 Runtime_Error(pszSrcFile, __LINE__, "no match");
873 // Refuse to select
874 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
875 MPFROMSHORT(LIT_NONE), FALSE);
876 return 0;
877 }
878 PrfWriteProfileData(fmprof, appname, "LastArchiver", &sSelect, sizeof(SHORT));
879 sLastSelect = sSelect;
880 WinDismissDlg(hwnd, TRUE);
881 return 0;
882
883 case DID_CANCEL:
884 if (arcsigsmodified) {
885 if (saymsg(MB_YESNO,
886 hwnd,
887 GetPString(IDS_ADCHANGESINMEMTEXT),
888 GetPString(IDS_ADREWRITETEXT), NullStr) == MBID_YES) {
889 PSZ ab2 = searchpath(PCSZ_ARCHIVERBB2); // Rewrite without prompting
890
891 rewrite_archiverbb2(ab2);
892 }
893 }
894 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
895 ASEL_LISTBOX,
896 LM_QUERYSELECTION,
897 MPFROMSHORT(LIT_FIRST), MPVOID);
898 if (sSelect != LIT_NONE) {
899 sLastSelect = sSelect;
900 PrfWriteProfileData(fmprof, appname, "LastArchiver", &sSelect, sizeof(SHORT));
901 }
902 *ppatReturn = NULL;
903 PostMsg(hwnd, WM_CLOSE, MPVOID, MPVOID); // fixme to understand why needed
904 return 0;
905
906 case ASEL_PB_ADD:
907 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
908 ASEL_LISTBOX,
909 LM_QUERYSELECTION,
910 MPFROMSHORT(LIT_FIRST), MPVOID);
911 if (sSelect != LIT_NONE) {
912 ARCDUMP ad;
913
914 memset(&ad, 0, sizeof(ARCDUMP));
915 ad.info = xmallocz(sizeof(ARC_TYPE), pszSrcFile, __LINE__);
916 if (ad.info) {
917 if (!WinDlgBox(HWND_DESKTOP,
918 hwnd,
919 ArcReviewDlgProc,
920 FM3ModHandle, AD_FRAME, MPFROMP(&ad))) {
921 free(ad.info);
922 }
923 else {
924 // Find self - assume all archivers listed since we are editing
925 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
926
927 if (!pat) {
928 if (arcsighead)
929 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
930 else
931 arcsighead = ad.info;
932 }
933 else {
934 // Insert before
935 if (pat->prev) {
936 ad.info->next = pat;
937 ad.info->prev = pat->prev;
938 pat->prev->next = ad.info;
939 pat->prev = ad.info;
940 }
941 else {
942 arcsighead = ad.info;
943 ad.info->next = pat;
944 pat->prev = ad.info;
945 }
946 }
947 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_INSERTITEM,
948 MPFROM2SHORT(sSelect, 0),
949 MPFROMP(ad.info->id ? ad.info->id : "?"));
950 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
951 MPFROMSHORT(sSelect - 1), MPFROMSHORT(TRUE));
952 arcsigsmodified = TRUE;
953 }
954 }
955 }
956 return 0;
957 case ASEL_PB_DELETE:
958 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
959 ASEL_LISTBOX,
960 LM_QUERYSELECTION,
961 MPFROMSHORT(LIT_FIRST), MPVOID);
962 if (sSelect != LIT_NONE) {
963 // Find self - assume all archivers listed since we are editing
964 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
965
966 if (!pat)
967 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
968 else {
969 // Delete current
970 if (pat->prev) {
971 pat->prev->next = pat->next;
972 if (pat->next)
973 pat->next->prev = pat->prev;
974 }
975 else {
976 arcsighead = pat->next;
977 if (pat->next)
978 pat->next->prev = pat->prev;
979 }
980 }
981 free_arc_type(pat);
982 arcsigsmodified = TRUE;
983 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_DELETEITEM,
984 MPFROM2SHORT(sSelect, 0), MPVOID);
985 sItemCount =
986 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
987 MPVOID, MPVOID);
988 if (sSelect >= sItemCount)
989 sSelect--;
990 if (sSelect >= 0) {
991 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
992 MPFROMSHORT(sSelect), MPFROMSHORT(TRUE));
993 }
994 }
995 return 0;
996 case ASEL_PB_UP:
997 sSelect = (SHORT) WinSendDlgItemMsg(hwnd,
998 ASEL_LISTBOX,
999 LM_QUERYSELECTION,
1000 MPFROMSHORT(LIT_FIRST), MPVOID);
1001 if (sSelect != LIT_NONE && sSelect > 0) {
1002 // Find self - assume all archivers listed since we are editing
1003 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
1004 if (!pat || !pat->prev)
1005 Runtime_Error(pszSrcFile, __LINE__, pszCantFindMsg, sSelect);
1006 else {
1007 ARC_TYPE *patGDad;
1008 ARC_TYPE *patDad;
1009 ARC_TYPE *patChild;
1010
1011 patChild = pat->next;
1012 patDad = pat->prev;
1013 patGDad = patDad->prev;
1014 patDad->next = patChild;
1015 if (patChild)
1016 patChild->prev = patDad;
1017 patDad->prev = pat;
1018 pat->next = patDad;
1019 if (patGDad) {
1020 patGDad->next = pat;
1021 pat->prev = patGDad;
1022 }
1023 else {
1024 arcsighead = pat;
1025 pat->prev = NULL;
1026 }
1027
1028 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
1029 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
1030 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
1031 MPFROM2SHORT(sSelect - 1, 255),
1032 MPFROMP(szPCItemText));
1033 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
1034 MPFROMSHORT(sSelect), MPFROMP(szPCItemText));
1035 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
1036 MPFROMSHORT(sSelect - 1), MPFROMP(szItemText));
1037 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
1038 MPFROMSHORT(sSelect - 1), MPFROMSHORT(TRUE));
1039 arcsigsmodified = TRUE;
1040 }
1041 }
1042 return 0;
1043 case ASEL_PB_DOWN:
1044 sSelect =
1045 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYSELECTION,
1046 MPFROMSHORT(LIT_FIRST), MPVOID);
1047 sItemCount =
1048 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMCOUNT,
1049 MPVOID, MPVOID);
1050 if (sSelect != LIT_NONE && sSelect < sItemCount - 1) {
1051 // Find self - assume all archivers listed since we are editing
1052 for (i = 0, pat = arcsighead; pat && i < sSelect; pat = pat->next, i++) ; // Find self
1053 if (!pat || !pat->next)
1054 Runtime_Error(pszSrcFile, __LINE__, "Can't find item %d of %d",
1055 sSelect, sItemCount);
1056 else {
1057 ARC_TYPE *patDad;
1058 ARC_TYPE *patChild;
1059
1060 patDad = pat->prev;
1061 patChild = pat->next;
1062 pat->next = patChild->next;
1063 patChild->next = pat;
1064 pat->prev = patChild;
1065 patChild->prev = patDad;
1066 if (patDad) {
1067 patDad->next = patChild;
1068 patChild->prev = patDad;
1069 }
1070 else {
1071 arcsighead = patChild;
1072 patChild->prev = NULL;
1073 }
1074
1075 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
1076 MPFROM2SHORT(sSelect, 255), MPFROMP(szItemText));
1077 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYITEMTEXT,
1078 MPFROM2SHORT(sSelect + 1, 255),
1079 MPFROMP(szPCItemText));
1080 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
1081 MPFROMSHORT(sSelect), MPFROMP(szPCItemText));
1082 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SETITEMTEXT,
1083 MPFROMSHORT(sSelect + 1), MPFROMP(szItemText));
1084 WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_SELECTITEM,
1085 MPFROMSHORT(sSelect + 1), MPFROMSHORT(TRUE));
1086 arcsigsmodified = TRUE;
1087 }
1088 }
1089 return 0;
1090
1091 case ASEL_PB_REVERT:
1092 // Reload without checking in case changed outside
1093 sSelect =
1094 (SHORT) WinSendDlgItemMsg(hwnd, ASEL_LISTBOX, LM_QUERYSELECTION,
1095 MPFROMSHORT(LIT_FIRST), MPVOID);
1096 load_archivers();
1097 fill_listbox(hwnd, TRUE, sSelect);
1098 return 0;
1099
1100 case IDM_HELP:
1101 if (hwndHelp) {
1102 WinSendMsg(hwndHelp, HM_DISPLAY_HELP, MPFROM2SHORT(HELP_EDITARC, 0), // fixme to be HELP_SELARC
1103 MPFROMSHORT(HM_RESOURCEID));
1104 }
1105 }
1106 return 0; // WM_COMMAND
1107
1108 case WM_CONTROL:
1109 if (SHORT1FROMMP(mp1) == ASEL_LISTBOX && SHORT2FROMMP(mp1) == LN_ENTER)
1110 PostMsg(hwnd, WM_COMMAND, MPFROM2SHORT(DID_OK, 0), MPVOID);
1111 return 0;
1112
1113 case WM_CLOSE:
1114 WinDismissDlg(hwnd, FALSE);
1115 return 0;
1116
1117 default:
1118 break;
1119 }
1120 return WinDefDlgProc(hwnd, msg, mp1, mp2);
1121}
1122
1123/**
1124 * see archiver.tmp
1125 * 02-08-96 23:55 1
1126 * 8 Feb 96 23:55:32 2
1127 * 8 Feb 96 11:55p 3
1128 * 96-02-08 23:55:32 4
1129 * 31-02-98 23:55 5
1130 * Aug 21 23:55 2011 6 Fixes tar.gz date/time formatting when using tar 1..15+
1131 */
1132
1133BOOL ArcDateTime(CHAR * dt, INT type, CDATE * cdate, CTIME * ctime)
1134{
1135 INT x;
1136 BOOL ret = FALSE;
1137 CHAR *p, *pp, *pd;
1138
1139 if (dt && cdate && ctime) {
1140 memset(cdate, 0, sizeof(CDATE));
1141 memset(ctime, 0, sizeof(CTIME));
1142 if (type) {
1143 p = dt;
1144 while (*p && *p == ' ')
1145 p++;
1146 pd = dt;
1147 switch (type) {
1148 case 1:
1149 cdate->month = atoi(pd);
1150 p = to_delim(pd, "-/.");
1151 if (p) {
1152 p++;
1153 cdate->day = atoi(p);
1154 pd = p;
1155 p = to_delim(pd, "-/.");
1156 if (p) {
1157 p++;
1158 cdate->year = atoi(p);
1159 if (cdate->year > 80 && cdate->year < 1900)
1160 cdate->year += 1900;
1161 else if (cdate->year < 1900)
1162 cdate->year += 2000;
1163 ret = TRUE;
1164 p = strchr(p, ' ');
1165 if (p) {
1166 while (*p && *p == ' ')
1167 p++;
1168 ctime->hours = atoi(p);
1169 p = to_delim(pd, ":.");
1170 if (p) {
1171 p++;
1172 ctime->minutes = atoi(p);
1173 p = to_delim(pd, ":.");
1174 if (p) {
1175 p++;
1176 ctime->seconds = atoi(p);
1177 }
1178 }
1179 }
1180 }
1181 }
1182 break;
1183
1184 case 2:
1185 cdate->day = atoi(p);
1186 p = strchr(p, ' ');
1187 if (p) {
1188 p++;
1189 for (x = 0; x < 12; x++) {
1190 if (!strnicmp(p, GetPString(IDS_JANUARY + x), 3))
1191 break;
1192 }
1193 if (x < 12) {
1194 cdate->month = x + 1;
1195 p = strchr(p, ' ');
1196 if (p) {
1197 p++;
1198 cdate->year = atoi(p);
1199 if (cdate->year > 80 && cdate->year < 1900)
1200 cdate->year += 1900;
1201 else if (cdate->year < 1900)
1202 cdate->year += 2000;
1203 ret = TRUE;
1204 p = strchr(p, ' ');
1205 if (p) {
1206 while (*p && *p == ' ')
1207 p++;
1208 ctime->hours = atoi(p);
1209 p = to_delim(pd, ":.");
1210 if (p) {
1211 p++;
1212 ctime->minutes = atoi(p);
1213 p = to_delim(pd, ":.");
1214 if (p) {
1215 p++;
1216 ctime->seconds = atoi(p);
1217 }
1218 }
1219 }
1220 }
1221 }
1222 }
1223 break;
1224
1225 case 3:
1226 cdate->day = atoi(p);
1227 p = strchr(p, ' ');
1228 if (p) {
1229 p++;
1230 for (x = 0; x < 12; x++) {
1231 if (!strnicmp(p, GetPString(IDS_JANUARY + x), 3))
1232 break;
1233 }
1234 if (x < 12) {
1235 cdate->month = x + 1;
1236 p = strchr(p, ' ');
1237 if (p) {
1238 p++;
1239 cdate->year = atoi(p);
1240 if (cdate->year > 80 && cdate->year < 1900)
1241 cdate->year += 1900;
1242 else if (cdate->year < 1900)
1243 cdate->year += 2000;
1244 ret = TRUE;
1245 p = strchr(p, ' ');
1246 if (p) {
1247 while (*p && *p == ' ')
1248 p++;
1249 ctime->hours = atoi(p);
1250 p = to_delim(pd, ":.");
1251 if (p) {
1252 p++;
1253 pp = p;
1254 ctime->minutes = atoi(p);
1255 p = to_delim(pd, ":.");
1256 if (p) {
1257 p++;
1258 ctime->seconds = atoi(p);
1259 p += 2;
1260 if (toupper(*p) == 'P')
1261 ctime->hours += 12;
1262 }
1263 else {
1264 p = pp;
1265 p += 2;
1266 if (toupper(*p) == 'P')
1267 ctime->hours += 12;
1268 }
1269 }
1270 }
1271 }
1272 }
1273 }
1274 break;
1275
1276 case 4:
1277 cdate->year = atoi(p);
1278 if (cdate->year > 80 && cdate->year < 1900)
1279 cdate->year += 1900;
1280 else if (cdate->year < 1900)
1281 cdate->year += 2000;
1282 p = to_delim(pd, "-/.");
1283 if (p) {
1284 p++;
1285 cdate->month = atoi(p);
1286 pd = p;
1287 p = to_delim(pd, "-/.");
1288 if (p) {
1289 p++;
1290 cdate->day = atoi(p);
1291 ret = TRUE;
1292 p = strchr(p, ' ');
1293 if (p) {
1294 while (*p && *p == ' ')
1295 p++;
1296 ctime->hours = atoi(p);
1297 p = to_delim(pd, ":.");
1298 if (p) {
1299 p++;
1300 ctime->minutes = atoi(p);
1301 p = to_delim(pd, ":.");
1302 if (p) {
1303 p++;
1304 ctime->seconds = atoi(p);
1305 }
1306 }
1307 }
1308 }
1309 }
1310 break;
1311
1312 case 5:
1313 cdate->day = atoi(pd);
1314 p = to_delim(pd, "-/.");
1315 if (p) {
1316 p++;
1317 cdate->month = atoi(p);
1318 pd = p;
1319 p = to_delim(pd, "-/.");
1320 if (p) {
1321 p++;
1322 cdate->year = atoi(p);
1323 if (cdate->year > 80 && cdate->year < 1900)
1324 cdate->year += 1900;
1325 else if (cdate->year < 1900)
1326 cdate->year += 2000;
1327 ret = TRUE;
1328 p = strchr(p, ' ');
1329 if (p) {
1330 while (*p && *p == ' ')
1331 p++;
1332 ctime->hours = atoi(p);
1333 p = to_delim(pd, ":.");
1334 if (p) {
1335 p++;
1336 ctime->minutes = atoi(p);
1337 p = to_delim(pd, ":.");
1338 if (p) {
1339 p++;
1340 ctime->seconds = atoi(p);
1341 }
1342 }
1343 }
1344 }
1345 }
1346 break;
1347 case 6:
1348 for (x = 0; x < 12; x++) {
1349 if (!strnicmp(p, GetPString(IDS_JANUARY + x), 3))
1350 break;
1351 }
1352 if (x < 12) {
1353 cdate->month = x + 1;
1354 p = strchr(p, ' ');
1355 if (p) {
1356 p++;
1357 cdate->day = atoi(p);
1358 p = strchr(p, ' ');
1359 if (p) {
1360 p++;
1361 ctime->hours = atoi(p);
1362 p = to_delim(pd, ":.");
1363 if (p) {
1364 p++;
1365 ctime->minutes = atoi(p);
1366 p = to_delim(pd, ":.");
1367 p = strchr(p, ' ');
1368 if (p) {
1369 p++;
1370 cdate->year = atoi(p);
1371 if (cdate->year > 80 && cdate->year < 1900)
1372 cdate->year += 1900;
1373 else if (cdate->year < 1900)
1374 cdate->year += 2000;
1375 ret = TRUE;
1376 }
1377 }
1378 }
1379 }
1380 }
1381 break;
1382 default:
1383 break;
1384 }
1385 }
1386 }
1387 return ret;
1388}
1389
1390#pragma alloc_text(MISC9,quick_find_type,find_type)
1391#pragma alloc_text(AVL,load_archivers, get_line_strip_comments, get_line_strip_white, free_archivers)
1392#pragma alloc_text(FMARCHIVE,SBoxDlgProc,SDlgListboxSubclassProc)
1393#pragma alloc_text(ARCCNRS,ArcDateTime)
Note: See TracBrowser for help on using the repository browser.