home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / analg211.zip / macstuff.c < prev    next >
C/C++ Source or Header  |  1997-03-14  |  12KB  |  432 lines

  1. /*** analog 2.1 ***/
  2. /* Please read Readme.html, or http://www.statslab.cam.ac.uk/~sret1/analog/  */
  3.  
  4. /*** macstuff.c; stuff only required for the Mac port ***/
  5. /* The functions in this file inside #ifdef MAC_EVENTS are due to, and
  6.    copyright, Jason Linhart (jason@summary.net), 1996. */
  7. /* The functions in this file inside #ifdef MACDIRENT are due to
  8.    Jason Linhart, January 1997. */
  9. /* The functions in this file inside #ifndef NODNS are due to, and
  10.    copyright, Jason Linhart and Stephan Somogyi, 1996, 1997.
  11.    Version history:
  12.    950531  SCS      First release
  13.    960716  JTL      Switched to async OT calls and improved failure cases
  14.                     to not recheck
  15.    960927  JTL      Added MacTCP support and combined check and open into
  16.                     OpenNetwork
  17. */
  18.  
  19. #include "analhea2.h"
  20. #ifdef MAC_EVENTS
  21.  
  22. void MacInit(void)
  23. {
  24.   SIOUXSettings.asktosaveonclose=false;
  25.   printf("Processing...\n");
  26. }
  27.  
  28. void MacFini(void)
  29. {
  30.   extern char *commandname;
  31.   extern long Mac_good_lines, Mac_bad_lines, Mac_tab_lines;  /* in sscanf.c */
  32.   extern int total_succ_reqs;
  33.   extern flag warnq, anywarns;
  34.  
  35.   if (!Mac_good_lines && Mac_tab_lines > 4 && total_succ_reqs < 5 && warnq) {
  36.     fprintf(stderr,"%s: Warning: No valid log entries found!\n", commandname);
  37.     fprintf(stderr,"WebStar logs must start with a LOG_FORMAT line something like:\n");
  38.     fprintf(stderr,"!!LOG_FORMAT DATE TIME RESULT URL TRANSFER_TIME BYTES_SENT HOSTNAME REFERER\n");
  39.     fprintf(stderr,"except with the fields listed in the order they actually occur.\n");
  40.     fprintf(stderr,"WebSTAR 1.2.1 or higher should create this line automatically.\n\n");
  41.     anywarns = ON;
  42.   }
  43.   if (!anywarns)
  44.     SIOUXSettings.autocloseonquit=true;
  45.   printf("Complete!\n");
  46. #ifndef NODNS
  47.   ResolverCleanup();
  48. #endif
  49. }
  50.  
  51. void MacIdle(void)
  52. {
  53.   static long time = 0;
  54.  
  55.   EventRecord myEvent;
  56.   WindowPtr whichWindow;
  57.   char theChar;
  58.  
  59.   if (TickCount()<time) return;
  60.   time=TickCount()+8;
  61.   SystemTask();
  62.   if (WaitNextEvent(everyEvent, &myEvent, 1, nil)) {
  63.  
  64.     if (!SIOUXHandleOneEvent(&myEvent)) switch (myEvent.what) {
  65.  
  66.     case mouseDown:
  67.       switch (FindWindow(myEvent.where,&whichWindow)) {
  68.  
  69.       case inMenuBar:
  70.     MenuSelect(myEvent.where);
  71.     break;
  72.       case inSysWindow:
  73.     SystemClick(&myEvent,whichWindow);
  74.     break;
  75.       case inContent:
  76.     SelectWindow(whichWindow);
  77.     break;
  78.       case inDrag:
  79.     DragWindow(whichWindow,myEvent.where,&qd.screenBits.bounds);
  80.     break;
  81.       }
  82.       break;
  83.     case keyDown:
  84.       theChar = myEvent.message & charCodeMask;
  85.       break;
  86.     case updateEvt:
  87.       BeginUpdate((WindowPtr) myEvent.message);
  88.       EndUpdate((WindowPtr) myEvent.message);
  89.       break;
  90.     }
  91.   }
  92. }
  93. #endif   /* (ifdef MAC_EVENTS) */
  94.  
  95. #ifdef MACDIRENT
  96. /* Assume #ifdef MAC, so MacHeaders already loaded */
  97. static int indx=0;
  98. /* offset to current entry, >0 is open, 0 is closed, -1 is at end */
  99. static CInfoPBRec finfo;
  100. static unsigned char fname[257];
  101.  
  102. static void
  103. CToPCpy(pstr,cstr)                 /* Convert a C string to a Pascal string */
  104.         unsigned char *pstr;
  105.         char *cstr;
  106. {
  107.         register char *dptr, len;
  108.  
  109.         len=0;
  110.         dptr=(char *)pstr+1;
  111.         while (len<255 && (*dptr++ = *cstr++)!=0) ++len;
  112.         *pstr=len;
  113.         }
  114.  
  115. DIR *
  116. opendir (const char *name)           /* Open a directory stream on NAME. */
  117. /* Return a DIR stream on the directory, or NULL if it could not be opened.  */
  118. {
  119.         WDPBRec pb;
  120.         VolumeParam vpb;
  121.         HVolumeParam hvpb;
  122.         int error;
  123.  
  124.         if (indx) {
  125.                 closedir((DIR *)1);
  126.                 return((DIR *)0);
  127.                 }
  128.         while (name[0]=='.') ++name;
  129.         finfo.hFileInfo.ioCompletion=(IOCompletionUPP)NULL;
  130.         finfo.hFileInfo.ioNamePtr=fname;
  131.         finfo.hFileInfo.ioFVersNum=0;
  132.         finfo.hFileInfo.ioVRefNum=0;
  133.  
  134.         CToPCpy(fname,name);
  135.         if (fname[fname[0]]!=':') {
  136.                 fname[fname[0]+1]=':';
  137.                 ++fname[0];
  138.                 }
  139.  
  140.         if (*name) {
  141.                 if (*strchr(name,':')) {
  142.                         if (name[0]!=':') {
  143.                                 hvpb.ioCompletion=(IOCompletionUPP)NULL;
  144.                                 hvpb.ioNamePtr=fname;
  145.                                 hvpb.ioVRefNum = -1;
  146.                                 hvpb.ioVolIndex = -1;
  147.                                 if (!PBHGetVInfo((HParmBlkPtr)&hvpb,FALSE))
  148.                   pb.ioVRefNum=hvpb.ioVRefNum;
  149.                                 else return((DIR *)0);
  150.                                 CToPCpy(fname,name);
  151.                 if (fname[fname[0]]!=':') {
  152.                   fname[fname[0]+1]=':';
  153.                   ++fname[0];
  154.                 }
  155.                   }
  156.                         else pb.ioVRefNum=0;
  157.                         pb.ioCompletion=(IOCompletionUPP)NULL;
  158.                         pb.ioNamePtr=NULL/*fname*/;
  159.                         pb.ioWDProcID='MAG^';
  160.                         finfo.hFileInfo.ioFDirIndex=0;
  161.                         finfo.hFileInfo.ioDirID=0;
  162.                         if (!PBGetCatInfo(&finfo,FALSE)) {
  163.                                 pb.ioWDDirID=finfo.hFileInfo.ioDirID;
  164.                                 if (!PBOpenWD(&pb,FALSE))
  165.                   finfo.hFileInfo.ioVRefNum=pb.ioVRefNum;
  166.                                 }
  167.                         else return((DIR *)0);
  168.                         }
  169.                 else {
  170.                         vpb.ioNamePtr=hvpb.ioNamePtr=fname;
  171.                         vpb.ioVRefNum=hvpb.ioVRefNum=-1;
  172.                         hvpb.ioVolIndex=vpb.ioVolIndex=-1;
  173.                         if ((!(error=PBHGetVInfo((HParmBlkPtr)&hvpb,FALSE))) &&
  174.                 hvpb.ioVDrvInfo){
  175.                                 vpb.ioVRefNum=hvpb.ioVRefNum;
  176.                                 vpb.ioNamePtr=NULL;
  177.                                 if (!PBGetVInfo((ParmBlkPtr)&vpb,FALSE))
  178.                   finfo.hFileInfo.ioVRefNum=vpb.ioVRefNum;
  179.                                 else return((DIR *)0);
  180.                                 }
  181.                         else return((DIR *)0);
  182.                         finfo.hFileInfo.ioNamePtr=fname;
  183.                         }
  184.                 }
  185.         indx=1;
  186.         return((DIR *)1);
  187.       }
  188.  
  189. int
  190. closedir (DIR * dirp)
  191. /* Close the directory stream DIRP. Return 0 if successful, -1 if not.  */
  192. {
  193.         if (indx) {
  194.                 PBCloseWD((WDPBPtr)&finfo,FALSE);
  195.                 indx=0;
  196.                 return(0);
  197.                 }
  198.         return(-1);
  199.         }
  200.  
  201. struct dirent *
  202. readdir (DIR * dirp)                 /* Read a directory entry from DIRP. */
  203. /* Return a pointer to a `struct dirent' describing the entry, or NULL for EOF
  204.    or error.  The storage returned may be overwritten by a later readdir call
  205.    on the same DIR stream.  */
  206. {
  207.         finfo.hFileInfo.ioFDirIndex=indx;
  208.         finfo.hFileInfo.ioDirID=0;
  209.         if (indx>0 && !PBGetCatInfo(&finfo,FALSE)) {
  210.                 fname[fname[0]+1]=0;
  211.                 ++indx;
  212.                 return((struct dirent *)(fname+1));
  213.                 }
  214.         if (indx) indx = -1;
  215.         return((struct dirent *)0);
  216.         }
  217.  
  218. void
  219. rewinddir (DIR * dirp)     /* Rewind DIRP to the beginning of the directory. */
  220. {
  221.         if (indx) indx=1;
  222.         }
  223.  
  224. void
  225. seekdir (DIR * dirp, off_t pos) /* Seek to position POS on DIRP.  */
  226. {
  227.         if (indx && pos>0) indx=pos;
  228.         }
  229.  
  230. off_t
  231. telldir (DIR * dirp)                 /* Return the current position of DIRP. */
  232. {
  233.         return((indx>0)?indx:-1);
  234.         }
  235.  
  236. int
  237. dirstat(const char *file_name, struct stat *buf)
  238. /* Special version of stat that only works for most recent dir entry */
  239. {
  240.         if (indx) {
  241.                 buf->st_mode=finfo.hFileInfo.ioFlAttrib;
  242.                 return(0);
  243.                 }
  244.         return(-1);
  245.         }
  246.  
  247.  
  248. #endif
  249.  
  250. #ifdef MAC
  251. #ifndef NODNS
  252. static long OpenNetwork(void);
  253.  
  254. /* Takes a string of an IP address in *hostname, resolves it to a domain name,
  255.    and returns the name in *hostname.
  256.    Returns nil if unresolvable (or something else went wrong), otherwise
  257.    returns 1. */
  258.  
  259. /* URL processing and host lookup */
  260.  
  261. static long slNetChecked = 0, slNetPresent = 0, slNetSvcOpen = 0;
  262. static ResultUPP gMacTCPDNRResultProcUPP = nil;
  263.  
  264. typedef struct {         /* Open Transport Internet services provider info */
  265.   InetSvcRef ref;        /* provider reference */
  266.   Boolean done;          /* true when asynch operation has completed */
  267.   OTResult result;       /* result code */
  268.   void *cookie;          /* cookie */
  269. } SvcInfo;
  270.  
  271. static SvcInfo sSvcRef;
  272.  
  273. int IpAddr2Name(char *hostname)
  274. {
  275.   struct hostInfo hInfoMacTCP;
  276.   OSStatus lStatus;
  277.   OSErr err;
  278.   InetHost lHostAddr;
  279.   int cnt, tmp;
  280.   char *cptr;
  281.   Boolean done;
  282.  
  283.   if (!slNetChecked) {
  284.     slNetPresent = OpenNetwork();
  285.     slNetChecked = 1;
  286.   }
  287.  
  288.   if (slNetPresent == 1) {
  289.  
  290.     /* turn ascii with periods into a long */
  291.     lStatus = OTInetStringToHost(hostname, &lHostAddr);
  292.     if (lStatus != noErr) return 0;
  293.  
  294.     /* turn the long into a reverse-resolved name */
  295.     sSvcRef.done=false;
  296.     lStatus=OTInetAddressToName(sSvcRef.ref,lHostAddr,hostname);
  297.     if (!lStatus) {
  298.       do {
  299.     MacIdle();
  300.       } while (!sSvcRef.done);
  301.       lStatus=sSvcRef.result;
  302.     }
  303.     if (!lStatus) {
  304.       if (hostname[strlen(hostname)-1]=='.') hostname[strlen(hostname)-1]=0;
  305.       return(1);
  306.     }
  307.   }
  308.   else if (slNetPresent==2) {
  309.     lHostAddr=0;
  310.     cptr=hostname;
  311.     for (cnt=0; cnt<4; ++cnt) {
  312.       if (!isdigit(*cptr)) return(0);
  313.       tmp=atoi(cptr);
  314.       if (tmp<0 || tmp>255) return(0);
  315.       lHostAddr=(lHostAddr<<8)|tmp;
  316.       while (isdigit(*cptr)) ++cptr;
  317.       if (cnt!=3 && *cptr!='.') return(0);
  318.       ++cptr;
  319.     }
  320.     memset(&hInfoMacTCP, 0, sizeof(hInfoMacTCP));
  321.     done=false;
  322.     err = AddrToName(lHostAddr, &hInfoMacTCP, gMacTCPDNRResultProcUPP,
  323.              (char*)&done);
  324.     if (err == cacheFault) {
  325.       while (!done) MacIdle();
  326.       err = hInfoMacTCP.rtnCode;
  327.     }
  328.     if (err == noErr) {
  329.       hInfoMacTCP.cname[254] = 0;
  330.       strcpy(hostname, hInfoMacTCP.cname);
  331.       if (hostname[strlen(hostname)-1]=='.') hostname[strlen(hostname)-1]=0;
  332.       return(1);
  333.     }
  334.   }
  335.   return 0;
  336. } /* end IpAddr2Name() */
  337.  
  338.  
  339. /*      Must call this before quitting app
  340. */
  341. void
  342. ResolverCleanup(void)
  343. {
  344.  
  345.   if (slNetChecked && slNetSvcOpen) {
  346.     if (slNetPresent==1) OTCloseProvider(sSvcRef.ref);
  347.     else if (slNetPresent==2) CloseResolver();
  348.   }
  349. } /* end ResolverCleanup() */
  350.  
  351. /* #pragma mark - */
  352.  
  353. /*
  354.         Check for availbility of OT/TCP 1.1 or later,
  355.         or MacTCP and open the service.
  356.         Return nil if it isn't.
  357. */
  358.  
  359. static pascal void
  360. SvcNotifyProc(void *dataPtr,OTEventCode code,OTResult result,void *cookie)
  361. {
  362.   register SvcInfo *svcInfo;
  363.  
  364.   svcInfo=(SvcInfo *)dataPtr;
  365.   svcInfo->done=true;
  366.   svcInfo->result=result;
  367.   svcInfo->cookie=cookie;
  368. }
  369.  
  370. static Boolean
  371. OpenInetServices(SvcInfo *svcInfo)
  372. {
  373.   OSStatus result;
  374.  
  375.   svcInfo->done=false;
  376.   result=OTAsyncOpenInternetServices(kDefaultInternetServicesPath, 0,
  377.                      SvcNotifyProc, svcInfo);
  378.   if (!result) {
  379.     do {
  380.       MacIdle();
  381.     } while (!svcInfo->done);
  382.     result=svcInfo->result;
  383.   }
  384.   if (result) return(false);
  385.   svcInfo->ref=(InetSvcRef)svcInfo->cookie;
  386.   return(true);
  387. }
  388.  
  389. static pascal void
  390. MacTCPDNRResultProc (struct hostInfo *hInfoPtr, char *userDataPtr)
  391. {
  392.   *(Boolean*)userDataPtr = true;
  393. }
  394.  
  395. static long
  396. OpenNetwork(void)
  397. {
  398.   OSStatus lStatus;
  399.   OSErr err;
  400.   long lResponse, lCriteria;
  401.  
  402.   err = Gestalt(gestaltOpenTpt, &lResponse);
  403.   if (err == noErr)       {
  404.     /* Older OpenTransport Headers require that thenext line read:
  405.        lCriteria = gestaltOpenTptPresent + gestaltOpenTptTCPPresent; */
  406.     lCriteria = gestaltOpenTptPresentMask + gestaltOpenTptTCPPresentMask;
  407.     lResponse = lCriteria & lResponse;
  408.     if (lResponse == lCriteria)     {
  409.       lStatus = InitOpenTransport();
  410.       if (lStatus == noErr) {
  411.     if (OpenInetServices(&sSvcRef)) {
  412.       slNetSvcOpen=1;
  413.       return(1);
  414.     }
  415.       }
  416.       return(0);
  417.       /* OT present, but won't open */
  418.     }
  419.   }
  420.   else {
  421.     gMacTCPDNRResultProcUPP = NewResultProc(MacTCPDNRResultProc);
  422.     err = OpenResolver(nil);
  423.     if (err == noErr) {
  424.       slNetSvcOpen=1;
  425.       return(2);
  426.     }
  427.   }
  428.   return(0);
  429. } /* end OpenNetwork() */
  430. #endif
  431. #endif
  432.