1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Original Code is Camino code.
15 *
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 2002
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 *   Nate Weaver (Wevah) - wevah@derailer.org
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38#import "NSURL+Utils.h"
39
40
41@implementation NSURL (CaminoExtensions)
42
43+ (NSURL*)decodeLocalFileURL:(NSURL*)url
44{
45  NSString* urlPathString = [url path];
46  NSString* ext = [[urlPathString pathExtension] lowercaseString];
47  OSType fileType = NSHFSTypeCodeFromFileType(NSHFSTypeOfFile(urlPathString));
48
49  if ([ext isEqualToString:@"url"] || fileType == 'LINK') {
50    url = [NSURL URLFromIEURLFile:urlPathString];
51  }
52  else if ([ext isEqualToString:@"webloc"] || [ext isEqualToString:@"ftploc"] ||
53           fileType == 'ilht' || fileType == 'ilft')
54  {
55    url = [NSURL URLFromInetloc:urlPathString];
56  }
57
58  return url;
59}
60
61//
62// Reads the URL from a .webloc/.ftploc file.
63// Returns the URL, or nil on failure.
64//
65+(NSURL*)URLFromInetloc:(NSString*)inFile
66{
67  FSRef ref;
68  NSURL *ret = nil;
69
70  if (inFile && FSPathMakeRef((UInt8 *)[inFile fileSystemRepresentation], &ref, NULL) == noErr) {
71    short resRef;
72
73    resRef = FSOpenResFile(&ref, fsRdPerm);
74
75    if (resRef != -1) { // Has resouce fork.
76      Handle urlResHandle;
77
78      if ((urlResHandle = Get1Resource('url ', 256))) { // Has 'url ' resource with ID 256.
79        long size;
80
81        size = GetMaxResourceSize(urlResHandle);
82// Begin Google Modified
83//        ret = [NSURL URLWithString:[NSString stringWithCString:(char *)*urlResHandle length:size]];
84        NSString *urlString = [[[NSString alloc] initWithBytes:(void *)*urlResHandle
85                                                        length:size
86                                                      encoding:NSMacOSRomanStringEncoding]  // best guess here
87                               autorelease];
88        ret = [NSURL URLWithString:urlString];
89// End Google Modified
90      }
91
92      CloseResFile(resRef);
93    }
94
95    if (!ret) { // Look for valid plist data.
96      NSDictionary *plist;
97      if ((plist = [[NSDictionary alloc] initWithContentsOfFile:inFile])) {
98        ret = [NSURL URLWithString:[plist objectForKey:@"URL"]];
99        [plist release];
100      }
101    }
102  }
103
104  return ret;
105}
106
107//
108// Reads the URL from a .url file.
109// Returns the URL or nil on failure.
110//
111+(NSURL*)URLFromIEURLFile:(NSString*)inFile
112{
113  NSURL *ret = nil;
114
115  // Is this really an IE .url file?
116  if (inFile) {
117    NSCharacterSet *newlines = [NSCharacterSet characterSetWithCharactersInString:@"\r\n"];
118    // Begin Google Modified
119//    NSScanner *scanner = [NSScanner scannerWithString:[NSString stringWithContentsOfFile:inFile]];
120    NSString *fileString = [NSString stringWithContentsOfFile:inFile
121                                                     encoding:NSWindowsCP1252StringEncoding  // best guess here
122                                                        error:nil];
123    NSScanner *scanner = [NSScanner scannerWithString:fileString];
124    // End Google Modified
125    [scanner scanUpToString:@"[InternetShortcut]" intoString:nil];
126
127    if ([scanner scanString:@"[InternetShortcut]" intoString:nil]) {
128      // Scan each non-empty line in this section. We don't need to explicitly scan the newlines or
129      // whitespace because NSScanner ignores these by default.
130      NSString *line;
131
132      while ([scanner scanUpToCharactersFromSet:newlines intoString:&line]) {
133        if ([line hasPrefix:@"URL="]) {
134          ret = [NSURL URLWithString:[line substringFromIndex:4]];
135          break;
136        }
137        else if ([line hasPrefix:@"["]) {
138          // This is the start of a new section, so if we haven't found an URL yet, we should bail.
139          break;
140        }
141      }
142    }
143  }
144
145  return ret;
146}
147
148@end
149