/*
* catdump - 電子ブック/EPWING カタログ/テキスト変換
*
* Written by Junn Ohta (ohta@src.ricoh.co.jp). Public Domain.
* Modified by yamagata@nwgpc.kek.jp on 2000/04/13
*/
char *progname = "catdump";
char *version = "1.1";
char *date = "1999/01/13";
char *author = "Junn Ohta (ohta@src.ricoh.co.jp)";
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
typedef unsigned char uchr;
#ifndef O_BINARY
#define O_BINARY 0
#endif
#define OK 0
#define ERR (-1)
#define FALSE 0
#define TRUE 1
/*
* 処理内容
*/
#define DUMP 0 /* カタログ → テキスト */
#define UNDUMP 1 /* テキスト → カタログ */
/*
* 書籍種別
*/
#define EB 0 /* 電子ブック */
#define EPWING 1 /* EPWING1 = 1, EPWING2 = 2, ... */
#define EPWING2 2 /* EPWING2 */
#define EPWING4 4 /* EPWING4 */
/*
* 書籍ブロックサイズ(= カタログファイルサイズ)
*/
#define BLKSIZ 2048
/*
* カタログファイルの構造
* (登録書籍数はEBで最大50、EPWINGで最大12)
*/
#define C_BOOKSLEN 2 /* 登録書籍数 */
#define C_CDTYPELEN 2 /* 書籍種別 */
#define C_SELECTLEN 2 /* 書籍選択画面の有無、書籍番号 */
#define C_RSVLEN 10 /* 将来拡張用 */
/* (以下登録書籍数だけくり返し) */
#define B_BKTYPELEN 2 /* 書籍情報 */
#define B_TTLLEN_EB 30 /* 書籍名称(電子ブック) */
#define B_TTLLEN_EPW 80 /* 書籍名称(EPWING) */
#define B_DIRLEN 8 /* 書籍ディレクトリー名 */
#define B_DPOSLEN_EPW 4 /* ディレクトリー位置(EPWING) */
#define B_INFBLEN_EPW 2 /* 管理情報記録位置(EPWING) */
#define B_APPLEN_EPW 4 /* 実装定義(EPWING) */
#define B_ZGAILEN_EPW 32 /* 全角外字ファイル名(EPWING) */
#define B_HGAILEN_EPW 32 /* 半角外字ファイル名(EPWING) */
/* (EPWING2以降、以下書籍数だけくり返し) */
#define B2_RSV1LEN 4 /* 不明 */
#define B2_BKFILELEN 8 /* 本文ファイル名称 */
#define B2_PAD1LEN 16 /* 不明 */
#define B2_STFILELEN 8 /* ストリームファイル名称 */
#define B2_PAD2LEN 16 /* 不明 */
#define B2_RSV2LEN 4 /* 不明 */
#define B2_PAD3LEN 108 /* 不明 */
/*
* カタログヘッダー
*/
typedef struct hdr_t {
uchr books[C_BOOKSLEN];
uchr cdtype[C_CDTYPELEN];
uchr select[C_SELECTLEN];
uchr reserved[C_RSVLEN];
} HDR_T;
/*
* カタログ内容(電子ブック)
*/
typedef struct eb_t {
uchr booktype[B_BKTYPELEN];
uchr title[B_TTLLEN_EB];
uchr directory[B_DIRLEN];
} EB_T;
/*
* カタログ内容(EPWING)
*/
typedef struct epw_t {
uchr booktype[B_BKTYPELEN];
uchr title[B_TTLLEN_EPW];
uchr directory[B_DIRLEN];
uchr dirpos[B_DPOSLEN_EPW];
uchr infoblock[B_INFBLEN_EPW];
uchr appdef[B_APPLEN_EPW];
uchr zgaijifile[B_ZGAILEN_EPW];
uchr hgaijifile[B_HGAILEN_EPW];
} EPW_T;
/*
* カタログ内容(EPWING2以降)
*/
typedef struct epw2_t {
uchr reserved1[B2_RSV1LEN];
uchr bookfile[B2_BKFILELEN];
uchr pad1[B2_PAD1LEN];
uchr streamfile[B2_STFILELEN];
uchr pad2[B2_PAD2LEN];
uchr reserved2[B2_RSV2LEN];
uchr pad3[B2_PAD3LEN];
} EPW2_T;
/*
* テキストファイルのタグ
*/
#define EB_ID "EB"
#define EPW_ID "EPWING"
#define CAT_ENTRY "[Catalog]"
#define CTAG_FILENAME "FileName"
#define CTAG_BOOKS "Books"
#define CTAG_CDTYPE "Type"
#define CTAG_SELECT "BookSelect"
#define CTAG_RESERVED "Reserved"
#define BOOK_ENTRY "[Book]"
#define BTAG_BOOKTYPE "BookType"
#define BTAG_TITLE "Title"
#define BTAG_DIRECTORY "Directory"
#define BTAG_DIRPOS "DirPos"
#define BTAG_INFOBLOCK "InfoBlock"
#define BTAG_APPDEF "AppDef"
#define BTAG_ZGAIJIFILE "ZenGaiji"
#define BTAG_HGAIJIFILE "HanGaiji"
#define B2TAG_RSV1 "Reserved1"
#define B2TAG_BKFILE "BookFile"
#define B2TAG_PAD1 "Padding1"
#define B2TAG_STFILE "StreamFile"
#define B2TAG_PAD2 "Padding2"
#define B2TAG_RSV2 "Reserved2"
#define B2TAG_PAD3 "Padding3"
/*
* 処理済みマスク
*/
#define M_FILENAME 0x00000001L
#define M_BOOKS 0x00000002L
#define M_CDTYPE 0x00000004L /* 必須 */
#define M_SELECT 0x00000008L
#define M_RESERVED 0x00000010L
#define M_BOOKTYPE 0x00000020L /* 必須 */
#define M_TITLE 0x00000040L /* 必須 */
#define M_DIRECTORY 0x00000080L /* 必須 */
#define M_DIRPOS 0x00000100L
#define M_INFOBLOCK 0x00000200L
#define M_APPDEF 0x00000400L
#define M_ZGAIJIFILE 0x00000800L
#define M_HGAIJIFILE 0x00001000L
#define M_RESERVED1 0x00002000L
#define M_BOOKFILE 0x00004000L
#define M_PADDING1 0x00008000L
#define M_STREAMFILE 0x00010000L
#define M_PADDING2 0x00020000L
#define M_RESERVED2 0x00040000L
#define M_PADDING3 0x00080000L
/*
* getstr()の処理方法
*/
#define F_NUL 0 /* 余りを0x00で埋める */
#define F_SPACE 1 /* 余りをスペースで埋める */
int proctype = DUMP;
int type;
int line;
char *catalog;
char *txtfile;
uchr catbuf[BLKSIZ * 2];
uchr epw2buf[BLKSIZ];
uchr buf[BUFSIZ];
int EBGmode = 0;
int main();
void usage();
int dump();
uchr *bookkind();
int guess();
int nonzero();
void outhex();
void outstr();
void outjstr();
int undump();
uchr *getline();
uchr *getvalue();
int gethex();
int hexdigit();
int getstr();
int getjstr();
int
main(ac, av)
int ac;
char **av;
{
int ret;
ac--, av++;
while (ac > 0 && **av == '-') {
switch (av[0][1]) {
case 'g':
case 'G':
EBGmode = 1;
break;
case 'd':
case 'D':
proctype = DUMP;
break;
case 'u':
case 'U':
proctype = UNDUMP;
ac--, av++;
if (ac <= 0)
usage();
txtfile = *av;
break;
default:
usage();
}
ac--, av++;
}
if (ac != 1)
usage();
catalog = *av;
switch (proctype) {
case DUMP:
ret = dump(catalog);
break;
case UNDUMP:
ret = undump(txtfile, catalog);
break;
}
if (ret == ERR)
exit(1);
exit(0);
}
void
usage()
{
fprintf(stderr, "電子ブック/EPWING カタログ/テキスト変換");
fprintf(stderr, " Ver.%s (%s)\n Written by %s, Public Domain.\n\n",
version, date, author);
fprintf(stderr, "使用法: %s", progname);
fprintf(stderr, " [-g] [-d] [-u <テキストファイル>] <カタログファイル>\n\n");
fprintf(stderr, "オプション:\n");
fprintf(stderr, " -g: EBG 専用モードにする\n");
fprintf(stderr, " -d: カタログファイルを標準出力にダンプする\n");
fprintf(stderr, " -u: テキストファイルをカタログファイルに変換する\n");
exit(1);
}
int
dump(catalog)
char *catalog;
{
int fd, i, num;
HDR_T *hdr;
EB_T *eb;
EPW_T *epw;
EPW2_T *epw2;
struct stat st;
if (stat(catalog, &st) < 0) {
fprintf(stderr, "%s の情報が取得できません\n", catalog);
return ERR;
}
if (st.st_size < 0 || st.st_size > BLKSIZ * 2) {
fprintf(stderr, "カタログサイズが異常です\n");
return ERR;
}
if ((fd = open(catalog, O_RDONLY|O_BINARY)) < 0) {
fprintf(stderr, "%s がオープンできません\n", catalog);
return ERR;
}
if (read(fd, (char *)catbuf, st.st_size) < st.st_size) {
fprintf(stderr, "ファイルの読み込みに失敗しました\n");
close(fd);
return ERR;
}
close(fd);
hdr = (HDR_T *)catbuf;
num = (hdr->books[0] << 8) + hdr->books[1];
type = hdr->cdtype[1];
printf("; 電子ブック/EPWING カタログ内容");
printf(" (generated by %s v%s)\n\n", progname, version);
printf("%s\n", CAT_ENTRY);
printf("%-11s= %s\n", CTAG_FILENAME, catalog);
if (type == EB)
printf("%-11s= %s\n", CTAG_CDTYPE, EB_ID);
else
printf("%-11s= %s%d\n", CTAG_CDTYPE, EPW_ID, type);
printf("%-11s= %d\n", CTAG_BOOKS, num);
if (hdr->select[0] == 0x01) {
printf("%-11s= %d\n", CTAG_SELECT,
(hdr->select[1] >> 4) * 10 + (hdr->select[1] & 0x0f));
}
if (type >= EPWING4 || nonzero(hdr->reserved, C_RSVLEN)) {
printf("%-11s= ", CTAG_RESERVED);
outhex(hdr->reserved, C_RSVLEN);
if (type >= EPWING4) {
printf(" (HD利用:%s, NETWORK利用:%s)",
(hdr->reserved[2] & 0x10)? "許可": "禁止",
(hdr->reserved[2] & 0x01)? "許可": "禁止");
}
printf("\n");
}
printf("\n");
if (type == EB) {
eb = (EB_T *)(catbuf + sizeof(HDR_T));
for (i = 0; i < num; i++) {
printf("%s\n", BOOK_ENTRY);
printf("%-11s= ", BTAG_BOOKTYPE);
outhex(eb->booktype, B_BKTYPELEN);
printf("\n");
printf("%-11s= \"", BTAG_TITLE);
if (!EBGmode) {
outjstr(eb->title, B_TTLLEN_EB);
} else {
outstr(eb->title, B_TTLLEN_EB);
}
printf("\"\n");
printf("%-11s= \"", BTAG_DIRECTORY);
outstr(eb->directory, B_DIRLEN);
printf("\"\n");
printf("\n");
eb++;
}
} else {
epw = (EPW_T *)(catbuf + sizeof(HDR_T));
epw2 = (EPW2_T *)((uchr *)epw + num * sizeof(EPW_T));
for (i = 0; i < num; i++) {
printf("%s\n", BOOK_ENTRY);
printf("%-11s= ", BTAG_BOOKTYPE);
outhex(epw->booktype, B_BKTYPELEN);
printf(" (%02X:%s, %02X:EPWING%d)\n",
epw->booktype[0], bookkind(epw->booktype),
epw->booktype[1], epw->booktype[1]);
printf("%-11s= \"", BTAG_TITLE);
if (!EBGmode) {
outjstr(epw->title, B_TTLLEN_EPW);
} else {
outstr(epw->title, B_TTLLEN_EPW);
}
printf("\"\n");
printf("%-11s= \"", BTAG_DIRECTORY);
outstr(epw->directory, B_DIRLEN);
printf("\"\n");
if (nonzero(epw->dirpos, B_DPOSLEN_EPW)) {
printf("%-11s= ", BTAG_DIRPOS);
outhex(epw->dirpos, B_DPOSLEN_EPW);
printf("\n");
}
if (nonzero(epw->infoblock, B_INFBLEN_EPW)) {
printf("%-11s= ", BTAG_INFOBLOCK);
outhex(epw->infoblock, B_INFBLEN_EPW);
printf("\n");
}
if (nonzero(epw->appdef, B_APPLEN_EPW)) {
printf("%-11s= ", BTAG_APPDEF);
outhex(epw->appdef, B_APPLEN_EPW);
printf("\n");
}
if (nonzero(epw->zgaijifile, B_ZGAILEN_EPW)) {
printf("%-11s= \"", BTAG_ZGAIJIFILE);
outstr(epw->zgaijifile, B_ZGAILEN_EPW);
printf("\"\n");
}
if (nonzero(epw->hgaijifile, B_HGAILEN_EPW)) {
printf("%-11s= \"", BTAG_HGAIJIFILE);
outstr(epw->hgaijifile, B_HGAILEN_EPW);
printf("\"\n");
}
if (type >= EPWING2) {
if (nonzero(epw2->bookfile, B2_BKFILELEN)) {
printf("%-11s= \"", B2TAG_BKFILE);
outstr(epw2->bookfile, B2_BKFILELEN);
printf("\"\n");
}
if (nonzero(epw2->streamfile, B2_STFILELEN)) {
printf("%-11s= \"", B2TAG_STFILE);
outstr(epw2->streamfile, B2_STFILELEN);
printf("\"\n");
}
if (nonzero(epw2->reserved1, B2_RSV1LEN)) {
printf("%-11s= ", B2TAG_RSV1);
outhex(epw2->reserved1, B2_RSV1LEN);
printf("\n");
}
if (nonzero(epw2->reserved2, B2_RSV2LEN)) {
printf("%-11s= ", B2TAG_RSV2);
outhex(epw2->reserved2, B2_RSV2LEN);
printf("\n");
}
if (nonzero(epw2->pad1, B2_PAD1LEN)) {
printf("%-11s= ", B2TAG_PAD1);
outhex(epw2->pad1, B2_PAD1LEN);
printf("\n");
}
if (nonzero(epw2->pad2, B2_PAD2LEN)) {
printf("%-11s= ", B2TAG_PAD2);
outhex(epw2->pad2, B2_PAD2LEN);
printf("\n");
}
if (nonzero(epw2->pad3, B2_PAD3LEN)) {
printf("%-11s= ", B2TAG_PAD3);
outhex(epw2->pad3, B2_PAD3LEN);
printf("\n");
}
}
printf("\n");
epw++;
epw2++;
}
}
return OK;
}
uchr *
bookkind(str)
uchr *str;
{
switch (*str & 0xf0) {
case 0x00: return "国語辞典";
case 0x10: return "漢和辞典";
case 0x20: return "英和辞典";
case 0x30: return "和英辞典";
case 0x40: return "現代用語辞典";
case 0x50: return "百科事典";
case 0x60: return "一般書物";
case 0x70: return "類語辞典";
case 0xf0: return "ストリーム";
default: return "不明";
}
}
int
nonzero(p, len)
uchr *p;
int len;
{
while (len--)
if (*p++)
return TRUE;
return FALSE;
}
void
outhex(p, len)
uchr *p;
int len;
{
while (len--)
printf("%02X", *p++);
}
void
outstr(p, len)
uchr *p;
int len;
{
uchr *pend;
pend = p + len;
while (pend > p && (pend[-1] == '\0' || pend[-1] == ' '))
pend--;
while (p < pend) {
if (*p >= 0x20 && *p <= 0x7f)
putchar(*p);
else if (*p == '"' || *p == '\\')
printf("\\%c", *p);
else if (*p == '\0')
printf("\\0");
else
printf("\\x%02X", *p);
p++;
}
}
void
outjstr(p, len)
uchr *p;
int len;
{
int c1, c2;
uchr *pend;
pend = p + len;
while (pend >= p + 2 &&
(pend[-1] == '\0' && pend[-2] == '\0' ||
pend[-1] == 0x21 && pend[-2] == 0x21))
pend -= 2;
#ifdef EUC
while (p < pend) {
putchar(*p | 0x80);
p++;
}
#endif
#ifdef SJIS
while (p < pend) {
c1 = *p++;
c2 = *p++;
if (c1 & 0x01) {
c2 += 0x1f;
if (c2 > 0x7e)
c2++;
} else {
c2 += 0x7e;
}
c1 = (c1 + 0xe1) >> 1;
if (c1 > 0x9f)
c1 += 0x40;
putchar(c1);
putchar(c2);
}
#endif
}
int
undump(txtfile, catalog)
char *txtfile, *catalog;
{
int fd, i, st, num, len, err;
long mask;
uchr *p, *t, *u;
FILE *fp;
HDR_T *hdr;
EB_T *eb;
EPW_T *epw;
EPW2_T *epw2;
if ((fp = fopen(txtfile, "r")) == NULL) {
fprintf(stderr, "%s がオープンできません\n", txtfile);
return ERR;
}
memset(catbuf, '\0', BLKSIZ * 2);
memset(epw2buf, '\0', BLKSIZ);
err = 0;
line = 0;
if (getline(buf, fp) == NULL ||
strncmp(buf, CAT_ENTRY, strlen(CAT_ENTRY))) {
fprintf(stderr, "ERR: 項目 %s がありません\n", CAT_ENTRY);
fclose(fp);
return ERR;
}
type = EB;
st = 0;
hdr = (HDR_T *)catbuf;
mask = 0L;
while (getline(buf, fp) != NULL && *buf != '[') {
if ((p = getvalue(buf)) == NULL) {
fprintf(stderr, "ERR: line %d: 構文に誤りがあります\n", line);
err++;
continue;
}
if (!strcmp(buf, CTAG_FILENAME)) {
if ((mask & M_FILENAME) != 0)
goto ctag_dup;
/*
* ファイル名の情報は使わないので読み飛ばす
*/
mask |= M_FILENAME;
} else if (!strcmp(buf, CTAG_BOOKS)) {
if ((mask & M_BOOKS) != 0)
goto ctag_dup;
/*
* 書籍数の情報は使わないので読み飛ばす
*/
mask |= M_BOOKS;
} else if (!strcmp(buf, CTAG_CDTYPE)) {
len = strlen(EPW_ID);
if ((mask & M_BOOKTYPE) != 0)
goto ctag_dup;
if (!strcmp(p, EB_ID)) {
type = EB;
} else if (!strncmp(p, EPW_ID, len) &&
p[len] >= '1' && p[len] <= '9' && p[len+1] == '\0') {
type = EPWING + p[len] - '1';
} else {
fprintf(stderr, "ERR: line %d: %s の値に誤りがあります(%s)\n",
line, CTAG_CDTYPE, p);
fclose(fp);
return ERR;
}
hdr->cdtype[1] = type;
mask |= M_BOOKTYPE;
} else if (!strcmp(buf, CTAG_SELECT)) {
if ((mask & M_SELECT) != 0)
goto ctag_dup;
st = 0;
while (isdigit(*p)) {
st = st * 10 + *p - '0';
p++;
}
if (*p == '\0' && i > 0) {
hdr->select[0] = 0x01;
hdr->select[1] = ((st / 10) << 4) + (st % 10);
} else {
fprintf(stderr, "ERR: line %d: %s の値に誤りがあります(%s)\n",
line, CTAG_SELECT, p);
fclose(fp);
return ERR;
}
mask |= M_SELECT;
} else if (!strcmp(buf, CTAG_RESERVED)) {
if ((mask & M_RESERVED) != 0)
goto ctag_dup;
mask |= M_RESERVED;
if (gethex(hdr->reserved, p, C_RSVLEN) == ERR)
goto ctag_invalid;
} else {
fprintf(stderr, "ERR: line %d: 不明のタグです(%s)\n",
line, buf);
err++;
continue;
}
continue;
ctag_dup:
fprintf(stderr, "ERR: line %d: タグが二重定義されています(%s)\n",
line, buf);
err++;
continue;
ctag_invalid:
fprintf(stderr, "ERR: line %d: 値が不正です(%s)\n", line, p);
err++;
continue;
}
if ((mask & M_BOOKTYPE) == 0) {
fprintf(stderr, "ERR: line %d: %s が見つかりませんでした\n",
line, CTAG_CDTYPE);
err++;
}
if (type == EB) {
eb = (EB_T *)(catbuf + sizeof(HDR_T));
} else {
epw = (EPW_T *)(catbuf + sizeof(HDR_T));
epw2 = (EPW2_T *)epw2buf;
}
num = 0;
while (*buf == '[') {
if (strncmp(buf, BOOK_ENTRY, strlen(BOOK_ENTRY))) {
fprintf(stderr, "ERR: line %d: 不明な項目です(%s)\n", line, buf);
err++;
while (getline(buf, fp) != NULL && *buf != '[')
;
if (*buf == '\0')
break;
continue;
}
if (type == EB && (uchr *)&eb[1] >= catbuf + BLKSIZ ||
type > EB && (uchr *)&epw[1] >= catbuf + BLKSIZ) {
fprintf(stderr, "ERR: line %d: 項目 %s の個数が多すぎます\n",
line, BOOK_ENTRY);
err++;
break;
}
mask = 0;
while (getline(buf, fp) != NULL && *buf != '[') {
if ((p = getvalue(buf)) == NULL) {
fprintf(stderr, "ERR: line %d: 構文に誤りがあります\n", line);
err++;
continue;
}
if (!strcmp(buf, BTAG_BOOKTYPE)) {
if ((mask & M_BOOKTYPE) != 0)
goto btag_dup;
mask |= M_BOOKTYPE;
t = (type == EB)? eb->booktype: epw->booktype;
if (gethex(t, p, B_BKTYPELEN) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, BTAG_TITLE)) {
if ((mask & M_TITLE) != 0)
goto btag_dup;
mask |= M_TITLE;
if (type == EB) {
t = eb->title;
len = B_TTLLEN_EB;
} else {
t = epw->title;
len = B_TTLLEN_EPW;
}
if (!EBGmode) {
if (getjstr(t, p, len) == ERR)
goto btag_invalid;
} else {
if (getstr(t, p, len) == ERR)
goto btag_invalid;
}
} else if (!strcmp(buf, BTAG_DIRECTORY)) {
if ((mask & M_DIRECTORY) != 0)
goto btag_dup;
mask |= M_DIRECTORY;
t = (type == EB)? eb->directory: epw->directory;
if (getstr(t, p, B_DIRLEN, F_SPACE) == ERR)
goto btag_invalid;
u = t;
for (i = 0; i < num; i++) {
u -= (type == EB)? sizeof(EB_T): sizeof(EPW_T);
if (!memcmp(t, u, B_DIRLEN)) {
fprintf(stderr,
"ERR: line %d: %s の値が重複しています(%s)\n",
line, buf, p);
err++;
break;
}
}
} else if (!strcmp(buf, BTAG_DIRPOS)) {
if (type < EPWING)
goto btag_epwonly;
if ((mask & M_DIRPOS) != 0)
goto btag_dup;
mask |= M_DIRPOS;
if (gethex(epw->dirpos, p, B_DPOSLEN_EPW) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, BTAG_INFOBLOCK)) {
if (type < EPWING)
goto btag_epwonly;
if ((mask & M_INFOBLOCK) != 0)
goto btag_dup;
mask |= M_INFOBLOCK;
if (gethex(epw->infoblock, p, B_INFBLEN_EPW) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, BTAG_APPDEF)) {
if (type < EPWING)
goto btag_epwonly;
if ((mask & M_APPDEF) != 0)
goto btag_dup;
mask |= M_APPDEF;
if (gethex(epw->appdef, p, B_APPLEN_EPW) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, BTAG_ZGAIJIFILE)) {
if (type < EPWING)
goto btag_epwonly;
if ((mask & M_ZGAIJIFILE) != 0)
goto btag_dup;
mask |= M_ZGAIJIFILE;
if (getstr(epw->zgaijifile, p, B_ZGAILEN_EPW, F_NUL) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, BTAG_HGAIJIFILE)) {
if (type < EPWING)
goto btag_epwonly;
if ((mask & M_HGAIJIFILE) != 0)
goto btag_dup;
mask |= M_HGAIJIFILE;
if (getstr(epw->hgaijifile, p, B_HGAILEN_EPW, F_NUL) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, B2TAG_RSV1)) {
if (type < EPWING2)
goto btag_epw2only;
if ((mask & M_RESERVED1) != 0)
goto btag_dup;
mask |= M_RESERVED1;
if (gethex(epw2->reserved1, p, B2_RSV1LEN) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, B2TAG_BKFILE)) {
if (type < EPWING2)
goto btag_epw2only;
if ((mask & M_BOOKFILE) != 0)
goto btag_dup;
mask |= M_BOOKFILE;
if (getstr(epw2->bookfile, p, B2_BKFILELEN, F_SPACE) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, B2TAG_PAD1)) {
if (type < EPWING2)
goto btag_epw2only;
if ((mask & M_PADDING1) != 0)
goto btag_dup;
mask |= M_PADDING1;
if (gethex(epw2->pad1, p, B2_PAD1LEN) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, B2TAG_STFILE)) {
if (type < EPWING2)
goto btag_epw2only;
if ((mask & M_STREAMFILE) != 0)
goto btag_dup;
mask |= M_STREAMFILE;
if (getstr(epw2->streamfile, p, B2_STFILELEN, F_SPACE) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, B2TAG_PAD2)) {
if (type < EPWING2)
goto btag_epw2only;
if ((mask & M_PADDING2) != 0)
goto btag_dup;
mask |= M_PADDING2;
if (gethex(epw2->pad2, p, B2_PAD2LEN) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, B2TAG_RSV2)) {
if (type < EPWING2)
goto btag_epw2only;
if ((mask & M_RESERVED2) != 0)
goto btag_dup;
mask |= M_RESERVED2;
if (gethex(epw2->reserved2, p, B2_RSV2LEN) == ERR)
goto btag_invalid;
} else if (!strcmp(buf, B2TAG_PAD3)) {
if (type < EPWING2)
goto btag_epw2only;
if ((mask & M_PADDING3) != 0)
goto btag_dup;
mask |= M_PADDING3;
if (gethex(epw2->pad3, p, B2_PAD3LEN) == ERR)
goto btag_invalid;
} else {
fprintf(stderr, "ERR: line %d: 不明のタグです(%s)\n",
line, buf);
err++;
continue;
}
continue;
btag_epwonly:
fprintf(stderr, "ERR: line %d: このタグはEPWING専用です(%s)\n",
line, buf);
err++;
continue;
btag_epw2only:
fprintf(stderr, "ERR: line %d: このタグはEPWING2以降専用です(%s)\n",
line, buf);
err++;
continue;
btag_dup:
fprintf(stderr, "ERR: line %d: タグが二重定義されています(%s)\n",
line, buf);
err++;
continue;
btag_invalid:
fprintf(stderr, "ERR: line %d: 値が不正です(%s)\n", line, p);
err++;
continue;
}
if (type >= EPWING && (mask & M_BOOKTYPE) == 0) {
fprintf(stderr, "ERR: line %d: %s が見つかりませんでした\n",
line, BTAG_BOOKTYPE);
err++;
}
if ((mask & M_TITLE) == 0) {
fprintf(stderr, "ERR: line %d: %s が見つかりませんでした\n",
line, BTAG_TITLE);
err++;
}
if ((mask & M_DIRECTORY) == 0) {
fprintf(stderr, "ERR: line %d: %s が見つかりませんでした\n",
line, BTAG_DIRECTORY);
err++;
}
if (type >= EPWING && (mask & M_INFOBLOCK) == 0) {
if (epw->booktype[0] != 0xf0) {
/*
* ストリーム書籍以外なら
* 書籍管理情報ブロックは
* 第1ブロックと仮定する
*/
epw->infoblock[1] = 0x01;
}
}
if (type == EB) {
eb++;
} else {
epw++;
epw2++;
}
num++;
}
hdr->books[0] = (num >> 8) & 0xff;
hdr->books[1] = num & 0xff;
if (st > num) {
fprintf(stderr, "ERR: %s の値が書籍数を超えています\n", CTAG_SELECT);
err++;
}
if (type >= EPWING2)
memcpy((char *)epw, epw2buf, sizeof(EPW2_T) * num);
fclose(fp);
if (err)
return ERR;
if ((fd = open(catalog, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, 0644)) < 0) {
fprintf(stderr, "%s が作成できません\n", catalog);
return ERR;
}
len = BLKSIZ;
if (type >= EPWING2) {
if (sizeof(HDR_T) + (sizeof(EPW_T) + sizeof(EPW2_T)) * num > BLKSIZ)
len = BLKSIZ * 2;
}
if (write(fd, (char *)catbuf, len) != len) {
fprintf(stderr, "書き込みに失敗しました\n");
close(fd);
return ERR;
}
close(fd);
return OK;
}
uchr *
getline(buf, fp)
uchr *buf;
FILE *fp;
{
for (;;) {
if (fgets(buf, BUFSIZ, fp) == NULL) {
*buf = '\0';
return NULL;
}
line++;
if (*buf != '\0' && *buf != '\n' && *buf != ';')
break;
}
buf[strlen(buf) - 1] = '\0';
return buf;
}
uchr *
getvalue(buf)
uchr *buf;
{
uchr *p, *q;
p = buf;
while (*p && *p != '=' && *p != ' ' && *p != '\t')
p++;
q = p;
while (*p == ' ' || *p == '\t')
p++;
if (*p != '=')
return NULL;
*q = '\0';
p++;
while (*p == ' ' || *p == '\t')
p++;
q = p;
if (*q == '"') {
q++;
while (*q && *q != '"') {
if (*q == '\\' && q[1])
q++;
q++;
}
if (*q != '"')
return NULL;
q++;
} else {
while (*q && *q != ' ' && *q != '\t')
q++;
}
*q = '\0';
return p;
}
int
gethex(buf, str, len)
uchr *buf, *str;
int len;
{
while (len-- > 0) {
if (!isxdigit(str[0]) || !isxdigit(str[1]))
break;
*buf = hexdigit(*str++) << 4;
*buf |= hexdigit(*str++);
buf++;
}
if (*str != '\0')
return ERR;
while (len-- > 0)
*buf++ = '\0';
return OK;
}
int
hexdigit(c)
int c;
{
if (c >= '0' && c <= '9')
return c - '0';
else if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
return -1;
}
int
getstr(buf, str, len, type)
uchr *buf, *str;
int len, type;
{
if (*str++ != '"')
return ERR;
while (len > 0) {
if (*str == '\0')
return ERR;
if (*str == '"')
break;
if (*str != '\\') {
*buf++ = *str++;
len--;
continue;
}
str++;
if (*str == '0') {
*buf++ = '\0';
str++;
} else if (*str == 'x' || *str == 'X') {
str++;
if (gethex(buf, str, 1) == ERR)
return ERR;
buf++;
str += 2;
} else {
*buf++ = *str++;
}
len--;
}
if (*str != '"')
return ERR;
if (type == F_NUL) {
while (len-- > 0)
*buf++ = '\0';
} else {
while (len-- > 0)
*buf++ = ' ';
}
return OK;
}
int
getjstr(buf, str, len)
uchr *buf, *str;
int len;
{
int c1, c2;
if (*str++ != '"')
return ERR;
#ifdef EUC
while (len > 0) {
if (*str == '\0')
return ERR;
if (*str == '"')
break;
if (*str < 0xa1 || *str > 0xfe || str[1] < 0xa1 || str[1] > 0xfe)
return ERR;
*buf++ = *str++ & 0x7f;
*buf++ = *str++ & 0x7f;
len -= 2;
}
#endif
#ifdef SJIS
while (len > 0) {
if (*str == '\0')
return ERR;
if (*str == '"')
break;
c1 = *str++;
c2 = *str++;
if (c1 < 0x81 || c1 > 0x9f && c1 < 0xe0 || c1 > 0xef)
return ERR;
if (c1 > 0x9f)
c1 -= 0x40;
c1 += c1;
if (c2 <= 0x9e) {
c1 -= 0xe1;
if (c2 >= 0x80)
c2 -= 1;
c2 -= 0x1f;
} else {
c1 -= 0xe0;
c2 -= 0x7e;
}
*buf++ = c1;
*buf++ = c2;
len -= 2;
}
#endif
if (*str != '"')
return ERR;
while (len-- > 0)
*buf++ = '\0';
return OK;
}
syntax highlighted by Code2HTML, v. 0.9.1