1 /**
2 * @namespace biew
3 * @file biew.c
4 * @brief This file contains entry point of BIEW project.
5 * @version -
6 * @remark this source file is part of Binary vIEW project (BIEW).
7 * The Binary vIEW (BIEW) is copyright (C) 1995 Nickols_K.
8 * All rights reserved. This software is redistributable under the
9 * licence given in the file "Licence.en" ("Licence.ru" in russian
10 * translation) distributed in the BIEW archive.
11 * @note Requires POSIX compatible development system
12 *
13 * @author Nickols_K
14 * @since 1995
15 * @note Development, fixes and improvements
16 * @author Kostya Nosov <k-nosov@yandex.ru>
17 * @date 27.11.2000
18 * @note Changing technology recognition of new-exe files
19 **/
20 #include <string.h>
21 #include <stdio.h>
22 #include <stdarg.h>
23 #include <signal.h>
24 #include <limits.h>
25 #include <sys/stat.h>
26 #ifdef HAVE_SYS_RESOURCE
27 #include <sys/resource.h>
28 #endif
29 #include <stdlib.h>
30 #include <errno.h>
31
32 #include "bconsole.h"
33 #include "colorset.h"
34 #include "bmfile.h"
35 #include "bin_util.h"
36 #include "codeguid.h"
37 #include "editor.h"
38 #include "tstrings.h"
39 #include "reg_form.h"
40 #include "biewutil.h"
41 #include "search.h"
42 #include "setup.h"
43 #include "biewlib/file_ini.h"
44 #include "biewlib/kbd_code.h"
45 #include "biewlib/biewlib.h"
46 #include "biewlib/pmalloc.h"
47
48
49 unsigned ArgCount;
50 char ** ArgVector;
51 unsigned ListFileCount;
52 static char **ListFile;
53 static char *LastOpenFileName;
54 __filesize_t LastOffset;
55 static tBool UseIniFile=True;
56 char biew_help_name[FILENAME_MAX+1] = "";
57 char biew_skin_name[FILENAME_MAX+1] = "";
58 char biew_syntax_name[FILENAME_MAX+1] = "";
59 char biew_codepage[256] = "CP866";
60 extern char last_skin_error[];
61 char biew_scheme_name[256] = "Built-in";
62 static char biew_ini_ver[32];
63 unsigned long biew_vioIniFlags = 0L;
64 unsigned long biew_twinIniFlags = 0L;
65 unsigned long biew_kbdFlags = 0L;
66 tBool iniSettingsAnywhere = False;
67 tBool fioUseMMF = False;
68 tBool iniPreserveTime = False;
69 tBool iniUseExtProgs = True;
70 __filesize_t headshift = 0L;
71 char *ini_name;
72
73 TWindow * MainWnd = 0,*HelpWnd = 0,*TitleWnd = 0,*ErrorWnd = 0;
74
75 #define SHORT_PATH_LEN __TVIO_MAXSCREENWIDTH-54
76
77 char shortname[SHORT_PATH_LEN + 1];
78
79 extern REGISTRY_BIN binTable;
80 extern REGISTRY_BIN rmTable;
81 extern REGISTRY_BIN movTable;
82 extern REGISTRY_BIN mp3Table;
83 extern REGISTRY_BIN mpegTable;
84 extern REGISTRY_BIN jpegTable;
85 extern REGISTRY_BIN wavTable;
86 extern REGISTRY_BIN aviTable;
87 extern REGISTRY_BIN asfTable;
88 extern REGISTRY_BIN bmpTable;
89 extern REGISTRY_BIN neTable;
90 extern REGISTRY_BIN peTable;
91 extern REGISTRY_BIN leTable;
92 extern REGISTRY_BIN lxTable;
93 extern REGISTRY_BIN nlm386Table;
94 extern REGISTRY_BIN elf386Table;
95 extern REGISTRY_BIN jvmTable;
96 extern REGISTRY_BIN coff386Table;
97 extern REGISTRY_BIN archTable;
98 extern REGISTRY_BIN aoutTable;
99 extern REGISTRY_BIN OldPharLapTable;
100 extern REGISTRY_BIN PharLapTable;
101 extern REGISTRY_BIN rdoffTable;
102 extern REGISTRY_BIN rdoff2Table;
103 extern REGISTRY_BIN sisTable;
104 extern REGISTRY_BIN sisxTable;
105 extern REGISTRY_BIN lmfTable;
106 extern REGISTRY_BIN mzTable;
107 extern REGISTRY_BIN dossysTable;
108
109 static REGISTRY_BIN *mainBinTable[] =
110 {
111 &neTable,
112 &peTable,
113 &leTable,
114 &lxTable,
115 &nlm386Table,
116 &elf386Table,
117 &jvmTable,
118 &coff386Table,
119 &archTable,
120 &aoutTable,
121 &OldPharLapTable,
122 &PharLapTable,
123 &rdoffTable,
124 &rdoff2Table,
125 &lmfTable,
126 &mzTable,
127 &dossysTable,
128 &sisTable,
129 &sisxTable,
130 &aviTable,
131 &asfTable,
132 &bmpTable,
133 &mpegTable,
134 &jpegTable,
135 &wavTable,
136 &movTable,
137 &rmTable,
138 &mp3Table,
139 &binTable
140 };
141
142 REGISTRY_BIN *detectedFormat = 0;
143
144
145 extern REGISTRY_MODE binMode;
146 extern REGISTRY_MODE textMode;
147 extern REGISTRY_MODE hexMode;
148 extern REGISTRY_MODE disMode;
149
150 static REGISTRY_MODE *mainModeTable[] =
151 {
152 &textMode,
153 &binMode,
154 &hexMode,
155 &disMode
156 };
157
158 REGISTRY_MODE *activeMode;
159 static size_t LastMode = sizeof(mainModeTable)/sizeof(REGISTRY_BIN *)+10;
160
161 static unsigned defMainModeSel = 0;
162
SelectMode(void)163 tBool SelectMode( void )
164 {
165 const char *modeName[sizeof(mainModeTable)/sizeof(REGISTRY_MODE *)];
166 size_t i,nModes;
167 int retval;
168
169 nModes = sizeof(mainModeTable)/sizeof(REGISTRY_MODE *);
170 for(i = 0;i < nModes;i++) modeName[i] = mainModeTable[i]->name;
171 retval = SelBoxA(modeName,nModes," Select translation mode: ",defMainModeSel);
172 if(retval != -1)
173 {
174 if(activeMode->term) activeMode->term();
175 activeMode = mainModeTable[retval];
176 if(activeMode->init) activeMode->init();
177 defMainModeSel = retval;
178 return True;
179 }
180 return False;
181 }
182
init_modes(hIniProfile * ini)183 static void __NEAR__ __FASTCALL__ init_modes( hIniProfile *ini )
184 {
185 if(activeMode->init) activeMode->init();
186 if(activeMode->read_ini) activeMode->read_ini(ini);
187 }
188
term_modes(void)189 static void __NEAR__ __FASTCALL__ term_modes( void )
190 {
191 if(activeMode->term) activeMode->term();
192 }
193
__init_biew(void)194 static void __NEAR__ __FASTCALL__ __init_biew( void )
195 {
196 LastOpenFileName = PMalloc(4096);
197 ListFile = PMalloc((ArgCount-1)*sizeof(char *));
198 if((!LastOpenFileName) || (!ListFile))
199 {
200 printm("BIEW initialization failed! Out of memory!");
201 exit(EXIT_FAILURE);
202 }
203 }
204
__term_biew(void)205 static void __NEAR__ __FASTCALL__ __term_biew( void )
206 {
207 PFREE(LastOpenFileName);
208 PFREE(ListFile);
209 }
210
QuickSelectMode(void)211 void QuickSelectMode( void )
212 {
213 unsigned nModes;
214 nModes = sizeof(mainModeTable)/sizeof(REGISTRY_MODE *);
215 if(defMainModeSel < nModes - 1) defMainModeSel++;
216 else defMainModeSel = 0;
217 if(activeMode->term) activeMode->term();
218 activeMode = mainModeTable[defMainModeSel];
219 if(activeMode->init) activeMode->init();
220 }
221
MakeShortName(void)222 static void __NEAR__ __FASTCALL__ MakeShortName( void )
223 {
224 unsigned l;
225 unsigned slen = twGetClientWidth(TitleWnd)-54;
226 l = strlen(ArgVector[1]);
227 if(l <= slen) strcpy(shortname,ArgVector[1]);
228 else
229 {
230 strncpy(shortname,ArgVector[1],slen/2 - 3);
231 shortname[slen/2-4] = 0;
232 strcat(shortname,"...");
233 strcat(shortname,&ArgVector[1][l - slen/2]);
234 }
235 __nls_CmdlineToOem((unsigned char *)shortname,strlen(shortname));
236 }
237
IsNewExe()238 __filesize_t IsNewExe()
239 {
240 __filesize_t ret;
241 char id[2];
242 bmReadBufferEx(id,sizeof(id),0,BM_SEEK_SET);
243 #if 0
244 /*
245 It is well documented technology, but it correctly working
246 only with normal stubs, i.e. when New EXE header is located at
247 offset > 0x40. However, in PC world exists files with wrong
248 stubs, which are normal for Host OS. Hence biew must recognize
249 them as normal New EXE files, despite the fact that DOS can
250 not execute ones.
251 Fixed by Kostya Nosov <k-nosov@yandex.ru>.
252 */
253 if(!( id[0] == 'M' && id[1] == 'Z' &&
254 bmReadWordEx(0x18,BM_SEEK_SET) >= 0x40 &&
255 (ret=bmReadDWordEx(0x3C,BM_SEEK_SET)) > 0x40L)) ret = 0;
256 #endif
257 if(!( id[0] == 'M' && id[1] == 'Z' &&
258 (ret=bmReadDWordEx(0x3C,BM_SEEK_SET)) > 0x02L)) ret = 0;
259 return (__filesize_t)ret;
260 }
261
AutoDetectMode(void)262 static void __NEAR__ __FASTCALL__ AutoDetectMode( void )
263 {
264 int i,n;
265 n = sizeof(mainModeTable) / sizeof(REGISTRY_MODE *);
266 for(i = 0;i < n;i++)
267 {
268 if(mainModeTable[i]->detect())
269 {
270 defMainModeSel = i;
271 break;
272 }
273 }
274 activeMode = mainModeTable[i];
275 BMSeek(0,BM_SEEK_SET);
276 }
277
278 struct tagbiewArg
279 {
280 const char key[4];
281 const char *prompt;
282 }biewArg[] =
283 {
284 { "-a", "autodetect mode (default)" },
285 { "-b", "view file in binary mode" },
286 { "-d", "view file in disassembler mode" },
287 { "-h", "view file in hexadecimal mode" },
288 { "-t", "view file in text mode" },
289 { "-s", "change size of file to NNN bytes (create, if file does not exist)" },
290 { "-i", "ignore .ini file (create new)" },
291 { "-?", "display this screen" }
292 };
293
queryKey(char * arg)294 static int __NEAR__ __FASTCALL__ queryKey(char *arg)
295 {
296 int ret = -1;
297 size_t i;
298 for(i = 0;i < sizeof(biewArg)/sizeof(struct tagbiewArg);i++)
299 {
300 if(strcmp(arg,biewArg[i].key) == 0) { ret = i; break; }
301 }
302 return ret;
303 }
304
305 static unsigned int biew_mode = UINT_MAX;
306 static __filesize_t new_file_size = FILESIZE_MAX;
307
ParseCmdLine(void)308 static void __NEAR__ __FASTCALL__ ParseCmdLine( void )
309 {
310 unsigned i;
311 ListFileCount = 0;
312 for(i = 1;i < ArgCount;i++)
313 {
314 int biew_key;
315 biew_key = queryKey(ArgVector[i]);
316 switch(biew_key)
317 {
318 case 0: biew_mode = UINT_MAX; break;
319 case 1: biew_mode = 1; break;
320 case 2: biew_mode = 3; break;
321 case 3: biew_mode = 2; break;
322 case 4: biew_mode = 0; break;
323 case 5:
324 #if (__WORDSIZE >= 32) && !defined(__QNX4__)
325 new_file_size = strtoull(ArgVector[++i],NULL,10);
326 #else
327 new_file_size = strtoul(ArgVector[++i],NULL,10);
328 #endif
329 break;
330 case 6: UseIniFile = False; break;
331 case 7: ListFileCount = 0; return;
332 default: ListFile[ListFileCount++] = ArgVector[i];
333 }
334 }
335 if(ListFileCount) ArgVector[1] = ListFile[0];
336 }
337
LoadInfo(void)338 static tBool __NEAR__ __FASTCALL__ LoadInfo( void )
339 {
340 MakeShortName();
341 if(new_file_size != FILESIZE_MAX)
342 {
343 bhandle_t handle;
344 if(__IsFileExists(ArgVector[1]) == False) handle = __OsCreate(ArgVector[1]);
345 else
346 {
347 handle = __OsOpen(ArgVector[1],FO_READWRITE | SO_DENYNONE);
348 if(handle == NULL_HANDLE) handle = __OsOpen(ArgVector[1],FO_READWRITE | SO_COMPAT);
349 }
350 if(handle != NULL_HANDLE)
351 {
352 __OsChSize(handle,new_file_size);
353 __OsClose(handle);
354 }
355 else
356 {
357 errnoMessageBox(OPEN_FAIL,NULL,errno);
358 return False;
359 }
360 }
361 if(BMOpen(ArgVector[1]) != 0) return False;
362 if(biew_mode != UINT_MAX)
363 {
364 defMainModeSel = biew_mode;
365 activeMode = mainModeTable[defMainModeSel];
366 }
367 else
368 {
369 if(LastMode >= sizeof(mainModeTable)/sizeof(REGISTRY_MODE *) || !isValidIniArgs()) AutoDetectMode();
370 else
371 {
372 defMainModeSel = LastMode;
373 activeMode = mainModeTable[defMainModeSel];
374 }
375 }
376 return True;
377 }
378
__detectBinFmt(void)379 static void __NEAR__ __FASTCALL__ __detectBinFmt( void )
380 {
381 unsigned i;
382 if(!bmGetFLength())
383 {
384 detectedFormat = &binTable;
385 return;
386 }
387 for(i = 0;i < sizeof(mainBinTable)/sizeof(REGISTRY_BIN *);i++)
388 {
389 if(mainBinTable[i]->check_format())
390 {
391 detectedFormat = mainBinTable[i];
392 if(detectedFormat->init) detectedFormat->init();
393 break;
394 }
395 }
396 /* Special case: mz initialization */
397 mzTable.check_format();
398 }
399
PaintTitle(void)400 void PaintTitle( void )
401 {
402 twUseWin(TitleWnd);
403 twFreezeWin(TitleWnd);
404 twGotoXY(1,1);
405 twClrEOL();
406 twPrintF("File : %s",shortname);
407 twGotoXY(twGetClientWidth(TitleWnd)-43,1);
408 twPrintF("Size : %8llu bytes",BMGetFLength());
409 twRefreshWin(TitleWnd);
410 }
411
MyAtExit(void)412 static void MyAtExit( void )
413 {
414 if(MainWnd) CloseWnd(MainWnd);
415 if(HelpWnd) CloseWnd(HelpWnd);
416 if(TitleWnd) CloseWnd(TitleWnd);
417 if(ErrorWnd) CloseWnd(ErrorWnd);
418 termBConsole();
419 __term_biew();
420 __term_sys();
421 }
422
isValidIniArgs(void)423 tBool isValidIniArgs( void )
424 {
425 return iniSettingsAnywhere ? True :
426 ArgVector[1] ?
427 strcmp(ArgVector[1],LastOpenFileName) == 0 ?
428 biew_mode != UINT_MAX && biew_mode != LastMode ?
429 False : True : False : False;
430 }
431
load_ini_info(void)432 static hIniProfile * __NEAR__ __FASTCALL__ load_ini_info( void )
433 {
434 char tmp[20], buf[20];
435 hIniProfile *ini;
436 ini_name = getenv("BIEW_INI");
437 if(!ini_name) ini_name = __get_ini_name("biew");
438 ini = UseIniFile ? iniOpenFile(ini_name,NULL) : NULL;
439 biewReadProfileString(ini,"Biew","Setup","HelpName","",biew_help_name,sizeof(biew_help_name));
440 biewReadProfileString(ini,"Biew","Setup","SkinName","",biew_skin_name,sizeof(biew_skin_name));
441 biewReadProfileString(ini,"Biew","Setup","SyntaxName","",biew_syntax_name,sizeof(biew_syntax_name));
442 biewReadProfileString(ini,"Biew","Search","String","",(char *)search_buff,sizeof(search_buff));
443 search_len = strlen((char *)search_buff);
444 biewReadProfileString(ini,"Biew","Search","Case","off",tmp,sizeof(tmp));
445 biewSearchFlg = stricmp(tmp,"on") == 0 ? SF_CASESENS : SF_NONE;
446 biewReadProfileString(ini,"Biew","Search","Word","off",tmp,sizeof(tmp));
447 if(stricmp(tmp,"on") == 0) biewSearchFlg |= SF_WORDONLY;
448 biewReadProfileString(ini,"Biew","Search","Backward","off",tmp,sizeof(tmp));
449 if(stricmp(tmp,"on") == 0) biewSearchFlg |= SF_REVERSE;
450 biewReadProfileString(ini,"Biew","Search","Template","off",tmp,sizeof(tmp));
451 if(stricmp(tmp,"on") == 0) biewSearchFlg |= SF_WILDCARDS;
452 biewReadProfileString(ini,"Biew","Search","UsePlugin","off",tmp,sizeof(tmp));
453 if(stricmp(tmp,"on") == 0) biewSearchFlg |= SF_PLUGINS;
454 biewReadProfileString(ini,"Biew","Search","AsHex","off",tmp,sizeof(tmp));
455 if(stricmp(tmp,"on") == 0) biewSearchFlg |= SF_ASHEX;
456 biewReadProfileString(ini,"Biew","Browser","LastOpen","",LastOpenFileName,4096);
457 sprintf(buf,"%u",LastMode); /* [dBorca] so that src and dst won't overlap for strncpy */
458 biewReadProfileString(ini,"Biew","Browser","LastMode",buf,tmp,sizeof(tmp));
459 LastMode = (size_t)strtoul(tmp,NULL,10);
460 biewReadProfileString(ini,"Biew","Browser","Offset","0",tmp,sizeof(tmp));
461 #if (__WORDSIZE >= 32) && !defined(__QNX4__)
462 LastOffset = atoll(tmp);
463 #else
464 LastOffset = atol(tmp); /** by watcom */
465 #endif
466 biewReadProfileString(ini,"Biew","Setup","Version","",biew_ini_ver,sizeof(biew_ini_ver));
467 biewReadProfileString(ini,"Biew","Setup","DirectConsole","yes",tmp,sizeof(tmp));
468 if(stricmp(tmp,"yes") == 0) biew_vioIniFlags = __TVIO_FLG_DIRECT_CONSOLE_ACCESS;
469 biewReadProfileString(ini,"Biew","Setup","ForceMono","no",tmp,sizeof(tmp));
470 if(stricmp(tmp,"yes") == 0) biew_twinIniFlags = TWIF_FORCEMONO;
471 biewReadProfileString(ini,"Biew","Setup","Force7Bit","no",tmp,sizeof(tmp));
472 if(stricmp(tmp,"yes") == 0) biew_vioIniFlags |= __TVIO_FLG_USE_7BIT;
473 biewReadProfileString(ini,"Biew","Setup","MouseSens","yes",tmp,sizeof(tmp));
474 if(stricmp(tmp,"yes") == 0) biew_kbdFlags = KBD_NONSTOP_ON_MOUSE_PRESS;
475 biewReadProfileString(ini,"Biew","Setup","IniSettingsAnywhere","no",tmp,sizeof(tmp));
476 if(stricmp(tmp,"yes") == 0) iniSettingsAnywhere = True;
477 biewReadProfileString(ini,"Biew","Setup","FioUseMMF","no",tmp,sizeof(tmp));
478 if(stricmp(tmp,"yes") == 0) fioUseMMF = True;
479 if(!__mmfIsWorkable()) fioUseMMF = False;
480 biewReadProfileString(ini,"Biew","Setup","PreserveTimeStamp","no",tmp,sizeof(tmp));
481 if(stricmp(tmp,"yes") == 0) iniPreserveTime = True;
482 biewReadProfileString(ini,"Biew","Setup","UseExternalProgs","yes",tmp,sizeof(tmp));
483 if(stricmp(tmp,"yes") == 0) iniUseExtProgs = True;
484 biewReadProfileString(ini,"Biew","Setup","Codepage","CP866",biew_codepage,sizeof(biew_codepage));
485 return ini;
486 }
487
save_ini_info(void)488 static void __NEAR__ __FASTCALL__ save_ini_info( void )
489 {
490 char tmp[20];
491 hIniProfile *ini;
492 search_buff[search_len] = 0;
493 ini = iniOpenFile(ini_name,NULL);
494 biewWriteProfileString(ini,"Biew","Setup","HelpName",biew_help_name);
495 biewWriteProfileString(ini,"Biew","Setup","SkinName",biew_skin_name);
496 biewWriteProfileString(ini,"Biew","Setup","SyntaxName",biew_syntax_name);
497 biewWriteProfileString(ini,"Biew","Setup","Version",BIEW_VERSION);
498 biewWriteProfileString(ini,"Biew","Search","String",(char *)search_buff);
499 biewWriteProfileString(ini,"Biew","Search","Case",biewSearchFlg & SF_CASESENS ? "on" : "off");
500 biewWriteProfileString(ini,"Biew","Search","Word",biewSearchFlg & SF_WORDONLY ? "on" : "off");
501 biewWriteProfileString(ini,"Biew","Search","Backward",biewSearchFlg & SF_REVERSE ? "on" : "off");
502 biewWriteProfileString(ini,"Biew","Search","Template",biewSearchFlg & SF_WILDCARDS ? "on" : "off");
503 biewWriteProfileString(ini,"Biew","Search","UsePlugin",biewSearchFlg & SF_PLUGINS ? "on" : "off");
504 biewWriteProfileString(ini,"Biew","Search","AsHex",biewSearchFlg & SF_ASHEX ? "on" : "off");
505 biewWriteProfileString(ini,"Biew","Browser","LastOpen",ArgVector[1]);
506 sprintf(tmp,"%u",defMainModeSel);
507 biewWriteProfileString(ini,"Biew","Browser","LastMode",tmp);
508 #if (__WORDSIZE >= 32) && !defined(__QNX4__)
509 sprintf(tmp,"%llu",LastOffset);
510 #else
511 sprintf(tmp,"%lu",LastOffset);
512 #endif
513 biewWriteProfileString(ini,"Biew","Browser","Offset",tmp);
514 strcpy(tmp,biew_vioIniFlags & __TVIO_FLG_DIRECT_CONSOLE_ACCESS ? "yes" : "no");
515 biewWriteProfileString(ini,"Biew","Setup","DirectConsole",tmp);
516 strcpy(tmp,biew_twinIniFlags & TWIF_FORCEMONO ? "yes" : "no");
517 biewWriteProfileString(ini,"Biew","Setup","ForceMono",tmp);
518 strcpy(tmp,(biew_vioIniFlags & __TVIO_FLG_USE_7BIT) == __TVIO_FLG_USE_7BIT ? "yes" : "no");
519 biewWriteProfileString(ini,"Biew","Setup","Force7Bit",tmp);
520 strcpy(tmp,biew_kbdFlags & KBD_NONSTOP_ON_MOUSE_PRESS ? "yes" : "no");
521 biewWriteProfileString(ini,"Biew","Setup","MouseSens",tmp);
522 strcpy(tmp,iniSettingsAnywhere ? "yes" : "no");
523 biewWriteProfileString(ini,"Biew","Setup","IniSettingsAnywhere",tmp);
524 strcpy(tmp,fioUseMMF ? "yes" : "no");
525 biewWriteProfileString(ini,"Biew","Setup","FioUseMMF",tmp);
526 strcpy(tmp,iniPreserveTime ? "yes" : "no");
527 biewWriteProfileString(ini,"Biew","Setup","PreserveTimeStamp",tmp);
528 strcpy(tmp,iniUseExtProgs ? "yes" : "no");
529 biewWriteProfileString(ini,"Biew","Setup","UseExternalProgs",tmp);
530 biewWriteProfileString(ini,"Biew","Setup","Codepage",biew_codepage);
531 if(activeMode->save_ini) activeMode->save_ini(ini);
532 udnTerm(ini);
533 iniCloseFile(ini);
534 }
535
536 static FTime ftim;
537 static tBool ftim_ok = False;
538
ShowUsage(void)539 static void __FASTCALL__ ShowUsage(void) {
540 unsigned evt,i,nln,h,y;
541 TWindow *win;
542 nln = sizeof(biewArg)/sizeof(struct tagbiewArg);
543 h = nln+4;
544 y = tvioHeight/2-h/2;
545 win = WindowOpen(2,y,tvioWidth-1,y+h,TWS_NONE | TWS_NLSOEM);
546 if(!win) goto done;
547 twSetTitleAttr(win,BIEW_VER_MSG,TW_TMODE_CENTER,error_cset.border);
548 twCentredWin(win,NULL);
549 twSetColorAttr(error_cset.main);
550 twSetFrameAttr(win,TW_DOUBLE_FRAME,error_cset.border);
551 twSetFooterAttr(win," Press [ ESC ] to quit ",TW_TMODE_RIGHT,error_cset.border);
552 twClearWin();
553 twGotoXY(1,1);
554 twPutS(" Usage: biew [OPTIONS] file...");
555 for(i = 0;i < nln;i++)
556 {
557 twGotoXY(1,4+i);
558 twPrintF(" %s %s\n",biewArg[i].key,biewArg[i].prompt);
559 }
560 twShowWin(win);
561 do {
562 evt = GetEvent(NULL,NULL,ErrorWnd);
563 }while(!(evt == KE_ESCAPE || evt == KE_F(10) || evt == KE_ENTER));
564 twDestroyWin(win);
565 done:
566 termBConsole();
567 }
568
main(int argc,char * argv[])569 int main( int argc, char *argv[] )
570 {
571 hIniProfile *ini;
572 tBool skin_err;
573 int retval;
574 #ifndef NDEBUG
575 #ifdef RLIMIT_CORE
576 {
577 /* on many systems default coresize is 0.
578 Enable any coresize here. */
579 struct rlimit rl;
580 getrlimit(RLIMIT_CORE,&rl);
581 rl.rlim_cur = rl.rlim_max;
582 setrlimit(RLIMIT_CORE,&rl);
583 }
584 #endif
585 #endif
586 ArgCount = argc;
587 ArgVector = argv;
588 __init_sys();
589 __init_biew();
590 ini = load_ini_info();
591 skin_err = csetReadIniFile(biew_skin_name);
592 initBConsole(biew_vioIniFlags,biew_twinIniFlags);
593 if(ArgCount < 2) goto show_usage;
594 ParseCmdLine();
595 if(!ListFileCount)
596 {
597 /** print usage message */
598 size_t i;
599 show_usage:
600 ShowUsage();
601 printm("\n"BIEW_VER_MSG"\n");
602 printm(" Usage: biew [OPTIONS] file...\n\n");
603 for(i = 0;i < sizeof(biewArg)/sizeof(struct tagbiewArg);i++)
604 {
605 printm(" %s\t%s\n",biewArg[i].key,biewArg[i].prompt);
606 }
607 printm("\n");
608 return EXIT_FAILURE;
609 }
610 udnInit(ini);
611 ErrorWnd = WindowOpen(1,1,50,16,TWS_NONE | TWS_NLSOEM);
612 if(ErrorWnd) twSetTitleAttr(ErrorWnd," Error ",TW_TMODE_CENTER,error_cset.border);
613 else { printm("fatal error: can't create window"); return EXIT_FAILURE; }
614 twCentredWin(ErrorWnd,NULL);
615 twSetColorAttr(error_cset.main);
616 twSetFrameAttr(ErrorWnd,TW_DOUBLE_FRAME,error_cset.border);
617 HelpWnd = WindowOpen(1,tvioHeight,tvioWidth,tvioHeight,TWS_NLSOEM);
618 twSetColorAttr(prompt_cset.digit);
619 twClearWin();
620 twShowWin(HelpWnd);
621 if(strcmp(biew_ini_ver,BIEW_VERSION) != 0) Setup();
622 TitleWnd = WindowOpen(1,1,tvioWidth,1,TWS_NONE);
623 twSetColorAttr(title_cset.main);
624 twClearWin();
625 twShowWin(TitleWnd);
626 activeMode = mainModeTable[1];
627 atexit(MyAtExit);
628 retval = EXIT_SUCCESS;
629 if(skin_err)
630 {
631 char sout[256];
632 sprintf(sout,"Error in skin file detected: '%s'",last_skin_error);
633 ErrMessageBox(sout,NULL);
634 }
635 /* We must do it before opening a file because of some RTL has bug
636 when are trying to open already open file with no sharing access */
637 ftim_ok = __OsGetFTime(ArgVector[1],&ftim);
638 if(!LoadInfo())
639 {
640 if(ini) iniCloseFile(ini);
641 retval = EXIT_FAILURE;
642 goto Bye;
643 }
644 __detectBinFmt();
645 init_modes(ini);
646 init_addons();
647 init_sysinfo();
648 if(ini) iniCloseFile(ini);
649 MainWnd = WindowOpen(1,2,tvioWidth,tvioHeight-1,TWS_NONE);
650 twSetColorAttr(browser_cset.main);
651 twClearWin();
652 PaintTitle();
653 if(!isValidIniArgs() || LastOffset > BMGetFLength()) LastOffset = 0;
654 twShowWin(MainWnd);
655 MainLoop();
656 LastOffset = BMGetCurrFilePos();
657 save_ini_info();
658 term_sysinfo();
659 term_addons();
660 term_modes();
661 if(detectedFormat->destroy) detectedFormat->destroy();
662 BMClose();
663 if(iniPreserveTime && ftim_ok) __OsSetFTime(ArgVector[1],&ftim);
664 Bye:
665 return retval;
666 }
667
NewSource(void)668 tBool NewSource( void )
669 {
670 int i;
671 tBool ret;
672 unsigned j,freq;
673 static int prev_file;
674 char ** nlsListFile;
675 nlsListFile = (char **)PMalloc(ListFileCount*sizeof(char *));
676 if(nlsListFile)
677 {
678 for(j = 0;j < ListFileCount;j++)
679 {
680 nlsListFile[j] = PMalloc(strlen(ListFile[j])+1);
681 if(!nlsListFile[j]) break;
682 }
683 }
684 else { MemOutBox("Initializing List of File\n"); return 0; }
685 for(freq = 0;freq < j;freq++)
686 {
687 unsigned ls;
688 ls = strlen(ListFile[freq]);
689 memcpy(nlsListFile[freq],ListFile[freq],ls+1);
690 __nls_CmdlineToOem((unsigned char *)nlsListFile[freq],ls);
691 }
692 i = SelBoxA((const char **)nlsListFile,j," Select new file: ",prev_file);
693 ret = 0;
694 for(freq = 0;freq < j;freq++) PFree(nlsListFile[freq]);
695 PFree(nlsListFile);
696 if(i != -1)
697 {
698 if(iniPreserveTime && ftim_ok) __OsSetFTime(ArgVector[1],&ftim);
699 BMClose();
700 ftim_ok = __OsGetFTime(ListFile[i],&ftim);
701 if(BMOpen(ListFile[i]) == 0)
702 {
703 ArgVector[1] = ListFile[i];
704 if(detectedFormat->destroy) detectedFormat->destroy();
705 if(activeMode->term) activeMode->term();
706 MakeShortName();
707 __detectBinFmt();
708 if(activeMode->init) activeMode->init();
709 ret = True;
710 }
711 else
712 {
713 if(BMOpen(ArgVector[1]) != 0)
714 {
715 exit(EXIT_FAILURE);
716 }
717 if(detectedFormat->destroy) detectedFormat->destroy();
718 if(activeMode->term) activeMode->term();
719 MakeShortName();
720 __detectBinFmt();
721 if(activeMode->init) activeMode->init();
722 ret = False;
723 }
724 }
725 return ret;
726 }
727
biewReadProfileString(hIniProfile * ini,const char * section,const char * subsection,const char * _item,const char * def_value,char * buffer,unsigned cbBuffer)728 unsigned __FASTCALL__ biewReadProfileString(hIniProfile *ini,
729 const char *section,
730 const char *subsection,
731 const char *_item,
732 const char *def_value,
733 char *buffer,
734 unsigned cbBuffer)
735 {
736 return UseIniFile ? iniReadProfileString(ini,section,subsection,
737 _item,def_value,buffer,cbBuffer)
738 : 1;
739 }
740
biewWriteProfileString(hIniProfile * ini,const char * section,const char * subsection,const char * item,const char * value)741 tBool __FASTCALL__ biewWriteProfileString(hIniProfile *ini,
742 const char *section,
743 const char *subsection,
744 const char *item,
745 const char *value)
746 {
747 return iniWriteProfileString(ini,section,subsection,item,value);
748 }
749