首页 > 代码库 > zboot/xtract.c

zboot/xtract.c

/*
 *  linux/zBoot/xtract.c
 *
 *  Copyright (C) 1993  Hannu Savolainen
 *
 *    Extracts the system image and writes it to the stdout.
 *    based on tools/build.c by Linus Torvalds
 */

#include <stdio.h>    /* fprintf */
#include <string.h>
#include <stdlib.h>    /* contains exit */
#include <sys/types.h>    /* unistd.h needs this */
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <unistd.h>    /* contains read/write */
#include <fcntl.h>
#include <a.out.h>
#include <linux/config.h>

#define GCC_HEADER 1024

#define STRINGIFY(x) #x

//中断退出
void die(char * str)
{
    fprintf(stderr,"%s\n",str);
    exit(1);
}

//使用方法
void usage(void)
{
    die("Usage: xtract system [ | gzip | piggyback > piggy.s]");
}

//主函数
int main(int argc, char ** argv)
{
    int i,c,id, sz;
    char buf[1024];
    char major_root, minor_root;
    struct stat sb;

    //可执行文件指向缓冲区
    struct exec *ex = (struct exec *)buf;

    //参数一定是两个,否则提示使用方法
    if (argc  != 2)
        usage();
    //打开第二个参数指定的文件
    if ((id=open(argv[1],O_RDONLY,0))<0)
        die("Unable to open ‘system‘");
    //读取GCC文件头
    if (read(id,buf,GCC_HEADER) != GCC_HEADER)
        die("Unable to read header of ‘system‘");
    //校验
    if (N_MAGIC(*ex) != ZMAGIC)
        die("Non-GCC header of ‘system‘");

    //计算系统长度
    sz = N_SYMOFF(*ex) - GCC_HEADER + 4;    /* +4 to get the same result than tools/build */

    //输出系统长度
    fprintf(stderr, "System size is %d\n", sz);

    //遍历System文件
    while (sz)
    {
        int l, n;

        l = sz;
        //如果剩余长度大于buff长度,那么取buff长度
        if (l > sizeof(buf)) l = sizeof(buf);
        //读取一定长度
        if ((n=read(id, buf, l)) !=l)
        {
            if (n == -1)
               perror(argv[1]);
            else
               fprintf(stderr, "Unexpected EOF\n");

            die("Can‘t read system");
        }
        //将内容写入到标准输出中
        write(1, buf, l);
        sz -= l;
    }

    close(id);
    return(0);
}