NP2kai/x11/dosio.c
2019-03-21 20:48:05 +09:00

457 lines
7.2 KiB
C
Executable File

#include "compiler.h"
#include <sys/stat.h>
#include <time.h>
#include "codecnv/codecnv.h"
#include "dosio.h"
static OEMCHAR curpath[MAX_PATH];
static OEMCHAR *curfilep = curpath;
#define ISKANJI(c) ((((c) - 0xa1) & 0xff) < 0x5c)
void
dosio_init(void)
{
/* nothing to do */
}
void
dosio_term(void)
{
/* nothing to do */
}
/* ファイル操作 */
FILEH
file_open(const OEMCHAR *path)
{
FILEH fh;
fh = fopen(path, "rb+");
if (fh)
return fh;
return fopen(path, "rb");
}
FILEH
file_open_rb(const OEMCHAR *path)
{
return fopen(path, "rb");
}
FILEH
file_create(const OEMCHAR *path)
{
return fopen(path, "wb+");
}
long
file_seek(FILEH handle, long pointer, int method)
{
fseek(handle, pointer, method);
return ftell(handle);
}
UINT
file_read(FILEH handle, void *data, UINT length)
{
return (UINT)fread(data, 1, length, handle);
}
UINT
file_write(FILEH handle, const void *data, UINT length)
{
return (UINT)fwrite(data, 1, length, handle);
}
short
file_close(FILEH handle)
{
fclose(handle);
return 0;
}
UINT
file_getsize(FILEH handle)
{
struct stat sb;
if (fstat(fileno(handle), &sb) == 0)
return sb.st_size;
return 0;
}
short
file_attr(const OEMCHAR *path)
{
struct stat sb;
short attr;
if (stat(path, &sb) == 0) {
if (S_ISDIR(sb.st_mode)) {
return FILEATTR_DIRECTORY;
}
attr = 0;
if (!(sb.st_mode & S_IWUSR)) {
attr |= FILEATTR_READONLY;
}
return attr;
}
return -1;
}
static BRESULT
cnvdatetime(struct stat *sb, DOSDATE *dosdate, DOSTIME *dostime)
{
struct tm *ftime;
ftime = localtime(&sb->st_mtime);
if (ftime) {
if (dosdate) {
dosdate->year = ftime->tm_year + 1900;
dosdate->month = ftime->tm_mon + 1;
dosdate->day = ftime->tm_mday;
}
if (dostime) {
dostime->hour = ftime->tm_hour;
dostime->minute = ftime->tm_min;
dostime->second = ftime->tm_sec;
}
return SUCCESS;
}
return FAILURE;
}
short
file_getdatetime(FILEH handle, DOSDATE *dosdate, DOSTIME *dostime)
{
struct stat sb;
if ((fstat(fileno(handle), &sb) == 0)
&& (cnvdatetime(&sb, dosdate, dostime) == SUCCESS))
return 0;
return -1;
}
short
file_delete(const OEMCHAR *path)
{
return (short)unlink(path);
}
short
file_dircreate(const OEMCHAR *path)
{
return (short)mkdir(path, 0777);
}
/* カレントファイル操作 */
void
file_setcd(const OEMCHAR *exepath)
{
milstr_ncpy(curpath, exepath, sizeof(curpath));
curfilep = file_getname(curpath);
*curfilep = '\0';
}
char *
file_getcd(const OEMCHAR *filename)
{
*curfilep = '\0';
file_catname(curpath, filename, sizeof(curpath));
return curpath;
}
FILEH
file_open_c(const OEMCHAR *filename)
{
*curfilep = '\0';
file_catname(curpath, filename, sizeof(curpath));
return file_open(curpath);
}
FILEH
file_open_rb_c(const OEMCHAR *filename)
{
*curfilep = '\0';
file_catname(curpath, filename, sizeof(curpath));
return file_open_rb(curpath);
}
FILEH
file_create_c(const OEMCHAR *filename)
{
*curfilep = '\0';
file_catname(curpath, filename, sizeof(curpath));
return file_create(curpath);
}
short
file_delete_c(const OEMCHAR *filename)
{
*curfilep = '\0';
file_catname(curpath, filename, sizeof(curpath));
return file_delete(curpath);
}
short
file_attr_c(const OEMCHAR *filename)
{
*curfilep = '\0';
file_catname(curpath, filename, sizeof(curpath));
return file_attr(curpath);
}
FLISTH
file_list1st(const OEMCHAR *dir, FLINFO *fli)
{
FLISTH ret;
ret = (FLISTH)_MALLOC(sizeof(_FLISTH), "FLISTH");
if (ret == NULL) {
VERBOSE(("file_list1st: couldn't alloc memory (size = %d)", sizeof(_FLISTH)));
return FLISTH_INVALID;
}
milstr_ncpy(ret->path, dir, sizeof(ret->path));
file_setseparator(ret->path, sizeof(ret->path));
ret->hdl = opendir(ret->path);
VERBOSE(("file_list1st: opendir(%s)", ret->path));
if (ret->hdl == NULL) {
VERBOSE(("file_list1st: opendir failure"));
_MFREE(ret);
return FLISTH_INVALID;
}
if (file_listnext((FLISTH)ret, fli) == SUCCESS) {
return (FLISTH)ret;
}
VERBOSE(("file_list1st: file_listnext failure"));
closedir(ret->hdl);
_MFREE(ret);
return FLISTH_INVALID;
}
BRESULT
file_listnext(FLISTH hdl, FLINFO *fli)
{
OEMCHAR buf[MAX_PATH];
struct dirent *de;
struct stat sb;
de = readdir(hdl->hdl);
if (de == NULL) {
VERBOSE(("file_listnext: readdir failure"));
return FAILURE;
}
milstr_ncpy(buf, hdl->path, sizeof(buf));
milstr_ncat(buf, de->d_name, sizeof(buf));
if (stat(buf, &sb) != 0) {
VERBOSE(("file_listnext: stat failure. (path = %s)", buf));
return FAILURE;
}
fli->caps = FLICAPS_SIZE | FLICAPS_ATTR | FLICAPS_DATE | FLICAPS_TIME;
fli->size = sb.st_size;
fli->attr = 0;
if (S_ISDIR(sb.st_mode)) {
fli->attr |= FILEATTR_DIRECTORY;
}
if (!(sb.st_mode & S_IWUSR)) {
fli->attr |= FILEATTR_READONLY;
}
cnvdatetime(&sb, &fli->date, &fli->time);
milstr_ncpy(fli->path, de->d_name, sizeof(fli->path));
VERBOSE(("file_listnext: success"));
return SUCCESS;
}
void
file_listclose(FLISTH hdl)
{
if (hdl) {
closedir(hdl->hdl);
_MFREE(hdl);
}
}
static int
euckanji1st(const OEMCHAR *str, int pos)
{
int ret;
int c;
for (ret = 0; pos >= 0; ret ^= 1) {
c = (UINT8)str[pos--];
if (!ISKANJI(c))
break;
}
return ret;
}
void
file_cpyname(OEMCHAR *dst, const OEMCHAR *src, int maxlen)
{
int i;
if (maxlen-- > 0) {
for (i = 0; i < maxlen && src[i] != '\0'; i++) {
dst[i] = src[i];
}
if (i > 0) {
if (euckanji1st(src, i-1)) {
i--;
}
}
dst[i] = '\0';
}
}
void
file_catname(OEMCHAR *path, const OEMCHAR *filename, int maxlen)
{
for (; maxlen > 0; path++, maxlen--) {
if (*path == '\0') {
break;
}
}
if (maxlen > 0) {
milstr_ncpy(path, filename, maxlen);
for (; *path != '\0'; path++) {
if (!ISKANJI(*path)) {
path++;
if (*path == '\0') {
break;
}
} else if (((*path - 0x41) & 0xff) < 26) {
*path |= 0x20;
} else if (*path == '\\') {
*path = G_DIR_SEPARATOR;
}
}
}
}
BOOL
file_cmpname(const OEMCHAR *path, const OEMCHAR *path2)
{
return strcasecmp(path, path2);
}
OEMCHAR *
file_getname(const OEMCHAR *path)
{
const OEMCHAR *ret;
for (ret = path; *path != '\0'; path++) {
if (ISKANJI(*path)) {
path++;
if (*path == '\0') {
break;
}
} else if (*path == G_DIR_SEPARATOR) {
ret = path + 1;
}
}
return (OEMCHAR *)ret;
}
void
file_cutname(OEMCHAR *path)
{
OEMCHAR *p;
p = file_getname(path);
*p = '\0';
}
OEMCHAR *
file_getext(const OEMCHAR *path)
{
const OEMCHAR *p, *q;
for (p = file_getname(path), q = NULL; *p != '\0'; p++) {
if (*p == '.') {
q = p + 1;
}
}
if (q == NULL) {
q = p;
}
return (OEMCHAR *)q;
}
void
file_cutext(OEMCHAR *path)
{
OEMCHAR *p, *q;
for (p = file_getname(path), q = NULL; *p != '\0'; p++) {
if (*p == '.') {
q = p;
}
}
if (q != NULL) {
*q = '\0';
}
}
void
file_cutseparator(OEMCHAR *path)
{
int pos;
pos = strlen(path) - 1;
if ((pos > 0) && (path[pos] == G_DIR_SEPARATOR)) {
path[pos] = '\0';
}
}
void
file_setseparator(OEMCHAR *path, int maxlen)
{
int pos;
pos = strlen(path);
if ((pos) && (path[pos-1] != G_DIR_SEPARATOR) && ((pos + 2) < maxlen)) {
path[pos++] = G_DIR_SEPARATOR;
path[pos] = '\0';
}
}
short file_rename(const char* ExistFile, const char* NewFile)
{
return (rename(ExistFile, NewFile) == 0) ? 0 : -1;
}
short file_dirdelete(const char* PathName)
{
return (remove(PathName)) ? 0 : -1;
}