2
* $Id: arj_file.c,v 1.9 2004/06/18 16:19:37 andrew_belov Exp $
3
* ---------------------------------------------------------------------------
4
* Various archive-management functions (mostly, file-related ones) are stored
11
DEBUGHDR(__FILE__) /* Debug information block */
13
/* Character used in counters */
15
#define COUNTER_CHAR 0xB2
17
#define COUNTER_CHAR '#'
19
#define UNDISP_CHAR '?' /* Replaces nonprintable characters */
23
static char reply_help[]="?"; /* Request for help */
25
static char ext_digits[]=".%03d"; /* Pattern used to serialize
29
/* Counter formatting sequences */
31
#if SFX_LEVEL>=ARJSFXV
32
static char del_single[]="\b\b\b\b\b";
33
static char del_double[]="\b\b\b\b\b\b\b\b\b\b";
34
static char sfmt_single[]=" %s";
35
static char sfmt_double[]=" %s";
36
static char sfmt_bytes[]="%10ld%s";
37
static char sfmt_start_graph[]=" 0%%%s";
38
static char sfmt_numeric[]="%4d%%%s";
40
static char sfmt_start_num[]=" %d%%";
42
static char sfmt_graph[]="����������%s";
43
static char sfmt_mid_graph[]="�����%s";
45
static char sfmt_graph[]="..........%s";
46
static char sfmt_mid_graph[]=".....%s";
48
static char sfmt_short_numeric[]="%4d%%";
51
static char sfmt_sfx[]="%4d%%\b\b\b\b\b";
54
/* Local forward-referenced functions */
56
static int display_block(char *str, int len);
57
static int block_op(int action, char *block, int len);
59
#if SFX_LEVEL>=ARJSFXV
61
/* Closes the file given */
63
int file_close(FILE *stream)
66
return(fclose(stream));
71
/* Opens a file, possibly clearing its FA_ARCH attribute (read-only modes are
74
FILE *file_open_noarch(char *name, char *mode)
79
if(clear_archive_bit&&(mode[0]=='w'||mode[0]=='a'||mode[1]=='+'||mode[2]=='+'))
80
dos_chmod(name, STD_FATTR_NOARCH);
82
if((stream=file_open(name, mode))==NULL)
83
error(M_CANTOPEN, name);
91
/* Overwrites a file, querying user if it exists */
93
FILE *file_create(char *name, char *mode)
97
if(!yes_on_all_queries&&!overwrite_existing)
99
msg_cprintf(0, M_EXISTS, name);
100
if(!query_action(REPLY_YES, QUERY_OVERWRITE, M_QUERY_OVERWRITE))
101
error(M_CANTOPEN, name);
104
if(clear_archive_bit&&(mode[0]=='w'||mode[0]=='a'||mode[1]=='+'||mode[2]=='+'))
105
dos_chmod(name, STD_FATTR_NOARCH);
108
return(file_open(name, mode));
115
/* Reads a byte from the file */
117
int fget_byte(FILE *stream)
121
buffer=fgetc(stream);
124
if(ignore_archive_errors)
126
#if SFX_LEVEL>=ARJSFXV
127
msg_cprintf(H_ERR, M_CANTREAD);
129
msg_cprintf(H_ERR, M_CANTREAD);
139
/* Reads two bytes from the file */
141
unsigned int fget_word(FILE *stream)
145
b0=fget_byte(stream);
146
b1=fget_byte(stream);
150
/* Reads four bytes from the file */
152
unsigned long fget_longword(FILE *stream)
156
w0=fget_word(stream);
157
w1=fget_word(stream);
158
return(((unsigned long)w1<<16)|(unsigned long)w0);
161
/* Reads a block from the file, updating CRC */
163
int fread_crc(char *buffer, int count, FILE *stream)
167
n=fread(buffer, 1, count, stream);
170
origsize+=(unsigned long)n;
171
crc_for_block((char *)buffer, n);
180
/* Writes a block, updating the CRC term */
182
void fwrite_crc(char *buffer, int count, FILE *stream)
184
crc_for_block(buffer, count);
186
file_write(buffer, 1, count, stream);
193
/* Processes the given block upon extraction. Returns a nonzero value if the
194
extraction is to be terminated. */
196
int extraction_stub(char *block, int block_len, int action)
203
if(!debug_enabled||strchr(debug_opt, 'c')==NULL)
204
crc_for_block(block, block_len);
206
crc32_for_block(block, block_len);
208
if(!file_packing) /* Not applicable for memory data */
210
if(encmem_limit<block_len) /* Check for overrun */
212
encmem_limit-=block_len;
213
far_memmove(encblock_ptr, (char FAR *)block, block_len);
214
encblock_ptr+=block_len;
215
encmem_remain+=block_len;
220
if(action==BOP_LIST||action==BOP_SEARCH||action==BOP_COMPARE||action==BOP_DISPLAY)
221
return(block_op(action, block, block_len));
225
/* Strip high bit from files created by different OS */
226
if(file_type==ARJT_TEXT&&host_os!=OS
228
&&type_override!=FT_BINARY
237
if(fputc((int)c, atstream)==EOF)
243
/* HACK for IBM LIBC implementations under 32-bit OS/2 */
244
#if SFX_LEVEL>=ARJSFXV&&TARGET==OS2&&(COMPILER==ICC||defined(LIBC))
245
int fn=fileno(atstream);
249
_setmode(fn, file_type?0x4000:0x8000); /* O_TEXT:O_BINARY */
250
cn=write(fn, block, block_len);
253
cn=fwrite(block, 1, block_len, atstream);
255
cn=fwrite(block, 1, block_len, atstream);
257
#if SFX_LEVEL>=ARJSFXV
267
/* Executed when decoding is initialized */
269
void decode_start_stub()
278
#if SFX_LEVEL>=ARJSFXV
285
#if SFX_LEVEL>=ARJSFXV
287
/* Executed when the decoding memory variables are released */
289
void decode_end_stub()
291
/* Currently empty, may contain debugging checks if needed. */
298
/* Finds an non-existent filename that matches the given format string. The
299
format string must contain "%d" somewhere because the names are numbered. */
301
char *find_tmp_filename(char *name_format)
303
char tmp_name[CCHMAXPATH];
308
sprintf(tmp_name, name_format, i);
309
if(!file_exists(tmp_name))
310
return(strcpy(name_format, tmp_name));
312
error(M_CANTOPEN, name_format);
313
return(0); /* not reached, avoid warning */
316
/* Creates an numeric extension to the name, returns -1 if failed */
318
int find_num_ext(char *name, int mode)
320
char tmp_name[CCHMAXPATHCOMP];
321
char tmp_ext[CCHMAXPATHCOMP];
326
strcpy(tmp_name, name);
327
name_offset=split_name(tmp_name, NULL, NULL);
328
if((ext_offset=strchr(&tmp_name[name_offset], '.'))==NULL)
329
strcat(tmp_name, ext_digits);
332
strcpy(tmp_ext, ext_offset); /* Remember the original extension */
333
strcpy(ext_offset, ext_digits); /* Substitute extension */
335
strcat(tmp_name, tmp_ext); /* Complete with original extension */
337
for(ext_num=0; ext_num<999; ext_num++)
339
sprintf(name, tmp_name, ext_num);
340
if(!file_exists(name))
343
msg_cprintf(0, M_EXISTS, name);
347
/* Treats filename as an ARCmail packet and finds a suitable name for it */
349
int find_arcmail_name(char *name)
351
unsigned long counter;
355
for(counter=0L; counter<100000000L; counter++)
357
if((nptr=strchr(name+1, '.'))==NULL)
358
nptr=name+strlen(name);
372
msg_cprintf(0, M_RANGE_EXCEEDED, name);
380
if(!file_exists(name))
383
msg_cprintf(0, M_EXISTS, name);
389
#if SFX_LEVEL>=ARJSFXV
391
/* Puts the given character to the console */
393
static int nputc(int c)
395
msg_cprintf(0, (FMSG *)"%c", c);
403
/* Reads a command for execution from the stdin */
407
char cmd[CMDLINE_LENGTH];
409
msg_cprintf(0, M_COMMAND);
410
read_line(cmd, sizeof(cmd));
418
/* Compares the first n characters of two MSG-strings (used exclusively by
419
query_action_proc()) */
423
static int cmp_far_str(char FAR *str1, char FAR *str2, int length)
428
nstr1=malloc_far_str(str1);
429
nstr2=malloc_far_str(str2);
430
result=strncmp(nstr1, nstr2, length);
436
#define msg_strncmp(str1, str2, length) cmp_far_str((char FAR *)str1, (char FAR *)str2, length)
439
#define msg_strncmp strncmp
442
/* Query routine - used exclusively by query_action() */
444
#if SFX_LEVEL>=ARJSFXV
446
static int query_action_proc(int def, int qtype, char *query)
448
char reply_text[INPUT_LENGTH];
450
char *sel_ptr, *rt_ptr;
454
msg_cprintf(H_PROMPT, (FMSG *)strform, query);
456
if(qtype!=QUERY_CRITICAL&&queries_assume_no[qtype])
458
msg_cprintf(H_OPER, M_NO);
459
msg_cprintf(0, (FMSG *)lf);
462
if(qtype!=QUERY_CRITICAL&&queries_assume_yes[qtype])
464
msg_cprintf(H_OPER, M_YES);
465
msg_cprintf(0, (FMSG *)lf);
469
if(kbd_cleanup_on_input)
472
if(accept_shortcut_keys)
481
/* If possible default action selected */
484
msg_cprintf(0, (FMSG *)lf);
491
far_strcpy(strcpy_buf, M_REPLIES);
492
sel_ptr=strchr(strcpy_buf, ukey);
493
sel=sel_ptr-strcpy_buf;
494
if(ukey!=0&&sel_ptr!=NULL&&(qtype!=QUERY_CRITICAL||sel<=REPLY_QUIT))
500
msg_cprintf(0, (FMSG *)lf);
501
} while(sel>MAX_REPLY);
509
exit(ARJ_ERL_WARNING);
511
if(qtype!=QUERY_CRITICAL)
512
queries_assume_yes[qtype]=1;
515
if(qtype!=QUERY_CRITICAL)
516
queries_assume_no[qtype]=1;
519
yes_on_all_queries=1;
524
msg_cprintf(H_PROMPT, (FMSG *)strform, query);
527
/* There is no way down here */
530
/* Use an editable field */
533
read_line(reply_text, INPUT_LENGTH);
534
for(rt_ptr=reply_text; rt_ptr[0]==' '; rt_ptr++);
535
if((rt_len=strlen(rt_ptr))>0)
538
if(!msg_strncmp(rt_ptr, reply_help, rt_len))
540
far_strcpy(strcpy_buf, (qtype==QUERY_CRITICAL)?M_REPLIES_HELP:M_ALL_REPLIES_HELP);
541
msg_cprintf(0, (FMSG *)strcpy_buf);
544
else if(!msg_strncmp(rt_ptr, M_NO, rt_len))
546
else if(!msg_strncmp(rt_ptr, M_YES, rt_len))
548
else if(!msg_strncmp(rt_ptr, M_QUIT, rt_len))
550
else if(qtype!=QUERY_CRITICAL)
553
if(!msg_strncmp(rt_ptr, M_ALWAYS, rt_len))
555
if(qtype!=QUERY_CRITICAL)
556
queries_assume_yes[qtype]=1;
559
if(!msg_strncmp(rt_ptr, M_SKIP, rt_len))
561
if(qtype!=QUERY_CRITICAL)
562
queries_assume_no[qtype]=1;
566
if(!msg_strncmp(rt_ptr, M_GLOBAL, rt_len))
568
yes_on_all_queries=1;
572
if(!msg_strncmp(rt_ptr, M_COMMAND, rt_len))
576
msg_cprintf(H_PROMPT, (FMSG *)strform, query);
591
msg_cprintf(0, M_REPLIES_HELP);
610
read_line(buf, sizeof(buf));
614
if((sl=strlen(buf_ptr))!=0)
617
fmsg_ptr=malloc_fmsg(M_NO);
618
rc=strncmp(buf_ptr, fmsg_ptr, sl);
622
fmsg_ptr=malloc_fmsg(M_YES);
623
rc=strncmp(buf_ptr, fmsg_ptr, sl);
628
fmsg_ptr=malloc_fmsg(M_QUIT);
629
rc=strncmp(buf_ptr, fmsg_ptr, sl);
632
exit(ARJSFX_ERL_ERROR);
635
msg_cprintf(0, M_REPLIES_HELP);
641
#if SFX_LEVEL>=ARJSFXV
643
/* Standard procedure that queries user. Accepts the following parameters:
644
- def=0 if no default action, or number of reply to be selected w/ENTER.
645
- qtype is the standard query number to allow pre-selections.
646
- query is the query text. */
648
int query_action(int def, int qtype, FMSG *query)
655
if((tmp_stdout=new_stdout)==new_stderr)
657
result=query_action_proc(def, qtype, nquery=malloc_fmsg(query));
659
new_stdout=tmp_stdout;
662
return(query_action_proc(def, qtype, query));
666
/* Prompts the user to press ENTER */
674
if((tmp_stdout=new_stdout)==new_stderr)
676
tmp_query=malloc_fmsg(M_PRESS_ENTER);
677
rc=query_action_proc(1, QUERY_PRESS_ENTER, tmp_query);
678
new_stdout=tmp_stdout;
683
/* Puts a LF character to the stdout */
687
msg_cprintf(0, (FMSG *)lf);
694
/* Deletes files specified by the given wildcard. Returns 1 if no files were
697
int delete_files(char *name)
699
char tmp_name[CCHMAXPATHCOMP];
700
struct flist_root root;
703
flist_init(&root, FCLIM_DELETION, FL_STANDARD);
704
if(flist_add_files(&root, NULL, name, 1, 0, FETCH_FILES, NULL))
706
for(curfile=0; curfile<root.files; curfile++)
708
flist_retrieve(tmp_name, NULL, &root, curfile);
709
msg_cprintf(0, M_DELETING, tmp_name);
710
if(is_directory(tmp_name)?file_rmdir(tmp_name):file_unlink(tmp_name))
711
msg_cprintf(H_ERR, M_CANT_DELETE, tmp_name);
713
flist_cleanup(&root);
721
/* Displays the given comment string */
723
#if SFX_LEVEL>=ARJSFXV
724
void display_comment(char FAR *cmt)
726
void display_comment(char *cmt)
730
#if SFX_LEVEL>=ARJSFXV
738
if(new_stderr==new_stdout)
744
VioSetAnsi(ANSI_ON, 0);
746
while((c=*(cmt++))!='\0')
748
#if SFX_LEVEL>=ARJSFXV
752
#if SFX_LEVEL>=ARJSFXV&&!defined(DIRECT_TO_ANSI)
762
/* Substitute non-printable control characters with "?"'s */
763
#ifndef DIRECT_TO_ANSI
764
if(c<' '&&c!=TAB&&c!=LF&&c!=CR)
767
#if SFX_LEVEL>=ARJSFXV
770
fputc((int)c, stdout);
776
if(lines_scrolled>=lines_per_page-1)
779
if(!yes_on_all_queries&&prompt_for_more&&is_tty(stdout))
787
#if SFX_LEVEL>=ARJSFXV&&!defined(DIRECT_TO_ANSI)
791
#if SFX_LEVEL>=ARJSFXV
794
#ifdef DIRECT_TO_ANSI
808
/* Puts repeatable character to stdout */
810
static char *nputnc(char *dest, int c, int count)
819
/* Displays progress indicator */
821
void display_indicator(long bytes)
826
/* Indicator width */
827
static unsigned char ind_sizes[]={5, 0, 11, 5, 8, 11, 11};
829
static int prev_pct=0;
836
arjdisp_scrn((unsigned long)bytes);
837
/* Different conditions for ARJ and ARJSFX! */
839
else if(indicator_style!=IND_NONE)
841
check_wrap(ind_sizes[indicator_style]);
845
p+=sprintf(p, sfmt_double, del_double);
846
p+=sprintf(p, sfmt_bytes, bytes, del_double);
850
if(indicator_style==IND_NORMAL||indicator_style==IND_TOTAL_PCT)
854
p+=sprintf(p, sfmt_single, del_single);
855
p+=sprintf(p, sfmt_start_graph, del_single);
859
if(total_size!=0&&display_totals&&indicator_style==IND_TOTAL_PCT)
860
pct=calc_percentage(total_written+bytes, total_size);
862
pct=calc_percentage(bytes, uncompsize);
863
if(pct==prev_pct&&CHECK_SENTRY())
865
p+=sprintf(p, sfmt_numeric, pct/10, del_single);
868
else if(indicator_style==IND_GRAPH||indicator_style==IND_TOTAL_GRAPH)
872
p+=sprintf(p, sfmt_double, del_double);
873
p+=sprintf(p, sfmt_graph, del_double);
875
msg_cprintf(H_HL, (FMSG *)strform, ind);
879
if(total_size!=0&&display_totals&&indicator_style==IND_TOTAL_GRAPH)
880
pct=calc_percentage(total_written+bytes, total_size);
882
pct=calc_percentage(bytes, uncompsize);
883
if(pct==prev_pct&&CHECK_SENTRY())
885
p=nputnc(p, COUNTER_CHAR, pct/100);
886
p=nputnc(p, '\b', pct/100);
888
msg_cprintf(H_OPER, (FMSG *)strform, ind);
891
else if(indicator_style==IND_PCT_GRAPH||indicator_style==IND_TOTAL_PCT_GRAPH||indicator_style==IND_TOTAL_PCT_LGRAPH)
893
if(total_size!=0&&display_totals&&(indicator_style==IND_TOTAL_PCT_GRAPH||indicator_style==IND_TOTAL_PCT_LGRAPH))
894
pct=calc_percentage(total_written+bytes, total_size);
896
pct=calc_percentage(bytes, uncompsize);
899
p+=sprintf(p, sfmt_double, del_double);
900
p+=sprintf(p, sfmt_start_num, pct/10);
902
if(pct==prev_pct&&CHECK_SENTRY())
904
msg_cprintf(H_OPER, (FMSG *)strform, ind);
905
msg_cprintf(H_HL, sfmt_mid_graph, del_double);
909
p+=sprintf(p, sfmt_short_numeric, pct/10);
910
if(total_size!=0&&indicator_style==IND_TOTAL_PCT_GRAPH)
911
pct=calc_percentage(total_written+bytes, total_size);
913
pct=calc_percentage(bytes, uncompsize);
914
if(pct==prev_pct&&CHECK_SENTRY())
916
p=nputnc(p, COUNTER_CHAR, pct/200);
917
p=nputnc(p, '\b', pct/200+5);
923
msg_cprintf(H_OPER, (FMSG *)strform, ind);
926
#elif SFX_LEVEL==ARJSFXV
927
else if(indicator_style==IND_NORMAL||indicator_style==IND_GRAPH)
932
p+=sprintf(p, sfmt_double, del_double);
933
p+=sprintf(p, sfmt_bytes, bytes, del_double);
935
if(indicator_style==IND_NORMAL)
939
p+=sprintf(p, sfmt_single, del_single);
940
p+=sprintf(p, sfmt_start_graph, del_single);
944
pct=calc_percentage(bytes, uncompsize);
945
p+=sprintf(p, sfmt_numeric, pct/10, del_single);
950
msg_cprintf(0, (FMSG *)strform, ind);
952
else if(indicator_style==IND_NORMAL)
954
pct=calc_percentage(bytes, uncompsize);
955
printf(sfmt_sfx, pct/10);
964
/* Puts a character to the output stream. The cursor position given is only for
965
checking purposes. Returns the new cursor position. */
967
static int arj_putc(unsigned char c, int p)
986
if(p<CONSOLE_LINE_LENGTH)
989
} while(p%TAB_POS!=1);
999
*q++=(c>=' ')?c:UNDISP_CHAR;
1003
msg_cprintf(0, (FMSG *)strform, t);
1007
/* Prints the given text to stdout, querying for "more?" when needed. Returns
1008
1 if the output was cancelled by the user in response to the "--More--?"
1011
static int list_with_more(char *str, unsigned int len)
1013
char i_field[CONSOLE_LINE_LENGTH+1]; /* Input field */
1026
far_strcpy((char FAR *)i_field, prompt_for_more?M_QUERY_MORE:M_QUERY_SCANNED_ENOUGH);
1034
if(verbose_display==VERBOSE_NONE&&!help_issued)
1035
c&=0x7F; /* Strip high bit from nonlocal text */
1039
cur_pos=arj_putc(c, cur_pos);
1043
if(cur_line>=lines_per_page-2)
1046
sf=(yes_on_all_queries|skip_scanned_query);
1049
sf=query_action(REPLY_NO, QUERY_SCANNED_ENOUGH, i_field);
1060
sf=(yes_on_all_queries|skip_scanned_query);
1063
sf=query_action(REPLY_NO, QUERY_SCANNED_ENOUGH, i_field);
1070
/* Compares the contents of the block with the input file. */
1072
static int compare_fblock(char *block, int len)
1075
char FAR *tmp_block;
1077
if(identical_filedata)
1079
tmp_block=farmalloc_msg((unsigned long)len);
1080
far_memmove(tmp_block, (char FAR *)block, len);
1081
if((bytes_read=fread(block, 1, len, tstream))!=len)
1082
identical_filedata=0;
1087
if(far_memcmp((char FAR *)block, tmp_block, bytes_read))
1088
identical_filedata=0;
1091
far_memmove((char FAR *)block, tmp_block, len);
1097
/* Displays the text found in a block. Returns the number of bytes displayed. */
1099
static int display_found_text(unsigned char FAR *block, int offset, int block_len)
1108
remain=min(fdisp_lines*TXTD_LENGTH, block_len);
1109
if(remain>TXTD_LENGTH)
1111
msg_cprintf(0, M_MARK_LLINE);
1112
d_offset=(remain/2>offset)?0:offset-remain/2;
1117
while(i<remain&&d_offset<block_len)
1119
if(column>=TXTD_LENGTH)
1131
if(c<CON_LBOUND||c>CON_UBOUND)
1133
fputc(c, new_stdout);
1139
return(i-(offset-d_offset));
1142
/* Performs a search for the given pattern in memory block */
1144
static int t_search_stub(char *pattern, char *cmpblock, char FAR *block, int skip, int block_len)
1154
len=strlen(pattern);
1158
limit=(len>=block_len)?0:block_len-len;
1161
while(t_offset<limit)
1165
if(!memcmp(pattern, p, len))
1167
if(!pattern_found&&search_mode!=SEARCH_DEFAULT)
1169
if(search_mode==SEARCH_SHOW_NAMES)
1170
msg_cprintf(0, strform, misc_buf);
1171
if(search_mode!=SEARCH_DEFAULT)
1172
msg_cprintf(0, strform, lf);
1176
if(fdisp_lines!=0&&t_offset>search_offset)
1177
search_offset=t_offset+display_found_text(block, t_offset, block_len)-len;
1178
if(extm_mode!=EXTM_NONE)
1188
/* Performs a search in the block of continuous data. */
1190
static int search_in_block(char *block, int block_len)
1192
int tmp_len, tail_len;
1194
char FAR *block_ptr;
1195
char FAR *reserve_ptr;
1198
block_ptr=(char FAR *)block;
1199
reserve_ptr=(char FAR *)search_reserve;
1202
block_ptr=farmalloc_msg((unsigned long)block_len);
1203
far_memmove(block_ptr, (char FAR *)block, block_len);
1204
toupper_loc(block, block_len);
1207
reserve_ptr=farmalloc_msg(160L);
1208
far_memmove(reserve_ptr, (char FAR *)search_reserve, reserve_size);
1209
toupper_loc(search_reserve, reserve_size);
1212
for(i=0; i<SEARCH_STR_MAX&&search_str[i]!=NULL; i++)
1214
sstr_ptr=search_str[i];
1217
tmp_len=(block_len>INPUT_LENGTH)?INPUT_LENGTH:block_len;
1218
memcpy(search_reserve+reserve_size, block, tmp_len);
1220
far_memmove(&reserve_ptr[reserve_size], block_ptr, tmp_len);
1221
tail_len=reserve_size-strlen(sstr_ptr)+1;
1222
search_occurences[i]+=(long)t_search_stub(sstr_ptr, search_reserve, reserve_ptr, tail_len, reserve_size+tmp_len);
1223
if(pattern_found&&extm_mode!=EXTM_NONE)
1226
search_occurences[i]+=(long)t_search_stub(sstr_ptr, block, block_ptr, 0, block_len);
1227
if(pattern_found&&extm_mode!=EXTM_NONE)
1232
far_memmove((char FAR *)block, block_ptr, block_len);
1235
farfree(reserve_ptr);
1237
reserve_size=(block_len>INPUT_LENGTH)?INPUT_LENGTH:block_len;
1238
memcpy(search_reserve, block+(block_len-reserve_size), reserve_size);
1242
/* Displays a block of text using ANSI comment display routine. */
1244
static int display_block(char *str, int len)
1246
if(new_stdout!=new_stderr)
1250
#ifndef DIRECT_TO_ANSI
1251
display_ansi(*(str++));
1260
/* Performs various actions involving the given block. */
1262
static int block_op(int action, char *block, int len)
1264
if(action==BOP_LIST)
1265
return(list_with_more(block, len));
1266
else if(action==BOP_DISPLAY)
1267
return(display_block(block, len));
1268
else if(action==BOP_SEARCH)
1269
return(search_in_block(block, len));
1270
else if(action==BOP_COMPARE)
1271
return(compare_fblock(block, len));
1278
#if SFX_LEVEL>=ARJ||defined(REARJ)
1280
/* Renames file and ensures that it has been successfully renamed */
1284
int rename_with_check(char *oldname, char *newname)
1286
if(!no_file_activity)
1288
if(file_rename(oldname, newname))
1290
if(file_exists(oldname)||!file_exists(newname))
1298
void rename_with_check(char *oldname, char *newname)
1300
if(!file_test_access(oldname))
1302
if(!file_rename(oldname, newname))
1304
if(!file_exists(oldname)&&file_exists(newname))
1308
error(M_CANTRENAME, oldname, newname);
1312
#endif /* SFX_LEVEL>=ARJ||defined(REARJ) */
1316
/* Returns number of <c> occurences in the given string */
1318
static int count_chars(char *str, char c)
1323
for(tmp_ptr=str; *tmp_ptr!='\0'; tmp_ptr++)
1329
/* Deletes the processed files */
1331
int delete_processed_files(struct flist_root *root)
1333
char name[FILENAME_MAX];
1335
int depth, max_depth;
1339
/* If break is requested, cancel the deletion */
1340
if(ctrlc_processing)
1344
for(i=0; i<root->files; i++)
1346
if(cfa_get(i)==FLFLAG_PROCESSED)
1349
if(delete_processed==DP_STD&&!yes_on_all_queries&&!query_delete)
1351
msg_sprintf(misc_buf, M_QUERY_DELETE_N_FILES, count);
1352
if(!query_action(REPLY_YES, QUERY_DELETE_N_FILES, (char FAR *)misc_buf))
1355
msg_cprintf(0, M_DELETE_COUNT, count);
1356
for(i=0; i<root->files; i++)
1358
if(cfa_get(i)==FLFLAG_PROCESSED)
1360
flist_retrieve(name, NULL, root, i);
1361
depth=count_chars(name, PATHSEP_DEFAULT);
1364
if(!is_directory(name))
1366
/* ASR fix for 2.78-TCO */
1367
if(delete_processed!=DP_ADD_TRUNC)
1369
if(file_unlink(name))
1371
msg_cprintf(H_ERR, M_CANT_DELETE, name);
1377
if((t=file_open(name, m_rbp))==NULL)
1379
msg_cprintf(H_ERR, M_CANT_TRUNCATE, name);
1385
cfa_store(i, FLFLAG_DELETED);
1389
for(depth=max_depth; depth>=0; depth--)
1391
for(i=0; i<root->files; i++)
1393
if(cfa_get(i)==FLFLAG_PROCESSED)
1395
flist_retrieve(name, NULL, root, i);
1396
if(count_chars(name, PATHSEP_DEFAULT)>=depth&&is_directory(name))
1398
if(file_rmdir(name))
1400
msg_cprintf(H_ERR, M_CANT_DELETE, name);
1403
cfa_store(i, FLFLAG_DELETED);
1411
/* Writes a byte to the file */
1413
void fput_byte(int b, FILE *stream)
1415
if(!no_file_activity)
1417
if(fputc(b, stream)==EOF)
1422
/* Writes two bytes to the file */
1424
void fput_word(unsigned int w, FILE *stream)
1426
fput_byte(w&0xFF, stream);
1427
fput_byte(w>>8, stream);
1430
/* Writes four bytes to the file */
1432
void fput_dword(unsigned long l, FILE *stream)
1434
#ifdef WORDS_BIGENDIAN
1435
fput_word((unsigned int)(l&0xFFFF), stream);
1436
fput_word((unsigned int)(l>>16), stream);
1438
if(!no_file_activity)
1440
if(!fwrite(&l,4,1,stream))
1446
/* Writes the compressed data */
1448
void flush_compdata()
1452
compsize+=(unsigned long)out_bytes;
1453
if(compsize>origsize&&(!garble_enabled||!file_packing))
1457
if(!no_file_activity)
1460
garble_encode_stub(out_buffer, out_bytes);
1463
file_write(out_buffer, 1, out_bytes, aostream);
1467
far_memmove(packblock_ptr, (char FAR *)out_buffer, out_bytes);
1468
packblock_ptr+=out_bytes;
1470
out_avail=PUTBIT_SIZE;
1477
/* Initializes compressed data output */
1487
if(!file_packing||no_file_activity)
1492
if(fp>MAX_FILE_SIZE)
1493
error(M_FILE_IS_TOO_LARGE);
1495
out_buffer=malloc_msg(PUTBIT_SIZE);
1496
out_avail=PUTBIT_SIZE-(fp%PUTBIT_SIZE);
1497
if(out_avail>PUTBIT_SIZE)
1498
error(M_PUTBIT_SIZE_ERROR);
1502
/* Ends the bitwise output */
1504
void shutdown_putbits()
1508
putbits(CHAR_BIT-1, 0);
1516
/* Clears the archive attribute for a set of files */
1518
int group_clear_arch(struct flist_root *root)
1520
char name[FILENAME_MAX];
1523
if(ctrlc_processing)
1525
for(i=0; i<root->files; i++)
1527
if(cfa_get(i)==FLFLAG_PROCESSED)
1529
flist_retrieve(name, NULL, root, i);
1530
if(dos_clear_arch_attr(name))
1531
msg_cprintf(H_ERR, M_CANT_RESET, name);
1532
cfa_store(i, FLFLAG_DELETED);