From: "Juan Manuel Guerrero" Organization: Darmstadt University of Technology To: Eli Zaretskii Date: Tue, 20 Mar 2001 18:15:00 +0200 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: 2 suggestions for djtar CC: djgpp-workers AT delorie DOT com References: <5167B200FDB AT HRZ1 DOT hrz DOT tu-darmstadt DOT de> In-reply-to: X-mailer: Pegasus Mail for Windows (v2.54DE) Message-ID: <528F0357083@HRZ1.hrz.tu-darmstadt.de> Reply-To: djgpp-workers AT delorie DOT com _ non-ANSI/non-POSIX functions like basename and stricmp have been used to simplify the code for .bat extension detection. This has been explicitly avoided in previous versions. _ buflen will be tested before testing src[0] and src[-1] in the if clause. _ patch for djtar's docs and wc204.txi have been added. Regards, Guerrero, Juan Manuel diff -acprNC5 djgpp.orig/src/docs/wc204.txi djgpp/src/docs/wc204.txi *** djgpp.orig/src/docs/wc204.txi Tue Mar 20 14:24:08 2001 --- djgpp/src/docs/wc204.txi Tue Mar 20 17:36:14 2001 *************** failed to rename the produced executable *** 352,356 **** --- 352,361 ---- @findex _write AT r{, security fix} When @code{write} and @code{_write} detect that a file pointer is past EOF, that space will now be filled with zeroes to increase POSIX compliance and plug a security hole on disks containing sensitive information. + @pindex djtar AT r{, DOS batch file conversion} + If a tar archive contains DOS batch files that have been stored in + UNIX-style EOL, @code{djtar} will now convert them automatically + to DOS-style EOL. This is because @file{COMMAND.COM} refuses to + run batch files that contain UNIX-style EOLs. diff -acprNC5 djgpp.orig/src/utils/djtar/djtar.c djgpp/src/utils/djtar/djtar.c *** djgpp.orig/src/utils/djtar/djtar.c Sat Mar 17 16:33:06 2001 --- djgpp/src/utils/djtar/djtar.c Sun Mar 18 17:19:34 2001 *************** get_new_name(char *name_to_change, int * *** 304,316 **** changed_name = get_entry(name_to_change); if (*should_be_written && !to_stdout && NO_LFN(changed_name)) { static char info_[] = ".info-"; static char _tar_gz[] = ".tar.gz", _tgz[] = ".tgz"; static char xx[] = "++"; ! char *info, *tgz, *plus; strcpy(new, changed_name); info = strstr(new, info_); if (info && isdigit(info[sizeof(info_)-1])) { --- 304,320 ---- changed_name = get_entry(name_to_change); if (*should_be_written && !to_stdout && NO_LFN(changed_name)) { static char info_[] = ".info-"; + static char _bzip2[] = ".bzip2", _bz2[] = ".bz2"; + static char *_tar_bz_extension[] = { ".tar.bz", ".tar.bz2", ".tar.bzip2", NULL}; + static char _tbz[] = ".tbz"; static char _tar_gz[] = ".tar.gz", _tgz[] = ".tgz"; static char xx[] = "++"; ! char *bz2, *info, *tbz, *tgz, *plus; ! int i = 0; strcpy(new, changed_name); info = strstr(new, info_); if (info && isdigit(info[sizeof(info_)-1])) { *************** get_new_name(char *name_to_change, int * *** 321,330 **** --- 325,350 ---- if (tgz && tgz[sizeof(_tar_gz)-1] == '\0') { strcpy(tgz, _tgz); fprintf(log_out, "[ changing %s to %s ]\n", changed_name, new); } + while (_tar_bz_extension[i]) + { + tbz = strstr(new, _tar_bz_extension[i]); + if (tbz && tbz[strlen(_tar_bz_extension[i])] == '\0') + { + strcpy(tbz, _tbz); + fprintf(log_out, "[ changing %s to %s ]\n", changed_name, new); + } + i++; + } + bz2 = strstr(new, _bzip2); + if (bz2 && bz2[sizeof(_bzip2)-1] == '\0') + { + strcpy(bz2, _bz2); + fprintf(log_out, "[ changing %s to %s ]\n", changed_name, new); + } plus = strstr(new, xx); if (plus) { register char *s = plus; diff -acprNC5 djgpp.orig/src/utils/djtar/untar.c djgpp/src/utils/djtar/untar.c *** djgpp.orig/src/utils/djtar/untar.c Sat Mar 17 16:39:54 2001 --- djgpp/src/utils/djtar/untar.c Tue Mar 20 16:42:08 2001 *************** static int skipping; *** 60,70 **** extern char new[]; int tarread(char *buf, long buf_size) { ! int should_be_written; while (buf_size) { int write_errno = 0; int dsize = 512, wsize; --- 60,70 ---- extern char new[]; int tarread(char *buf, long buf_size) { ! int should_be_written, batch_file_processing = 0; while (buf_size) { int write_errno = 0; int dsize = 512, wsize; *************** tarread(char *buf, long buf_size) *** 89,98 **** --- 89,99 ---- } } if (looking_for_header) { + char *extension; int head_csum = 0; int i; size_t nlen; memcpy(&header, buf, sizeof header); *************** tarread(char *buf, long buf_size) *** 106,115 **** --- 107,123 ---- bytes_out += sizeof header; first_block = 1; file_type = DOS_BINARY; looking_for_header = 0; + /* command.com refuses to run batch files + that have been stored with UNIX-style EOL, + so we will extract them with DOS-style EOL. */ + extension = strrchr(basename(header.name), '.'); + if (extension && !stricmp(extension, ".bat")) + batch_file_processing = 1; /* LF -> CRLF */ + sscanf(header.operm, " %lo", &perm); sscanf(header.ouid, " %lo", &uid); sscanf(header.ogid, " %lo", &gid); sscanf(header.osize, " %lo", &size); sscanf(header.otime, " %o", &ftime); *************** open_file: *** 223,271 **** } while (size) { ! char tbuf[512]; char *wbuf = buf; if (buf_size <= 0) /* this buffer exhausted */ return 0; if (size < 512) dsize = size; else if (buf_size < 512) dsize = buf_size; else dsize = 512; ! if (first_block && (text_dos || text_unix || to_tty)) { ! file_type = guess_file_type(buf, dsize); ! first_block = 0; ! if (file_type == UNIX_TEXT && text_dos) ! setmode(r, O_TEXT); /* will add CR chars to each line */ ! } ! if ((text_unix || to_tty) && file_type == DOS_TEXT) ! { ! /* If they asked for text files to be written Unix style, or ! we are writing to console, remove the CR and ^Z characters ! from DOS text files. ! Note that we don't alter the original uncompressed data so ! as not to screw up the CRC computations. */ ! char *s=buf, *d=tbuf; ! while (s-buf < dsize) ! { ! if (*s != '\r' && *s != 26) ! *d++ = *s; ! s++; } ! wsize = d - tbuf; wbuf = tbuf; } else { ! wbuf = buf; ! wsize = dsize; } errno = 0; if (write(r, wbuf, wsize) < wsize) { if (errno == 0) --- 231,299 ---- } while (size) { ! char tbuf[1024]; char *wbuf = buf; if (buf_size <= 0) /* this buffer exhausted */ return 0; if (size < 512) dsize = size; else if (buf_size < 512) dsize = buf_size; else dsize = 512; ! if (batch_file_processing && !to_tty) { ! /* LF -> CRLF. ! Note that we don't alter the original uncompressed ! data so as not to screw up the CRC computations. */ ! char *src = buf, *dest = tbuf; ! int buflen = 0; ! while (buflen < dsize) ! { ! if (buflen && *src == '\n' && src[-1] != '\r') ! *dest++ = '\r'; ! *dest++ = *src++; ! buflen = src - buf; } ! wsize = dest - tbuf; wbuf = tbuf; } else { ! if (first_block && (text_dos || text_unix || to_tty)) ! { ! file_type = guess_file_type(buf, dsize); ! first_block = 0; ! if (file_type == UNIX_TEXT && text_dos) ! setmode(r, O_TEXT); /* will add CR chars to each line */ ! } ! if ((text_unix || to_tty) && file_type == DOS_TEXT) ! { ! /* If they asked for text files to be written Unix style, or ! we are writing to console, remove the CR and ^Z characters ! from DOS text files. ! Note that we don't alter the original uncompressed data so ! as not to screw up the CRC computations. */ ! char *s=buf, *d=tbuf; ! while (s-buf < dsize) ! { ! if (*s != '\r' && *s != 26) ! *d++ = *s; ! s++; ! } ! wsize = d - tbuf; ! wbuf = tbuf; ! } ! else ! { ! wbuf = buf; ! wsize = dsize; ! } } errno = 0; if (write(r, wbuf, wsize) < wsize) { if (errno == 0) *************** open_file: *** 293,302 **** --- 321,331 ---- ftimes.ft_year = tm->tm_year - 80; setftime(r, &ftimes); close(r); chmod(changed_name, perm); } + batch_file_processing = 0; looking_for_header = 1; if (write_errno == ENOSPC) /* target disk full: quit early */ { bytes_out += buf_size; return EOF; diff -acprNC5 djgpp.orig/src/utils/utils.tex djgpp/src/utils/utils.tex *** djgpp.orig/src/utils/utils.tex Tue Mar 20 14:26:08 2001 --- djgpp/src/utils/utils.tex Tue Mar 20 16:45:04 2001 *************** test; this usually means the file is eit *** 174,190 **** tar format. An additional bonus of using @code{djtar} is that it can convert Unix-style text files to DOS-style text files, and vice versa. By default, it will write all files exactly as found in the archive, but the ! @samp{-u} and @samp{-d} options can change that. @code{djtar} performs a number of file name conversions in an attempt to make the files fit into MS-DOS's restricted file names. Any file ending in @file{.info- AT var{n}}, where @var{n} is a number, becomes @file{.i AT var{n}}. Any file ending in @file{.tar.gz} becomes ! @file{.tgz}. Any @file{++} string within a file name becomes @file{xx}. Any leading dots are changed to underscores (but current and parent directories, @file{./} and @file{../} are left alone). Any remaining multiple dots are changed to dashes, unless the part before the dot is shorter than 3 characters and there are more than 1 dot in the filename, in which case the dot also becomes an underscore. As a result, e.g., --- 174,197 ---- tar format. An additional bonus of using @code{djtar} is that it can convert Unix-style text files to DOS-style text files, and vice versa. By default, it will write all files exactly as found in the archive, but the ! @samp{-u} and @samp{-d} options can change that. @code{djtar} will ! always convert DOS batch files to DOS-style text files, if they ! have been stored as UNIX-style text files. This is because ! @file{command.com} refuses to run batch files that contain ! UNIX-style EOLs. @code{djtar} performs a number of file name conversions in an attempt to make the files fit into MS-DOS's restricted file names. Any file ending in @file{.info- AT var{n}}, where @var{n} is a number, becomes @file{.i AT var{n}}. Any file ending in @file{.tar.gz} becomes ! @file{.tgz}. Any file ending in @file{.tar.bzip2}, @file{.tar.bz2} ! or @file{.tar.bz} becomes @file{.tbz} and any file ending in ! @file{.bzip2} becomes @file{.bz2}. Any @file{++} string within ! a file name becomes @file{xx}. Any leading dots are changed to underscores (but current and parent directories, @file{./} and @file{../} are left alone). Any remaining multiple dots are changed to dashes, unless the part before the dot is shorter than 3 characters and there are more than 1 dot in the filename, in which case the dot also becomes an underscore. As a result, e.g.,