home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1997 / MacHack 1997.toast / Hacks / Hacks ’97 / EDO Hack / source code / sources / FetchParseURL.c < prev    next >
Encoding:
Text File  |  1997-06-28  |  8.0 KB  |  329 lines  |  [TEXT/CWIE]

  1. // --------------------------------------------------------------------------------------
  2. //  FetchParseURL.c
  3. //
  4. //  Written by Don Arbow and Marc A. Raiser, EveryDay Objects, Inc.
  5. //     in one day - June 26, 1997
  6. // --------------------------------------------------------------------------------------
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11.  
  12. #include "Subwoofer.h"
  13.  
  14. #include "FetchParseURL.h"
  15. #include "HackWindows.h"
  16.  
  17. #include <Folders.h>
  18. #include <Files.h>
  19. #include <Threads.h>
  20.  
  21. #define DEBUG 0
  22.  
  23. void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName);
  24. void PathNameFromWD(long vRefNum, StringPtr pathName);
  25. void pstrcat(StringPtr dst, StringPtr src);
  26. void pstrinsert(StringPtr dst, StringPtr src);
  27. void ParseFile(void);
  28.  
  29. // GLOBALS
  30. Str255  uniqueName;
  31. char    baseURL[256];
  32. FSSpec  gFSSpec;
  33.  
  34. void QueryURL(Str255 url)
  35. {
  36.     OSErr err = 0;
  37.     char urlName[255];
  38.     short    vRefNum;
  39.     long   dirID;
  40.     unsigned long secs;
  41.     
  42.     BlockMoveData(url + 1, baseURL, url[0]);
  43.     baseURL[url[0]] = '\0';
  44.     
  45.     // Define the URLReference
  46.     BlockMoveData(url + 1, urlName, url[0]);
  47.     urlName[url[0]] = '\0';    
  48. #if DEBUG
  49.     err =  FindFolder(kOnSystemDisk, kDesktopFolderType, true, &vRefNum, &dirID);
  50. #else
  51.     err =  FindFolder(kOnSystemDisk, kTemporaryFolderType, true, &vRefNum, &dirID);
  52.  
  53. #endif
  54.     GetDateTime(&secs);
  55.     NumToString(secs, uniqueName);
  56.     FSMakeFSSpec(vRefNum, dirID, uniqueName, &gFSSpec);
  57.     err = URLDownload(urlName, &gFSSpec, kURLDisplayProgressFlag + kURLDisplayAuthFlag);
  58.     
  59.     if (err == noErr) {
  60.         ClearList();
  61.         ParseFile();
  62.     } else {
  63.  
  64.         ShowError(err);
  65.     }
  66. #if !DEBUG
  67.     FSpDelete(&gFSSpec);
  68.  
  69. #endif
  70. }
  71.  
  72. void ParseFile(void) {
  73.     
  74.     FILE   *ref;
  75.     Str255  pathName;
  76.     char    c;
  77.     char    tagBuf[1000], *p;
  78.     char    urlBuf[1000], *q, *z;
  79.     Boolean   searchTag;
  80.     char    absURL[256];
  81.     
  82.     strcpy(absURL, baseURL);
  83.     PathNameFromDirID(gFSSpec.parID, gFSSpec.vRefNum, pathName);
  84.     pstrcat(pathName, gFSSpec.name);
  85.     p2cstr(pathName);
  86.     // open
  87.     ref = fopen((char*)pathName, "r");
  88.  
  89.     while (!feof(ref)) {
  90.     
  91.         // skip to begin of tag '<'
  92.         while ((c = getc(ref)) != '<' && !feof(ref)) {
  93.         }
  94.         
  95.         p = tagBuf;
  96.         // skip to begin of tag '<'
  97.         while ((c = getc(ref)) != '>' && !feof(ref)) {
  98.             *p++ = tolower(c);
  99.         }
  100.         *p = '\0';
  101.         
  102.         p = tagBuf;
  103.         searchTag = true;
  104.         while (searchTag) {
  105.             char term = '\0';
  106.             while ((*p == ' ' || *p == '\t') && *p != '\0') p++;   // skip whitespace
  107.             
  108.             if ((strncmp(p, "href", 4) == 0) || (strncmp(p, "src", 3) == 0)) {
  109.  
  110.                 if (strncmp(p, "src", 3) == 0)
  111.                     p += 3;
  112.                 else
  113.                     p += 4;            
  114.         
  115.                 while (*p != ' ' && *p != '\t' && *p != '=')  p++;   // skip non-whitespace
  116.             
  117.                 while (*p == ' ' || *p == '\t') p++;   // skip whitespace
  118.                 if (*p++ == '=') {
  119.                     while (*p == ' ' || *p == '\t') p++;   // skip whitespace
  120.                     if (*p == '\"') {
  121.                         term = '\"';
  122.                         p++;
  123.                     } else {
  124.                         term = ' ';
  125.                     }
  126.                     // copy until term
  127.                     q = urlBuf;
  128.                     while (*p != term)
  129.                         *q++ = *p++;
  130.                     *q = '\0';
  131.                     q = urlBuf;
  132.                     
  133.                     if ((q = strpbrk(urlBuf, "#")) != NULL)
  134.                         *q = '\0';
  135.                     
  136.                     if (urlBuf[0] == '/') {
  137.                         strncpy(absURL + strlen(baseURL), urlBuf, strlen(urlBuf) + 1);
  138.                     }
  139.                     // add to list
  140.                     c2pstr(urlBuf);
  141.                     AddListItem((unsigned char*)urlBuf);
  142.                 }
  143.             }
  144.             term = '\0';
  145.             while (*p != ' ' && *p != '\t') {
  146.                 if (*p == term) {
  147.                     searchTag = false;
  148.                     break;
  149.                 }
  150.                 p++;   // skip non-whitespace
  151.             }
  152.         }
  153.     }
  154.     fclose(ref);
  155. }
  156.  
  157. void ShowError(OSErr err)
  158. {
  159.     Str63 theString;
  160.     
  161.     switch ( err )
  162.     {
  163.     case noErr:
  164.         return;
  165.         break;
  166.         
  167.     case kURLInvalidURLReferenceError:
  168.         ParamText("\pThat URL is not a valid link.", "\p", "\p", "\p");
  169.         break;
  170.     case kURLInvalidParameterError:
  171.         ParamText("\p kURLInvalidParameterError", "\p", "\p", "\p");
  172.         break;
  173.     case kURLProgressAlreadyDisplayedError:
  174.         ParamText("\p kURLProgressAlreadyDisplayedError", "\p", "\p", "\p");
  175.         break;
  176.     case kURLFileExistsError:
  177.         ParamText("\pThat file already exists", "\p", "\p", "\p");
  178.         break;
  179.     case kURLInvalidURLError:
  180.         ParamText("\pThat is not a valid URL.", "\p", "\p", "\p");
  181.         break;
  182.     case kURLUnsupportedSchemeError:
  183.         ParamText("\pSorry, that internet protocol is not supported.", "\p", "\p", "\p");
  184.         break;
  185.     case kURLServerBusyError:
  186.         ParamText("\pThe server is busy, please try later.", "\p", "\p", "\p");
  187.         break;
  188.     case kURLAuthenticationError:
  189.         ParamText("\pCannot find that domain.", "\p", "\p", "\p");
  190.         break;
  191.     case kURLUnkownPropertyError:
  192.         ParamText("\p kURLUnkownPropertyError", "\p", "\p", "\p");
  193.         break;
  194.     case kURLPropertyBufferToSmallError:
  195.         ParamText("\p kURLPropertyBufferToSmallError", "\p", "\p", "\p");
  196.         break;
  197.     case kURLUnsetablePropertyError:
  198.         ParamText("\p kURLUnsetablePropertyError", "\p", "\p", "\p");
  199.         break;
  200.     case kURLInvalidCallError:
  201.         ParamText("\p kURLInvalidCallError", "\p", "\p", "\p");
  202.         break;
  203.     case kURLNoInternetConfigError:
  204.         ParamText("\pYou must have Internet Config to run this hack.", "\p", "\p", "\p");
  205.         break;
  206.     case kURLUserCancelledError:
  207.         ParamText("\pDownload has been aborted per your request.", "\p", "\p", "\p");
  208.         break;
  209.     case kURLFileEmptyError:
  210.         ParamText("\pThe resource you requested is empty", "\p", "\p", "\p");
  211.         break;
  212.     case kURLResourceNotFoundError:
  213.         ParamText("\pThe resource you requested was not found", "\p", "\p", "\p");
  214.         break;
  215. #if 0
  216.     // unknown at this time
  217.     case kURLExtensionFailureError:
  218.         ParamText("\p kURLExtensionFailureError", "\p", "\p", "\p");
  219.         break;
  220. #endif
  221.  
  222.     default :
  223.         NumToString(err, theString);
  224.         ParamText("\pUnknown error: ", theString, "\p", "\p");
  225.         break;
  226.     }
  227.     
  228.     StopAlert(128, nil);
  229. }
  230.  
  231. // Assumes inclusion of <MacHeaders>
  232. #define haveAUX() 0
  233.  
  234. /*
  235.  * Pascal string utilities
  236.  */
  237. /*
  238.  * pstrcat - add string 'src' to end of string 'dst'
  239.  */
  240. void pstrcat(StringPtr dst, StringPtr src)
  241. {
  242.     /* copy string in */
  243.     BlockMove(src + 1, dst + *dst + 1, *src);
  244.     /* adjust length byte */
  245.     *dst += *src;
  246. }
  247.  
  248. /*
  249.  * pstrinsert - insert string 'src' at beginning of string 'dst'
  250.  */
  251. void pstrinsert(StringPtr dst, StringPtr src)
  252. {
  253.     /* make room for new string */
  254.     BlockMove(dst + 1, dst + *src + 1, *dst);
  255.     /* copy new string in */
  256.     BlockMove(src + 1, dst + 1, *src);
  257.     /* adjust length byte */
  258.     *dst += *src;
  259. }
  260.  
  261. void PathNameFromDirID(long dirID, short vRefNum, StringPtr fullPathName)
  262. {
  263.     CInfoPBRec    block;
  264.     Str255    directoryName;
  265.     OSErr    err;
  266.     
  267.     memset(&block, '\0', sizeof(CInfoPBRec));
  268.     
  269.     fullPathName[0] = '\0';
  270.  
  271.     block.dirInfo.ioDrParID = dirID;
  272.     block.dirInfo.ioNamePtr = directoryName;
  273.     do {
  274.         block.dirInfo.ioVRefNum = vRefNum;
  275.         block.dirInfo.ioFDirIndex = -1;
  276.         block.dirInfo.ioDrDirID = block.dirInfo.ioDrParID;
  277.         err = PBGetCatInfoSync(&block);
  278.         if (haveAUX()) {
  279.             if (directoryName[1] != '/')
  280.                 /* If this isn't root (i.e. "/"), append a slash ('/') */
  281.                 pstrcat(directoryName, (StringPtr)"\p/");
  282.         }
  283.         else
  284.             pstrcat(directoryName, (StringPtr)"\p:");
  285.         pstrinsert(fullPathName, directoryName);
  286.     } while (block.dirInfo.ioDrDirID != 2);
  287. }
  288.  
  289. /*
  290. PathNameFromWD:
  291. Given an HFS working directory, this routine returns the full pathname that
  292. corresponds to it. It does this by calling PBGetWDInfo to get the VRefNum and
  293. DirID of the real directory. It then calls PathNameFromDirID, and returns its
  294. result.
  295.  
  296. */
  297. void PathNameFromWD(long vRefNum, StringPtr pathName)
  298. {
  299.     WDPBRec    myBlock;
  300.     OSErr    err;
  301.     /*
  302.      PBGetWDInfo has a bug under A/UX 1.1.  If vRefNum is a real
  303.      vRefNum and not a wdRefNum, then it returns garbage.
  304.      Since A/UX has only 1 volume (in the Macintosh sense) and
  305.      only 1 root directory, this can occur only when a file has been
  306.      selected in the root directory (/).
  307.      So we look for this and hardcode the DirID and vRefNum.
  308.     */
  309.     if ((haveAUX()) && (vRefNum == -1))
  310.             PathNameFromDirID(2, -1, pathName);
  311.     else {
  312.             myBlock.ioNamePtr = nil;
  313.             myBlock.ioVRefNum = vRefNum;
  314.             myBlock.ioWDIndex = 0;
  315.             myBlock.ioWDProcID = 0;
  316.     /*
  317.      Change the Working Directory number in vRefnum into a real
  318.     vRefnum and DirID. The real vRefnum is returned in ioVRefnum,
  319.      and the real DirID is returned in ioWDDirID.
  320.     */
  321.             err = PBGetWDInfoSync(&myBlock);
  322.             if (err != noErr)
  323.                     return;
  324.             PathNameFromDirID(myBlock.ioWDDirID, myBlock.ioWDVRefNum,
  325.                     pathName);
  326.     }
  327. }
  328.  
  329.