■ Macintosh から送信された添付ファイルを識別
/*
* inspect.c : Macintosh から送信された添付ファイルを識別
*
* Copyright (c) 2001 AOK.
*
* 2001.1.24 - 初版
*
* 使い方: INSPECT 入力ファイル名
*
* Macintosh を使っている友人から送られてきた添付ファイルが開けない
* 経験はありませんか。Macintosh は Windows と違い、ファイルに拡張
* 子をつける必要がありません。そのため、そのデータがどのような形式
* であるのかを拡張子のみで判断している Windows では解釈できないの
* です。たとえば、OutLook Express などのメールソフトで受信した時、
* 次のようなファイルが添付されていることはありませんか?
*
* %xxxxxxxx (nnn バイト)
* xxxxxxxx (mmm KB)
*
* これは、AppleDouble と呼ばれる形式で、2つでひとつのファイルを表
* しています。Windows で必要なのは下のファイルのみですが、そのファ
* イルに関するさまざまな情報が上のファイルに入っています。
* この頭に % のついたファイルを INSPECT.EXE にドラッグ&ドロップす
* るとファイルの様々な情報とともに、Macintosh 特有のファイルタイプ
* とクリエーターと呼ばれる識別子を読み取り、このデータを作成したア
* プリケーションとデータの形式、および、拡張子を推測します。
* 拡張子がわかれば、下のファイルにその拡張子を付けて保存して、該当
* するアプリケーションがインストールされている環境であれば開くこと
* が出来るようになります(該当するアプリケーションがない場合は開け
* ません)。また、拡張子が分からない場合でも、アプリケーションから
* 直接開くことが出来ます。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "applefil.h" /* original:applefile.h see:RFC1740 */
/* BIG-ENDIAN -> LITTLE-ENDIAN */
#define B2L32(x) (((x)>>24)|(((x)>>8)&0xFF00)|(((x)<<8)&0xFF0000)|((x)<<24))
#define B2L16(x) (((x)>>8)|((x)<<8))
#define LINE() puts("-------------------------------------------------------")
typedef struct {
char* text;
char* comment;
} DATA;
/* ファイル タイプのデータベース */
const DATA d_type[] = {
{ "..CT","サイテックスCT画像 (.sct)" },
{ "3DMF","QuickDraw 3D Meta File" },
{ "8BPS","Photoshop 画像 (.psd)" },
{ "????","タイプ不明" },
{ "AB65","Adobe Page Maker 6.5J (.p65)" },
{ "AD3D","Adobe Dimension書類" },
{ "AD3F","Adobe Dimensions (.dim)" },
{ "AGD2","FREEHAND 7.0J (.fh7)" },
{ "AGD3","FREEHAND 8.0J (.fh8)" },
{ "AIFC","AIFF圧縮サウンド" },
{ "AIFF","AIFFサウンド (.aiff)" },
{ "ALB2","Aldus Page Maker 2.0J" },
{ "ALB3","Aldus Page Maker 3.0J (.pm3)" },
{ "ALB4","Aldus Page Maker 4.0/4.5J (.pm4)" },
{ "ALB5","Aldus Page Maker 5.0J (.pm5)" },
{ "ALB6","Adobe Page Maker 6.0J (.pm6)" },
{ "ALTV","Quick View (.qv)" },
{ "APPL","アプリケーション" },
{ "ArCv","AutoSqueeze" },
{ "BINA","MS-DOSバイナリ形式" },
{ "BMPp","BMP形式 (.bmp)" },
{ "CDBJ","ClarisWorks J 4.0 データベース" },
{ "CGRJ","ClarisWorks J 4.0 ドロー" },
{ "COMP","ShrinkToFit" },
{ "CPTJ","ClarisWorks J 4.0 ペイント" },
{ "CSSJ","ClarisWorks J 4.0 表計算" },
{ "CWCM","ClarisWorks (Communication) (.cwk)" },
{ "CWDB","ClarisWorks (Database) (.cwk)" },
{ "CWGR","ClarisWorks (Drawing & Printing) (.cwk)" },
{ "CWPJ","ClarisWorks J 4.0 ワープロ" },
{ "CWSS","ClarisWorks (Spreadsheet) (.cwk)" },
{ "CWWP","ClarisWorks (Word Processing) (.cwk)" },
{ "DD01","DiskDoubler" },
{ "DDAR","DiskDoubler" },
{ "DDF.","DiskDoubler" },
{ "DDf.","DiskDoubler" },
{ "DEXE","Windowsアプリケーション(実行ファイル)" },
{ "EGD7","EGWord 8.0" },
{ "EPSF","EPSF画像 (.eps)" },
{ "EggP","Adobe After Effects (.aep)" },
{ "FMP3","FileMakerPro 3J" },
{ "Film","Film Strip形式" },
{ "GIFf","GIF画像 (.gif)" },
{ "Gzip","GNU Gzip 圧縮ファイル (.gz)" },
{ "HELP","Helpファイル" },
{ "ILBM","IFF形式 (.iff)" },
{ "JPEG","JPEG画像 (.jpg .jpeg)" },
{ "LARC","LHarc圧縮形式" },
{ "LHA ","LHa圧縮形式" },
{ "MPEG","MPEGファイル (.mpg .mpeg)" },
{ "MPG ","MPEGファイル" },
{ "MV93","MacroMedia Director 4.0ムービー" },
{ "MV95","MacroMedia Director 5.0ムービー" },
{ "MV97","Macromedia Director 6.0J (.dir)" },
{ "Midi","MIDI形式 (.mid)" },
{ "MooV","QuickTimeムービー (.mov .qt .qtvr)" },
{ "NSPL","Netscapeプラグイン" },
{ "PACT","CompactPro圧縮形式" },
{ "PCDI","Photo CD" },
{ "PDF ","PDF形式 (.pdf)" },
{ "PICS","PICS形式(連番PICT)" },
{ "PICT","PICT画像 (.pct .pict)" },
{ "PIT ","PackIt" },
{ "PNTG","Mac Paint画像" },
{ "PPSS", "PowerPoint 98 スライドショー" },
{ "PREF","プレファレンス" },
{ "PROJ","Adobe Premiere (.ppj)" },
{ "PRS2","Persuasion 3.0 2.1プレゼンテーション" },
{ "PRS3","Persuasion 3.0 プレゼンテーション" },
{ "PUBF","Aldus Page Maker 2.0 (.pub)" },
{ "PXR ","Pixar画像" },
{ "Pack","Diamond" },
{ "RIFF","Metacreation Painter 5.0J (.rif)" },
{ "SAnF","Scenary Animator書類" },
{ "SCRN","スタートアップスクリーン" },
{ "SIT!","StuffIt 1.5.1圧縮形式 (.sit)" },
{ "SIT2","StuffIt Deluxe圧縮形式" },
{ "SIT5","StuffIt アーカイブ (.sit)" },
{ "SITD","StuffIt Deluxe (.sit)" },
{ "SLD3","Microsoft PowerPoint 4.0 (.ppt)" },
{ "SLD8","Microsoft PowerPoint 98 (.ppt)" },
{ "SMED","SMI EDICOLOR 2.2J (.ec2)" },
{ "SPA ","Macromedia Flash 2J (.fla)" },
{ "SPn3","SuperPaint 3.5J" },
{ "STrk","サウンド (.mod)" },
{ "Smal","Compress It" },
{ "TARF","圧縮ファイル (.tar)" },
{ "TEXT","テキスト形式" },
{ "TIFF","TIFF画像 (.tif .tiff)" },
{ "TPIC","TGA画像 (.tga)" },
{ "TPIC","PIC形式 (X68000とは異なる)" },
{ "ULAW","オーディオ形式 (.au .snd .ulw)" },
{ "VWMD","MacroMedia Director 3.0ムービー" },
{ "W8BN","Microsoft Word 98 (.doc)" },
{ "WAVE","WAVEサウンド (.wav)" },
{ "WDBN","Microsoft Word (.doc)" },
{ "XDOC","Quark XPress 文書" },
{ "XLS ","Microsoft Excel (.xls)" },
{ "XLS3","Microsoft Excel (.xls)" },
{ "XLS4","Microsoft Excel ワークシート" },
{ "XLS5","Microsoft Excel ブック" },
{ "XLS8","Microsoft Excel 98 ワークシート" },
{ "XPRF","Metacreation Expressions (.xpr)" },
{ "XPRa","QuarkXPress 3.1J/3.3J (.qxd)" },
{ "WSit","ホームページPro3 サイト定義書類" },
{ "ZIP ","Zip圧縮ファイル (.zip)" },
{ "ZIVM","MacCompress(M) (.z)" },
{ "ZIVU","MacCompress(U)" },
{ "aCf2","Font Grapher書類" },
{ "cdev","コントロールパネル書類" },
{ "dDoc","MacDraw形式" },
{ "dImg","ディスクイメージ" },
{ "drw2","Canvas 3.5" },
{ "drw5","Canvas 5.0.2J" },
{ "drwt","Canvas 5.0.2J テンプレート" },
{ "jB1 ","Sound Edit 16 サウンド" },
{ "mArc","ArcMac" },
{ "pref","プレファレンス" },
{ "pzr2","Metacreation Poser 20J (.pzr)" },
{ "rsrc","リソースデータ" },
{ "ttro","TeachText Read Only形式" },
{ "zooM","Zoom" },
{ "","" }
};
/* クリエータのデータベース */
const DATA d_crtr[] = {
{ "8BIM","Adobe Photoshop 3.0J" },
{ "<SL>","Silverlining 5.6" },
{ "AD3D","Adobe Dimensions 2.0" },
{ "AFTB","Afterburner" },
{ "AI5J","Adobe Illustrator 5.5" },
{ "AK65","Adobe Page Maker 6.5J" },
{ "ALD2","Aldus Page Maker 2.0" },
{ "ALD3","Aldus Page Maker 3.0J" },
{ "ALD4","Aldus Page Maker 4.5" },
{ "ALK4","Aldus Page Maker 4.0/4.5J" },
{ "ALK5","Aldus Page Maker 5.0" },
{ "ALK6","Adobe Page Maker 6.0" },
{ "ALTV","Quick View" },
{ "ART3","Adobe Illustrator 3.0" },
{ "ART5","Adobe Illustrator 5.0/7.0" },
{ "ARTY","Adobe Illustrator 1.1" },
{ "ARTZ","Adobe Illustrator 88" },
{ "ASFL","Font Downloader" },
{ "BKCT","Magic Works Ver 2.0" },
{ "BOBO","ClarisWorks" },
{ "Blwd","ホームページPro3" },
{ "BnHq","BinHex 5.0" },
{ "Bry2","KPT Bryce 2" },
{ "CARO","Adobe Acrobat Reader 3.0" },
{ "CPCT","Compact Pro J-1.50" },
{ "CSOm","Eudora 1.3.8/Pro" },
{ "CWIE","Code Warrior IDE" },
{ "CWKJ","ClarisWorks J 4.0" },
{ "DAD5","Canvas 5.0.2J" },
{ "DDAP","DiskDoubler" },
{ "DSEA","DiskDoubler" },
{ "DSTL","Acrobat Distiller 3.0J" },
{ "EGW7","EGWord 8.0" },
{ "EWd3","KPT Bryce" },
{ "EXPr","Metacreation Expressions" },
{ "EXTR","Compactor" },
{ "Edt7","Edit 7" },
{ "FH70","FREEHAND 7.0J" },
{ "FH80","FREEHAND 8.0J" },
{ "FMJ3","File Maker Pro" },
{ "FSX3","Metacreation Painter 5.0J" },
{ "FTCh","Fetch" },
{ "FXTC","Adobe After Effects" },
{ "GJBU","MacBinary 1.0" },
{ "GKON","Graphic Converter" },
{ "GSBM","Drive 7" },
{ "Gzip","" },
{ "JEDT","Jedit" },
{ "JVWR","JPEGView" },
{ "Jdw ","Compress It" },
{ "LARC","MacLHa" },
{ "LVIn","LogoVista Internet" },
{ "LW3D","LightWave 3D Ver 5.0" },
{ "LWMD","LightWave 3D Ver 5.0" },
{ "LZIV","MacCompress" },
{ "MD93","MacroMedia Director 4" },
{ "MD95","MacroMedia Director 5" },
{ "MD97","Macromedia Director 6.0J" },
{ "MFL2","Macromedia Flash 2" },
{ "MGIC","Color Magicial III" },
{ "MMDR","MacroMedia Director 3" },
{ "MOSS","Netscape Navigator" },
{ "MRIP","TScript 4.0" },
{ "MSIE","Internet Explorer 3.0" },
{ "MSWD","Microsoft Word" },
{ "Mooz","Zoom" },
{ "PIT ","PackIt" },
{ "PLP2","Persuasion 3.0" },
{ "PLP3","Persuasion 3.0" },
{ "PNnu","Norton Utility" },
{ "PPT3","Microsoft PowerPoint" },
{ "Pack","Diamond" },
{ "Pnut","茄子R" },
{ "PrMr","Adobe Premiere" },
{ "RSED","Res Edit" },
{ "Roku","六角大王 Ver 5.5" },
{ "SAnP","Scenary Animator 1.2" },
{ "SCS!","SCSI Probe" },
{ "SEDA","SMI EDICOLOR 2.2J" },
{ "SIT!","StuffIt" },
{ "SITx","StuffIt Expander" },
{ "SNdm","" },
{ "SPNT","SuperPaint 3.5J" },
{ "STF ","ShrinkToFit" },
{ "STrk","" },
{ "StMl","Adobe PageMill" },
{ "TAR!","" },
{ "TVOD","Movie Player" },
{ "TrAS","AutoSqueeze" },
{ "UMcp","UMCP" },
{ "VIPR","Video Monitor Pro" },
{ "VisP","Vistapro" },
{ "WMLR","Will Mail" },
{ "Wrap","ShrinkWrap" },
{ "XCEL","Microsoft Excel" },
{ "XDOC","QuarkXPress 3.1J/3.3J" },
{ "XPRa","Quark Xpress 3.1" },
{ "ZBAS","Future BASIC 1.0x/II" },
{ "ZIP ","" },
{ "aCa2","Font Grapher 3.3" },
{ "arc*","ArcMac" },
{ "arc@","ArcMac" },
{ "aust","StuffIt" },
{ "cNif","ComNifty" },
{ "dPro","MacDraw Pro" },
{ "gfBr","GIF Builder" },
{ "jB・x","Sound Edit 16" },
{ "mMPG","MPEGファイル" },
{ "mPAK","Mpack 1.5J" },
{ "ttxt","SimpleText" },
{ "viOj","Metacreation Poser 2" },
{ "xxxX","Shade III Light 1.2.5" },
{ "zooM","Zoom" },
{ "","" }
};
ASHeader header; /* AppleSingle Header */
ASEntry *pentry = NULL;
const char *data_search(int flag, const char* s)
{
int i;
if (flag == 0)
{
for (i=0; i<sizeof(d_type)/sizeof(d_type[0]); i++)
{
if (strcmp(s, d_type[i].text) == 0)
return d_type[i].comment;
}
return d_type[i].comment;
}
else
{
for (i=0; i<sizeof(d_crtr)/sizeof(d_crtr[0]); i++)
{
if (strcmp(s, d_crtr[i].text) == 0)
return d_crtr[i].comment;
}
return d_crtr[i].comment;
}
return NULL;
}
int read_header(FILE *fp)
{
if (fread(&header.magicNum, sizeof(uint32), 1, fp) != 1)
return 0;
if (fread(&header.versionNum, sizeof(uint32), 1, fp) != 1)
return 0;
if (fread(&header.filler, sizeof(uchar8), 16, fp) != 16)
return 0;
if (fread(&header.numEntries, sizeof(uint16), 1, fp) != 1)
return 0;
header.magicNum = B2L32(header.magicNum);
header.versionNum = B2L32(header.versionNum);
header.numEntries = B2L16(header.numEntries);
if ((header.magicNum != 0x00051600) && (header.magicNum != 0x00051607))
{
printf("入力ファイルの形式が違います.\n");
return 0;
}
printf("ファイル形式:0x%08lX\n", header.magicNum);
printf("バージョン :0x%08lX\n", header.versionNum);
printf("エントリー数:%u\n", header.numEntries);
return 1;
}
int read_entries(FILE *fp)
{
int i;
pentry = (ASEntry *)malloc(sizeof(ASEntry) * header.numEntries);
if (pentry == NULL)
return 0;
if (fread(pentry, sizeof(ASEntry), header.numEntries, fp) != header.numEntries)
{
free(pentry);
pentry = NULL;
return 0;
}
for (i = 0; i < header.numEntries; i++)
{
(pentry+i)->entryID = B2L32((pentry+i)->entryID);
(pentry+i)->entryOffset = B2L32((pentry+i)->entryOffset);
(pentry+i)->entryLength = B2L32((pentry+i)->entryLength);
printf(" [%u] ID:%2lu Offset:0x%08lX Length:%6lu byte\n",
i+1, (pentry+i)->entryID, (pentry+i)->entryOffset, (pentry+i)->entryLength);
}
return 1;
}
void read_data(FILE *fp)
{
int i;
char *buf = NULL;
char type[5], crtr[5];
for (i = 0; i < header.numEntries; i++)
{
fseek(fp, (pentry+i)->entryOffset, SEEK_SET);
switch ((pentry+i)->entryID)
{
case AS_REALNAME:
buf = (char *)malloc((pentry+i)->entryLength + 1);
fread(buf, (pentry+i)->entryLength, 1, fp);
*(buf+(pentry+i)->entryLength) = '\0';
printf("ファイル名 :%s\n", buf);
free(buf);
break;
case AS_FINDERINFO:
fread(type, sizeof(char), 4, fp);
fread(crtr, sizeof(char), 4, fp);
type[4] = crtr[4] = '\0';
printf("タイプ :%s -> %s\n", type, data_search(0, type));
printf("クリエーター:%s -> %s\n", crtr, data_search(1, crtr));
break;
default:
break;
}
}
}
/* メインルーチン */
int main(int argc, char **argv)
{
FILE *fp = NULL;
char *p = NULL;
puts("AppleSingle Header Inspector Copyright (c) 2001 AOK");
if (argc < 2)
{
puts("Syntax is: INSPECT file");
return 0;
}
if ((fp = fopen(*++argv, "rb")) == NULL)
return 0;
LINE();
p = strrchr(*argv, '\\');
if (p != NULL)
printf("入力ファイル:%s\n", ++p);
LINE();
if (read_header(fp))
{
LINE();
if (read_entries(fp))
{
LINE();
read_data(fp);
free(pentry);
LINE();
}
}
fclose(fp);
return 0;
}