forked from xuos/xiuos
				
			
		
			
				
	
	
		
			163 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright (c) 2020 AIIT XUOS Lab
 | 
						|
 * XiUOS is licensed under Mulan PSL v2.
 | 
						|
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 | 
						|
 * You may obtain a copy of Mulan PSL v2 at:
 | 
						|
 *        http://license.coscl.org.cn/MulanPSL2
 | 
						|
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
						|
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
						|
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
						|
 * See the Mulan PSL v2 for more details.
 | 
						|
*/
 | 
						|
 | 
						|
#include <xiuos.h>
 | 
						|
 | 
						|
#if defined(FS_VFS) && defined(TOOL_SHELL)
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdint.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include <iot-vfs_posix.h>
 | 
						|
#include <bzip2.h>
 | 
						|
#include "bzlib/bzlib.h"
 | 
						|
#include "utility.h"
 | 
						|
 | 
						|
#define IOBUF_SIZE          8192
 | 
						|
 | 
						|
char *in_buf, *out_buf;
 | 
						|
 | 
						|
 | 
						|
static int BzWrite(BzStream *stream, int ReadSize, int out_fd)
 | 
						|
 | 
						|
{
 | 
						|
    stream->avail_in = ReadSize;
 | 
						|
    stream->next_in = in_buf;
 | 
						|
 | 
						|
    while (1) {
 | 
						|
        stream->avail_out = IOBUF_SIZE;
 | 
						|
        stream->next_out = out_buf;
 | 
						|
 | 
						|
        int ret = BZ2BzCompress(stream,
 | 
						|
                ReadSize > 0 ? BZ_RUN : BZ_FINISH);
 | 
						|
 | 
						|
        if (ret != BZ_RUN_OK && ret != BZ_FINISH_OK &&
 | 
						|
                ret != BZ_STREAM_END)
 | 
						|
            return -1;
 | 
						|
 | 
						|
        int out_buf_cnt = IOBUF_SIZE - stream->avail_out;
 | 
						|
        if (out_buf_cnt) {
 | 
						|
            int written_size = write(out_fd, out_buf, out_buf_cnt);
 | 
						|
            if (written_size != out_buf_cnt)
 | 
						|
                return -1;
 | 
						|
        }
 | 
						|
 | 
						|
        if (ret == BZ_STREAM_END || (ReadSize > 0 && stream->avail_in == 0))
 | 
						|
            break;
 | 
						|
    }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
int Bzip2Compress(char *file_name)
 | 
						|
{
 | 
						|
    int ret = 0;
 | 
						|
    char *bz_file_name;
 | 
						|
    struct stat statbuf;
 | 
						|
    int in_fd, out_fd;
 | 
						|
    BzStream stream;
 | 
						|
 | 
						|
    if ((in_fd = open(file_name, O_RDONLY)) < 0)
 | 
						|
        return -1;
 | 
						|
    if (fstat(in_fd, &statbuf) < 0 || !S_ISREG(statbuf.st_mode)) {
 | 
						|
        ret = -1;
 | 
						|
        goto close_in_fd;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((bz_file_name = malloc(strlen(file_name) + 5)) == NULL) {
 | 
						|
        ret = -1;
 | 
						|
        goto close_in_fd;
 | 
						|
    }
 | 
						|
    strcpy(bz_file_name, file_name);
 | 
						|
    strcat(bz_file_name, ".bz2");
 | 
						|
 | 
						|
    if ((out_fd = open(bz_file_name, O_WRONLY | O_CREAT | O_TRUNC)) < 0) {
 | 
						|
        ret = -1;
 | 
						|
        goto free_bz_file_name;
 | 
						|
    }
 | 
						|
 | 
						|
    if ((in_buf = malloc(2 * IOBUF_SIZE)) == NULL) {
 | 
						|
        ret = -1;
 | 
						|
        goto close_out_fd;
 | 
						|
    }
 | 
						|
    out_buf = in_buf + IOBUF_SIZE;
 | 
						|
 | 
						|
    memset(&stream, 0, sizeof(BzStream));
 | 
						|
    BZ2BzCompressInit(&stream, 1);
 | 
						|
 | 
						|
    while (1) {
 | 
						|
        int ReadSize = read(in_fd, in_buf, IOBUF_SIZE);
 | 
						|
        if (ReadSize < 0) {
 | 
						|
            ret = -1;
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
        ret = BzWrite(&stream, ReadSize, out_fd);
 | 
						|
        if (ReadSize == 0 || ret < 0)
 | 
						|
 | 
						|
            break;
 | 
						|
    }
 | 
						|
 | 
						|
    BZ2BzCompressEnd(&stream);
 | 
						|
 | 
						|
    free(in_buf);
 | 
						|
close_out_fd:
 | 
						|
    close(out_fd);
 | 
						|
free_bz_file_name:
 | 
						|
    free(bz_file_name);
 | 
						|
close_in_fd:
 | 
						|
    close(in_fd);
 | 
						|
 | 
						|
    return ret;
 | 
						|
}
 | 
						|
 | 
						|
static void Bzip2PrintUsage()
 | 
						|
{
 | 
						|
    KPrintf("Usage: bzip2 [OPTIONS]... [FILES]...\n");
 | 
						|
    KPrintf("Supported option flags:\n");
 | 
						|
    KPrintf("    d   decompress bzip2 file(s)\n");
 | 
						|
}
 | 
						|
 | 
						|
extern int Bzip2Decompress(char *file_name);
 | 
						|
 | 
						|
int bzip2(int argc, char **argv)
 | 
						|
{
 | 
						|
    int (*bzip2_func)(char *file_name) = Bzip2Compress;
 | 
						|
    if (argc == 1) {
 | 
						|
        Bzip2PrintUsage();
 | 
						|
        return 0;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (argv[1][0] == '-') {
 | 
						|
        if (strcmp(argv[1], "-b") != 0) {
 | 
						|
            KPrintf("Bad options\n");
 | 
						|
            Bzip2PrintUsage();
 | 
						|
            return 0;
 | 
						|
        }
 | 
						|
        bzip2_func = Bzip2Decompress;
 | 
						|
        argv++;
 | 
						|
        argc--;
 | 
						|
    }
 | 
						|
 | 
						|
    for (int i = 1; i < argc; i++)
 | 
						|
        if (bzip2_func(argv[i]) < 0) {
 | 
						|
            KPrintf("Operation failed\n");
 | 
						|
            break;
 | 
						|
        }
 | 
						|
 | 
						|
    return 0;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#endif
 |