File indexing completed on 2018-03-02 18:44:51 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 #include <Folders.h>
0030 #include <Script.h>
0031 #include <GestaltEqu.h>
0032
0033 #include <stdio.h>
0034 #include <time.h>
0035 #include <string.h>
0036 #include <ctype.h>
0037 #include "version.h"
0038 #include "part.h"
0039 #include "macnapp.h"
0040 #include "macmpack.h"
0041 #include "macICTypes.h"
0042 #include "macICAPI.h"
0043 #include "macICKeys.h"
0044
0045
0046 #include <ansi_private.h>
0047
0048
0049 #define DECODELIST 1
0050 #define PREFWIN 2
0051
0052
0053 Cursor watch;
0054
0055
0056 struct pref_folder *pfolder = NULL;
0057 struct mpack_preferences **mpack_prefs = NULL;
0058 static ICInstance icinst = NULL;
0059
0060
0061 static WindowPtr helpw = NULL;
0062
0063
0064 static na_win *curstatwin = NULL;
0065 short didchat;
0066
0067
0068 static short tcpstart = 0;
0069
0070
0071 SFTypeList textList = { 'TEXT', 0, 0, 0 };
0072
0073
0074
0075 typedef struct filelist {
0076 short vRefNum;
0077 long dirID;
0078 PCstr fname[65];
0079 } filelist;
0080 typedef struct listwin {
0081 na_win win;
0082 int count;
0083 filelist **hflist;
0084 ListHandle l;
0085 } listwin;
0086
0087
0088
0089 typedef struct statuswin {
0090 na_win win;
0091 RgnHandle urgn;
0092 Rect urect;
0093 Rect frect;
0094 short row;
0095 short nrow;
0096 long size, used;
0097 Handle text;
0098 ControlHandle sb;
0099 short height, ascent;
0100 } statuswin;
0101
0102
0103
0104 typedef struct encodewin {
0105 nate_win w;
0106 Boolean nateon;
0107 Boolean useemail;
0108 long partsize;
0109 OSType ftype;
0110 FSSpec fspec;
0111 FSSpec ofile;
0112 } encodewin;
0113
0114
0115
0116 typedef struct progresswin {
0117 natcp_win w;
0118 short percent;
0119 } progresswin;
0120
0121
0122
0123 typedef struct mailwin {
0124 progresswin w;
0125 Handle headers;
0126 Handle envelope;
0127 short state;
0128 short remaining;
0129 Boolean sending;
0130 Boolean useemail;
0131 Boolean gothost;
0132 long partsize;
0133 long dirID;
0134 OSType ftype;
0135 FSSpec fspec;
0136 FSSpec ofile;
0137 FILE *dfile;
0138 PCstr server[257];
0139 PCstr subj[257];
0140 CInfoPBRec cpb;
0141 } mailwin;
0142
0143
0144 #define MS_MACTCP 0
0145 #define MS_GETHOST 1
0146 #define MS_ENCODE 2
0147 #define MS_SENDING 3
0148
0149
0150 void warn(char *str);
0151 void stattext(Str255, unsigned char);
0152 static void do_decodefiles(na_win *);
0153 static void addfile(listwin *, FSSpec *);
0154 static void removefile(listwin *);
0155 static short listclose(na_win *);
0156 static short listmouse(na_win *, Point, short, short);
0157 static short listctrl(na_win *, Point, short, short, ControlHandle);
0158 static short listupdate(na_win *, Boolean);
0159 static short listinit(na_win *,long *);
0160 static short prefsctrl(na_win *, Point, short, short, ControlHandle);
0161 static short prefsinit(na_win *, long *);
0162 static void do_decode(FSSpec *);
0163 static void do_encode(FSSpec *, OSType);
0164 static short mainmenu(struct na_win*, WORD, WORD);
0165
0166 #define dwin ((listwin *) win)
0167 #define swin ((statuswin *) win)
0168 #define ewin ((encodewin *) win)
0169 #define twin ((nate_win *) win)
0170 #define prwin ((progresswin *) win)
0171 #define mwin ((mailwin *) win)
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187 FILE *Macopen(FILE *sample, Str255 name, short vRefNum, long dirID,
0188 short binary_flag, short res_fork, SignedByte permission)
0189 {
0190 FILE *fp = NULL;
0191 short refnum;
0192 long curEOF;
0193 OSErr err;
0194
0195 if ((!res_fork && (err = HOpen(vRefNum, dirID, name, permission, &refnum)) == noErr)
0196 || (res_fork && (err = HOpenRF(vRefNum, dirID, name, permission, &refnum)) == noErr)) {
0197 if ((fp = __getfile()) == NULL) {
0198 FSClose(refnum);
0199 } else {
0200 if (permission == fsWrPerm) {
0201
0202 SetEOF(refnum, curEOF = 0);
0203 } else {
0204 GetEOF(refnum, &curEOF);
0205 }
0206 fp->refnum = refnum;
0207 fp->len = (fpos_t) curEOF;
0208 fp->binary = binary_flag;
0209 setvbuf(fp, NULL, _IOFBF, BUFSIZ);
0210 fp->proc = sample->proc;
0211 }
0212 }
0213
0214 return (fp);
0215 }
0216
0217
0218
0219
0220 void warn(char *str)
0221 {
0222 PCstr wstr[257];
0223
0224 CtoPCstrncpy(wstr, str, 255);
0225 ParamText(P(wstr), NULL, NULL, NULL);
0226 NAalert(warnALRT);
0227 }
0228
0229
0230
0231 void yell(char *str)
0232 {
0233 PCstr wstr[257];
0234
0235 CtoPCstrncpy(wstr, str, 255);
0236 ParamText(P(wstr), NULL, NULL, NULL);
0237 NAalert(errorALRT);
0238 }
0239
0240
0241
0242 chat(char *str)
0243 {
0244 PCstr tmpstr[257];
0245
0246 CtoPCstrcpy(tmpstr, str);
0247 stattext(P(tmpstr), 0);
0248 }
0249
0250
0251
0252 static short alldone(na_win *win)
0253 {
0254 if (win->next == NULL && win->afterp == NULL && (*mpack_prefs)->quit_finished
0255 && RecoverHandle((Ptr) win) == (Handle) NAhead) {
0256 return (NA_ALLCLOSED);
0257 }
0258
0259 return (NA_CLOSED);
0260 }
0261
0262
0263
0264 static short statupdate(na_win *win, Boolean newsize)
0265 {
0266 RgnHandle savergn;
0267 unsigned char *s;
0268 short row, top;
0269 Rect tmpr;
0270
0271 FrameRect(&swin->frect);
0272 savergn = NewRgn();
0273 if (savergn) {
0274 GetClip(savergn);
0275 SetClip(swin->urgn);
0276 }
0277
0278
0279 HLock(swin->text);
0280 s = * (unsigned char **) swin->text;
0281 top = swin->urect.top;
0282 for (row = 0; row < swin->row; ++row) {
0283 s += s[1] + 2;
0284 }
0285 for (; row < swin->nrow && top + swin->height <= swin->urect.bottom; ++row) {
0286 MoveTo(swin->urect.left, top + swin->ascent);
0287 if (*s) TextFace(1);
0288 DrawString(s + 1);
0289 if (*s) TextFace(0);
0290
0291 top += swin->height;
0292 s += s[1] + 2;
0293 }
0294 HUnlock(swin->text);
0295
0296 if (savergn) {
0297 SetClip(savergn);
0298 DisposeRgn(savergn);
0299 }
0300
0301 return (NA_NOTPROCESSED);
0302 }
0303
0304
0305
0306 void statrefresh()
0307 {
0308 na_win *win = curstatwin;
0309
0310 Draw1Control(swin->sb);
0311 statupdate(win, false);
0312 }
0313
0314
0315
0316 void stattext(Str255 str, unsigned char bold)
0317 {
0318 na_win *win = curstatwin;
0319 short i, len;
0320 unsigned char *s, *start;
0321 RgnHandle rgn;
0322 Rect tmpr;
0323
0324 if (!win) return;
0325 didchat = 1;
0326
0327
0328 if (swin->height * (swin->nrow++ - swin->row)
0329 >= swin->urect.bottom - swin->urect.top) {
0330 SetCtlMax(swin->sb, ++swin->row);
0331 SetCtlValue(swin->sb, swin->row);
0332 if ((rgn = NewRgn()) != NULL) {
0333 tmpr = swin->urect;
0334 ScrollRect(&tmpr, 0, -swin->height, rgn);
0335 DisposeRgn(rgn);
0336 }
0337 }
0338
0339
0340 len = * (unsigned char *) str;
0341 if (swin->size - swin->used < len + 1) {
0342 SetHandleSize(swin->text, swin->size * 2);
0343 if (MemError() == 0) swin->size *= 2;
0344 }
0345 HLock(swin->text);
0346 s = start = * (unsigned char **) swin->text;
0347 for (i = 1; i < swin->nrow; ++i) {
0348 s += s[1] + 2;
0349 }
0350 if (len + 2 + s < start + swin->size) {
0351 *s = bold;
0352 memcpy(s + 1, str, len + 1);
0353 swin->used = s + len + 2 - start;
0354 }
0355 HUnlock(swin->text);
0356 statupdate(win, false);
0357 }
0358
0359
0360
0361 static void statscroll(na_win *win, short rows)
0362 {
0363 RgnHandle rgn;
0364
0365 if ((rgn = NewRgn()) != NULL) {
0366 SetCtlValue(swin->sb, swin->row += rows);
0367 ScrollRect(&swin->urect, 0, - swin->height * rows, rgn);
0368 EraseRgn(rgn);
0369 DisposeRgn(rgn);
0370 }
0371 statupdate(win, false);
0372 }
0373
0374
0375
0376 static pascal void statscollbar(ControlHandle ctrlh, short part)
0377 {
0378 na_win *win = (na_win *) GetCRefCon(ctrlh);
0379 short max, new, page;
0380
0381 max = GetCtlMax(ctrlh);
0382 page = (swin->urect.bottom - swin->urect.top) / swin->height - 1;
0383 switch (part) {
0384 case inUpButton:
0385 page = 1;
0386
0387 case inPageUp:
0388 if (swin->row > 0) {
0389 statscroll(win, - (swin->row < page ? swin->row : page));
0390 }
0391 break;
0392 case inDownButton:
0393 page = 1;
0394
0395 case inPageDown:
0396 if (swin->row < max) {
0397 statscroll(win, max - swin->row < page ? max - swin->row : page);
0398 }
0399 break;
0400 case inThumb:
0401 break;
0402 }
0403 }
0404
0405
0406
0407 static short statctrl(na_win *win, Point p, short item, short mods, ControlHandle ctrlh)
0408 {
0409 short value;
0410
0411 if (ctrlh == swin->sb) {
0412 ctrlh = swin->sb;
0413 if (item != inThumb) {
0414 SetCRefCon(ctrlh, (long) win);
0415 TrackControl(ctrlh, p, statscollbar);
0416 } else {
0417 TrackControl(ctrlh, p, nil);
0418 value = GetCtlValue(ctrlh);
0419 if (value != swin->row) statscroll(win, value - swin->row);
0420 }
0421 } else if (item == iOk) {
0422 return (NA_REQCLOSE);
0423 }
0424
0425 return (NA_NOTPROCESSED);
0426 }
0427
0428
0429
0430 static short statclose(na_win *win)
0431 {
0432 DisposeRgn(swin->urgn);
0433 DisposHandle(swin->text);
0434 DisposeControl(swin->sb);
0435
0436 return (alldone(win));
0437 }
0438
0439
0440
0441 static short statinit(na_win *win, long *data)
0442 {
0443 Rect tmpr;
0444 FontInfo finfo;
0445
0446
0447 NAhiliteDItem(win->pwin, iOk, 255);
0448
0449
0450 if ((swin->urgn = NewRgn()) == NULL) return (NA_CLOSED);
0451 TextFont(geneva);
0452 TextSize(9);
0453 GetFontInfo(&finfo);
0454 swin->ascent = finfo.ascent;
0455 swin->height = finfo.ascent + finfo.descent + finfo.leading;
0456 NAgetDRect(win->pwin, iStatus, &swin->frect);
0457 swin->urect = swin->frect;
0458 InsetRect(&swin->urect, 2,
0459 2 + ((swin->urect.bottom - swin->urect.top - 4) % swin->height) / 2);
0460 RectRgn(swin->urgn, &swin->urect);
0461
0462
0463 if ((swin->text = NewHandle(swin->size = 1024)) == NULL) {
0464 DisposeRgn(swin->urgn);
0465 return (NA_CLOSED);
0466 }
0467 **(char **)swin->text = '\0';
0468
0469
0470 NAgetDRect(win->pwin, iStatScroll, &tmpr);
0471 swin->sb = NewControl(win->pwin, &tmpr, "\p", true, 0, 0, 0, scrollBarProc, 0);
0472 if (!swin->sb) {
0473 DisposeRgn(swin->urgn);
0474 DisposHandle(swin->text);
0475 return (NA_CLOSED);
0476 }
0477
0478
0479 win->closep = statclose;
0480 win->ctrlp = statctrl;
0481 win->updatep = statupdate;
0482
0483
0484 ++win->locks;
0485 curstatwin = win;
0486
0487 return (NA_NOTPROCESSED);
0488 }
0489
0490
0491
0492 static void do_decodefiles(na_win *win)
0493 {
0494 int count = dwin->count;
0495 filelist *fl;
0496 FILE *dfile, *tmpf;
0497 extern long _ftype, _fcreator;
0498 long ticks;
0499 int result;
0500
0501 MapTypeCreator("text/plain", 0);
0502 SetCursor(&watch);
0503 if (NAwindow(0, NA_DIALOGWINDOW | NA_TITLEBAR | NA_DEFBUTTON | NA_USERESOURCE
0504 | NA_CLOSEBOX | NA_HASCONTROLS,
0505 0, dstatDLOG, 0, sizeof (statuswin), statinit) == NA_CLOSED) {
0506 warn("Not enough memory to decode");
0507 return;
0508 }
0509 MoveHHi((Handle) dwin->hflist);
0510 HLock((Handle) dwin->hflist);
0511 fl = *dwin->hflist;
0512 tmpf = tmpfile();
0513 while (count--) {
0514 stattext(fl->fname, 1);
0515 didchat = 0;
0516 if (dfile = Macopen(tmpf, fl->fname, fl->vRefNum, fl->dirID, 0, 0, 1)) {
0517 result = handleMessage(part_init(dfile), "text/plain",
0518 0, (*mpack_prefs)->extract_text);
0519 if (result != 0 || didchat <= 0) {
0520 if (didchat < 0) {
0521 chat("Decoding cancelled");
0522 } else {
0523 chat("Found nothing to decode");
0524 }
0525 }
0526 fclose(dfile);
0527 } else {
0528 chat("Couldn't find source file");
0529 }
0530 ++fl;
0531 }
0532 fclose(tmpf);
0533 HUnlock((Handle) dwin->hflist);
0534 NAhiliteDItem(curstatwin->pwin, iOk, 0);
0535 NAunlockWindow(curstatwin);
0536 curstatwin = NULL;
0537 SetCursor(&arrow);
0538 DisposHandle((Handle) dwin->hflist);
0539 }
0540
0541
0542
0543 static int fprefixMatch(char *base, PCstr *match)
0544 {
0545 PCstr temp[257];
0546 char *scan;
0547 short prefixlen;
0548
0549 PtoPCstrcpy(temp, base);
0550 scan = C(temp) + PCstrlen(temp) - 1;
0551 while (isdigit(*scan) && scan > C(temp)) --scan;
0552 prefixlen = scan - C(temp) + 1;
0553 if (strncmp(C(temp), C(match), prefixlen)) return (0);
0554 scan = C(match) + prefixlen;
0555 while (isdigit(*scan)) ++scan;
0556
0557 return (!*scan);
0558 }
0559
0560
0561
0562 static void addit(listwin *dw, short vRefNum, long dirID, char *fname)
0563 {
0564 long size = GetHandleSize((Handle) dw->hflist) / sizeof (filelist);
0565 filelist *fl;
0566 char *bp;
0567 Cell c;
0568 int i;
0569 PCstr fbuf[42];
0570
0571 if (size == dw->count) {
0572 SetHandleSize((Handle) dw->hflist, (++size * sizeof (filelist)));
0573 if (MemError() != noErr) return;
0574 }
0575 MoveHHi((Handle) dw->hflist);
0576 HLock((Handle) dw->hflist);
0577 fl = *dw->hflist;
0578 for (i = dw->count; i; --i, ++fl) {
0579 if (fl->vRefNum == vRefNum && fl->dirID == dirID &&
0580 *fl->fname == *fname && !strncmp(C(fl->fname), C(fname), *fl->fname)) {
0581 break;
0582 }
0583 }
0584 if (!i) {
0585 fl->vRefNum = vRefNum;
0586 fl->dirID = dirID;
0587 PtoPCstrcpy(fl->fname, fname);
0588 SetPt(&c, 0, dw->count);
0589 LAddRow(1, ++dw->count, dw->l);
0590 LSetCell((Ptr) C(fname), (short) Pstrlen(fname), c, dw->l);
0591 }
0592 HUnlock((Handle) dw->hflist);
0593 }
0594
0595
0596
0597 static void addfile(dw, fspec)
0598 listwin *dw;
0599 FSSpec *fspec;
0600 {
0601 CInfoPBRec cipbr;
0602 HFileInfo *fpb = (HFileInfo *)&cipbr;
0603 PCstr fbuf[42];
0604 short idx, foundone = 0;
0605 long procid;
0606
0607
0608 if (fspec->parID == 0) {
0609 GetWDInfo(fspec->vRefNum, &fspec->vRefNum, &fspec->parID, &procid);
0610 }
0611
0612
0613 for (idx = 1; ; ++idx) {
0614 fpb->ioVRefNum = fspec->vRefNum;
0615 fpb->ioNamePtr = P(fbuf);
0616 fpb->ioDirID = fspec->parID;
0617 fpb->ioFDirIndex = idx;
0618 if (PBGetCatInfoSync(&cipbr)) break;
0619 SetClen(fbuf);
0620
0621 if (!(fpb->ioFlAttrib & 16) && fprefixMatch((char *)fspec->name, fbuf)) {
0622 addit(dw, fspec->vRefNum, fspec->parID, (char *) P(fbuf));
0623 foundone = 1;
0624 }
0625 }
0626 if (!foundone) {
0627 addit(dw, fspec->vRefNum, fspec->parID, (char *) fspec->name);
0628 }
0629 }
0630
0631
0632
0633 static void removefile(dw)
0634 listwin *dw;
0635 {
0636 filelist *fl;
0637 int count;
0638 Cell c;
0639
0640 c.h = c.v = 0;
0641 if (LGetSelect(TRUE, &c, dw->l)) {
0642 MoveHHi((Handle) dw->hflist);
0643 HLock((Handle) dw->hflist);
0644 fl = *dw->hflist + c.v;
0645 count = dw->count - c.v;
0646 while (--count) {
0647 fl[0] = fl[1];
0648 ++fl;
0649 }
0650 HUnlock((Handle) dw->hflist);
0651 --dw->count;
0652 LDelRow(1, c.v, dw->l);
0653 }
0654 }
0655
0656
0657
0658 static short listclose(win)
0659 na_win *win;
0660 {
0661 LDispose(dwin->l);
0662
0663 return (alldone(win));
0664 }
0665
0666
0667
0668 static short listmouse(na_win *win, Point p, short type, short mods)
0669 {
0670 Cell c;
0671
0672 if (!(type & 1)) {
0673 LClick(p, mods, dwin->l);
0674 c.h = c.v = 0;
0675 NAhiliteDItem((DialogPtr)win->pwin, iRemove, LGetSelect(TRUE, &c, dwin->l) ? 0 : 255);
0676 }
0677
0678 return (NA_NOTPROCESSED);
0679 }
0680
0681
0682
0683 static short listctrl(na_win *win, Point p, short item, short mods, ControlHandle ctrlh)
0684 {
0685 StandardFileReply reply;
0686
0687 switch (item) {
0688 case iAdd:
0689 NAgetFile(NULL, 1, textList, &reply);
0690 if (reply.sfGood) {
0691 if (!dwin->count) {
0692 NAhiliteDItem((DialogPtr)win->pwin, iOk, 0);
0693 }
0694 addfile(dwin, &reply.sfFile);
0695 }
0696 return (NA_PROCESSED);
0697
0698 case iRemove:
0699 removefile(dwin);
0700 NAhiliteDItem((DialogPtr)win->pwin, iRemove, 255);
0701 if (!dwin->count) {
0702 NAhiliteDItem((DialogPtr)win->pwin, iOk, 255);
0703 }
0704 return (NA_PROCESSED);
0705
0706 case iOk:
0707 win->afterp = do_decodefiles;
0708 case iCancel:
0709 return (NA_REQCLOSE);
0710 }
0711
0712 return (NA_NOTPROCESSED);
0713 }
0714
0715
0716
0717 static short listupdate(na_win *win, Boolean resize)
0718 {
0719 Rect r;
0720
0721 NAgetDRect(win->pwin, iFileList, &r);
0722 FrameRect(&r);
0723 LUpdate(win->pwin->visRgn, dwin->l);
0724
0725 return (NA_NOTPROCESSED);
0726 }
0727
0728
0729
0730 static short listinit(win, data)
0731 na_win *win;
0732 long *data;
0733 {
0734 FSSpec *fspec = (FSSpec *) data;
0735 Rect r, zrect;
0736 Point p;
0737 Handle hand;
0738 short type;
0739
0740 GetDItem((DialogPtr)win->pwin, iFileList, &type, &hand, &r);
0741 InsetRect(&r, 1, 1);
0742 zrect.top = zrect.bottom = zrect.left = p.h = p.v = 0;\
0743 zrect.right = 1;
0744 dwin->l = LNew(&r, &zrect, p, 0, win->pwin, 0, 0, 0, 1);
0745 if (!dwin->l) return (NA_CLOSED);
0746 (*dwin->l)->selFlags = lOnlyOne;
0747 dwin->hflist = (filelist **) NewHandle(sizeof (filelist));
0748 if (!dwin->hflist) {
0749 LDispose(dwin->l);
0750 return (NA_CLOSED);
0751 }
0752 dwin->count = 0;
0753 addfile(dwin, fspec);
0754 win->closep = listclose;
0755 win->updatep = listupdate;
0756 win->ctrlp = listctrl;
0757 win->mousep = listmouse;
0758 win->type = DECODELIST;
0759 NAhiliteDItem((DialogPtr)win->pwin, iRemove, 255);
0760 ShowWindow(win->pwin);
0761 LDoDraw(TRUE, dwin->l);
0762
0763 return (NA_NOTPROCESSED);
0764 }
0765
0766
0767
0768 static void do_decode(FSSpec *fspec)
0769 {
0770 StandardFileReply infile;
0771 na_win **wh, *wp;
0772
0773 if (!fspec) {
0774 NAgetFile(NULL, 1, textList, &infile);
0775 if (!infile.sfGood) return;
0776 fspec = &infile.sfFile;
0777 } else {
0778
0779 for (wh = NAhead; wh && (*wh)->type != DECODELIST; wh = (*wh)->next);
0780 if (wh && (wp = NAlockWindow(wh)) != NULL) {
0781 addfile((listwin *) wp, fspec);
0782 NAunlockWindow(wp);
0783 return;
0784 }
0785 }
0786 NAwindow(0, NA_DIALOGWINDOW | NA_USERESOURCE | NA_DEFBUTTON |
0787 NA_HASCONTROLS | NA_CLOSEBOX, NULL, decodeDLOG, (long *) fspec,
0788 sizeof (listwin), listinit);
0789 }
0790
0791
0792
0793 void MapTypeCreator(char *contenttype, OSType type)
0794 {
0795 extern long _ftype, _fcreator;
0796 PCstr tstr[257];
0797 Handle h;
0798 ICAttr attr;
0799 long size = 0;
0800 Ptr map;
0801 ICMapEntry *ment;
0802 unsigned char *scan, *end, *pstr;
0803 short mapcount, i, foundit = 0;
0804 OSType temp;
0805
0806 if (!type) CtoPCstrncpy(tstr, contenttype, 255);
0807
0808
0809 if (icinst && ICBegin(icinst, icReadOnlyPerm) == noErr) {
0810 if (ICGetPref(icinst, kICMapping, &attr, nil, &size) == noErr
0811 && size > 0 && (map = NewPtr(size)) != nil) {
0812 if (ICGetPref(icinst, kICMapping, &attr, map, &size) == noErr) {
0813 scan = (unsigned char *) map;
0814 end = scan + size;
0815 while (scan < end) {
0816 ment = (ICMapEntry *) scan;
0817 pstr = scan + ment->fixed_length;
0818 scan += ment->total_length;
0819 if (type && ment->file_type != type) continue;
0820 pstr += *pstr + 1;
0821 pstr += *pstr + 1;
0822 pstr += *pstr + 1;
0823 if (type) {
0824 PtoPCstrcpy((PCstr *) contenttype, (char *) pstr);
0825 foundit = 1;
0826 break;
0827 } else if (EqualString(P(tstr), pstr, false, true)) {
0828 _ftype = ment->file_type;
0829 _fcreator = ment->file_creator;
0830 foundit = 1;
0831 break;
0832 }
0833 }
0834 }
0835 DisposPtr(map);
0836 }
0837 ICEnd(icinst);
0838 }
0839
0840
0841 if (!foundit) {
0842 if (type) {
0843 mapcount = CountResources('TyCr');
0844 for (i = 1; i <= mapcount; ++i) {
0845 h = GetIndResource('TyCr', i);
0846 if (h && **(OSType **)h == type) {
0847 GetResInfo(h, &i, &temp, P(contenttype));
0848 if (ResError() == noErr) break;
0849 }
0850 }
0851 SetClen((PCstr *) contenttype);
0852 } else {
0853 h = GetNamedResource('TyCr', P(tstr));
0854 if (h) {
0855 _ftype = (*(OSType **)h)[0];
0856 _fcreator = (*(OSType **)h)[1];
0857 } else {
0858 _ftype = '????';
0859 _fcreator = 'mPAK';
0860 }
0861 }
0862 }
0863 }
0864
0865
0866
0867 static short getICprefs(na_win *win, PCstr *eaddr, PCstr *smtphost)
0868 {
0869 char *scan, *end;
0870 ICAttr attr;
0871 long size;
0872 ICError err = noErr;
0873
0874 *C(eaddr) = '\0';
0875 SetPlen(eaddr);
0876 *C(smtphost) = '\0';
0877 SetPlen(smtphost);
0878 if (icinst && ICBegin(icinst, icReadOnlyPerm) == noErr) {
0879 size = 256;
0880 if (ICGetPref(icinst, kICEmail, &attr, (Ptr) eaddr, &size) == noErr
0881 && win && (attr & ICattr_locked_mask)) {
0882 NAenableDItem(win->pwin, iEmailAddr, 0);
0883 }
0884 SetClen(eaddr);
0885 size = 256;
0886 if (ICGetPref(icinst, kICSMTPHost, &attr, (Ptr) smtphost, &size) == noErr
0887 && win && (attr & ICattr_locked_mask)) {
0888 NAenableDItem(win->pwin, iMailServer, 0);
0889 }
0890 SetClen(smtphost);
0891 ICEnd(icinst);
0892 } else {
0893 HLock((Handle) mpack_prefs);
0894 end = (char *) (*mpack_prefs) + GetHandleSize((Handle) mpack_prefs);
0895 scan = (*mpack_prefs)->internet_host;
0896 while (scan < end && *scan++);
0897 if (scan < end) CtoPCstrcpy(eaddr, scan);
0898 while (scan < end && *scan++);
0899 if (scan < end) CtoPCstrcpy(smtphost, scan);
0900 HUnlock((Handle) mpack_prefs);
0901 }
0902 }
0903
0904
0905
0906 static short copydesc(FILE *out, TEHandle hTE)
0907 {
0908 char c;
0909 short i, count, word, col, reset;
0910 char **htxt;
0911
0912 count = (*hTE)->teLength;
0913 htxt = (char **) (*hTE)->hText;
0914 for (i = word = col = 0; i < count; ++i) {
0915 c = (*htxt)[i];
0916 reset = i - word == 80 || c == '\r';
0917 if (reset || c == ' ') {
0918 while (word < i) putc((*htxt)[word], out), ++word;
0919 }
0920 if (reset || ++col == 80) {
0921 putc('\r', out);
0922 c = (*htxt)[word];
0923 if (c == ' ' || c == '\r') ++word;
0924 col = 0;
0925 }
0926 }
0927 while (word < i) putc((*htxt)[word], out), ++word;
0928 rewind(out);
0929 }
0930
0931
0932
0933 static void mytcpinit(short status)
0934 {
0935 static DialogPtr dialog = NULL;
0936 GrafPtr save;
0937 Rect box;
0938
0939 if (status < 0) {
0940 tcpstart = -1;
0941 } else if (status == 0) {
0942 tcpstart = 1;
0943 } else {
0944 if (!dialog && status < 100) {
0945 dialog = GetNewDialog(progDLOG, nil, (WindowPtr) -1);
0946 NAsetIText(dialog, iWorkText, "\pWaiting for MacTCP to finish. Press \021. to stop.");
0947 }
0948 if (dialog) {
0949 GetPort(&save);
0950 SetPort(dialog);
0951 NAgetDRect(dialog, iProgress, &box);
0952 FrameRect(&box);
0953 InsetRect(&box, 1, 1);
0954 box.right = box.left + (box.right - box.left) * status / 100;
0955 FillRect(&box, qd.dkGray);
0956 SetPort(save);
0957 if (status == 100) {
0958 DisposDialog(dialog);
0959 dialog = NULL;
0960 }
0961 }
0962 }
0963 }
0964
0965
0966
0967 static short progressupdate(na_win *win, Boolean newsize)
0968 {
0969 Rect box;
0970
0971 if (prwin->percent >= 0) {
0972 NAgetDRect(win->pwin, iProgress, &box);
0973 FrameRect(&box);
0974 InsetRect(&box, 1, 1);
0975 if (prwin->percent) {
0976 box.right = box.left + (box.right - box.left) * prwin->percent / 100;
0977 FillRect(&box, qd.dkGray);
0978 } else {
0979 EraseRect(&box);
0980 }
0981 }
0982
0983 return (NA_NOTPROCESSED);
0984 }
0985
0986
0987
0988 static short progressctrl(na_win *win, Point p, short item, short mods,
0989 ControlHandle ctrlh)
0990 {
0991 return (item == iCancel ? NA_REQCLOSE : NA_NOTPROCESSED);
0992 }
0993
0994
0995
0996 static short progressclose(na_win *win)
0997 {
0998 NAmodalMenus(0);
0999
1000 return (NA_CLOSED);
1001 }
1002
1003
1004
1005 static OSErr prefsubdir(PCstr *name, long *dirID)
1006 {
1007 CInfoPBRec cipbr;
1008 DirInfo *dpb = &cipbr.dirInfo;
1009 long subdir, dir;
1010 short vref = pfolder->fspec.vRefNum;
1011 OSErr err;
1012
1013 err = DirCreate(vref, dir = pfolder->fspec.parID, P(name), &subdir);
1014 if (err == dupFNErr) {
1015 dpb->ioVRefNum = vref;
1016 dpb->ioNamePtr = P(name);
1017 dpb->ioDrDirID = dir;
1018 dpb->ioFDirIndex = 0;
1019 if ((err = PBGetCatInfoSync(&cipbr)) != noErr) return (err);
1020 subdir = dpb->ioDrDirID;
1021 } else if (err != noErr) {
1022 return (err);
1023 }
1024 *dirID = subdir;
1025
1026 return (noErr);
1027 }
1028
1029
1030
1031 static void smtpstat(void *wh, short code, short err, long num, char *errstr)
1032 {
1033 na_win *win, **winh;
1034 char msg[256];
1035 OSErr oserr = noErr;
1036
1037
1038 for (winh = NAhead; winh && winh != wh; winh = (*winh)->next);
1039 if (!winh) return;
1040
1041
1042 win = NAlockWindow((na_win **) wh);
1043 if (code == NASMTP_progress) {
1044 prwin->percent = err;
1045 progressupdate(win, false);
1046 } else if (code == NASMTP_badaddr) {
1047 sprintf(msg, "Invalid address: <%s>. Email will be sent to valid recipients.",
1048 errstr);
1049 yell(msg);
1050 } else {
1051 switch (code) {
1052 case NASMTP_nomem:
1053 yell("Not enough memory to send email");
1054 break;
1055 case NASMTP_tcpfail:
1056 yell("Failed to connect to mail host");
1057 break;
1058 case NASMTP_temperr:
1059 case NASMTP_permerr:
1060 sprintf(msg, "Delivery failed: %s", errstr);
1061 yell(msg);
1062 break;
1063 default:
1064 yell("Mail delivery failed.");
1065 case NASMTP_completed:
1066 break;
1067 }
1068 mwin->sending = false;
1069 oserr = HDelete(mwin->fspec.vRefNum, mwin->fspec.parID, mwin->fspec.name);
1070 }
1071 if (oserr != noErr && oserr != fnfErr) {
1072 if (mwin->remaining) ++mwin->cpb.hFileInfo.ioFDirIndex;
1073 yell("Unable to remove temporary email file.");
1074 }
1075 NAunlockWindowh((na_win **) wh, win);
1076 }
1077
1078
1079
1080 static void mailhost(void *user, na_tcp s, short status, long size, char *data)
1081 {
1082 struct mpack_preferences *mp;
1083 char *ihost;
1084 na_win *win, **winh;
1085 long len, oldsize;
1086
1087
1088 for (winh = NAhead; winh && winh != user; winh = (*winh)->next);
1089 if (!winh) return;
1090 win = NAlockWindow(winh);
1091
1092
1093 if (status != NATCP_connect) {
1094 warn("Failed to get hostname from MacTCP");
1095 } else {
1096 mwin->gothost = true;
1097 if (data[size - 1] == '.') --size;
1098
1099
1100 len = strlen((*mpack_prefs)->internet_host);
1101 oldsize = GetHandleSize((Handle) mpack_prefs);
1102 if (len < size) {
1103 SetHandleSize((Handle) mpack_prefs, oldsize + (size - len));
1104 if (MemError() != noErr) return;
1105 }
1106 HLock((Handle) mpack_prefs);
1107 mp = *mpack_prefs;
1108 ihost = mp->internet_host;
1109 memmove(ihost + size + 1, ihost + len + 1,
1110 oldsize - len - 1 - ((char *) ihost - (char *) mp));
1111 memcpy(ihost, data, size);
1112 ihost[size] = '\0';
1113 HUnlock((Handle) mpack_prefs);
1114 }
1115 NAunlockWindowh(winh, win);
1116 }
1117
1118
1119
1120 static short mailclose(na_win *win)
1121 {
1122 if (mwin->dfile != NULL) fclose(mwin->dfile);
1123 if (mwin->envelope) DisposeHandle(mwin->envelope);
1124 if (mwin->headers) DisposeHandle(mwin->headers);
1125 NAmodalMenus(0);
1126
1127 return (alldone(win));
1128 }
1129
1130
1131
1132 static short mailtask(na_win *win)
1133 {
1134 short vrefnum, encoding, refnum, result;
1135 long procid;
1136 FILE *tmpf, *fp, *resfork;
1137 OSErr err;
1138 CInfoPBRec cipbr;
1139 HFileInfo *fpb = (HFileInfo *)&cipbr;
1140 PCstr tstr[257], mtype[257], fname[257];
1141 extern long _ftype, _fcreator;
1142
1143 switch (mwin->state) {
1144 case MS_MACTCP:
1145 if (tcpstart < 0) {
1146 yell("Couldn't find MacTCP");
1147 return (NA_REQCLOSE);
1148 }
1149 if (tcpstart == 0) break;
1150 ++mwin->state;
1151 NAsetIText(win->pwin, iWorkText, "\pGetting Hostname");
1152 mwin->gothost = false;
1153 NATCPgethost(mailhost, (void *) GetWRefCon(win->pwin));
1154
1155 case MS_GETHOST:
1156 if (!mwin->gothost) break;
1157 ++mwin->state;
1158
1159 case MS_ENCODE:
1160 NAsetIText(win->pwin, iWorkText, "\pEncoding file");
1161
1162
1163 if (mwin->useemail) {
1164 mwin->ofile.vRefNum = pfolder->fspec.vRefNum;
1165 memcpy(mwin->ofile.name, "\pemail", 6);
1166 if (prefsubdir("\poutgoing-email", &mwin->ofile.parID) != noErr) {
1167 yell("Failed to write encoded file");
1168 return (NA_REQCLOSE);
1169 }
1170 }
1171
1172
1173 SetCursor(&watch);
1174 MapTypeCreator((char *) mtype, mwin->ftype);
1175
1176
1177 encoding = (*mpack_prefs)->encoding;
1178 fpb->ioVRefNum = mwin->fspec.vRefNum;
1179 fpb->ioNamePtr = mwin->fspec.name;
1180 fpb->ioDirID = mwin->fspec.parID;
1181 fpb->ioFDirIndex = 0;
1182 if (PBGetCatInfoSync(&cipbr) != noErr) {
1183 SetCursor(&arrow);
1184 yell("File disappeared before being encoded!");
1185 return (NA_REQCLOSE);
1186 }
1187 if (encoding == EN_AUTO) {
1188 encoding = EN_DOUBLE;
1189 if (!fpb->ioFlRLgLen && *mtype != '\0') encoding = EN_DATA;
1190 }
1191 if (!fpb->ioFlLgLen) encoding = EN_SINGLE;
1192
1193
1194 tmpf = tmpfile();
1195 fp = Macopen(tmpf, mwin->fspec.name, mwin->fspec.vRefNum, mwin->fspec.parID,
1196 strcmp(C(mtype), "text/plain") ? 1 : 0, 0, fsRdPerm);
1197 if (!fp) {
1198 fclose(tmpf);
1199 SetCursor(&arrow);
1200 yell("Couldn't save encoded file");
1201 return (NA_REQCLOSE);
1202 }
1203 if (encoding == EN_DATA) {
1204 fclose(tmpf);
1205 tmpf = NULL;
1206 } else {
1207
1208 resfork = Macopen(tmpf, mwin->fspec.name, mwin->fspec.vRefNum,
1209 mwin->fspec.parID, 1, 1, 1);
1210 if (encode_applefile(tmpf, fpb, resfork, encoding == EN_SINGLE ? fp : NULL) < 0) {
1211 SetCursor(&arrow);
1212 yell("Couldn't save encoded file");
1213 return (NA_REQCLOSE);
1214 }
1215 rewind(tmpf);
1216 if (encoding == EN_SINGLE) {
1217 fp = tmpf;
1218 tmpf = NULL;
1219 strcpy(C(mtype), "application/applefile");
1220 SetPlen(mtype);
1221 }
1222 }
1223
1224
1225 _fcreator = 'mPAK';
1226 _ftype = 'TEXT';
1227 GetVol(0, &vrefnum);
1228 err = OpenWD(mwin->ofile.vRefNum, mwin->ofile.parID, 0, &refnum);
1229 SetVol(0, err == noErr ? refnum : mwin->ofile.vRefNum);
1230 PtoPCstrcpy(tstr, (char *) mwin->ofile.name);
1231 PtoPCstrcpy(fname, (char *) mwin->fspec.name);
1232 result = encode(fp, tmpf, C(fname), mwin->dfile, C(mwin->subj), NULL,
1233 mwin->partsize, PCstrlen(mtype) ? C(mtype) : NULL, C(tstr));
1234 if (err == noErr) CloseWD(refnum);
1235 SetVol(0, vrefnum);
1236 if (tmpf) fclose(tmpf);
1237 fclose(fp);
1238 if (mwin->dfile) {
1239 fclose(mwin->dfile);
1240 mwin->dfile = NULL;
1241 }
1242 SetCursor(&arrow);
1243 if (!mwin->useemail) return (NA_REQCLOSE);
1244 prwin->percent = 0;
1245 progressupdate(win, false);
1246 ++mwin->state;
1247
1248
1249 mwin->cpb.dirInfo.ioVRefNum = mwin->ofile.vRefNum;
1250 mwin->cpb.dirInfo.ioDrDirID = mwin->dirID = mwin->ofile.parID;
1251 mwin->cpb.dirInfo.ioFDirIndex = -1;
1252 if (PBGetCatInfoSync(&mwin->cpb) != noErr) {
1253 return (NA_CLOSED);
1254 }
1255 mwin->remaining = mwin->cpb.dirInfo.ioDrNmFls;
1256 mwin->cpb.dirInfo.ioFDirIndex = 1;
1257
1258 case MS_SENDING:
1259 if (mwin->sending) break;
1260 if (!mwin->remaining) return (NA_REQCLOSE);
1261 sprintf(C(tstr), "Email parts remaining to submit: %d", mwin->remaining--);
1262 SetPlen(tstr);
1263 NAsetIText(win->pwin, iWorkText, tstr);
1264 prwin->percent = 0;
1265 progressupdate(win, false);
1266 mwin->cpb.hFileInfo.ioDirID = mwin->dirID;
1267 mwin->cpb.hFileInfo.ioNamePtr = (StringPtr) &mwin->fspec.name;
1268 if (PBGetCatInfoSync(&mwin->cpb) != noErr) {
1269 yell("Email disappeared before submission!");
1270 return (NA_REQCLOSE);
1271 }
1272 mwin->sending = true;
1273 mwin->fspec.vRefNum = mwin->cpb.hFileInfo.ioVRefNum;
1274 mwin->fspec.parID = mwin->dirID;
1275 NASMTPsubmit(smtpstat, C(mwin->server), &mwin->fspec,
1276 mwin->headers, mwin->envelope,
1277 NASMTP_crtrans, (void *) GetWRefCon(win->pwin));
1278 break;
1279 }
1280
1281 return (NA_NOTPROCESSED);
1282 }
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294 void rfc822_date(char *string)
1295 {
1296 long tz, tzm;
1297 time_t ti = time (0);
1298 struct tm *t = localtime (&ti);
1299 MachineLocation loc;
1300
1301
1302 strcpy(string, "Date: ");
1303 string += 6;
1304 strftime (string,1024,"%a, %d %b %Y %H:%M:%S ",t);
1305
1306 tz = 0;
1307 if (Gestalt(gestaltScriptMgrVersion, &tz) == noErr && tz >= 200) {
1308 ReadLocation(&loc);
1309
1310 tz = (loc.gmtFlags.gmtDelta & 0x00ffffff) |
1311 ((loc.gmtFlags.gmtDelta & 0x00800000) ? 0xff000000 : 0);
1312 tz /= 60;
1313 tzm = tz % 60;
1314 sprintf (string += strlen(string),"%+03ld%02ld",
1315 tz/60,tzm >= 0 ? tzm : -tzm);
1316 if (!tzm && tz <= -240 && tz >= -660) {
1317 string += strlen(string);
1318 if (loc.gmtFlags.dlsDelta & 0x80) {
1319 sprintf(string, " (%cDT)", "AECMPYHB"[- (tz / 60) - 3]);
1320 } else {
1321 sprintf(string, " (%cST)", "AECMPYHB"[- (tz / 60) - 4]);
1322 }
1323 }
1324 } else {
1325 sprintf(string + strlen(string), "+0000 (Local Time Zone Unknown)");
1326 }
1327 }
1328
1329
1330
1331 static short mailinit(na_win *win, long *data)
1332 {
1333 encodewin *ew = (encodewin *) data;
1334 WindowPtr pwin = ew->w.winp.pwin;
1335 ControlHandle ctrlh;
1336 PCstr tstr[257], email[257];
1337
1338
1339 NAgetIText(pwin, iSubj, mwin->subj);
1340 NAgetIText(pwin, iEmailto, email);
1341 mwin->partsize = ew->partsize;
1342 mwin->useemail = ew->useemail;
1343 mwin->fspec = ew->fspec;
1344 mwin->ftype = ew->ftype;
1345 mwin->ofile = ew->ofile;
1346
1347
1348 mwin->dfile = NULL;
1349 if ((*ew->w.hTE)->teLength && (mwin->dfile = tmpfile()) != NULL) {
1350 copydesc(mwin->dfile, ew->w.hTE);
1351 }
1352
1353
1354 win->taskp = mailtask;
1355 win->updatep = progressupdate;
1356 win->ctrlp = progressctrl;
1357 win->closep = mailclose;
1358
1359
1360 prwin->percent = -1;
1361 NAgetDHandle(win->pwin, iCancel, &ctrlh);
1362 SetCTitle(ctrlh, "\pStop");
1363 NAmodalMenus(1);
1364 if (!mwin->useemail) {
1365 mwin->state = MS_ENCODE;
1366 } else {
1367 if (!tcpstart) NATCPinit(mytcpinit);
1368 NAsetIText(win->pwin, iWorkText, "\pLooking for MacTCP");
1369 mwin->state = MS_MACTCP;
1370
1371
1372 getICprefs(NULL, tstr, mwin->server);
1373 if (PtrToHand(C(tstr), &mwin->envelope, PCstrlen(tstr) + 1) != noErr
1374 || PtrAndHand(C(email), mwin->envelope, PCstrlen(email) + 1) != noErr) {
1375 if (mwin->envelope) DisposeHandle(mwin->envelope);
1376 return (NA_CLOSED);
1377 }
1378
1379
1380 if ((mwin->headers = NewHandle(1024)) == NULL) {
1381 DisposeHandle(mwin->envelope);
1382 return (NA_CLOSED);
1383 }
1384 HLock(mwin->headers);
1385 rfc822_date((char *) *mwin->headers);
1386 sprintf((char *) (*mwin->headers) + strlen((char *) (*mwin->headers)),
1387 "\r\nFrom: %s\r\nTo: %s\r\n", C(tstr), C(email));
1388 HUnlock(mwin->headers);
1389 SetHandleSize(mwin->headers, strlen((char *) (*mwin->headers)));
1390 }
1391
1392 return (NA_NOTPROCESSED);
1393 }
1394
1395
1396
1397 static short encodeupdate(na_win *win, Boolean newsize)
1398 {
1399 Rect btmp;
1400 ControlHandle ctrlh;
1401
1402
1403 NAgetDRect(win->pwin, iBar, &btmp);
1404 FrameRect(&btmp);
1405
1406
1407 NAgetDHandle(win->pwin, iLimit, &ctrlh);
1408 if (!GetCtlValue(ctrlh)) {
1409 NAhiliteDItem(win->pwin, iPartLimit, 255);
1410 }
1411 if (NAradioGet(win->pwin, iEmail, iSavefile) == iSavefile) {
1412 NAhiliteDItem(win->pwin, iEmailto, 255);
1413 }
1414
1415 return (NATEupdatep(win, newsize));
1416 }
1417
1418
1419
1420 static short seldesctext(na_win *win)
1421 {
1422 win->activep = NATEactivep;
1423 win->idlep = NATEidlep;
1424 NATEactivep(win, true);
1425 ewin->nateon = true;
1426 SelIText(win->pwin, iDescEdit, 0, 0);
1427 TESetSelect(32767, 32767, twin->hTE);
1428 }
1429
1430
1431
1432 static short encodectrl(na_win *win, Point p, short item,
1433 short mods, ControlHandle ctrlh)
1434 {
1435 short value;
1436 DialogPeek dpeek = (DialogPeek) win->pwin;
1437 char *scan;
1438 Boolean good;
1439 StandardFileReply reply;
1440 PCstr tstr[257];
1441
1442 if (ctrlh == twin->vctrl) {
1443 return (NATEctrlp(win, p, item, mods, ctrlh));
1444 }
1445 switch (item) {
1446 case iOk:
1447
1448 ewin->partsize = 0;
1449 NAgetDHandle(win->pwin, iLimit, &ctrlh);
1450 if (GetCtlValue(ctrlh)) {
1451 NAgetIText(win->pwin, iPartLimit, tstr);
1452 ewin->partsize = atol(C(tstr)) * 1000;
1453 }
1454 NAgetIText(win->pwin, iEmailto, tstr);
1455 ewin->useemail = NAradioGet(win->pwin, iEmail, iSavefile) == iEmail;
1456 if (ewin->useemail) {
1457
1458 if (!strchr(C(tstr), '@')) {
1459 yell("Invalid Email address, please re-enter");
1460 SelIText(win->pwin, iEmailto, 0, 32767);
1461 break;
1462 }
1463 } else {
1464
1465 PtoPCstrcpy(tstr, (char *) ewin->fspec.name);
1466 if (PCstrlen(tstr) > 23) {
1467 PCstrlen(tstr) = 23;
1468 SetClen(tstr);
1469 }
1470 strcat(C(tstr), ".mime");
1471 SetPlen(tstr);
1472 do {
1473 NAputFile(ewin->partsize ? "\pPart prefix" : "\pEmail file:",
1474 tstr, &reply);
1475 good = true;
1476 if (reply.sfGood
1477 && EqualString(reply.sfFile.name,
1478 ewin->fspec.name, true, false)) {
1479 good = false;
1480 yell("The output filename must be different from the input filename");
1481 }
1482 } while (!good);
1483 if (!reply.sfGood) break;
1484 ewin->ofile = reply.sfFile;
1485 }
1486 if (NAwindow(0, NA_DIALOGWINDOW | NA_TITLEBAR | NA_HASTASK
1487 | NA_USERESOURCE | NA_MODAL, NULL, progDLOG,
1488 (long *) win, sizeof (mailwin), mailinit) == NA_CLOSED) {
1489 warn("Not enough memory to proceed");
1490 break;
1491 }
1492 case iCancel:
1493 return (NA_REQCLOSE);
1494 case iEmail:
1495 case iSavefile:
1496 NAradioSet(win->pwin, iEmail, iSavefile, item);
1497 NAenableDItem(win->pwin, iEmailto, item == iEmail ? 1 : 0);
1498 NAhiliteDItem(win->pwin, iEmailto, item == iEmail ? 0 : 255);
1499 if (item == iEmail || dpeek->editField == iEmailto - 1) {
1500 SelIText(win->pwin, item == iEmail ? iEmailto : iSubj, 0, 32767);
1501 }
1502 break;
1503 case iLimit:
1504 SetCtlValue(ctrlh, value = !GetCtlValue(ctrlh));
1505 NAenableDItem(win->pwin, iPartLimit, value ? 1 : 0);
1506 NAhiliteDItem(win->pwin, iPartLimit, value ? 0 : 255);
1507 if (value || dpeek->editField == iPartLimit - 1) {
1508 SelIText(win->pwin, value ? iPartLimit : iSubj, 0, 32767);
1509 }
1510 break;
1511 case iDescEdit:
1512 case iSubj:
1513 case iEmailto:
1514 case iPartLimit:
1515 if (!ewin->nateon && dpeek->editField == iDescEdit - 1) {
1516 seldesctext(win);
1517 }
1518 break;
1519 }
1520 if (ewin->nateon && dpeek->editField != iDescEdit - 1) {
1521 win->activep = NULL;
1522 win->idlep = NULL;
1523 NATEactivep(win, false);
1524 ewin->nateon = false;
1525 }
1526
1527 return (NA_NOTPROCESSED);
1528 }
1529
1530
1531
1532 static short encodekey(na_win *win, long c, short mods)
1533 {
1534 if (!(mods & cmdKey)) {
1535 if (ewin->nateon && c != '\t' && c != '\n' && c != '\3' && c != '\033') {
1536 return (NATEkeyp(win, c, mods));
1537 }
1538 }
1539
1540 return (NA_NOTPROCESSED);
1541 }
1542
1543
1544
1545 static short encodemenu(na_win *win, WORD menu, WORD item)
1546 {
1547 StandardFileReply descfile;
1548 MenuHandle mf = NAmenuh(mFile);
1549 short result = NA_NOTPROCESSED;
1550 short refnum;
1551 long size;
1552 Ptr text;
1553 Boolean success;
1554
1555 switch (menu) {
1556 case 0:
1557 EnableItem(mf, iInsert);
1558
1559 case mEdit:
1560 result = ewin->nateon ? NATEmenup(win, menu, item)
1561 : NAdialogMenu(win, menu, item);
1562 break;
1563 case mFile:
1564 if (item != iInsert) break;
1565 result = NA_PROCESSED;
1566 NAgetFile(NULL, 1, textList, &descfile);
1567 if (!descfile.sfGood) break;
1568 if (HOpen(descfile.sfFile.vRefNum, descfile.sfFile.parID,
1569 descfile.sfFile.name, fsRdPerm, &refnum) != noErr) {
1570 warn("Failed to open file");
1571 break;
1572 }
1573 text = NULL;
1574 success = GetEOF(refnum, &size) == noErr && (text = NewPtr(size)) != NULL
1575 && FSRead(refnum, &size, text) == noErr;
1576 if (success) {
1577 TEInsert(text, size, twin->hTE);
1578 TESelView(twin->hTE);
1579 NATEsetscroll(win, false, (Rect*) NULL, (Rect*) NULL);
1580 } else {
1581 warn("Failed to read file");
1582 }
1583 if (text) DisposPtr(text);
1584 FSClose(refnum);
1585 break;
1586 }
1587 if (menu != 0) DisableItem(mf, iInsert);
1588
1589 return (result);
1590 }
1591
1592
1593
1594 static short encodemouse(na_win *win, Point p, short type, short mods)
1595 {
1596 if (p.v >= twin->topoff && !ewin->nateon) seldesctext(win);
1597
1598 return (NATEmousep(win, p, type, mods));
1599 }
1600
1601
1602
1603 static short encodeclose(na_win *win)
1604 {
1605 NATEclosep(win);
1606
1607 return (NA_CLOSED);
1608 }
1609
1610
1611
1612 static short encodeinit(na_win *win, long *data)
1613 {
1614 StandardFileReply *sf = (StandardFileReply *) data;
1615 Rect rtmp, btmp;
1616 FontInfo finfo;
1617
1618
1619 ewin->fspec = sf->sfFile;
1620 ewin->ftype = sf->sfType;
1621
1622
1623 NAgetDRect(win->pwin, iBar, &btmp);
1624 rtmp = win->pwin->portRect;
1625 win->minw = win->maxw = rtmp.right - rtmp.left;
1626 win->minh = btmp.bottom + 64;
1627 twin->topoff = btmp.bottom;
1628
1629
1630 TextFont(monaco);
1631 TextSize(9);
1632 GetFontInfo(&finfo);
1633 NATEinit(win, NATE_NOHSCROLL, 80 * finfo.widMax + 2, NULL, 0);
1634 ewin->nateon = 0;
1635 TextFont(0);
1636 TextSize(0);
1637
1638
1639 NAradioSet(win->pwin, iEmail, iSavefile, iSavefile);
1640 if (tcpstart < 0) NAhiliteDItem(win->pwin, iEmail, 255);
1641 NAenableDItem(win->pwin, iEmailto, 0);
1642 NAenableDItem(win->pwin, iPartLimit, 0);
1643 NAsetIText(win->pwin, iSubj, ewin->fspec.name);
1644 SelIText(win->pwin, iSubj, 0, 32767);
1645 SetWTitle(win->pwin, ewin->fspec.name);
1646 ShowWindow(win->pwin);
1647
1648
1649 win->updatep = encodeupdate;
1650 win->closep = encodeclose;
1651 win->keyp = encodekey;
1652 win->ctrlp = encodectrl;
1653 win->mousep = encodemouse;
1654 win->menup = encodemenu;
1655 win->idlep = NULL;
1656 win->activep = NULL;
1657
1658 return (NA_NOTPROCESSED);
1659 }
1660
1661
1662
1663 static void do_encode(FSSpec *fspec, OSType ftype)
1664 {
1665 StandardFileReply infile;
1666
1667 if (!fspec) {
1668 NAgetFile(NULL, -1, NULL, &infile);
1669 if (!infile.sfGood) return;
1670 } else {
1671 infile.sfFile = *fspec;
1672 infile.sfType = ftype;
1673 }
1674 NAwindow(NULL, NA_DIALOGWINDOW | NA_TITLEBAR | NA_GROWBOX | NA_USERESOURCE
1675 | NA_DEFBUTTON | NA_HASCONTROLS,
1676 NULL, sendDLOG, (long *) &infile, sizeof (encodewin), encodeinit);
1677 }
1678
1679
1680
1681 static short openfile(short message, FSSpec *fspec, FInfo *finfo)
1682 {
1683 if (message != appOpen) return (-1);
1684
1685
1686 if (finfo->fdType == 'TEXT') {
1687 do_decode(fspec);
1688 } else {
1689 do_encode(fspec, finfo->fdType);
1690 }
1691
1692 return (0);
1693 }
1694
1695 #define hwinfo ((nate_win *)win)
1696
1697
1698
1699 static short helpclose(na_win *win)
1700 {
1701 helpw = NULL;
1702
1703 return (NATEclosep(win));
1704 }
1705
1706
1707
1708 static short helpwindow(na_win *win, long *data)
1709 {
1710 Rect rtemp, vtemp;
1711 Handle h, hs;
1712 long len;
1713 TEHandle hTE;
1714
1715 rtemp = win->pwin->portRect;
1716 vtemp = rtemp;
1717 vtemp.right = vtemp.left + (hwinfo->docwidth = 475);
1718 win->mousep = NATEmousep;
1719 win->idlep = NATEidlep;
1720 win->menup = NATEmenup;
1721 win->activep = NATEactivep;
1722 win->updatep = NATEupdatep;
1723 win->ctrlp = NATEctrlp;
1724 win->closep = helpclose;
1725 win->cursorRgn = NewRgn();
1726 hwinfo->vctrl = hwinfo->hctrl = NULL;
1727
1728 TEAutoView(true, hTE = hwinfo->hTE = TEStylNew(&vtemp, &rtemp));
1729 h = GetResource('TEXT', helpTEXT);
1730 hs = GetResource('styl', helpSTYL);
1731 len = GetHandleSize(h);
1732 HLock(h);
1733 TEStylInsert(*h, len, (StScrpHandle) hs, hTE);
1734 HUnlock(h);
1735 TESetSelect(0, 0, hTE);
1736 hwinfo->lheight = TEGetHeight((*hTE)->nLines, 0, hTE) / (*hTE)->nLines;
1737 ShowWindow(helpw = win->pwin);
1738
1739 return (NA_NOTPROCESSED);
1740 }
1741
1742
1743
1744 static void sethost(void *user, na_tcp s, short status, long size, char *data)
1745 {
1746 PCstr host[65];
1747 Rect box;
1748 na_win *win, **winh;
1749
1750
1751 for (winh = NAhead; winh && (*winh)->type != PREFWIN; winh = (*winh)->next);
1752 if (!winh || (*winh)->child != user) return;
1753 win = NAlockWindow((na_win **) user);
1754
1755
1756 if (status != NATCP_connect) {
1757 warn("Failed to get hostname from MacTCP");
1758 } else {
1759 if (data[size - 1] == '.') --size;
1760 PCstrlen(host) = size;
1761 memcpy(C(host), data, size);
1762 NAsetIText((*winh)->pwin, iHost, host);
1763 SelIText((*winh)->pwin, iHost, 0, 32767);
1764 }
1765 prwin->percent = 100;
1766 progressupdate(win, false);
1767 NAunlockWindowh(winh, win);
1768 }
1769
1770
1771
1772 static short settask(na_win *win)
1773 {
1774 if (tcpstart == 0 && !prwin->percent) {
1775 NAsetIText(win->pwin, iWorkText, "\pLooking for MacTCP");
1776 prwin->percent = 1;
1777 progressupdate(win, false);
1778 NATCPinit(mytcpinit);
1779 } else if (tcpstart == 1 && prwin->percent < 50) {
1780 NAsetIText(win->pwin, iWorkText, "\pLooking up Internet hostname");
1781 prwin->percent = 50;
1782 progressupdate(win, false);
1783 NATCPgethost(sethost, (void *) GetWRefCon(win->pwin));
1784 }
1785 progressupdate(win, false);
1786 if (tcpstart == -1) {
1787 warn("MacTCP not available");
1788 NAhiliteDItem((*win->parent)->pwin, iSet, 255);
1789 }
1790
1791 return (tcpstart == -1 || prwin->percent == 100 ? NA_CLOSED : NA_NOTPROCESSED);
1792 }
1793
1794
1795
1796 static short setinit(na_win *win, long *data)
1797 {
1798 win->taskp = settask;
1799 win->updatep = progressupdate;
1800 win->closep = progressclose;
1801 NAmodalMenus(1);
1802
1803 return (NA_NOTPROCESSED);
1804 }
1805
1806
1807
1808 static short prefsctrl(na_win *win, Point p, short item, short mods, ControlHandle ctrlh)
1809 {
1810 PCstr tmpstr[257];
1811 short encoding, extract_text, quit_finished, result = NA_NOTPROCESSED;
1812 ControlHandle ctrl;
1813 char *scan, *end;
1814 short changed, len, i, useic;
1815 static short prefitem[3] = { iHost, iEmailAddr, iMailServer };
1816
1817 switch (item) {
1818 case iOk:
1819 HLock((Handle) mpack_prefs);
1820 changed = 0;
1821 encoding = NAradioGet(win->pwin, iAuto, iDouble) - iAuto;
1822 NAgetDHandle(win->pwin, iTextEncode, &ctrl);
1823 extract_text = GetCtlValue(ctrl);
1824 NAgetDHandle(win->pwin, iQuitFinish, &ctrl);
1825 quit_finished = GetCtlValue(ctrl);
1826 if (encoding != (*mpack_prefs)->encoding
1827 || extract_text != (*mpack_prefs)->extract_text
1828 || quit_finished != (*mpack_prefs)->quit_finished) {
1829 changed = 1;
1830 }
1831 if (changed) {
1832 (*mpack_prefs)->encoding = encoding;
1833 (*mpack_prefs)->extract_text = extract_text;
1834 (*mpack_prefs)->quit_finished = quit_finished;
1835 ChangedResource((Handle) mpack_prefs);
1836 changed = 0;
1837 }
1838 len = 1;
1839 scan = (*mpack_prefs)->internet_host;
1840 end = (char *) *mpack_prefs + GetHandleSize((Handle) mpack_prefs);
1841 for (i = 0; i < 3; ++i) {
1842 NAgetIText(win->pwin, prefitem[i], P(tmpstr));
1843 SetClen(tmpstr);
1844 len += PCstrlen(tmpstr);
1845 if (scan == end || strcmp(C(tmpstr), scan)) {
1846 changed = 1;
1847 }
1848 while (scan < end && *scan++);
1849 }
1850 if (changed) {
1851 HUnlock((Handle) mpack_prefs);
1852
1853 SetHandleSize((Handle) mpack_prefs, sizeof (struct mpack_preferences)
1854 + len);
1855 HLock((Handle) mpack_prefs);
1856 scan = (*mpack_prefs)->internet_host;
1857 useic = icinst && ICBegin(icinst, icReadWritePerm) == noErr;
1858 for (i = 0; i < 3; ++i) {
1859 NAgetIText(win->pwin, prefitem[i], P(tmpstr));
1860 SetClen(tmpstr);
1861 strcpy(scan, C(tmpstr));
1862 scan += PCstrlen(tmpstr) + 1;
1863 if (i && useic) {
1864 ICSetPref(icinst, i == 1 ? kICEmail : kICSMTPHost,
1865 ICattr_no_change, (Ptr) P(tmpstr), PCstrlen(tmpstr) + 1);
1866 }
1867 }
1868 if (useic) ICEnd(icinst);
1869 ChangedResource((Handle) mpack_prefs);
1870 }
1871 HUnlock((Handle) mpack_prefs);
1872 case iCancel:
1873 result = NA_REQCLOSE;
1874 NAmodalMenus(0);
1875 break;
1876 case iAuto:
1877 case iData:
1878 case iSingle:
1879 case iDouble:
1880 NAradioSet(win->pwin, iAuto, iDouble, item);
1881 break;
1882 case iTextEncode:
1883 case iQuitFinish:
1884 SetCtlValue(ctrlh, !GetCtlValue(ctrlh));
1885 break;
1886 case iSet:
1887 NAwindow(0, NA_DIALOGWINDOW | NA_TITLEBAR | NA_HASTASK | NA_USERESOURCE
1888 | NA_MODAL | NA_CHILDWINDOW,
1889 NULL, progDLOG, NULL, sizeof (progresswin), setinit);
1890 break;
1891 }
1892
1893 return (result);
1894 }
1895
1896
1897
1898 static short prefsupdate(na_win *win, Boolean newsize)
1899 {
1900 Handle hn;
1901 Rect box;
1902 short type;
1903
1904
1905 GetDItem(win->pwin, iEmailAddr, &type, &hn, &box);
1906 if (type == statText) NAhiliteDItem(win->pwin, iEmailAddr, 255);
1907 GetDItem(win->pwin, iMailServer, &type, &hn, &box);
1908 if (type == statText) NAhiliteDItem(win->pwin, iMailServer, 255);
1909
1910 return (NA_NOTPROCESSED);
1911 }
1912
1913
1914
1915 static short prefsinit(na_win *win, long *data)
1916 {
1917 PCstr tmpstr[257], eaddr[257];
1918 ControlHandle ctrl;
1919
1920 win->type = PREFWIN;
1921 win->ctrlp = prefsctrl;
1922 win->menup = NAdialogMenu;
1923 win->updatep = prefsupdate;
1924 HLock((Handle) mpack_prefs);
1925 strcpy(C(tmpstr), (*mpack_prefs)->internet_host);
1926 HUnlock((Handle) mpack_prefs);
1927 SetPlen(tmpstr);
1928 NAsetIText(win->pwin, iHost, P(tmpstr));
1929 SelIText(win->pwin, iHost, 0, 32767);
1930 getICprefs(win, eaddr, tmpstr);
1931 NAsetIText(win->pwin, iEmailAddr, P(eaddr));
1932 NAsetIText(win->pwin, iMailServer, P(tmpstr));
1933 NAradioSet(win->pwin, iAuto, iDouble, (*mpack_prefs)->encoding + iAuto);
1934 NAsetIval(win->pwin, iTextEncode, (*mpack_prefs)->extract_text);
1935 NAsetIval(win->pwin, iQuitFinish, (*mpack_prefs)->quit_finished);
1936 if (tcpstart == -1) NAhiliteDItem(win->pwin, iSet, 255);
1937 NAmodalMenus(1);
1938 ShowWindow(win->pwin);
1939
1940 return (NA_NOTPROCESSED);
1941 }
1942
1943
1944
1945 static short mainmenu(na_win *win, WORD menuid, WORD itemno)
1946 {
1947 short status = NA_NOTPROCESSED;
1948 MenuHandle mh;
1949 PCstr version[32];
1950
1951 switch (menuid) {
1952 case 0:
1953 NAenableMItem(mApple, iAbout);
1954 return (status);
1955 case mApple:
1956 if (itemno == iAbout) {
1957 CtoPCstrcpy(version, MPACK_VERSION);
1958 ParamText(P(version), NULL, NULL, NULL);
1959 return (NA_NOTPROCESSED);
1960 }
1961 break;
1962
1963 case mFile:
1964 switch (itemno) {
1965 case iEncode:
1966 do_encode(NULL, 0);
1967 status = NA_PROCESSED;
1968 break;
1969
1970 case iDecode:
1971 do_decode(NULL);
1972 status = NA_PROCESSED;
1973 break;
1974
1975 case iClose:
1976 break;
1977
1978 case iPrefs:
1979 status = NAwindow(0, NA_DIALOGWINDOW | NA_USERESOURCE
1980 | NA_MODAL | NA_DEFBUTTON | NA_TITLEBAR,
1981 NULL, prefsDLOG, (long *) NULL, 0, prefsinit);
1982 break;
1983
1984 case iQuit:
1985 status = NA_REQCLOSEALL;
1986 break;
1987 }
1988 break;
1989
1990 case mEdit:
1991 break;
1992
1993 case mHelp:
1994 if (!helpw) {
1995 NAwindow(0, NA_USERESOURCE | NATEflags | NATE_READONLY | NA_SMARTSIZE,
1996 NULL, helpWIND, (long *) NULL, sizeof (nate_win), helpwindow);
1997 } else {
1998 SelectWindow(helpw);
1999 }
2000 break;
2001 }
2002 NAdisableMItem(mApple, iAbout);
2003
2004 return (status);
2005 }
2006
2007
2008
2009
2010 static short makepref()
2011 {
2012 Handle hpref = NULL, htmpl;
2013 long dirID;
2014 short vRefNum;
2015 char *scan, *end;
2016 PCstr dname[257];
2017 CInfoPBRec cpb;
2018 DirInfo *dp = &cpb.dirInfo;
2019 ParamBlockRec pb;
2020 VolumeParam *vp = &pb.volumeParam;
2021 FInfo finfo;
2022 static unsigned char pname[] = "\pprefs";
2023
2024
2025 pfolder = (struct pref_folder *) NewPtr(sizeof (struct pref_folder));
2026 if (!pfolder) return (-1);
2027 end = scan = (char *) pfolder->prefs + sizeof (pfolder->prefs) - 1;
2028 *scan = '\0';
2029
2030
2031 if (FindFolder(kOnSystemDisk, kPreferencesFolderType,
2032 kCreateFolder, &vRefNum, &pfolder->fspec.parID) != noErr) {
2033 return (-1);
2034 }
2035
2036
2037 PtoPCstrcpy(dname, (char *) "\pMpack");
2038 (void) DirCreate(vRefNum, pfolder->fspec.parID, P(dname), &dirID);
2039
2040
2041 dp->ioNamePtr = P(dname);
2042 dp->ioVRefNum = vRefNum;
2043 dp->ioFDirIndex = 0;
2044 dp->ioDrDirID = pfolder->fspec.parID;
2045 if (PBGetCatInfoSync(&cpb) != noErr) return (-1);
2046 pfolder->fspec.parID = dirID = dp->ioDrDirID;
2047 pfolder->fspec.vRefNum = vRefNum;
2048
2049
2050 dp->ioFDirIndex = -1;
2051 for (;;) {
2052 *--scan = ':';
2053 if (scan - (char *) pfolder->prefs < 1 + PCstrlen(dname)) return (-1);
2054 scan -= PCstrlen(dname);
2055 memcpy(scan, C(dname), PCstrlen(dname));
2056 if ((dp->ioDrDirID = dp->ioDrParID) == 2) break;
2057 if (PBGetCatInfoSync(&cpb) != noErr) return (-1);
2058 }
2059 vp->ioVolIndex = 0;
2060 vp->ioNamePtr = P(dname);
2061 vp->ioVRefNum = vRefNum;
2062 if (PBGetVInfoSync(&pb) != noErr) return (-1);
2063 *--scan = ':';
2064 if (scan - (char *) pfolder->prefs < 16 + PCstrlen(dname)) return (-1);
2065 PtoPCstrcpy(pfolder->prefs, (char *) P(dname));
2066 CtoPCstrcat(pfolder->prefs, scan);
2067
2068
2069 HCreateResFile(vRefNum, dirID, pname);
2070 if (ResError() == noErr) {
2071 HGetFInfo(vRefNum, dirID, pname, &finfo);
2072 finfo.fdType = 'pref';
2073 finfo.fdCreator = 'mPAK';
2074 HSetFInfo(vRefNum, dirID, pname, &finfo);
2075 hpref = GetResource('mPRF', prefsID);
2076 DetachResource(hpref);
2077 htmpl = GetResource('TMPL', IDnaID);
2078 DetachResource(htmpl);
2079 }
2080 pfolder->refnum = HOpenResFile(vRefNum, dirID, pname, fsRdWrPerm);
2081 if (pfolder->refnum < 0) return (-1);
2082 if (hpref) {
2083 AddResource(hpref, 'mPRF', prefsID, "\p");
2084 AddResource(htmpl, 'TMPL', IDnaID, "\pIDna");
2085 ReleaseResource(htmpl);
2086 } else {
2087 hpref = GetResource('mPRF', prefsID);
2088 }
2089 if (!hpref) return (-1);
2090 mpack_prefs = (struct mpack_preferences **) hpref;
2091
2092 return (0);
2093 }
2094
2095
2096
2097 void maccleanup()
2098 {
2099 if (pfolder) {
2100 CloseResFile(pfolder->refnum);
2101 DisposPtr((Ptr) pfolder);
2102 }
2103 if (icinst) ICStop(icinst);
2104 if (tcpstart == 1) NATCPdone(120);
2105 }
2106
2107 main()
2108 {
2109 CursHandle cursH;
2110
2111 if (NAinit(128, 2, openfile, mainmenu, 3, 1, 0, iClose) == 0) {
2112
2113 if (makepref() < 0) {
2114 yell("Couldn't create preferences file");
2115 } else {
2116
2117 if (ICStart(&icinst, 'mPAK') == noErr) {
2118 (void) ICFindConfigFile(icinst, 0, NULL);
2119 }
2120
2121 cursH = GetCursor(watchCursor);
2122 watch = **cursH;
2123
2124 NAmainloop();
2125 maccleanup();
2126 }
2127 }
2128 }