home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 2001 January
/
VPR0101A.BIN
/
OLS
/
TAR32053
/
tar32053.exe
/
SRC
/
CHKFNAME.C
< prev
next >
Wrap
C/C++ Source or Header
|
1999-05-23
|
16KB
|
780 lines
#ifndef __DEFCONF_H
#include "defconf.h"
#endif
/*
This file was hacked for kmtar for WIN32
at 1996-05-06.
by tantan SGL00213@niftyserve.or.jp
*/
/*
* chkfname - check & rename file name to MS-DOS style
*
* Written by AssistantIO
*/
#include <stdio.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <io.h>
#include <fcntl.h>
#include <string.h>
#include "defs.h"
#include "chkfname.h"
#include "misc.h"
#define USE_QSORT 1
#include <direct.h>
#if USE_QSORT
#include <search.h>
#endif
#undef tolower
struct _rename_t {
char *org_name;
char *new_name;
int dir_p;
struct _rename_t *next;
};
typedef struct _rename_t rename_t;
#define NAMLEN 300
#define NAMLEN_NT 256
#define MAX_NAM 8
#define MAX_EXT 3
#define NO 0
#define YES 1
#define is_pathchar(c) ((c) == '\\' || (c) == '/')
static int register_rename_table(char *org_name, int dir_p, char *new_name);
static char *search_orgname(char *org_name, int dir_p);
static char *search_newname(char *new_name);
static char *make_new_fname(char *newname, char *name, int make_new, int dir_p);
static int last_char(char *p);
static char *normalize_fname(char *destin, char *source, int dir_p);
static char *trim_jstr(char *p, char *q, int len);
static int is_dir(char *filename);
static int is_character_device(char *name);
void erase_rename_table(void);
static int out_of_memory=0;
void em_erase_rename_table(void)
{
out_of_memory = 1;
fputs("\aError Out of memory !! file name check will not work\n",stderr);
fputs("\t ------- Hit RET Key for continue. -------",stderr);
getchar();
/* fputs("\t OK !. Now erase the wast array.\n",stderr);*/
erase_rename_table();
}
global void check_fname(char *dest, char *sour, int make_new, int dir_p)
{
char *p;
if ((p = search_orgname(sour, dir_p)) != NULL) {
strcpy((char *)dest, p);
return;
}
if (make_new_fname(dest, sour, make_new, dir_p) == NULL) {
strcpy(dest, sour);
}
if (out_of_memory)
return;
if (register_rename_table(sour, dir_p, dest) == NO){
em_erase_rename_table();
}
}
static rename_t *rename_table = NULL;
static int
register_rename_table(char *org_name, int dir_p, char *new_name) {
rename_t *nt;
if ((nt = (rename_t *)malloc((unsigned int)sizeof(rename_t))) == NULL) {
return NO;
}
if ((nt->org_name = strdup((char *)org_name)) == NULL) {
return NO;
}
if ((nt->new_name = strdup((char *)new_name)) == NULL) {
return NO;
}
nt->dir_p = dir_p;
nt->next = rename_table;
rename_table = nt;
return YES;
}
void erase_rename_table(void) /* tantan */
{
rename_t *nt, *bt;
for (nt = rename_table; nt != NULL;) {
free(nt->org_name);
free(nt->new_name);
bt = nt->next;
free(nt);
nt = bt;
}
rename_table = NULL;
}
int chk_rename_table()
{ return rename_table==NULL ? 0:1; }
static char *
search_orgname(char *org_name, int dir_p) {
rename_t *nt;
for (nt = rename_table; nt != NULL; nt = nt->next) {
if (strcmp(org_name, nt->org_name) == 0
&& dir_p == nt->dir_p) {
return nt->new_name;
}
}
return NULL;
}
static char *
search_newname(char *new_name) {
rename_t *nt;
for (nt = rename_table; nt != NULL; nt = nt->next) {
if (strcmp(new_name, nt->new_name) == 0) {
return nt->new_name;
}
}
return NULL;
}
static char *
make_new_fname(char *newname, char *name, int make_new, int dir_p) {
int is_dir();
char *d, *s, *p, *q, *period;
char tmpname[NAMLEN], basename[NAMLEN];
int extent_no;
struct stat statbuf;
normalize_fname(tmpname, name, dir_p);
d = newname;
s = tmpname;
if (isascii(*s) && isalpha(*s) && *(s + 1) ==':') {
*d++ = *s++;
*d++ = *s++;
}
while (*s != '\0') {
if (is_pathchar(*s)) {
*d++ = *s++;
}
if (*s == '.' && *(s + 1) == '.' && is_pathchar(*(s + 2))) { /* ..\ */
*d++ = *s++;
*d++ = *s++;
} else if (*s == '.' && is_pathchar(*(s + 1))) { /* .\ */
*d++ = *s++;
} else {
p = d;
period = NULL;
while (*s != '\0' && !is_pathchar(*s)) {
if (iskanji(*s) && iskanji2(*(s + 1))) {
*d++ = *s++;
*d++ = *s++;
} else if (*s == '.') {
period = d;
*d++ = *s++;
} else {
*d++ = *s++;
}
}
*d = '\0';
if (dir_p || *s != '\0') {
if (strchr("/\\:", last_char(newname)) == NULL
&& !is_dir(newname)
&& make_new
&& mkdir(newname) < 0) {
basename[0] = '_';
strcpy(basename + 1, p);
normalize_fname(p, basename, 1);
d = p + strlen(p);
if (!is_dir(newname) && mkdir(newname) < 0) {
return NULL;
}
}
}
}
}
if (dir_p) {
return newname;
}
/* printf("-- %s\n",newname); */
if (stat(newname, &statbuf) != 0) {
return newname;
}
if (!is_character_device(newname)
&& make_new == 0 && search_newname(newname) == NULL) {
return newname;
}
basename[0] = '_';
strcpy(basename + 1, p);
extent_no = -1;
q = d;
while (++extent_no < 1000) {
sprintf(q, ".%03d", extent_no);
if (stat(newname, &statbuf) != 0) {
return newname;
}
if (is_character_device(newname)) {
break;
}
if (make_new == 0 && search_newname(newname) == NULL) {
return newname;
}
}
normalize_fname(p, basename, 0);
if (stat(newname, &statbuf) != 0) {
return newname;
}
if (!is_character_device(newname) && make_new == 0) {
return newname;
}
d = p + strlen(p);
q = d;
while (*p != '\0') {
if (iskanji(*p) && iskanji2(*(p + 1))) {
p++;
} else if (*p == '.') {
q = p;
}
p++;
}
extent_no = -1;
while (++extent_no < 1000) {
sprintf(q, ".%03d", extent_no);
if (stat(newname, &statbuf) != 0) {
return newname;
}
if (is_character_device(newname)) {
break;
}
if (make_new == 0 && search_newname(newname) == NULL) {
return newname;
}
}
return NULL;
}
static int
last_char(char *p) {
int c;
for (c = *p; *p; p++) {
c = *p;
if (iskanji(*p) && iskanji2(p[1])) {
p++;
}
}
return c;
}
#ifdef WIN32
int is_forbid_char(int c)
{
return (int)strchr("?\"/\\<>*|:",c);
}
#endif
static char *
normalize_fname(char *destin, char *source, int dir_p) {
char *d, *s, *p, *q, *period;
d = destin;
s = source;
if (isascii(*s) && isalpha(*s) && *(s + 1) ==':') {
*d++ = tolower(*s++);
*d++ = *s++;
}
while (*s != '\0') {
if (is_pathchar(*s)) {
*d++ = *s++;
}
while (is_pathchar(*s)) {
s++;
}
p = d;
if (*s == '.' && *(s + 1) == '.' &&
(is_pathchar(*(s + 2)) || (dir_p && *(s + 2) == '\0'))) {
*d++ = *s++;
*d++ = *s++;
} else if (*s == '.' &&
(is_pathchar(*(s + 1)) || (dir_p && *(s + 1) == '\0'))) {
*d++ = *s++;
} else {
#ifndef WIN32
if (*s == '.') { /* WIN32 では .forward も許される */
*d++ = '_';
s++;
}
#endif
period = NULL;
while (*s != '\0' && !is_pathchar(*s)) {
if (iskanji(*s) && iskanji2(*(s + 1))) {
*d++ = *s++;
*d++ = *s++;
} else if ((isascii(*s) && isalnum(*s))
|| iskana(*s)
|| is_forbid_char(*s) == 0){
*d++ = *s++;
} else {
*d++ = '_';
s++;
}
}
if (period != NULL) {
if ((q = trim_jstr(p, period, MAX_NAM)) != NULL) {
memmove(q, period, d - period);
d += q - period;
period = q;
}
if ((q = trim_jstr(period + 1, d, MAX_EXT)) != NULL) {
d = q;
}
} else {
if ((q = trim_jstr(p, d, NAMLEN_NT)) != NULL) {
d = q;
}
}
}
}
*d = '\0';
return destin;
}
static char *
trim_jstr(char *p, char *q, int len) {
char *r, *s;
if (q - p <= len) {
return NULL;
}
r = p;
while ((s = r + (iskanji(*r) ? 2 : 1)) - p <= len) {
r = s;
}
return r;
}
static int
is_dir(char *filename) {
struct stat stat_buf;
int result;
result = stat(filename, &stat_buf);
if (result < 0
&& (access(filename, 0) == 0
|| (isascii(*filename)
&& isalpha(*filename)
&& strcmp(filename + 1, ":") == 0))) {
result = 0;
stat_buf.st_mode = S_IFDIR;
/* July 30 1990 */
}
return result == 0 && (stat_buf.st_mode & S_IFMT) == S_IFDIR;
/* July 30 1990 */
}
static int
is_character_device(char *name) {
int ret;
FILE *fp;
if ((fp = fopen(name, "r")) == NULL) {
return 0;
}
ret = isatty(fileno(fp));
fclose(fp);
return ret ? 1: 0;
}
#include <time.h>
#include "main.h"
static rename_t **fn_list;
static rename_t *t_rename_table = NULL;
static int n_rename=0;
#define OVERLAP_flag 11
#define CHANGED_flag 12
#if LSI_C
static char far *lsi_far_strdup(char far *str)
{
char far *dest;
dest = (char far *)_far_malloc((unsigned long)(_far_strlen(str)+1));
if (dest != NULL)
_far_strcpy(dest,str);
return dest;
}
char *f_to_n(char far *str)
{
static char buf[NAMLEN];
_far_strcpy((char far *)buf,str);
return buf;
}
#endif
static int store_name(char *sour,char *dest) /* for t commnad */
{
rename_t *nt;
if ((nt = (rename_t *) malloc((unsigned int)sizeof(rename_t))) == NULL) {
return NO;
}
if ((nt->org_name = strdup(sour)) == NULL) {
return NO;
}
if ((nt->new_name = strdup(dest)) == NULL) {
return NO;
}
nt->dir_p = 0;
nt->next = t_rename_table;
n_rename++;
t_rename_table = nt;
return YES;
}
static void print_header(void)
{
time_t ltime;
printf(
"# This report is made by kmtar for WIN-NT \n"
"#\t by tantan at "__DATE__ "\n#\n");
time(<ime);
printf("# FILE :%s\n# DATE :%s",Archives[0],ctime(<ime));
printf("# TOTAL:%d files detect\n#\n",n_rename);
}
static void print_names(int flag)
{
int i;
for (i=0;i<n_rename;i++){
if (fn_list[i]->dir_p == flag){
#if !LSI_C
printf("%s\t%s\n",fn_list[i]->org_name,fn_list[i]->new_name);
#else
printf("%s\t",f_to_n(fn_list[i]->org_name));
printf("%s\n",f_to_n(fn_list[i]->new_name));
#endif
}
}
}
static int check_overlap(void) /* used by t command */
{
int i,flag=0,count=0;
for (i=1;i<n_rename;i++){
#ifdef WIN32
if (stricmp(fn_list[i-1]->new_name,fn_list[i]->new_name) == 0){
#else
if (strcmp(fn_list[i-1]->new_name,fn_list[i]->new_name) == 0){
#endif
if (!flag){
fn_list[i-1]->dir_p = OVERLAP_flag;
flag = 1;
count++;
}
fn_list[i]->dir_p = OVERLAP_flag;
count++;
}else
flag=0;
}
return count;
}
int check_rename_or_not(void) /* used by t command */
{
int i,count=0;
for (i=0;i<n_rename;i++){
if (fn_list[i]->dir_p == OVERLAP_flag) /* skip overlap name */
continue;
if (strcmp(fn_list[i]->new_name,fn_list[i]->org_name) != 0){
count++;
fn_list[i]->dir_p = CHANGED_flag;
}
}
return count;
}
/*----------------------------------------------------*/
static int count_sl(char *str)
{
int i;
for(i=0;*str;++str)
if (*str == '/')
i++;
return i;
}
static int fname_cmp(char *n1,char *n2)
{
int n;
if ((n = count_sl(n1) - count_sl(n2)) != 0)
return n;
return strcmp(n1,n2);
}
#ifdef USE_QSORT
static int
#ifdef MSC
__cdecl
#endif
compare(const void *x,const void *y)
{
int n;
n = fname_cmp((*(rename_t **)x)->new_name,
(*(rename_t **)y)->new_name);
if (n != 0)
return n;
return fname_cmp((*(rename_t **)x)->org_name,
(*(rename_t **)y)->org_name);
}
#endif
#ifdef MSC
#pragma loop_opt(off)
#endif
void sort_rename_table(void)
{
#ifdef USE_QSORT
qsort((void *)fn_list,(size_t)n_rename,(size_t)sizeof(rename_t *),compare);
#else
/*
* This sorting algorithm
* "NIKKEY BYTE ",
*
*/
#define SHRINKFACTOR 1.3
/*use combsort11 */
int switches, i, j, top, gap, size = n_rename, di;
rename_t *tmp;
gap = size;
do{
gap = (int)((float)gap /SHRINKFACTOR);
switch(gap){
case 0:
gap = 1;
break;
case 9:
case 10:
gap = 11;
default:
break;
}
switches = 0;
top = size - gap;
for(i=0;i<top;++i){
j=i+gap;
if ((di = fname_cmp(fn_list[i]->new_name,
fn_list[j]->new_name)) > 0 ||
(di == 0 && fname_cmp(fn_list[i]->org_name,
fn_list[j]->org_name) > 0)){
tmp = fn_list[i];
fn_list[i] = fn_list[j];
fn_list[j] = tmp;
++switches;
}
}
}while(switches || (gap > 1));
#endif
}
#ifdef MSC
#pragma loop_opt(on)
#endif
int inspect_fname_list(void) /* used by t command */
{
rename_t *nt;
int i,n_over,n_change;
if((fn_list = (rename_t **)malloc((unsigned int)sizeof(rename_t *)*n_rename)) == NULL)
fatal("chkfname","Out of memory");
for (i=0,nt = t_rename_table; nt != NULL; nt = nt->next,i++) {
fn_list[i] = nt;
}
sort_rename_table();
n_over = check_overlap(); /* mark overlap name */
n_change = check_rename_or_not(); /* mark changed name */
print_header();
printf("#--------- check OVERLAP\t[total %d]\n",n_over);
printf("#\t[in Archive]\t\t\t[in WIN32]\n");
print_names(OVERLAP_flag);
printf("#\n#--------- check RENAME\t[total %d]\n",n_change);
printf("#\t[in Archive]\t\t\t[in WIN32]\n");
print_names(CHANGED_flag);
return YES;
}
/*read_res_file関数の内部変数*/
static int read_res_file_first=1;
void read_res_file(char ***argv) /* used by x or t command */
{
return;
/* comment out by tsuneo 1997.8.25 */
/* response file(間接引数)はここでは扱わないようにした。*/
/* 理由:mallocのところでメモリが次々消費されていくため。 */
#if 0
FILE *rf;
char **p,line[220],*s1;
char **new_argv,**pp;
int argc=0;
// static int first=1;
if (!read_res_file_first)
return;
if ((new_argv = (char **)malloc(sizeof(char *)*MAXARG)) == NULL)
fatal("chkfname","Out of memory");
read_res_file_first = 0;
for(pp = new_argv,p = *argv;*p != NULL;p++){
if(**p == '@'){ /* response file */
if ((rf = fopen(*p+1,"rb")) == NULL){
printf("Response file [%s] can't open\n",p[0]+1);
exit(1);
}
while(fgets(line, sizeof(line), rf) != NULL){
if (line[0] == '#')
continue;
if ((s1 = strtok(line," \t\n\r")) != NULL){
*pp = strdup(s1);
argc++;
pp++;
if (argc >= MAXARG){
fatal("chkfname","ARG size too big");
}
}
}
fclose(rf);
}else{
*pp = strdup(*p);
argc++;
pp++;
if (argc >= MAXARG){
fatal("chkfname","ARG size too big");
}
}
}
*pp = NULL;
*argv = new_argv;
#endif
}
char *get_orgname(char *new_name)
{
rename_t *nt;
for (nt = rename_table; nt != NULL; nt = nt->next) {
if (strcmp(new_name, nt->new_name) == 0)
return nt->org_name;
}
return NULL;
}
void recode_names(char *sour) /* for t command */
{
char dest[NAMLEN], *p;
if ((p = search_orgname(sour, 0)) != NULL) {
if(store_name((char *)sour, p) == NO)
fatal("chkfname","Out of memory");
return;
}
if (make_new_fname(dest, sour, 0, 0) == NULL) {
strcpy(dest, sour);
}
if (store_name((char *)sour,(char *)dest) == NO){
fatal("chkfname","Out of memory");
}
}
/* Read rule file into rename table */
/* and erase "#file" argument from */
/* argv */
void read_rule_file(char **argv) /* used by all command */
{
FILE *rf;
char **p,line[NAMLEN*2+30],*s1,*s2;
for(p = argv;*p != NULL;p++){
if(**p == '#'){ /* rule-file */
if ((rf = fopen(*p+1,"rb")) == NULL){
printf("Rule file [%s] can't open\n",p[0]+1);
exit(1);
}
while(fgets(line, sizeof(line), rf) != NULL){
if ((s1 = strtok(line," \t\n\r")) == NULL)
continue;
if (*s1=='#') /* comment line */
continue;
if ((s2 = strtok(NULL," \t\n\r")) == NULL)
continue;
if (register_rename_table(s1, 0, s2)== NO)
fatal("chkfname","Out of memory");
}
fclose(rf);
while(*p){
*p = *(p + 1);
p++;
}
return;
}
}
}
#ifdef DLL
void chkfname_static_init(void)
{
out_of_memory=0;
/* rename_table = NULL;*/
if(rename_table!=NULL){
erase_rename_table();
}
fn_list=NULL;
t_rename_table = NULL;
n_rename=0;
read_res_file_first=1;
}
#endif