Skip to content

Instantly share code, notes, and snippets.

@ahmpro
Created March 19, 2014 17:43
Show Gist options
  • Save ahmpro/9647221 to your computer and use it in GitHub Desktop.
Save ahmpro/9647221 to your computer and use it in GitHub Desktop.
Simple file archiver. Make for lab in MAI(Russia).
/*
* File: zupper.c
* Copyright 2014 L1S & ahmpro
*/
#include <stdio.h>
#include <dirent.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#define BUF_SIZE 8192
struct zup_attr {
char name_file[128];
unsigned long protection;
long long size_file;
};
int error_out(int in_fd, int out_fd, struct zup_attr *my_attr, DIR *pDir)
{
if (in_fd != 0)
close(in_fd);
if (!out_fd != 0)
close(out_fd);
if (my_attr != NULL)
free(my_attr);
closedir(pDir);
return 0;
}
int zupping(char **argv)
{
int in_fd = 0, out_fd = 0;
char buf[BUF_SIZE];
int FN = -1;/*files number*/
int stat_d;
int ret_out, ret_in;
DIR *pDir = NULL;
struct dirent *pDirent;
struct zup_attr *my_attr, *temp_attr;
struct stat attrib;
long META_SIZE;
printf("Zupping\npath = [%s]\nfile = [%s]\n", argv[1], argv[2]);
pDir = opendir(argv[1]);
if (pDir == NULL) {
printf("Cannot open directory '%s'`\n", argv[1]);
return 0;
}
out_fd = open(argv[2], O_WRONLY | O_CREAT, 0644);
if (out_fd == -1) {
printf("Error in openning the output file\n");
return error_out(in_fd, out_fd, NULL, pDir);
}
my_attr = (struct zup_attr *) malloc(1);
while ((pDirent = readdir(pDir)) != NULL) {
if (strcmp(pDirent->d_name, ".") != 0
&& strcmp(pDirent->d_name, "..") != 0) {
chdir(argv[1]);
in_fd = open((pDirent->d_name), O_RDONLY);
if (in_fd == -1) {
printf("Error in openning the input file\n");
return error_out(in_fd, out_fd, my_attr, pDir);
} else {
stat_d = fstat(in_fd, &attrib);
if (stat_d == 0) {
FN++;
my_attr[FN].size_file = attrib.st_size;
my_attr[FN].protection = attrib.st_mode;
strcpy(my_attr[FN].name_file, pDirent->d_name);
temp_attr = (struct zup_attr *) realloc(my_attr, FN+1);
if (temp_attr == NULL)
return error_out(in_fd, out_fd, my_attr, pDir);
my_attr = temp_attr;
while ((ret_in = read(in_fd, &buf, BUF_SIZE)) > 0) {
ret_out = write(out_fd, &buf, ret_in);
if (ret_out != ret_in) {
printf("Error in writing file [%s]\n",
pDirent->d_name);
return error_out(in_fd, out_fd, my_attr, pDir);
}
}
printf("zupped file [%s]\n", my_attr[FN].name_file);
} else {
printf("stat not readed\n");
return error_out(in_fd, out_fd, my_attr, pDir);
}
close(in_fd);
}
}
}
META_SIZE = sizeof(struct zup_attr)*(FN+1);
ret_out = write(out_fd, my_attr, META_SIZE);
if (ret_out != META_SIZE) {
printf("Error in writing meta\n");
return error_out(in_fd, out_fd, my_attr, pDir);
}
ret_out = write(out_fd, &FN, sizeof(int));
if (ret_out != sizeof(int)) {
printf("Error in writing amount files\n");
return error_out(in_fd, out_fd, my_attr, pDir);
}
error_out(in_fd, out_fd, my_attr, pDir);
printf("Zupping complete\n");
return 0;
}
int unzupping(char **argv)
{
int Temp, i;
int in_fd = 0, out_fd = 0;
char buf[BUF_SIZE];
int FN;
int ret_out, ret_in;
struct zup_attr *my_attr;
long META_SIZE;
printf("Unzupping\nfile = [%s]\npath = [%s]\n", argv[1], argv[2]);
in_fd = open(argv[1], O_RDONLY);
if (in_fd == -1) {
printf("Error in openning the input file[%s]\n", argv[1]);
return error_out(in_fd, out_fd, NULL, NULL);
}
if (lseek(in_fd, (-sizeof(int)), SEEK_END) == -1) {
printf("Seek Failed to read FN\n");
return error_out(in_fd, out_fd, NULL, NULL);
}
ret_in = read(in_fd, &FN, sizeof(int));
if (ret_in != sizeof(int)) {
printf("Error in reading FN\n");
return error_out(in_fd, out_fd, NULL, NULL);
}
my_attr = (struct zup_attr *) malloc(FN+1);
META_SIZE = sizeof(struct zup_attr)*(FN+1);
if (lseek(in_fd, -(META_SIZE+sizeof(int)), SEEK_END) == -1) {
printf("Seek Failed to META\n");
return error_out(in_fd, out_fd, my_attr, NULL);
}
ret_in = read(in_fd, my_attr, META_SIZE);
if (ret_in != META_SIZE) {
printf("Meta not readed\n");
return error_out(in_fd, out_fd, my_attr, NULL);
}
if (lseek(in_fd, 0L, SEEK_SET) == -1) {
printf("Seek Failed to BEGIN\n");
return error_out(in_fd, out_fd, my_attr, NULL);
}
Temp = mkdir(argv[2], 0777);
if (Temp == -1) {
printf("Cannot create directory '%s'`\n", argv[2]);
return error_out(in_fd, out_fd, my_attr, NULL);
}
if (chdir(argv[2]) != 0) {
printf("Error change directory\n");
error_out(in_fd, out_fd, my_attr, NULL);
}
for (i = 0; i <= FN; i++) {
out_fd = open(my_attr[i].name_file,
O_WRONLY | O_CREAT,
my_attr[i].protection);
if (out_fd == -1) {
printf("Error in openning the output file\n");
return error_out(in_fd, out_fd, my_attr, NULL);
}
Temp = my_attr[i].size_file;
while (Temp > 0) {
ret_in = read(in_fd, &buf, Temp > BUF_SIZE?BUF_SIZE:Temp);
ret_out = write(out_fd, &buf, ret_in);
if (ret_out != ret_in) {
printf("Error in writing file [%s]\n",
my_attr[i].name_file);
}
Temp = Temp-BUF_SIZE;
}
printf("unzupped file [%s]\n", my_attr[i].name_file);
close(out_fd);
}
close(in_fd);
free(my_attr);
printf("Unzupping complete\n");
return 0;
}
int main(int argc, char *argv[])
{
if (argc != 3) {
printf("Usage: %s <dirname>\n", argv[0]);
return 1;
}
if (strstr(argv[1], ".zup") == NULL)
zupping(argv);
else
unzupping(argv);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment