~ubuntu-branches/ubuntu/precise/arj/precise-security

« back to all changes in this revision

Viewing changes to fardata.c

  • Committer: Bazaar Package Importer
  • Author(s): Guillem Jover
  • Date: 2004-06-27 08:07:09 UTC
  • Revision ID: james.westby@ubuntu.com-20040627080709-1gkxm72ex66gkwe4
Tags: upstream-3.10.21
ImportĀ upstreamĀ versionĀ 3.10.21

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: fardata.c,v 1.6 2004/04/17 11:39:43 andrew_belov Exp $
 
3
 * ---------------------------------------------------------------------------
 
4
 * This file contains routines dealing with far data segment and CRC.
 
5
 *
 
6
 */
 
7
 
 
8
#include "arj.h"
 
9
#ifdef TILED
 
10
#include <dos.h>                        /* Weird, eh? */
 
11
#endif
 
12
 
 
13
/* ASR fix 02/05/2003: need that regardless of COLOR_OUTPUT to support -jp
 
14
   correctly */
 
15
#if SFX_LEVEL>=ARJ
 
16
 #define CUSTOM_PRINTF
 
17
 #define CHUNK_SIZE               512    /* Size of the output block */
 
18
 #define CHUNK_THRESHOLD (CHUNK_SIZE-256) /* Safety bound */
 
19
#endif
 
20
 
 
21
DEBUGHDR(__FILE__)                      /* Debug information block */
 
22
 
 
23
#ifdef CUSTOM_PRINTF
 
24
 
 
25
/* Forward Declaration */
 
26
 
 
27
int vcprintf(int ccode, FMSG *fmt, va_list args);
 
28
 
 
29
#endif
 
30
 
 
31
#if SFX_LEVEL>=ARJ
 
32
 
 
33
/* Checks if the error can have an error code or not */
 
34
 
 
35
static int is_std_error(FMSG *errmsg)
 
36
{
 
37
 return(errmsg==M_DISK_FULL||errmsg==M_CANT_DELETE||errmsg==M_CANTOPEN||
 
38
        errmsg==M_CANTRENAME||errmsg==M_CANTREAD||errmsg==M_CANT_DELETE||
 
39
        errmsg==M_CANT_COPY_TEMP)?1:0;
 
40
}
 
41
 
 
42
#endif
 
43
 
 
44
/* Makes various cleanup depending on the error message received and quits. */
 
45
 
 
46
int error_proc(FMSG *errmsg, ...)
 
47
{
 
48
 char *tmp_errmsg;
 
49
 va_list marker;
 
50
 
 
51
 #if SFX_LEVEL>=ARJ
 
52
  /* Check if the message could have a standard error code */
 
53
  if(errno!=0&&is_std_error(errmsg))
 
54
  {
 
55
   msg_cprintf(0, lf);
 
56
   error_report();
 
57
  }
 
58
 #endif
 
59
 #if SFX_LEVEL>=ARJSFXV
 
60
  if(quiet_mode==ARJ_SILENT)
 
61
   freopen(dev_con, m_w, stdout);
 
62
 #endif
 
63
 #if SFX_LEVEL>=ARJ
 
64
  file_settype(stdout, ARJT_TEXT);
 
65
 #endif
 
66
 /* For SFX archives, don't forget to display our logo */
 
67
 #if SFX_LEVEL==ARJSFXV
 
68
  show_sfx_logo();
 
69
 #elif SFX_LEVEL==ARJSFX
 
70
  if(!logo_shown)
 
71
  {
 
72
   msg_cprintf(0, M_ARJSFX_BANNER, exe_name);
 
73
   msg_cprintf(0, M_PROCESSING_ARCHIVE, archive_name);
 
74
  }
 
75
 #endif
 
76
 #if SFX_LEVEL>=ARJ
 
77
  nputlf();
 
78
 #elif SFX_LEVEL>=ARJSFXV
 
79
  fputc(LF, new_stdout);
 
80
 #else
 
81
  fputc(LF, stdout);
 
82
 #endif
 
83
 /* Format and print the error message */
 
84
 va_start(marker, errmsg);
 
85
 #ifdef CUSTOM_PRINTF
 
86
  vcprintf(H_ERR, errmsg, marker);
 
87
 #else
 
88
  tmp_errmsg=malloc_fmsg(errmsg);
 
89
  #if SFX_LEVEL>=ARJSFXV
 
90
   vfprintf(new_stdout, (FMSG *)tmp_errmsg, marker);
 
91
  #else
 
92
   vprintf(tmp_errmsg, marker);
 
93
  #endif
 
94
  free_fmsg(tmp_errmsg);
 
95
 #endif
 
96
 va_end(marker);
 
97
 #if SFX_LEVEL>=ARJ
 
98
  nputlf();
 
99
 #elif SFX_LEVEL>=ARJSFXV
 
100
  fputc(LF, new_stdout);
 
101
 #else
 
102
  fputc(LF, stdout);
 
103
 #endif
 
104
 /* Terminate the execution with a specific errorlevel */
 
105
 #if SFX_LEVEL>=ARJSFXV
 
106
  /* If there's no errorlevel yet, select errorlevel by message class */
 
107
  if(errorlevel==0)
 
108
   errorlevel=subclass_errors(errmsg);
 
109
  /* If the error was the lack of memory, display final memory statistics to
 
110
     find memory leaks */
 
111
  #if SFX_LEVEL>=ARJ
 
112
   if(errorlevel==ARJ_ERL_NO_MEMORY)
 
113
    mem_stats();
 
114
  #endif
 
115
  error_occured=1;
 
116
  exit(errorlevel);
 
117
 #elif defined(REARJ)
 
118
  exit(REARJ_ERL_WARNING);
 
119
 #elif defined(REGISTER)
 
120
  exit(REGISTER_ERL_ERROR);
 
121
 #elif SFX_LEVEL>=ARJSFX
 
122
  exit(ARJSFX_ERL_ERROR);
 
123
 #else
 
124
  exit(1);
 
125
 #endif
 
126
 return(0);
 
127
}
 
128
 
 
129
#ifdef FMSG_ST
 
130
 
 
131
/* A printf() function for far strings */
 
132
 
 
133
int msg_printf(FMSG *fmt, ...)
 
134
{
 
135
 va_list marker;
 
136
 char *storage;
 
137
 int result;
 
138
 
 
139
 storage=malloc_far_str(fmt);
 
140
 va_start(marker, fmt);
 
141
 result=vfprintf(new_stdout, (FMSG *)storage, marker);
 
142
 va_end(marker);
 
143
 free(storage);
 
144
 return(result);
 
145
}
 
146
 
 
147
/* A fprintf() function for far strings */
 
148
 
 
149
int msg_fprintf(FILE *stream, FMSG *fmt, ...)
 
150
{
 
151
 va_list marker;
 
152
 char *storage;
 
153
 int result;
 
154
 
 
155
 storage=malloc_far_str(fmt);
 
156
 va_start(marker, fmt);
 
157
 result=vfprintf(stream, storage, marker);
 
158
 va_end(marker);
 
159
 free(storage);
 
160
 return(result);
 
161
}
 
162
 
 
163
/* A sprintf() function for far strings */
 
164
 
 
165
int msg_sprintf(char *str, FMSG *fmt, ...)
 
166
{
 
167
 va_list marker;
 
168
 char *storage;
 
169
 int result;
 
170
 
 
171
 storage=malloc_far_str(fmt);
 
172
 va_start(marker, fmt);
 
173
 result=vsprintf(str, storage, marker);
 
174
 va_end(marker);
 
175
 free(storage);
 
176
 return(result);
 
177
}
 
178
 
 
179
#endif
 
180
 
 
181
#ifdef CUSTOM_PRINTF
 
182
 
 
183
/*
 
184
 * A Q&D custom printf() implementation. Derived from:
 
185
 *
 
186
 * vsprintf.c -- Lars Wirzenius & Linus Torvalds.
 
187
 * Wirzenius wrote this portably, Torvalds f*cked it up :-)
 
188
 *
 
189
 */
 
190
 
 
191
/* Length-limited strlen() */
 
192
 
 
193
static int strnlen(const char FAR *s, int count)
 
194
{
 
195
 const char FAR *sc;
 
196
 
 
197
 for(sc=s; *sc!='\0'&&count--; ++sc)
 
198
  ;
 
199
 return(sc-s);
 
200
}
 
201
 
 
202
/* Hex representation of digits */
 
203
 
 
204
static char adigit(unsigned long n, int is_uc)
 
205
{
 
206
 if(n<10)
 
207
  return('0'+n);
 
208
 n-=10;
 
209
 return((is_uc?'A':'a')+n);
 
210
}
 
211
 
 
212
/* Q'n'D strtoul() implementation */
 
213
 
 
214
unsigned long simple_strtoul(const FMSG *cp, FMSG **endp, unsigned int base)
 
215
{
 
216
 unsigned long result=0, value;
 
217
 
 
218
 if(!base)
 
219
 {
 
220
  base=10;
 
221
  if(*cp=='0')
 
222
  {
 
223
   base=8;
 
224
   cp++;
 
225
   if((*cp=='x')&&isxdigit(cp[1]))
 
226
   {
 
227
    cp++;
 
228
    base=16;
 
229
   }
 
230
  }
 
231
 }
 
232
 while(isxdigit(*cp)&&(value=isdigit(*cp)?
 
233
                       *cp-'0':
 
234
                       (islower(*cp)?toupper(*cp):*cp)-'A'+10)<base)
 
235
 {
 
236
  result=result*base+value;
 
237
  cp++;
 
238
 }
 
239
 if(endp)
 
240
  *endp=(FMSG *)cp;
 
241
 return(result);
 
242
}
 
243
 
 
244
/* Convert digits and skip over them */
 
245
 
 
246
static int skip_atoi(FMSG **s)
 
247
{
 
248
 int i=0;
 
249
 
 
250
 while(isdigit(**s))
 
251
  i=i*10+*((*s)++)-'0';
 
252
 return(i);
 
253
}
 
254
 
 
255
#define ZEROPAD                    1    /* pad with zero */
 
256
#define SIGN                       2    /* unsigned/signed long */
 
257
#define PLUS                       4    /* show plus */
 
258
#define SPACE                      8    /* space if plus */
 
259
#define LEFT                      16    /* left justified */
 
260
#define SPECIAL                   32    /* 0x */
 
261
#define LARGE                     64    /* use 'ABCDEF' instead of 'abcdef' */
 
262
#define FAR_STR                  128    /* Far strings (Fs) */
 
263
 
 
264
/* Number representation routine */
 
265
 
 
266
static int number(char *istr, long num, int base, int size, int precision, int type)
 
267
{
 
268
 char c, sign, tmp[66];
 
269
 int i;
 
270
 int ucase_dig=0;
 
271
 char *str;
 
272
 
 
273
 str=istr;
 
274
 if(type&LARGE)
 
275
  ucase_dig=1;
 
276
 if(type&LEFT)
 
277
  type&=~ZEROPAD;
 
278
 if(base<2||base>36)
 
279
  return(0);
 
280
 c=(type&ZEROPAD)?'0':' ';
 
281
 sign=0;
 
282
 if(type&SIGN)
 
283
 {
 
284
  if(num<0)
 
285
  {
 
286
   sign='-';
 
287
   num=-num;
 
288
   size--;
 
289
  }
 
290
  else if(type&PLUS)
 
291
  {
 
292
   sign='+';
 
293
   size--;
 
294
  }
 
295
  else if(type&SPACE)
 
296
  {
 
297
   sign=' ';
 
298
   size--;
 
299
  }
 
300
 }
 
301
 if(type&SPECIAL)
 
302
 {
 
303
  if(base==16)
 
304
   size-=2;
 
305
  else if(base==8)
 
306
   size--;
 
307
 }
 
308
 i=0;
 
309
 if(num==0)
 
310
  tmp[i++]='0';
 
311
 else while (num!=0)
 
312
 {
 
313
  unsigned long __res;
 
314
 
 
315
  __res=((unsigned long)num)%(unsigned long)base;
 
316
  num=((unsigned long)num)/(unsigned long)base;
 
317
  tmp[i++]=adigit(__res, ucase_dig);
 
318
 }
 
319
 if(i>precision)
 
320
  precision=i;
 
321
 size-=precision;
 
322
 if(!(type&(ZEROPAD+LEFT)))
 
323
 {
 
324
  while(size-->0)
 
325
   *str++=' ';
 
326
 }
 
327
 if(sign)
 
328
  *str++=sign;
 
329
 if(type&SPECIAL)
 
330
 {
 
331
  if(base==8)
 
332
   *str++='0';
 
333
  else if(base==16)
 
334
  {
 
335
   *str++='0';
 
336
   *str++=ucase_dig?'X':'x';
 
337
  }
 
338
 }
 
339
 if(!(type&LEFT))
 
340
 {
 
341
  while(size-->0)
 
342
   *str++=c;
 
343
 }
 
344
 while(i<precision--)
 
345
  *str++='0';
 
346
 while(i-->0)
 
347
  *str++=tmp[i];
 
348
 while(size-->0)
 
349
  *str++=' ';
 
350
 return(str-istr);
 
351
}
 
352
 
 
353
/* Flushes the output buffer downstream. The buffer gets clobbered. */
 
354
 
 
355
static void flush_cbuf(int ccode, char *text)
 
356
{
 
357
 char *n_text, *t_text;
 
358
 int need_pause, rc;
 
359
 char c;
 
360
 
 
361
 if(quiet_mode==ARJ_SILENT||(quiet_mode==ARJ_QUIET&&!(ccode&H_FORCE)))
 
362
  return;
 
363
 CLOBBER_SENTRY();
 
364
 need_pause=(prompt_for_more&&!yes_on_all_queries&&!print_with_more);
 
365
 n_text=t_text=text;
 
366
#ifdef COLOR_OUTPUT
 
367
 if(!redirected&&!no_colors)
 
368
  textcolor(color_table[ccode&H_COLORMASK].color);
 
369
#endif
 
370
 while((c=*t_text)!='\0')
 
371
 {
 
372
  if(c==LF)
 
373
  {
 
374
   *t_text='\0';
 
375
   #ifdef COLOR_OUTPUT
 
376
    if(redirected)
 
377
    {
 
378
     #if SFX_LEVEL>=ARJSFXV
 
379
      fprintf(new_stdout, strform, n_text);
 
380
      fprintf(new_stdout, lf);
 
381
     #else
 
382
      printf(strform, n_text);
 
383
      printf(lf);
 
384
     #endif
 
385
    }
 
386
    else
 
387
    {
 
388
     scr_out(n_text);
 
389
     if(!no_colors)
 
390
      textcolor(7);
 
391
     #ifdef NEED_CRLF
 
392
      scr_out("\r");
 
393
     #endif
 
394
     scr_out(lf);
 
395
    }
 
396
    if(!no_colors)
 
397
     textcolor(color_table[ccode&H_COLORMASK].color);
 
398
   #else
 
399
    printf(strform, n_text);
 
400
    printf(lf);
 
401
   #endif
 
402
   n_text=t_text+1;
 
403
   #if SFX_LEVEL>=ARJ
 
404
    lines_scrolled++;
 
405
    if(lines_scrolled>=lines_per_page-1)
 
406
    {
 
407
     lines_scrolled=0;
 
408
     if(need_pause)
 
409
     {
 
410
      rc=pause();
 
411
      #ifdef COLOR_OUTPUT
 
412
       /* Restore the color after implicit recursion to msg_cprintf() */
 
413
       if(!no_colors)
 
414
        textcolor(color_table[ccode&H_COLORMASK].color);
 
415
      #endif
 
416
      if(!rc&&(ccode&H_WEAK))
 
417
       longjmp(main_proc, 1);
 
418
     }
 
419
    }
 
420
   #endif
 
421
  }
 
422
  t_text++;
 
423
 }
 
424
#ifdef COLOR_OUTPUT
 
425
 if(redirected)
 
426
  #if SFX_LEVEL>=ARJSFXV
 
427
   fprintf(new_stdout, strform, n_text);
 
428
  #else
 
429
   printf(strform, n_text);
 
430
  #endif
 
431
 else
 
432
  scr_out(n_text);
 
433
#else
 
434
 printf(strform, n_text);
 
435
#endif
 
436
}
 
437
 
 
438
/* vcprintf() implementation */
 
439
 
 
440
int vcprintf(int ccode, FMSG *fmt, va_list args)
 
441
{
 
442
 int len;
 
443
 unsigned long num;
 
444
 int i, base;
 
445
 char FAR *s;
 
446
 int flags;                             /* flags to number() */
 
447
 int field_width;                       /* width of output field */
 
448
 int precision;                         /* min. # of digits for integers; max
 
449
                                           number of chars for from string */
 
450
 int qualifier;                         /* 'h', 'l', or 'L' for integer
 
451
                                           fields */
 
452
 int far_str;                           /* Far string qualifier */
 
453
 char buf[CHUNK_SIZE];                  /* Output buffer */
 
454
 int p_buf;
 
455
 int rc=0;
 
456
 int ocode;                             /* Output color code for formatted
 
457
                                           fields (that's what the whole
 
458
                                           routine is about!) */
 
459
 long *ipl;
 
460
 int *ipi;
 
461
 int last_fmt=0;
 
462
 
 
463
 ocode=(ccode&H_NFMT)?H_STD:ccode;
 
464
 for(p_buf=0; *fmt; ++fmt)
 
465
 {
 
466
  if(last_fmt&&ccode&H_NFMT)
 
467
  {
 
468
   last_fmt=0;
 
469
   buf[p_buf]='\0';
 
470
   rc+=p_buf;
 
471
   p_buf=0;
 
472
   flush_cbuf(ocode, buf);
 
473
  }
 
474
  if(*fmt!='%'||*(fmt+1)=='%')
 
475
  {
 
476
   if(p_buf>=CHUNK_SIZE-1)
 
477
   {
 
478
    buf[p_buf]='\0';
 
479
    rc+=p_buf;
 
480
    p_buf=0;
 
481
    flush_cbuf(ccode, buf);
 
482
   }
 
483
   buf[p_buf++]=*fmt;
 
484
   if(*fmt=='%')
 
485
    ++fmt;                              /* Skip over the 2nd percent - we've handled
 
486
                                           it here */
 
487
   continue;
 
488
  }
 
489
  /* A format symbol is found - flush the buffer if:
 
490
     1. It's H_NFMT, so we need to change the brush, OR
 
491
     2. CHUNK_THRESHOLD has been exceeded (for numeric) */
 
492
  if(ccode&H_NFMT||p_buf>=CHUNK_THRESHOLD)
 
493
  {
 
494
   buf[p_buf]='\0';
 
495
   rc+=p_buf;
 
496
   p_buf=0;
 
497
   flush_cbuf(ccode, buf);
 
498
  }
 
499
  last_fmt=1;
 
500
  /* Process flags */
 
501
  flags=0;
 
502
  repeat:
 
503
  ++fmt;                                /* This also skips first '%' */
 
504
  switch(*fmt)
 
505
  {
 
506
   case '-': flags|=LEFT; goto repeat;
 
507
   case '+': flags|=PLUS; goto repeat;
 
508
   case ' ': flags|=SPACE; goto repeat;
 
509
   case '#': flags|=SPECIAL; goto repeat;
 
510
   case '0': flags|=ZEROPAD; goto repeat;
 
511
   case 'F': flags|=FAR_STR; goto repeat;
 
512
  }
 
513
  /* Get field width */
 
514
  field_width=-1;
 
515
  if(isdigit(*fmt))
 
516
   field_width=skip_atoi((FMSG **)&fmt);
 
517
  else if(*fmt=='*')
 
518
  {
 
519
   ++fmt;
 
520
   /* It's the next argument */
 
521
   field_width=va_arg(args, int);
 
522
   if(field_width<0)
 
523
   {
 
524
    field_width=-field_width;
 
525
    flags|=LEFT;
 
526
   }
 
527
  }
 
528
  /* Get the precision */
 
529
  precision=-1;
 
530
  if(*fmt=='.')
 
531
  {
 
532
   ++fmt; 
 
533
   if(isdigit(*fmt))
 
534
    precision=skip_atoi((FMSG **)&fmt);
 
535
   else if(*fmt=='*')
 
536
   {
 
537
    ++fmt;
 
538
    /* It's the next argument */
 
539
    precision=va_arg(args, int);
 
540
   }
 
541
   if(precision<0)
 
542
    precision=0;
 
543
  }
 
544
  /* Get the conversion qualifier */
 
545
  qualifier=-1;
 
546
  if(*fmt=='h'||*fmt=='l'||*fmt=='L')
 
547
  {
 
548
   qualifier=*fmt;
 
549
   ++fmt;
 
550
  }
 
551
  /* Default base */
 
552
  base=10;
 
553
  switch(*fmt)
 
554
  {
 
555
   case 'c':
 
556
    if(!(flags&LEFT))
 
557
     while(--field_width>0)
 
558
      buf[p_buf++]=' ';
 
559
    buf[p_buf++]=(unsigned char)va_arg(args, int);
 
560
    while(--field_width>0)
 
561
     buf[p_buf++]=' ';
 
562
    continue;
 
563
   case 's':
 
564
    if(!(flags&FAR_STR))
 
565
     s=(char FAR *)va_arg(args, char NEAR *);
 
566
    else
 
567
     s=va_arg(args, char FAR *);
 
568
#ifdef DEBUG
 
569
    if(!s)
 
570
     s="(null)";
 
571
#endif
 
572
    len=strnlen(s, precision);
 
573
    if(!(flags&LEFT))
 
574
    {
 
575
     while(len<field_width--)
 
576
     {
 
577
      if(p_buf>=CHUNK_SIZE-1)
 
578
      {
 
579
       buf[p_buf]='\0';
 
580
       rc+=p_buf;
 
581
       p_buf=0;
 
582
       flush_cbuf(ocode, buf);
 
583
      }
 
584
      buf[p_buf++]=' ';
 
585
     }
 
586
    }
 
587
    for(i=0; i<len; ++i)
 
588
    {
 
589
     if(p_buf>=CHUNK_SIZE-1)
 
590
     {
 
591
      buf[p_buf]='\0';
 
592
      rc+=p_buf;
 
593
      p_buf=0;
 
594
      flush_cbuf(ocode, buf);
 
595
     }
 
596
     buf[p_buf++]=*s++;
 
597
    }
 
598
    while(len<field_width--)
 
599
    {
 
600
     if(p_buf>=CHUNK_SIZE-1)
 
601
     {
 
602
      buf[p_buf]='\0';
 
603
      rc+=p_buf;
 
604
      p_buf=0;
 
605
      flush_cbuf(ocode, buf);
 
606
     }
 
607
     buf[p_buf++]=' ';
 
608
    }
 
609
    continue;
 
610
   case 'p':
 
611
    if(field_width==-1)
 
612
    {
 
613
     field_width=2*sizeof(void *);
 
614
     flags|=ZEROPAD;
 
615
    }
 
616
    p_buf+=number(buf+p_buf, (unsigned long)va_arg(args, void *), 16,
 
617
                  field_width, precision, flags);
 
618
    continue;
 
619
   case 'n':
 
620
    if(qualifier=='l')
 
621
    {
 
622
     ipl=va_arg(args, long *);
 
623
     *ipl=p_buf;
 
624
    }
 
625
    else
 
626
    {
 
627
     ipi=va_arg(args, int *);
 
628
     *ipi=p_buf;
 
629
    }
 
630
    continue;
 
631
   /* Integer number formats - set up the flags and "break" */
 
632
   case 'o':
 
633
    base=8;
 
634
    break;
 
635
   case 'X':
 
636
    flags|=LARGE;
 
637
   case 'x':
 
638
    base=16;
 
639
    break;
 
640
   case 'd':
 
641
   case 'i':
 
642
    flags|=SIGN;
 
643
   case 'u':
 
644
    break;
 
645
   default:
 
646
    if(*fmt!='%')
 
647
     buf[p_buf++]='%';
 
648
    if(*fmt)
 
649
     buf[p_buf++]=*fmt;
 
650
    else
 
651
     --fmt;
 
652
    continue;
 
653
   }
 
654
   if(qualifier=='l')
 
655
    num=va_arg(args, unsigned long);
 
656
   else if(qualifier=='h')
 
657
   {
 
658
#ifdef __linux__
 
659
    if (flags&SIGN)
 
660
     num=va_arg(args, int);             /* num=va_arg(args, short);      */
 
661
    else
 
662
     num=va_arg(args, int);             /* num=va_arg(args, unsigned short);*/
 
663
#else
 
664
    if(flags&SIGN)
 
665
     num=va_arg(args, short);
 
666
    else
 
667
     num=va_arg(args, unsigned short);
 
668
#endif
 
669
   }
 
670
   else if(flags&SIGN)
 
671
    num=va_arg(args, int);
 
672
   else
 
673
    num=va_arg(args, unsigned int);
 
674
   p_buf+=number(buf+p_buf, num, base, field_width, precision, flags);
 
675
 }
 
676
 if(p_buf>0)
 
677
 {
 
678
  buf[p_buf]='\0';
 
679
  rc+=p_buf;
 
680
  flush_cbuf(last_fmt?ocode:ccode, buf);
 
681
 }
 
682
 return(rc);
 
683
}
 
684
 
 
685
#endif /* CUSTOM_PRINTF */
 
686
 
 
687
#if SFX_LEVEL>=ARJSFX||defined(REARJ)
 
688
 
 
689
/* Helper routine for scrprintf() */
 
690
 
 
691
int msg_cprintf(int ccode, FMSG *fmt, ...)
 
692
{
 
693
 #ifndef CUSTOM_PRINTF
 
694
  char *storage;
 
695
 #endif
 
696
 va_list marker;
 
697
 int result;
 
698
 
 
699
 #ifndef CUSTOM_PRINTF
 
700
  #ifdef FMSG_ST
 
701
   storage=malloc_far_str(fmt);
 
702
  #else
 
703
   storage=fmt;
 
704
  #endif
 
705
 #endif
 
706
 va_start(marker, fmt);
 
707
 #if defined(CUSTOM_PRINTF)
 
708
  result=vcprintf(ccode, fmt, marker);
 
709
 #elif SFX_LEVEL>=ARJSFXV
 
710
  result=vfprintf(new_stdout, (FMSG *)storage, marker);
 
711
 #else
 
712
  result=vprintf(storage, marker);
 
713
 #endif
 
714
 va_end(marker);
 
715
 #if defined(FMSG_ST)&&!defined(CUSTOM_PRINTF)
 
716
  free(storage);
 
717
 #endif
 
718
 return(result);
 
719
}
 
720
 
 
721
#endif
 
722
 
 
723
#if SFX_LEVEL>=ARJSFX&&defined(TILED)
 
724
 
 
725
/* A model-independent movedata() function (it must go to ENVIRON.C) */
 
726
 
 
727
void far_memmove(char FAR *dest, char FAR *src, int length)
 
728
{
 
729
 movedata(FP_SEG(src), FP_OFF(src), FP_SEG(dest), FP_OFF(dest), length);
 
730
}
 
731
 
 
732
#endif
 
733
 
 
734
#if SFX_LEVEL>=ARJ
 
735
 
 
736
/* Initializes CRC32 subsystem (only used by main()) */
 
737
 
 
738
void init_crc()
 
739
{
 
740
 build_crc32_table();
 
741
}
 
742
 
 
743
/* Returns CRC32 for the given block */
 
744
 
 
745
void crc_for_block(char *block, unsigned int length)
 
746
{
 
747
 crc32_for_block(block, length);
 
748
}
 
749
 
 
750
/* Returns CRC32 for the given string */
 
751
 
 
752
void crc_for_string(char *str)
 
753
{
 
754
 crc32_for_string(str);
 
755
}
 
756
 
 
757
#endif
 
758
 
 
759
#ifdef COLOR_OUTPUT
 
760
 
 
761
/* Parse the color table */
 
762
 
 
763
int parse_colors(char *opt)
 
764
{
 
765
 int i, c;
 
766
 char *p;
 
767
 int rc=0;
 
768
 
 
769
 if(*opt=='\0')
 
770
 {
 
771
  no_colors=1;
 
772
  textcolor(7);                         /* HACK */
 
773
  return(0);
 
774
 }
 
775
 while(*opt!='\0')
 
776
 {
 
777
  for(p=opt; !isdigit(*p); p++)
 
778
  {
 
779
   if(*p=='\0')
 
780
   {
 
781
    opt=p;
 
782
    goto next_opt;
 
783
   }
 
784
  }
 
785
  c=atoi(p);
 
786
  if(c>=32)
 
787
   rc++;
 
788
  else
 
789
  {
 
790
   for(i=0; color_table[i].arg!='\0'||!(++rc); i++)
 
791
   {
 
792
    if(color_table[i].arg==tolower(*opt))
 
793
    {
 
794
     color_table[i].color=(char)c;
 
795
     break;
 
796
    }
 
797
   }
 
798
  }
 
799
  next_opt:
 
800
  while(*opt!='\0'&&!isdigit(*opt))
 
801
   opt++;
 
802
  while(*opt!='\0'&&(isdigit(*opt)||!isalpha(*opt)))
 
803
   opt++;
 
804
 }
 
805
 return(rc);
 
806
}
 
807
 
 
808
#endif