#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "nfs_iio.h"
#include "nfs_pmatch.h"
#include "nfs_dt.h"
#include "nfs_nt.h"
#include "nfs_fat.h"
#include "nfs_data.h"
#include "nfs.h"
int nfs_errno;
static int file_exists(char* filename) {
FILE* f = fopen(filename, "rb");
if (f == NULL)
return 0;
fclose(f);
return 1;
}
static void file_truncate(nfs_Handle* fs, nfs_FH* fh, int size) {
int node_no, node;
node_no = size / nfs_data_BLOCK_SIZE;
node = nfs_fat_chain_get_nth(fs->fat, fh->chain, node_no);
nfs_fat_chain_truncate(fs->fat, node);
nfs_nt_node_set_size(fs->nt, fh->nt_index, size);
}
static int allocate_file_descriptor(nfs_Handle* fs) {
int i = 0;
nfs_FH* fh = (nfs_FH*)malloc(sizeof(nfs_FH));
if (fh == NULL)
return -1;
fh->dt_index = 0;
fh->nt_index = 0;
fh->chain = 0;
fh->fp = 0;
if (fs->handles != NULL) {
while ( (i < fs->ht_size) && (fs->handles[i] != NULL) )
i++;
if (i >= fs->ht_size) {
fs->handles = (nfs_FH**)realloc(fs->handles, sizeof(nfs_FH*) * (fs->ht_size * 2));
if (fs->handles == NULL)
return -1;
for (i = fs->ht_size; i < (fs->ht_size * 2); fs->handles[i++] = NULL);
i = fs->ht_size;
fs->ht_size <<= 1;
fs->handles[i] = fh;
return i;
} else {
fs->handles[i] = fh;
return i;
}
}
fs->ht_size = nfs_INITIAL_HT_SIZE;
fs->handles = (nfs_FH**)malloc(sizeof(nfs_FH*) * fs->ht_size);
if (fs->handles == NULL)
return -1;
for (i = 0; i < fs->ht_size; fs->handles[i++] = NULL);
fs->handles[0] = fh;
return 0;
}
static int deallocate_file_descriptor(nfs_Handle* fs, int filedes) {
if (fs == NULL)
return nfs_ERR_INVALID_FS;
if (fs->handles[filedes] == NULL)
return nfs_ERR_ALREADY_CLSD;
free(fs->handles[filedes]);
fs->handles[filedes] = NULL;
return 0;
}
int nfs_exists(char* filename) {
char iio_name[nfs_NAME_LEN];
char data_name[nfs_NAME_LEN];
strcpy(iio_name, filename);
strcpy(&iio_name[strlen(filename)], nfs_IIO_SUFFIX);
strcpy(data_name, filename);
strcpy(&data_name[strlen(filename)], nfs_DATA_SUFFIX);
return (file_exists(iio_name) && file_exists(data_name));
}
static int lock_create(char* filename, int mode) {
int refcount;
FILE* f;
char lock_name[nfs_NAME_LEN];
strcpy(lock_name, filename);
strcpy(&lock_name[strlen(filename)], nfs_LOCK_SUFFIX);
f = fopen(lock_name, "wb");
if (f == NULL)
return -1;
fwrite(&mode, 1, sizeof(int), f);
refcount = 1;
fwrite(&refcount, 1, sizeof(int), f);
fclose(f);
return 0;
}
static int lock_enter(char* filename, int mode) {
int refcount, r;
FILE* f;
char lock_name[nfs_NAME_LEN];
strcpy(lock_name, filename);
strcpy(&lock_name[strlen(filename)], nfs_LOCK_SUFFIX);
f = fopen(lock_name, "r+b");
if (f == NULL)
return lock_create(filename, mode);
fseek(f, 0, 0);
fwrite(&mode, 1, sizeof(int), f);
fflush(f);
fseek(f, sizeof(int), 0);
r = fread(&refcount, 1, sizeof(int), f);
if (r != sizeof(int))
refcount = 0;
refcount++;
fflush(f);
fseek(f, sizeof(int), 0);
fwrite(&refcount, 1, sizeof(int), f);
fclose(f);
return 0;
}
static int lock_check(char* filename, int mode) {
FILE* f;
int mm, ret;
char lock_name[nfs_NAME_LEN];
strcpy(lock_name, filename);
strcpy(&lock_name[strlen(filename)], nfs_LOCK_SUFFIX);
f = fopen(lock_name, "rb");
if (f == NULL)
return 1;
fseek(f, 0, 0);
fread(&mm, 1, sizeof(int), f);
if (mm & FS_WRITE)
ret = 0;
else
if (mm & FS_READ)
ret = (mode == FS_READ);
else
ret = 0;
fclose(f);
return ret;
}
static int lock_remove(char* filename) {
char lock_name[nfs_NAME_LEN];
strcpy(lock_name, filename);
strcpy(&lock_name[strlen(filename)], nfs_LOCK_SUFFIX);
return remove(lock_name);
}
static int lock_leave(char* filename) {
FILE* f;
int mode, refcount = 0;
char lock_name[nfs_NAME_LEN];
strcpy(lock_name, filename);
strcpy(&lock_name[strlen(filename)], nfs_LOCK_SUFFIX);
f = fopen(lock_name, "r+b");
if (f == NULL)
return -1;
fseek(f, 0, 0);
fread(&mode, 1, sizeof(int), f);
fread(&refcount, 1, sizeof(int), f);
refcount--;
fflush(f);
fseek(f, sizeof(int), 0);
fwrite(&refcount, 1, sizeof(int), f);
fclose(f);
if (refcount <= 0)
return lock_remove(filename);
return 0;
}
nfs_Handle* nfs_start(char* filename, int flags) {
char iio_name[nfs_NAME_LEN];
char data_name[nfs_NAME_LEN];
nfs_Handle* fs = NULL;
strcpy(iio_name, filename);
strcpy(&iio_name[strlen(filename)], nfs_IIO_SUFFIX);
strcpy(data_name, filename);
strcpy(&data_name[strlen(filename)], nfs_DATA_SUFFIX);
fs = (nfs_Handle*)malloc(sizeof(nfs_Handle));
fs->ht_size = 0;
fs->handles = 0;
nfs_errno = 0;
fs->fls_open = 0;
nfs_iio_IOMODE = flags;
nfs_data_IOMODE = flags;
if (!lock_check(filename, flags)) {
nfs_errno = nfs_ERR_LOCKED;
return nfs_NULL;
}
if (file_exists(iio_name) && file_exists(data_name)) {
fs->file = nfs_iio_open(iio_name);
if (fs->file == NULL) {
nfs_errno = nfs_ERR_IIO_INIT;
return nfs_NULL;
}
fs->data = nfs_data_open(data_name);
if (fs->data == NULL) {
nfs_errno = nfs_ERR_NO_DATA;
return nfs_NULL;
}
fs->dt = nfs_dt_open(fs->file, nfs_CHANNEL_DT1, nfs_CHANNEL_DT2);
if (fs->dt == NULL) {
nfs_errno = nfs_ERR_NO_DT;
return nfs_NULL;
}
fs->nt = nfs_nt_open(fs->file, nfs_CHANNEL_NT);
if (fs->nt == NULL) {
nfs_errno = nfs_ERR_NO_NT;
return nfs_NULL;
}
fs->fat = nfs_fat_open(fs->file, nfs_CHANNEL_FAT);
if (fs->fat == NULL) {
nfs_errno = nfs_ERR_NO_FAT;
return nfs_NULL;
}
} else {
if (flags == FS_READ) {
nfs_errno = nfs_ERR_IIO_INIT;
return nfs_NULL;
}
fs->file = nfs_iio_create(iio_name);
if (fs->file == NULL) {
nfs_errno = nfs_ERR_IIO_INIT;
return nfs_NULL;
}
fs->data = nfs_data_create(data_name);
if (fs->data == NULL) {
nfs_errno = nfs_ERR_NO_DATA;
return nfs_NULL;
}
fs->dt = nfs_dt_create(fs->file, nfs_CHANNEL_DT1_SIZE, nfs_CHANNEL_DT2_SIZE);
if (fs->dt == NULL) {
nfs_errno = nfs_ERR_A_DT;
return nfs_NULL;
}
fs->nt = nfs_nt_create(fs->file, nfs_CHANNEL_NT_SIZE);
if (fs->nt == NULL) {
nfs_errno = nfs_ERR_A_NT;
return nfs_NULL;
}
fs->fat = nfs_fat_create(fs->file, nfs_CHANNEL_FAT_SIZE);
if (fs->fat == NULL) {
nfs_errno = nfs_ERR_A_FAT;
return nfs_NULL;
}
}
fs->filename = (char*)malloc(128);
strcpy(fs->filename, filename);
lock_enter(filename, flags);
return fs;
}
void nfs_end(nfs_Handle* fs, int remove_fs) {
int i;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return;
}
if (remove_fs) {
nfs_dt_destroy(fs->dt);
nfs_nt_destroy(fs->nt);
nfs_fat_close(fs->fat);
nfs_data_destroy(fs->data);
nfs_iio_destroy(fs->file);
} else {
nfs_dt_close(fs->dt);
nfs_nt_close(fs->nt);
nfs_fat_close(fs->fat);
nfs_data_close(fs->data);
nfs_iio_close(fs->file);
}
if (fs->handles != NULL) {
for (i = 0; i < fs->ht_size; i++)
deallocate_file_descriptor(fs, i);
free(fs->handles);
}
lock_leave(fs->filename);
if (fs->filename != NULL)
free(fs->filename);
free(fs);
}
int nfs_file_exists(nfs_Handle* fs, char* path) {
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return 0;
}
return (nfs_dt_filename_lookup(fs->dt, (char*)path) >= 0);
}
int nfs_file_open(nfs_Handle* fs, const char* path, int oflag) {
int filedes;
nfs_FH* fh;
int dt_idx;
nfs_nt_Node ni;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
dt_idx = nfs_dt_filename_lookup(fs->dt, (char*)path);
if (dt_idx < 0) {
nfs_errno = nfs_ERR_NOT_FOUND;
return -1;
}
filedes = allocate_file_descriptor(fs);
if (filedes < 0) {
nfs_errno = nfs_ERR_NOMEM_OPEN;
return -1;
}
fs->fls_open++;
fh = fs->handles[filedes];
fh->oflags = oflag;
fh->dt_index = dt_idx;
fh->nt_index = nfs_dt_filename_get_nt_index(fs->dt, dt_idx);
nfs_nt_get_node(fs->nt, fh->nt_index, &ni);
fh->chain = ni.chain;
fh->fp = 0;
if ( ((oflag & O_RDWR) || (oflag & O_WRONLY)) &&
(oflag & O_TRUNC) ) {
file_truncate(fs, fh, 0);
}
return filedes;
}
int nfs_file_create(nfs_Handle* fs, const char* path, int) {
int filedes, oflag;
nfs_FH* fh;
int dt_idx;
nfs_nt_Node ni;
int already = 1;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
dt_idx = nfs_dt_filename_lookup(fs->dt, (char*)path);
if (dt_idx < 0) {
already = 0;
dt_idx = nfs_dt_filename_add(fs->dt, (char*)path);
if (dt_idx < 0) {
nfs_errno = nfs_ERR_DT_INTERNAL;
return -1;
}
}
filedes = allocate_file_descriptor(fs);
if (filedes < 0) {
nfs_errno = nfs_ERR_NOMEM_OPEN;
return -1;
}
fs->fls_open++;
fh = fs->handles[filedes];
fh->oflags = O_CREAT | O_RDWR | O_TRUNC;
oflag = fh->oflags;
fh->dt_index = dt_idx;
if (already)
fh->nt_index = nfs_dt_filename_get_nt_index(fs->dt, dt_idx);
else {
fh->nt_index = nfs_nt_allocate_node(fs->nt);
nfs_dt_filename_set_nt_index(fs->dt, dt_idx, fh->nt_index);
}
nfs_nt_get_node(fs->nt, fh->nt_index, &ni);
if (!already) {
ni.chain = nfs_fat_create_chain(fs->fat);
nfs_nt_set_node(fs->nt, fh->nt_index, &ni);
}
fh->chain = ni.chain;
fh->fp = 0;
if ( ((oflag & O_RDWR) || (oflag & O_WRONLY)) &&
(oflag & O_TRUNC) &&
already ) {
file_truncate(fs, fh, 0);
}
return filedes;
}
int nfs_file_close(nfs_Handle* fs, int filedes) {
int ret;
if (fs == nfs_NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
ret = deallocate_file_descriptor(fs, filedes);
if (ret == 0)
fs->fls_open--;
if (ret == 0)
return 0;
return -1;
}
static int nblocks(int size) {
if (size == 0)
return 1;
return (((size - 1) / nfs_data_BLOCK_SIZE) + 1);
}
static int blockno(int fp) {
return (fp / nfs_data_BLOCK_SIZE);
}
int nfs_file_lseek(nfs_Handle* fs, int filedes, int offset, int whence) {
int fp, size;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
if (fs->handles == NULL) {
nfs_errno = nfs_ERR_NO_OPEN;
return -1;
}
if (fs->handles[filedes] == NULL) {
nfs_errno = nfs_ERR_INVALID_FH;
return -1;
}
size = nfs_nt_node_get_size(fs->nt, fs->handles[filedes]->nt_index);
if (whence == (int)SEEK_SET) {
fp = offset;
} else if (whence == (int)SEEK_CUR) {
fp = fs->handles[filedes]->fp + offset;
} else if (whence == (int)SEEK_END) {
fp = size + offset;
} else {
fp = offset;
}
fs->handles[filedes]->fp = fp;
if (blockno(fp) >= nblocks(size)) {
int node = fs->handles[filedes]->chain;
int sz = size;
while (blockno(fp) >= nblocks(sz)) {
node = nfs_fat_chain_extend(fs->fat, node);
sz += nfs_data_BLOCK_SIZE;
}
}
if (size < fp)
nfs_nt_node_set_size(fs->nt, fs->handles[filedes]->nt_index, (fp + 1));
return 0;
}
int nfs_file_read(nfs_Handle* fs, int filedes, void* buf, int nbyte) {
int fp, size;
int startb, endb;
int start_in_block, end_in_block;
int node, idx;
int sidx, eidx, kk, pp;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
if (fs->handles == NULL) {
nfs_errno = nfs_ERR_NO_OPEN;
return -1;
}
if (fs->handles[filedes] == NULL) {
nfs_errno = nfs_ERR_INVALID_FH;
return -1;
}
if (nbyte == 0)
return 0;
fp = fs->handles[filedes]->fp;
size = nfs_nt_node_get_size(fs->nt, fs->handles[filedes]->nt_index);
if (fp + nbyte > size)
nbyte = size - fp;
if (nbyte <= 0)
return 0;
startb = (fp / nfs_data_BLOCK_SIZE);
endb = ((fp + nbyte - 1) / nfs_data_BLOCK_SIZE);
start_in_block = (fp % nfs_data_BLOCK_SIZE);
end_in_block = ((fp + nbyte - 1) % nfs_data_BLOCK_SIZE);
node = nfs_fat_chain_get_nth(fs->fat, fs->handles[filedes]->chain, startb);
idx = startb;
kk = 0;
while (idx <= endb) {
if (idx == startb)
sidx = start_in_block;
else
sidx = 0;
if (idx == endb)
eidx = end_in_block;
else
eidx = (nfs_data_BLOCK_SIZE - 1);
if ((sidx == 0) && (eidx == (nfs_data_BLOCK_SIZE - 1)))
pp = nfs_data_read(fs->data, node, (char*)buf + kk);
else {
char tmpbuf[nfs_data_BLOCK_SIZE];
pp = nfs_data_read(fs->data, node, tmpbuf);
memcpy((char*)buf + kk, &tmpbuf[sidx], (eidx - sidx + 1));
}
node = nfs_fat_chain_get_nth(fs->fat, node, 1);
idx++;
if (pp == 0)
kk += (eidx - sidx + 1);
}
fs->handles[filedes]->fp = fp + nbyte;
return nbyte;
}
int nfs_file_write(nfs_Handle* fs, int filedes, const void* buf, int nbyte) {
int fp, size;
int startb, endb;
int start_in_block, end_in_block;
int node, idx;
int sidx, eidx, kk;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
if (fs->handles == NULL) {
nfs_errno = nfs_ERR_NO_OPEN;
return -1;
}
if (fs->handles[filedes] == NULL) {
nfs_errno = nfs_ERR_INVALID_FH;
return -1;
}
if (nbyte <= 0)
return 0;
fp = fs->handles[filedes]->fp;
size = nfs_nt_node_get_size(fs->nt, fs->handles[filedes]->nt_index);
if ( (fs->handles[filedes]->oflags & O_APPEND) &&
(fp < size) ) {
nfs_file_lseek(fs, filedes, size, (int)SEEK_SET);
size = nfs_nt_node_get_size(fs->nt, fs->handles[filedes]->nt_index);
fp = fs->handles[filedes]->fp;
}
startb = (fp / nfs_data_BLOCK_SIZE);
endb = ((fp + nbyte - 1) / nfs_data_BLOCK_SIZE);
start_in_block = (fp % nfs_data_BLOCK_SIZE);
end_in_block = ((fp + nbyte - 1) % nfs_data_BLOCK_SIZE);
nfs_file_lseek(fs, filedes, fp + nbyte - 1, (int)SEEK_SET);
nfs_file_lseek(fs, filedes, fp, (int)SEEK_SET);
node = nfs_fat_chain_get_nth(fs->fat, fs->handles[filedes]->chain, startb);
idx = startb;
kk = 0;
while (idx <= endb) {
if (idx == startb)
sidx = start_in_block;
else
sidx = 0;
if (idx == endb)
eidx = end_in_block;
else
eidx = (nfs_data_BLOCK_SIZE - 1);
if ((sidx == 0) && (eidx == (nfs_data_BLOCK_SIZE - 1)))
nfs_data_write(fs->data, node, (char*)buf + kk);
else {
char tmpbuf[nfs_data_BLOCK_SIZE];
nfs_data_read(fs->data, node, tmpbuf);
memcpy(&tmpbuf[sidx], (char*)buf + kk, (eidx - sidx + 1));
nfs_data_write(fs->data, node, tmpbuf);
}
node = nfs_fat_chain_get_nth(fs->fat, node, 1);
idx++;
kk += (eidx - sidx + 1);
}
nfs_file_lseek(fs, filedes, fp + nbyte - 1, (int)SEEK_SET);
fs->handles[filedes]->fp = fp + nbyte;
return nbyte;
}
int nfs_file_inc_refcount(nfs_Handle* fs, char* path) {
int dt_idx, nt_idx;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
if (path == NULL) {
nfs_errno = nfs_ERR_INVALID_PARMS;
return -1;
}
dt_idx = nfs_dt_filename_lookup(fs->dt, (char*)path);
if (dt_idx < 0) {
nfs_errno = nfs_ERR_NOT_FOUND;
return -1;
}
nt_idx = nfs_dt_filename_get_nt_index(fs->dt, dt_idx);
if (nt_idx < 0) {
nfs_errno = nfs_ERR_INVALID_NT;
return -1;
}
nfs_nt_refcount_incr(fs->nt, nt_idx);
return 0;
}
int nfs_file_dec_refcount(nfs_Handle* fs, const char* path) {
int dt_idx, nt_idx, chain;
int must_go, ret = 0;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
if (path == NULL) {
nfs_errno = nfs_ERR_INVALID_PARMS;
return -1;
}
dt_idx = nfs_dt_filename_lookup(fs->dt, (char*)path);
if (dt_idx < 0) {
nfs_errno = nfs_ERR_NOT_FOUND;
return -1;
}
nt_idx = nfs_dt_filename_get_nt_index(fs->dt, dt_idx);
if (nt_idx < 0) {
nfs_errno = nfs_ERR_INVALID_NT;
return -1;
}
chain = nfs_nt_node_get_chain(fs->nt, nt_idx);
if (chain <= 0)
return -1;
must_go = nfs_nt_refcount_decr(fs->nt, nt_idx);
if (must_go) {
ret = nfs_dt_filename_delete(fs->dt, (char*)path);
if (ret < 0)
return ret;
}
if (must_go)
ret = nfs_fat_destroy_chain(fs->fat, chain);
return ret;
}
int nfs_file_link(nfs_Handle* fs, char* existing, const char* new_) {
int dt_idx, nt_idx;
int dt_idx2;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
dt_idx = nfs_dt_filename_lookup(fs->dt, (char*)existing);
if (dt_idx < 0) {
nfs_errno = nfs_ERR_NOT_FOUND;
return -1;
}
nt_idx = nfs_dt_filename_get_nt_index(fs->dt, dt_idx);
if (nt_idx < 0) {
nfs_errno = nfs_ERR_INVALID_NT;
return -1;
}
nfs_nt_refcount_incr(fs->nt, nt_idx);
dt_idx2 = nfs_dt_filename_add(fs->dt, (char*)new_);
if (dt_idx2 < 0) {
nfs_errno = nfs_ERR_DUPLICATEF;
return -1;
}
nfs_dt_filename_set_nt_index(fs->dt, dt_idx2, nt_idx);
return 0;
}
int nfs_file_unlink(nfs_Handle* fs, const char* path) {
int dt_idx, nt_idx, chain;
int must_go, ret;
if (fs == NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
dt_idx = nfs_dt_filename_lookup(fs->dt, (char*)path);
if (dt_idx < 0) {
nfs_errno = nfs_ERR_NOT_FOUND;
return -1;
}
nt_idx = nfs_dt_filename_get_nt_index(fs->dt, dt_idx);
if (nt_idx < 0) {
nfs_errno = nfs_ERR_INVALID_NT;
return -1;
}
chain = nfs_nt_node_get_chain(fs->nt, nt_idx);
if (chain <= 0)
return -1;
must_go = nfs_nt_refcount_decr(fs->nt, nt_idx);
ret = nfs_dt_filename_delete(fs->dt, (char*)path);
if (ret < 0)
return ret;
if (must_go)
ret = nfs_fat_destroy_chain(fs->fat, chain);
return ret;
}
typedef struct _nfs_tmp {
nfs_glob_t* pglob;
char* pattern;
int flags;
int (*e)(const char*, int);
int errnum;
} nfs_tmp;
static int __nfs_glob_cbk(nfs_dt_DT*, char* filename, int, void* t) {
int n;
nfs_tmp* tmp = (nfs_tmp*)t;
int must_extend = 0;
if (!(tmp->pglob->gl_pathc & 0x1F))
must_extend = 1;
tmp->pglob->gl_pathc++;
n = tmp->pglob->gl_pathc;
if (tmp->flags & GLOB_DOOFFS)
n += tmp->pglob->gl_offs;
if (must_extend) {
tmp->pglob->gl_pathv = (char**)realloc(tmp->pglob->gl_pathv, ((n-1)+40) * sizeof(char*));
if (tmp->pglob->gl_pathv == NULL) {
tmp->pglob->gl_pathc--;
if (tmp->e)
tmp->e(filename, GLOB_NOSPACE);
tmp->errnum = GLOB_NOSPACE;
return 0;
}
}
tmp->pglob->gl_pathv[n-1] = (char*)malloc(strlen(filename) + 4);
strcpy(tmp->pglob->gl_pathv[n-1], filename);
tmp->pglob->gl_pathv[n] = NULL;
if (tmp->flags & GLOB_FIRSTONLY)
return 0;
return 1;
}
int __nfs_glob_sort(const void* e1, const void* e2) {
return strcmp(*(char**)e1, *(char**)e2);
}
int nfs_glob(nfs_Handle* fs,
const char* pattern,
int flags,
int (*errfunc)(const char*, int),
nfs_glob_t* pglob) {
nfs_tmp tmp;
int lastc;
if (fs == nfs_NULL) {
nfs_errno = nfs_ERR_INVALID_FS;
return -1;
}
if ((pattern == NULL) || (pglob == NULL)) {
nfs_errno = nfs_ERR_INVALID_PARMS;
return -1;
}
tmp.pglob = pglob;
tmp.pattern = (char*)pattern;
tmp.flags = flags;
tmp.e = errfunc;
if (!(flags & GLOB_APPEND)) {
pglob->gl_pathv = NULL;
pglob->gl_pathc = 0;
}
if (!(flags & GLOB_DOOFFS))
pglob->gl_offs = 0;
lastc = pglob->gl_pathc;
nfs_dt_filename_glob(fs->dt, (char*)pattern, __FNM_FLAGS, __nfs_glob_cbk, &tmp);
if ((flags & GLOB_NOCHECK) && (pglob->gl_pathc == lastc))
__nfs_glob_cbk(fs->dt, (char*)pattern, 0, &tmp);
if (!(flags & GLOB_NOSORT)) {
if (pglob->gl_pathc > 0)
qsort(&(pglob->gl_pathv[pglob->gl_offs]), pglob->gl_pathc, sizeof(char*), __nfs_glob_sort);
}
return 0;
}
void nfs_glob_free(nfs_Handle*, nfs_glob_t* pglob) {
int i;
if (pglob == NULL) {
nfs_errno = nfs_ERR_INVALID_PARMS;
return;
}
if (pglob->gl_pathv != NULL) {
for (i = pglob->gl_offs; i < (pglob->gl_offs + pglob->gl_pathc); i++) {
if (pglob->gl_pathv[i] != NULL)
free(pglob->gl_pathv[i]);
}
free(pglob->gl_pathv);
}
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
}
void nfs_perror(nfs_Handle*, const char* s) {
char* e = "Internal error";
switch ((char)nfs_errno) {
case nfs_ERR_IIO_INIT:
e = "Could not open/create the IIO file"; break;
case nfs_ERR_NO_DATA:
e = "Could not open/create the data file"; break;
case nfs_ERR_NO_FAT:
e = "Could not initialize the FAT channel"; break;
case nfs_ERR_NO_NT:
e = "Could not initialize the NT channel"; break;
case nfs_ERR_NO_DT:
e = "Could not initialize the DT channel"; break;
case nfs_ERR_A_FAT:
e = "Could not allocate the FAT channel"; break;
case nfs_ERR_A_NT:
e = "Could not allocate the NT channel"; break;
case nfs_ERR_A_DT:
e = "Could not allocate the DT channel"; break;
case nfs_ERR_INVALID_FS:
e = "Invalid file system handle"; break;
case nfs_ERR_ALREADY_CLSD:
e = "File already closed"; break;
case nfs_ERR_NOT_FOUND:
e = "File not found"; break;
case nfs_ERR_NO_OPEN:
e = "No files open"; break;
case nfs_ERR_INVALID_FH:
e = "Invalid file descriptor"; break;
case nfs_ERR_INVALID_NT:
e = "Invalid node in NT"; break;
case nfs_ERR_NOMEM_OPEN:
e = "No memory available for opening files"; break;
case nfs_ERR_LOCKED:
e = "File system is locked by another process"; break;
case nfs_ERR_DUPLICATEF:
e = "The file you are trying to create already exists"; break;
case nfs_ERR_DT_INTERNAL:
e = "Internal error in DT"; break;
case nfs_ERR_INVALID_PARMS:
e = "Invalid parameters"; break;
default:
e = "Internal error";
}
printf("%s: %s\n", s, e);
}