您好,欢迎来到思海网络,我们将竭诚为您提供优质的服务! 诚征网络推广 | 网站备案 | 帮助中心 | 软件下载 | 购买流程 | 付款方式 | 联系我们 [ 会员登录/注册 ]
促销推广
客服中心
业务咨询
有事点击这里…  531199185
有事点击这里…  61352289
点击这里给我发消息  81721488
有事点击这里…  376585780
有事点击这里…  872642803
有事点击这里…  459248018
有事点击这里…  61352288
有事点击这里…  380791050
技术支持
有事点击这里…  714236853
有事点击这里…  719304487
有事点击这里…  1208894568
有事点击这里…  61352289
在线客服
有事点击这里…  531199185
有事点击这里…  61352288
有事点击这里…  983054746
有事点击这里…  893984210
当前位置:首页 >> 技术文章 >> 文章浏览
技术文章

UNIX操作系统tar命令之隐患及解决方法

添加时间:2011-5-17  添加: admin 
  目前,UNIX操作系统在我国金融界被广泛地采用,UNIX以其强大的功能(分时、多任务、多用户、网络互连、图形接口等),倍受金融企业青睐。中国农业银行现应用的SCO UNIX OPENSERVER50更是功能强劲。
   各家银行的储蓄、会计、信用卡等计算机业务处理系统均运行在UNIX操作系统平台上。电子化的发展拓展了银行的业务领域,提高了工作效率,加强了业务的准确性、保密性、安全性,树立了银行的社会形象,产生间接的经济效益。电子化银行的发展对计算机数据的可靠性提出了更高的要求。
   据笔者调查,在UNIX操作系统上备份和恢复数据的控制程序决大多数是用tar命令实现的。tar命令具有使用简单好学易用的特点。但笔者在使用tar命令的过程中,发现tar命令对于中国用户具有一个严重的隐患:对文件名为汉字且较长的文件能够归档打包,但不能解开该档案包。
   例如:
   1先创立一个长汉字文件名文件:
   # cd /tmp
   # cat /etc/passwd>长长长长长长长长长长长长长长长长长长
   2将该文件归档至abc文件包:
   # mtar cvf abc *
   3解开或查看abc档案包:
   # tar xvf abc 或atr tvf abc
   abc档案包将不能解开或查看。

二、 剖析
   UNIX的tar命令产生的归档文件称tar格式档案文件,具有以下格式:
   1每个文件被加上了一个512字节的文件属性头,然后以512字节为单位块在包中连续存放,占有整数个块。最后一个块不能写满,其后用0x00填写。
   2如文件长度为零字节或是链接文件,则只有512字节的文件属性头。
   3用1024字节的0x00作为档案文件尾。
   4文件属性头结构:
union hblock {
   char dummy [512];    512字节文件属性头
   struct header {
     char name[100];   100字节以内文件名
     char mode [8];    八进制文件权限
     char uid[8];     八进制文件主人号
     char gid[8];     八进制文件组号
     char size[12];    八进制文件长度
     char mtime[12];   八进制文件修改时间
     char chksum[8];   八进制属性头校验和
     char 1inkf1ag;    文件连接状态
     char 1inkname[100]; 连接文件名
     char extno[4];    连续卷分卷号
     char extota1[4];   分卷个数
     char efsize[12];   八进制续分卷文件长度
     char compid;    文件压缩状态
    }dbuf;
   }dblock;
   文件属性头结构中字节校验和chksum是(头结构除chksum部分的字节和)加(八进制数400)加(文件压缩状态值)后转换为八进制得到的。文件压缩状态为‘1'时表示文件内容处于压缩状态,在解包时,tar命令将自动调用compress把文件内容解压缩,而不改变文件名。
   笔者在分析一个含有长汉字文件名的tar档案文件时发现:长汉字文件名的属性头中chksum值是错误的。经分析发现造成这种错误的原因是:一个汉字的字节和是负整数,长汉字文件名的属性头的字节和有可能为负整数,tar命令源程序由于为西文而设计未能判断属性头字节和为负的情况。在创立档案文件时,tar命令用sprintf()函数转换属性头字节和为八进制输出到chksum,这时破坏了chksum正常格式。在打开档案文件时,tar命令用sscanf()函数从属性头按八进制格式化读取chksum时,不能得到正确数据,tar命令将中止展开档案文件。

三、 解决方法
   从上面分析我们得出以下结论:(1)要解决问题必须修改tar源程序,充分考虑汉化UNIX产生的tar档案包文件属性头中字节校验和为负的情况。(2)编写修补程序,将出错的tar档案文件属性头中字节校验和chksum修复。
   第一种方法需得到UNIX公司源程序级的技术支持或由UNIX公司技术人员解决,这也是笔者对UNIX公司的建议,我们只能期待。
   第二种方法笔者进行了有效的尝试,并用c编写了一个修补程序mtar.c,经编译成mtar运行程序,本程序具有以下功能:
   Amtar -v tarfi1e 修补任何原因造成的tar档案包中文件的chksum错误(包括本程序的-c功能)。
   Bmtar -t tarfi1e 查考tar档案包中文件信息。
   C mtar -c tarfi1e 加密tar档案包,使tar命令不能打开该包。
   D mtar -p tarfi1e 将包中的所有文件置压缩状态标志。
   E mtar -u tarfi1e 将包中所有文件置非压缩状态标志。

四、 实际应用
   本程序使用5个选项 -t -c -v -p -u,每次只能用一个参数,每个参数对应一个功能。
   例如:mtar -v abc 既可修复上面提到的abc包打不开问题。
   mtar -v /dev/fd0135ds18可修复tar格式3″软盘。
   mtar -c /dev/fd0135ds18可加密tar格式3″软盘。
   mtar -v /dev/fd0135ds18可解密tar格式3″软盘。
   mtar -t abc可详细列出abc包中文件信息,sum_v=0表示文件属性头校验正常,compress=[1]表示文件抽取时自动解压缩。
   本程序从编写至今笔者进行了十四次改版,使该程序适合含任何文件类型的tar档案包。并在SCO UNIX 3242和SCO OPENSERVER 50下多次进行编译和全面功能测试。现将该程序整理出来,敬请同行多加指教。源程序附后。
   Mtar.c内容如下:
   #include″stdio.h″
   #include″string.h″
   #include″unistd.h″
   #include″sys/types.h″
   #include″sys/stat.h″
   #include″fcntl.h″

   #define TBLOCK 512
   #define NBLOCK 20
   #define NAMSIZ 100
    union hblock {
       char dummy[TBLOCK];
       struct header {
        char name[NAMSIZ];
        char mode[8];
        char uid[8];
        char gid[8];
        char size[12];
        char mtime[12];
        char chksum[8];
        char linkflag;
        char linkname[NAMSIZ];
        char extno[4];
        char extotal[4];
        char efsize[12];
        char compid;
      } dbuf,
    } dblock;
   main(argc,argv)
   int argc;
   char *argv[];
   {
     char compress;
     int i,seekip=0,ip,compc;
     long sum,sum_v,filesize=0,mvblock=0,total;
     FILE*fp;
   ip=0;
   if(strncmp(argv[1],″-c″,2)==0) ip=1;
   if(strncmp(argv[1],″-v″,2)==0) ip=1;
   if(strncmp(argv[1],″-t″,2)==0) ip=1;
   if(strncmp(argv[1],″-p″,2)==0) ip=1;
   if(strncmp(argv[1],″-u″,2)==0) ip=1;

   if(argc !=3||ip !=1)
     {
     printf(″Usage:mtar-[c,v,t,p,u]tarfile\n″);
     exit(1);
     }
   if((fp=fopen(argv[2],″r+″))==NULL)
     {
     printf(″Can not open the %s\n″,argv[2]);
     exit(1);
     }
   while(seekip==0)
   {
     if(fread((dblock.dummy),TBLOCK,1,fp)!=1)
      {
      printf(″Can not read the%s !\n″,argv[2]);
      break;
      }
   sum=0;
   compc=0;
   for(i=0;i< TBLOCK;i++) sum=sum+dblock.dumm
y[i];
   for(i=0;i< 8,i++)sum=sum-dblock.dbuf.chksum[i];
   if(sum==0)break;

   ip=0;
   if(strncmp(argv[1],″-c″,2)==0)
      compress=dblock.dbuf.compid;
      sum_v=270*0xff+0400; ip=1;
      }
   if(strncmp(argv[1],″-v″,2)==0)
      compress=dblock.dbuf.compid;
      sum_v=sum+0400; ip=1
      }
   if(strncmp(argv[1],″-p″,2)==0)
      compc=dblock.dbuf.compid;
      compc=0x31-compc;
      sum_v=sum+0400+compc;
      compress=0x31; ip=1;
      }
   if(strncmp(argv[1],″-u″,2)==0)
      compc=dblock.dbuf.compid;
      compc=0x00-compc;
      sum_v=sum+0400+compc;
      compress=0x00; ip=1;
   }
if(ip==1)
   {
   if(sum-v >=0)sprintf (dblock.dbuf.
chksum,″%60″,sum_v);
   else
   {
   dblock.dbuf.chksum[0]=′-′;
   dblock.dbuf.chksum[6]=0x00;
   dblock.dbuf.chksum[7]=0x00;
   sum_v=sum_v-dblock.dbuf.linkflag;
   sum=sum-dblock.dbuf.linkflag;
   dblock.dbuf.linkflag=0x00;
   for(i=0;i<NAMSIZ;i++){
      sum_v=sum_v-dblock.dbuf.linkname[i];
      sum=sum-dblock.dbuf.linkname[i];
      dblock.dbuf.linkname[i]=0x00;
      }
   sprintf(dblock.dbuf.chksum+1,″%-50″,-sum_v);
   }
   sprintf(&dblock.dbuf.compid,″%c″,compress);
   seekip=fseek(fp,-TBLOCK,SEEK_CUR);
   if(seekip==0)
     {
     if(fwrite((dblock.dummy),TBLOCK,1,fp)!=1)
       {
     printf(″Can not read the %s!\n″,argv[2]);
       break;
       }
     fflush(fp);
     }
   }
   sscanf(dblock.dbuf.size,″%12o″,&filesize);
   sscanf(dblock,dbuf.chksum,″%6o″,&sum_v);
   sum_v=sum_v-sum-0400-compc;
   if(filesize>0&&(dblock.dbuf.linkflag==0x00|| dbloc
k.dbuf.chksum[0]==0x33))
     {
     mvblock=(filesize-1)/TBLOCK+1;
    seekip=fseek(fp,(long)mvblock*TBLOCK,SEEK
_CUR);
     }
     seekip=fseek(fp,0L,SEEK_CUR);
   if(dblock.dbuf.linkflag==″1″)
    printf(″%s\n\t\tnormal linked to %s\t\tcompress=[%c]\tsum_v=%o\n″,
   dblock.dbuf.name,dblock.dbuf.linkname,dblock.dbuf.
compid,sum-v);
   else if (dblock.dbuf.linkflag==″2″)
   printf(″%s\n\t\tsymbolic linked to %s\tcompress=[%c]\tsum_v=%o\n,
   ″dblock.dbuf.name,dblock.dbuf.linkname,dblock.dbuf.
compid,sum_v);
   else
   printf(″%s\n\t %8d byte-->%6d tape_blocks\tcompress=[%c]\tsum_v=%o\n″,dblock.dbuf.name,filesize,mvblock,dblock.dbuf.cmpid,sum_v);

   }
   printf(″Total=%dK\n″,ftell(fp)/1024);
   fclose(fp);
   }
关键字:系统、tar命令、分时、多任务、多用户、网络互连、图形接口

分享到:

顶部 】 【 关闭
版权所有:佛山思海电脑网络有限公司 ©1998-2024 All Rights Reserved.
联系电话:(0757)22630313、22633833
中华人民共和国增值电信业务经营许可证: 粤B1.B2-20030321 备案号:粤B2-20030321-1
网站公安备案编号:44060602000007 交互式栏目专项备案编号:200303DD003  
察察 工商 网安 举报有奖  警警  手机打开网站