Default driver
This commit is contained in:
parent
dd825149d9
commit
8cae731729
12
inc/board.h
Normal file
12
inc/board.h
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
#ifndef __BOARD_H__
|
||||||
|
#define __BOARD_H__
|
||||||
|
|
||||||
|
#include "driver.h"
|
||||||
|
#include "test_drv.h"
|
||||||
|
|
||||||
|
static const struct driver tst_drv = {
|
||||||
|
.fp = &tst_fp,
|
||||||
|
.dev = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
28
inc/driver.h
Normal file
28
inc/driver.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef __DRIVER_H__
|
||||||
|
#define __DRIVER_H__
|
||||||
|
|
||||||
|
struct driver;
|
||||||
|
|
||||||
|
typedef int (*fp_open_t)(const struct driver *);
|
||||||
|
typedef int (*fp_close_t)(const struct driver *);
|
||||||
|
typedef int (*fp_read_t)(const struct driver *, char *, unsigned int);
|
||||||
|
typedef int (*fp_write_t)(const struct driver *, const char *, unsigned int);
|
||||||
|
|
||||||
|
struct driver_fp {
|
||||||
|
fp_open_t open;
|
||||||
|
fp_close_t close;
|
||||||
|
fp_read_t read;
|
||||||
|
fp_write_t write;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct driver {
|
||||||
|
const struct driver_fp *fp;
|
||||||
|
const void *dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
int drv_open(const struct driver *drv);
|
||||||
|
int drv_close(const struct driver *drv);
|
||||||
|
int drv_read(const struct driver *drv, char *buffer, unsigned int length);
|
||||||
|
int drv_write(const struct driver *drv, const char *buffer, unsigned int length);
|
||||||
|
|
||||||
|
#endif
|
20
inc/test_drv.h
Normal file
20
inc/test_drv.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef __TEST_DRV_H__
|
||||||
|
#define __TEST_DRV_H__
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "driver.h"
|
||||||
|
|
||||||
|
int tst_open(const struct driver *drv);
|
||||||
|
int tst_close(const struct driver *drv);
|
||||||
|
int tst_read(const struct driver *drv, char *buffer, unsigned int length);
|
||||||
|
int tst_write(const struct driver *drv, const char *buffer, unsigned int length);
|
||||||
|
|
||||||
|
static const struct driver_fp tst_fp = {
|
||||||
|
.open = tst_open,
|
||||||
|
.close = tst_close,
|
||||||
|
.read = tst_read,
|
||||||
|
.write = tst_write
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
32
src/driver.c
Normal file
32
src/driver.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "driver.h"
|
||||||
|
|
||||||
|
int drv_open(const struct driver *drv)
|
||||||
|
{
|
||||||
|
assert(drv != NULL);
|
||||||
|
|
||||||
|
return drv->fp->open(drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drv_close(const struct driver *drv)
|
||||||
|
{
|
||||||
|
assert(drv != NULL);
|
||||||
|
|
||||||
|
return drv->fp->close(drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drv_read(const struct driver *drv, char *buffer, unsigned int length)
|
||||||
|
{
|
||||||
|
assert(drv != NULL);
|
||||||
|
|
||||||
|
return drv->fp->read(drv, buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drv_write(const struct driver *drv, const char *buffer, unsigned int length)
|
||||||
|
{
|
||||||
|
assert(drv != NULL);
|
||||||
|
|
||||||
|
return drv->fp->write(drv, buffer, length);
|
||||||
|
}
|
124
src/main.c
124
src/main.c
@ -8,129 +8,15 @@
|
|||||||
#include <tar.h>
|
#include <tar.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#define ASCII_TO_NUMBER(num) ((num) - 48) //Converts an ascii digit to the corresponding number
|
|
||||||
|
|
||||||
#define TAR_FILE "test.tar"
|
|
||||||
#define BLOCK_SIZE 512
|
|
||||||
#define TAR_FILE_HEADER 512
|
|
||||||
struct tar_file_header {
|
|
||||||
char filename[100];
|
|
||||||
char mode[8];
|
|
||||||
char uid[8];
|
|
||||||
char gid[8];
|
|
||||||
char file_size[12];
|
|
||||||
char last_modification[12];
|
|
||||||
char checksum[8];
|
|
||||||
char type_flag;
|
|
||||||
char linked_file_name[100];
|
|
||||||
char ustar_indicator[6];
|
|
||||||
char ustar_version[2];
|
|
||||||
char owner_user_name[32];
|
|
||||||
char owner_group_name[32];
|
|
||||||
char device_major_number[8];
|
|
||||||
char device_minor_number[8];
|
|
||||||
char filename_prefix[155];
|
|
||||||
char padding[12];
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decode a TAR octal number.
|
|
||||||
* Ignores everything after the first NUL or space character.
|
|
||||||
* @param data A pointer to a size-byte-long octal-encoded
|
|
||||||
* @param size The size of the field pointer to by the data pointer
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
static uint64_t decode_tar_octal(char* data, size_t size)
|
|
||||||
{
|
|
||||||
unsigned char *current_ptr = (unsigned char *) data + size;
|
|
||||||
uint64_t sum = 0;
|
|
||||||
uint64_t current_multiplier = 1;
|
|
||||||
|
|
||||||
// Skip everything after the last NUL/space character
|
|
||||||
// In some TAR archives the size field has non-trailing NULs/spaces, so
|
|
||||||
// thisis neccessary.
|
|
||||||
unsigned char* check_ptr = current_ptr; //This is used to check where the last NUL/space char is
|
|
||||||
for(; check_ptr >= (unsigned char *) data; --check_ptr) {
|
|
||||||
if((*check_ptr) == 0 || (*check_ptr) == ' ') {
|
|
||||||
current_ptr = check_ptr - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(; current_ptr >= (unsigned char *) data; --current_ptr) {
|
|
||||||
sum += ASCII_TO_NUMBER(*current_ptr) * current_multiplier;
|
|
||||||
current_multiplier *= 8;
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool check_checksum(struct tar_file_header *tar_header)
|
|
||||||
{
|
|
||||||
assert(tar_header != NULL);
|
|
||||||
|
|
||||||
char original_checksum[8];
|
|
||||||
memcpy(original_checksum, tar_header->checksum, 8);
|
|
||||||
memset(tar_header->checksum, ' ', 8);
|
|
||||||
|
|
||||||
int64_t unsigned_sum = 0;
|
|
||||||
int64_t signed_sum = 0;
|
|
||||||
unsigned char *uc_tar = (unsigned char *)tar_header;
|
|
||||||
signed char *sc_tar = (signed char *)tar_header;
|
|
||||||
for(int i = 0; i < TAR_FILE_HEADER; i++) {
|
|
||||||
unsigned_sum += uc_tar[i];
|
|
||||||
signed_sum += sc_tar[i];
|
|
||||||
}
|
|
||||||
//Copy back the checksum
|
|
||||||
memcpy(tar_header->checksum, original_checksum, 8);
|
|
||||||
//Decode the original checksum
|
|
||||||
uint64_t reference_checksum = decode_tar_octal(original_checksum, sizeof(original_checksum));
|
|
||||||
return (reference_checksum == unsigned_sum || reference_checksum == signed_sum);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
int fd;
|
printf("Hello\r\r");
|
||||||
|
unsigned long stamp = 55;
|
||||||
|
|
||||||
fd = open(TAR_FILE, O_RDONLY);
|
char buffer[80];
|
||||||
if(fd < 0) {
|
|
||||||
fprintf(stderr, "Unable to open %s\r\n", TAR_FILE);
|
|
||||||
return fd;
|
|
||||||
}
|
|
||||||
|
|
||||||
int res;
|
snprintf(buffer, sizeof(buffer), "%lu",stamp);
|
||||||
char block[BLOCK_SIZE];
|
|
||||||
uint64_t read_count = 0, next_tar_header = 0, file_size, tmp, loop_count = 1;
|
|
||||||
do {
|
|
||||||
res = read(fd, block, sizeof(block));
|
|
||||||
if(next_tar_header == read_count) {
|
|
||||||
struct tar_file_header tar_header;
|
|
||||||
if(res != sizeof(tar_header)) {
|
|
||||||
fprintf(stderr, "tar header size wrong\r\n");
|
|
||||||
close(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(&tar_header, block, sizeof(tar_header));
|
|
||||||
if(!check_checksum(&tar_header)) {
|
|
||||||
fprintf(stderr, "checksum missmatch\r\n");
|
|
||||||
close(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
file_size = decode_tar_octal(tar_header.file_size, sizeof(tar_header.file_size));
|
|
||||||
printf("%s - size: %lu\r\n", tar_header.filename, file_size);
|
|
||||||
next_tar_header = (file_size / BLOCK_SIZE + 1) * BLOCK_SIZE + loop_count * BLOCK_SIZE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for(int i = 0; i < BLOCK_SIZE; i++) {
|
|
||||||
if(block[i] == '\0') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
printf("%c", block[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
read_count += res;
|
|
||||||
loop_count++;
|
|
||||||
tmp = next_tar_header + ((file_size / BLOCK_SIZE + 1) * BLOCK_SIZE);
|
|
||||||
} while(tmp >= read_count);
|
|
||||||
|
|
||||||
close(fd);
|
printf(buffer);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
27
src/test_drv.c
Normal file
27
src/test_drv.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "test_drv.h"
|
||||||
|
|
||||||
|
int tst_open(const struct driver *drv)
|
||||||
|
{
|
||||||
|
printf("%s called\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tst_close(const struct driver *drv)
|
||||||
|
{
|
||||||
|
printf("%s called\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tst_read(const struct driver *drv, char *buffer, unsigned int length)
|
||||||
|
{
|
||||||
|
printf("%s called\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tst_write(const struct driver *drv, const char *buffer, unsigned int length)
|
||||||
|
{
|
||||||
|
printf("%s called\n", __func__);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user