File indexing completed on 2018-03-02 18:44:48 UTC
view on githubraw file Latest commit ec6cf3b0 on 2003-08-26 20:45:25 UTC
ec6cf3b09d Ed H*0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 #include <stdio.h>
0050 #include <string.h>
0051 #include "macmpack.h" /* for copy_buf & watch */
0052
0053
0054 #define APPLESINGLE_MAGIC 0x00051600L
0055 #define APPLEDOUBLE_MAGIC 0x00051607L
0056 #define VERSION 0x00020000
0057 #define ENT_DFORK 1
0058 #define ENT_RFORK 2
0059 #define ENT_NAME 3
0060 #define ENT_COMMENT 4
0061 #define ENT_DATES 8
0062 #define ENT_FINFO 9
0063 #define CONVERT_TIME 1265437696L
0064
0065
0066 typedef struct ap_header {
0067 long magic;
0068 long version;
0069 char fill[16];
0070 short entries;
0071 } ap_header;
0072 typedef struct ap_entry {
0073 unsigned long id;
0074 unsigned long offset;
0075 unsigned long length;
0076 } ap_entry;
0077 typedef struct ap_dates {
0078 long create, modify, backup, access;
0079 } ap_dates;
0080
0081
0082 #define NUM_ENTRIES 6
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 int encode_applefile(FILE *outfile, HFileInfo *fpb, FILE *rfork, FILE *dfork)
0093 {
0094 ap_header head;
0095 ap_entry entries[NUM_ENTRIES];
0096 ap_dates dates;
0097 short i, count;
0098 long comlen, procID;
0099 DateTimeRec cur_time;
0100 unsigned long cur_secs;
0101 IOParam vinfo;
0102 GetVolParmsInfoBuffer vp;
0103 DTPBRec dtp;
0104 char comment[256];
0105
0106
0107 if (!rfork || !outfile) {
0108 if (rfork) fclose(rfork);
0109 if (dfork) fclose(dfork);
0110 if (outfile) fclose(outfile);
0111 return (-1);
0112 }
0113
0114
0115 procID = 0;
0116 GetWDInfo(fpb->ioVRefNum, &fpb->ioVRefNum, &fpb->ioDirID, &procID);
0117 memset((void *) &vinfo, '\0', sizeof (vinfo));
0118 vinfo.ioVRefNum = fpb->ioVRefNum;
0119 vinfo.ioBuffer = (Ptr) &vp;
0120 vinfo.ioReqCount = sizeof (vp);
0121 comlen = 0;
0122 if (PBHGetVolParmsSync((HParmBlkPtr) &vinfo) == noErr &&
0123 ((vp.vMAttrib >> bHasDesktopMgr) & 1)) {
0124 memset((void *) &dtp, '\0', sizeof (dtp));
0125 dtp.ioVRefNum = fpb->ioVRefNum;
0126 if (PBDTGetPath(&dtp) == noErr) {
0127 dtp.ioDTBuffer = (Ptr) comment;
0128 dtp.ioNamePtr = fpb->ioNamePtr;
0129 dtp.ioDirID = fpb->ioFlParID;
0130 if (PBDTGetCommentSync(&dtp) == noErr) comlen = dtp.ioDTActCount;
0131 }
0132 }
0133
0134
0135 head.magic = dfork ? APPLESINGLE_MAGIC : APPLEDOUBLE_MAGIC;
0136 head.version = VERSION;
0137 memset(head.fill, '\0', sizeof (head.fill));
0138 head.entries = NUM_ENTRIES - (dfork ? 0 : 1);
0139 fwrite((char *) &head, sizeof (head), 1, outfile);
0140
0141
0142 entries[0].offset = sizeof (head) + sizeof (ap_entry) * head.entries;
0143 entries[0].id = ENT_NAME;
0144 entries[0].length = *fpb->ioNamePtr;
0145 entries[1].id = ENT_FINFO;
0146 entries[1].length = sizeof (FInfo) + sizeof (FXInfo);
0147 entries[2].id = ENT_DATES;
0148 entries[2].length = sizeof (ap_dates);
0149 entries[3].id = ENT_COMMENT;
0150 entries[3].length = comlen;
0151 entries[4].id = ENT_RFORK;
0152 entries[4].length = fpb->ioFlRLgLen;
0153 entries[5].id = ENT_DFORK;
0154 entries[5].length = fpb->ioFlLgLen;
0155 for (i = 1; i < NUM_ENTRIES; ++i) {
0156 entries[i].offset = entries[i-1].offset + entries[i-1].length;
0157 }
0158 fwrite((char *) entries, sizeof (ap_entry), head.entries, outfile);
0159
0160
0161 fwrite((char *) fpb->ioNamePtr + 1, *fpb->ioNamePtr, 1, outfile);
0162
0163 fwrite((char *) &fpb->ioFlFndrInfo, sizeof (FInfo), 1, outfile);
0164 fwrite((char *) &fpb->ioFlXFndrInfo, sizeof (FXInfo), 1, outfile);
0165
0166 GetTime(&cur_time);
0167 Date2Secs(&cur_time, &cur_secs);
0168 dates.create = fpb->ioFlCrDat + CONVERT_TIME;
0169 dates.modify = fpb->ioFlMdDat + CONVERT_TIME;
0170 dates.backup = fpb->ioFlBkDat + CONVERT_TIME;
0171 dates.access = cur_secs + CONVERT_TIME;
0172 fwrite((char *) &dates, sizeof (ap_dates), 1, outfile);
0173
0174 if (comlen) fwrite(comment, sizeof (char), comlen, outfile);
0175
0176 while ((count = fread(copy_buf, sizeof (char), sizeof (copy_buf), rfork)) > 0) {
0177 fwrite(copy_buf, sizeof (char), count, outfile);
0178 }
0179 fclose(rfork);
0180
0181 if (dfork) {
0182 while ((count = fread(copy_buf, sizeof (char), sizeof (copy_buf), dfork)) > 0) {
0183 fwrite(copy_buf, sizeof (char), count, outfile);
0184 }
0185 fclose(dfork);
0186 }
0187
0188 return (0);
0189 }
0190
0191
0192
0193
0194
0195
0196 int decode_applefile(FILE *infile, FSSpec *fspec)
0197 {
0198 ap_header head;
0199 ap_entry entries[NUM_ENTRIES + 1];
0200 ap_dates dates;
0201 StandardFileReply reply;
0202 int i, j;
0203 short refnum;
0204 long count;
0205 OSErr err;
0206 HFileInfo *fpb;
0207 CInfoPBRec cipbr;
0208 long procID;
0209 IOParam vinfo;
0210 GetVolParmsInfoBuffer vp;
0211 DTPBRec dtp;
0212 char comment[256];
0213
0214
0215 fread((char *) &head, sizeof (head), 1, infile);
0216 if (head.magic != APPLESINGLE_MAGIC && head.magic != APPLEDOUBLE_MAGIC) {
0217 return (-1);
0218 }
0219 if (head.version != VERSION) {
0220 return (-1);
0221 }
0222
0223
0224 for (i = j = 0; i < head.entries; ++i) {
0225 fread((char *) (entries + j), sizeof (ap_entry), 1, infile);
0226 if (j < NUM_ENTRIES) switch (entries[j].id) {
0227 case ENT_NAME:
0228 case ENT_FINFO:
0229 case ENT_DATES:
0230 case ENT_COMMENT:
0231 case ENT_RFORK:
0232 case ENT_DFORK:
0233 ++j;
0234 break;
0235 }
0236 }
0237
0238
0239 for (i = 0; i < j && entries[i].id != ENT_NAME; ++i);
0240 if (i == j) return (-1);
0241 fseek(infile, entries[i].offset, SEEK_SET);
0242 if (entries[i].length > 63) entries[i].length = 63;
0243 *fspec->name = fread((char *) fspec->name + 1, sizeof (char), entries[i].length, infile);
0244 SetCursor(&arrow);
0245 NAputFile("\pSave decoded file as:", fspec->name, &reply);
0246 SetCursor(&watch);
0247 statrefresh();
0248 if (!reply.sfGood) return (didchat = -1);
0249 *fspec = reply.sfFile;
0250
0251
0252 if (reply.sfReplacing) HDelete(fspec->vRefNum, fspec->parID, fspec->name);
0253 if (HCreate(fspec->vRefNum, fspec->parID, fspec->name, '????', '????') != noErr) {
0254 return (-1);
0255 }
0256 fpb = (HFileInfo *) &cipbr;
0257 fpb->ioVRefNum = fspec->vRefNum;
0258 fpb->ioNamePtr = fspec->name;
0259 fpb->ioDirID = fspec->parID;
0260 fpb->ioFDirIndex = 0;
0261 PBGetCatInfoSync(&cipbr);
0262
0263
0264 for (i = 0; i < j && entries[i].id != ENT_FINFO; ++i);
0265 if (i < j) {
0266 fseek(infile, entries[i].offset, SEEK_SET);
0267 fread((char *) &fpb->ioFlFndrInfo, sizeof (FInfo), 1, infile);
0268 fread((char *) &fpb->ioFlXFndrInfo, sizeof (FXInfo), 1, infile);
0269 fpb->ioFlFndrInfo.fdFlags &= 0xf800;
0270 }
0271
0272
0273 for (i = 0; i < j && entries[i].id != ENT_DATES; ++i);
0274 if (i < j) {
0275 fseek(infile, entries[i].offset, SEEK_SET);
0276 fread((char *) &dates, sizeof (dates), 1, infile);
0277 fpb->ioFlCrDat = dates.create - CONVERT_TIME;
0278 fpb->ioFlMdDat = dates.modify - CONVERT_TIME;
0279 fpb->ioFlBkDat = dates.backup - CONVERT_TIME;
0280 }
0281
0282
0283 fpb->ioDirID = fpb->ioFlParID;
0284 PBSetCatInfoSync(&cipbr);
0285
0286
0287 for (i = 0; i < j && entries[i].id != ENT_COMMENT; ++i);
0288 if (i < j && entries[i].length != 0) {
0289 memset((void *) &vinfo, '\0', sizeof (vinfo));
0290 vinfo.ioVRefNum = fpb->ioVRefNum;
0291 vinfo.ioBuffer = (Ptr) &vp;
0292 vinfo.ioReqCount = sizeof (vp);
0293 if (PBHGetVolParmsSync((HParmBlkPtr) &vinfo) == noErr &&
0294 ((vp.vMAttrib >> bHasDesktopMgr) & 1)) {
0295 memset((void *) &dtp, '\0', sizeof (dtp));
0296 dtp.ioVRefNum = fpb->ioVRefNum;
0297 if (PBDTGetPath(&dtp) == noErr) {
0298 if (entries[i].length > 255) entries[i].length = 255;
0299 fseek(infile, entries[i].offset, SEEK_SET);
0300 fread(comment, entries[i].length, 1, infile);
0301 dtp.ioDTBuffer = (Ptr) comment;
0302 dtp.ioNamePtr = fpb->ioNamePtr;
0303 dtp.ioDirID = fpb->ioDirID;
0304 dtp.ioDTReqCount = entries[i].length;
0305 if (PBDTSetCommentSync(&dtp) == noErr) {
0306 PBDTFlushSync(&dtp);
0307 }
0308 }
0309 }
0310 }
0311
0312
0313 for (i = 0; i < j; ++i) {
0314 if (entries[i].id == ENT_RFORK || entries[i].id == ENT_DFORK) {
0315 fseek(infile, entries[i].offset, SEEK_SET);
0316 if (entries[i].id == ENT_DFORK) {
0317 err = HOpen(fspec->vRefNum, fspec->parID, fspec->name, 2, &refnum);
0318 } else {
0319 err = HOpenRF(fspec->vRefNum, fspec->parID, fspec->name, 2, &refnum);
0320 }
0321 if (err != noErr) {
0322 HDelete(fspec->vRefNum, fspec->parID, fspec->name);
0323 return (-1);
0324 }
0325 while (entries[i].length > sizeof (copy_buf)) {
0326 count = fread(copy_buf, sizeof (char), sizeof (copy_buf), infile);
0327 entries[i].length -= count;
0328 FSWrite(refnum, &count, (Ptr) copy_buf);
0329 }
0330 count = fread(copy_buf, sizeof (char), entries[i].length, infile);
0331 FSWrite(refnum, &count, (Ptr) copy_buf);
0332 FSClose(refnum);
0333 }
0334 }
0335
0336 return (0);
0337 }