1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Benjamin Smedberg <benjamin@smedbergs.us>
24 : *
25 : * Alternatively, the contents of this file may be used under the terms of
26 : * either of the GNU General Public License Version 2 or later (the "GPL"),
27 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 : * in which case the provisions of the GPL or the LGPL are applicable instead
29 : * of those above. If you wish to allow use of your version of this file only
30 : * under the terms of either the GPL or the LGPL, and not to allow others to
31 : * use your version of this file under the terms of the MPL, indicate your
32 : * decision by deleting the provisions above and replace them with the notice
33 : * and other provisions required by the GPL or the LGPL. If you do not delete
34 : * the provisions above, a recipient may use your version of this file under
35 : * the terms of any one of the MPL, the GPL or the LGPL.
36 : *
37 : * ***** END LICENSE BLOCK ***** */
38 :
39 : /*
40 : Implementation for a file system RDF data store.
41 : */
42 :
43 : #include "nsFileSystemDataSource.h"
44 :
45 : #include <ctype.h> // for toupper()
46 : #include <stdio.h>
47 : #include "nsIEnumerator.h"
48 : #include "nsIRDFDataSource.h"
49 : #include "nsIRDFObserver.h"
50 : #include "nsIServiceManager.h"
51 : #include "nsXPIDLString.h"
52 : #include "nsRDFCID.h"
53 : #include "rdfutil.h"
54 : #include "plhash.h"
55 : #include "plstr.h"
56 : #include "prlong.h"
57 : #include "prlog.h"
58 : #include "prmem.h"
59 : #include "prprf.h"
60 : #include "prio.h"
61 : #include "rdf.h"
62 : #include "nsEnumeratorUtils.h"
63 : #include "nsIURL.h"
64 : #include "nsIFileURL.h"
65 : #include "nsNetUtil.h"
66 : #include "nsIChannel.h"
67 : #include "nsIFile.h"
68 : #include "nsEscape.h"
69 : #include "nsCRTGlue.h"
70 : #include "nsAutoPtr.h"
71 :
72 : #ifdef XP_WIN
73 : #include "windef.h"
74 : #include "winbase.h"
75 : #include "nsILineInputStream.h"
76 : #include "nsDirectoryServiceDefs.h"
77 : #endif
78 :
79 : #ifdef XP_OS2
80 : #define INCL_DOSFILEMGR
81 : #include <os2.h>
82 : #endif
83 :
84 : #define NS_MOZICON_SCHEME "moz-icon:"
85 :
86 : static const char kFileProtocol[] = "file://";
87 :
88 : bool
89 0 : FileSystemDataSource::isFileURI(nsIRDFResource *r)
90 : {
91 0 : bool isFileURIFlag = false;
92 0 : const char *uri = nsnull;
93 :
94 0 : r->GetValueConst(&uri);
95 0 : if ((uri) && (!strncmp(uri, kFileProtocol, sizeof(kFileProtocol) - 1)))
96 : {
97 : // XXX HACK HACK HACK
98 0 : if (!strchr(uri, '#'))
99 : {
100 0 : isFileURIFlag = true;
101 : }
102 : }
103 0 : return(isFileURIFlag);
104 : }
105 :
106 :
107 :
108 : bool
109 0 : FileSystemDataSource::isDirURI(nsIRDFResource* source)
110 : {
111 : nsresult rv;
112 0 : const char *uri = nsnull;
113 :
114 0 : rv = source->GetValueConst(&uri);
115 0 : if (NS_FAILED(rv)) return(false);
116 :
117 0 : nsCOMPtr<nsIFile> aDir;
118 :
119 0 : rv = NS_GetFileFromURLSpec(nsDependentCString(uri), getter_AddRefs(aDir));
120 0 : if (NS_FAILED(rv)) return(false);
121 :
122 0 : bool isDirFlag = false;
123 :
124 0 : rv = aDir->IsDirectory(&isDirFlag);
125 0 : if (NS_FAILED(rv)) return(false);
126 :
127 0 : return(isDirFlag);
128 : }
129 :
130 :
131 : nsresult
132 0 : FileSystemDataSource::Init()
133 : {
134 : nsresult rv;
135 :
136 0 : mRDFService = do_GetService("@mozilla.org/rdf/rdf-service;1");
137 0 : NS_ENSURE_TRUE(mRDFService, NS_ERROR_FAILURE);
138 :
139 0 : rv = mRDFService->GetResource(NS_LITERAL_CSTRING("NC:FilesRoot"),
140 0 : getter_AddRefs(mNC_FileSystemRoot));
141 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "child"),
142 0 : getter_AddRefs(mNC_Child));
143 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Name"),
144 0 : getter_AddRefs(mNC_Name));
145 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "URL"),
146 0 : getter_AddRefs(mNC_URL));
147 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Icon"),
148 0 : getter_AddRefs(mNC_Icon));
149 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "Content-Length"),
150 0 : getter_AddRefs(mNC_Length));
151 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IsDirectory"),
152 0 : getter_AddRefs(mNC_IsDirectory));
153 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(WEB_NAMESPACE_URI "LastModifiedDate"),
154 0 : getter_AddRefs(mWEB_LastMod));
155 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "FileSystemObject"),
156 0 : getter_AddRefs(mNC_FileSystemObject));
157 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "pulse"),
158 0 : getter_AddRefs(mNC_pulse));
159 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "instanceOf"),
160 0 : getter_AddRefs(mRDF_InstanceOf));
161 0 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(RDF_NAMESPACE_URI "type"),
162 0 : getter_AddRefs(mRDF_type));
163 :
164 : static const PRUnichar kTrue[] = {'t','r','u','e','\0'};
165 : static const PRUnichar kFalse[] = {'f','a','l','s','e','\0'};
166 :
167 0 : rv |= mRDFService->GetLiteral(kTrue, getter_AddRefs(mLiteralTrue));
168 0 : rv |= mRDFService->GetLiteral(kFalse, getter_AddRefs(mLiteralFalse));
169 0 : NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
170 :
171 : #ifdef USE_NC_EXTENSION
172 0 : rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "extension"),
173 0 : getter_AddRefs(mNC_extension));
174 0 : NS_ENSURE_SUCCESS(rv, rv);
175 : #endif
176 :
177 : #ifdef XP_WIN
178 : rv = mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IEFavorite"),
179 : getter_AddRefs(mNC_IEFavoriteObject));
180 : rv |= mRDFService->GetResource(NS_LITERAL_CSTRING(NC_NAMESPACE_URI "IEFavoriteFolder"),
181 : getter_AddRefs(mNC_IEFavoriteFolder));
182 : NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
183 :
184 : nsCOMPtr<nsIFile> file;
185 : NS_GetSpecialDirectory(NS_WIN_FAVORITES_DIR, getter_AddRefs(file));
186 : if (file)
187 : {
188 : nsCOMPtr<nsIURI> furi;
189 : NS_NewFileURI(getter_AddRefs(furi), file);
190 : NS_ENSURE_TRUE(furi, NS_ERROR_FAILURE);
191 :
192 : file->GetNativePath(ieFavoritesDir);
193 : }
194 : #endif
195 :
196 0 : return NS_OK;
197 : }
198 :
199 : //static
200 : nsresult
201 0 : FileSystemDataSource::Create(nsISupports* aOuter, const nsIID& aIID, void **aResult)
202 : {
203 0 : NS_ENSURE_NO_AGGREGATION(aOuter);
204 :
205 0 : nsRefPtr<FileSystemDataSource> self = new FileSystemDataSource();
206 0 : if (!self)
207 0 : return NS_ERROR_OUT_OF_MEMORY;
208 :
209 0 : nsresult rv = self->Init();
210 0 : NS_ENSURE_SUCCESS(rv, rv);
211 :
212 0 : return self->QueryInterface(aIID, aResult);
213 : }
214 :
215 1464 : NS_IMPL_CYCLE_COLLECTION_0(FileSystemDataSource)
216 0 : NS_IMPL_CYCLE_COLLECTING_ADDREF(FileSystemDataSource)
217 0 : NS_IMPL_CYCLE_COLLECTING_RELEASE(FileSystemDataSource)
218 0 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(FileSystemDataSource)
219 0 : NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
220 0 : NS_INTERFACE_MAP_ENTRY(nsISupports)
221 0 : NS_INTERFACE_MAP_END
222 :
223 : NS_IMETHODIMP
224 0 : FileSystemDataSource::GetURI(char **uri)
225 : {
226 0 : NS_PRECONDITION(uri != nsnull, "null ptr");
227 0 : if (! uri)
228 0 : return NS_ERROR_NULL_POINTER;
229 :
230 0 : if ((*uri = NS_strdup("rdf:files")) == nsnull)
231 0 : return NS_ERROR_OUT_OF_MEMORY;
232 :
233 0 : return NS_OK;
234 : }
235 :
236 :
237 :
238 : NS_IMETHODIMP
239 0 : FileSystemDataSource::GetSource(nsIRDFResource* property,
240 : nsIRDFNode* target,
241 : bool tv,
242 : nsIRDFResource** source /* out */)
243 : {
244 0 : NS_PRECONDITION(property != nsnull, "null ptr");
245 0 : if (! property)
246 0 : return NS_ERROR_NULL_POINTER;
247 :
248 0 : NS_PRECONDITION(target != nsnull, "null ptr");
249 0 : if (! target)
250 0 : return NS_ERROR_NULL_POINTER;
251 :
252 0 : NS_PRECONDITION(source != nsnull, "null ptr");
253 0 : if (! source)
254 0 : return NS_ERROR_NULL_POINTER;
255 :
256 0 : *source = nsnull;
257 0 : return NS_RDF_NO_VALUE;
258 : }
259 :
260 :
261 :
262 : NS_IMETHODIMP
263 0 : FileSystemDataSource::GetSources(nsIRDFResource *property,
264 : nsIRDFNode *target,
265 : bool tv,
266 : nsISimpleEnumerator **sources /* out */)
267 : {
268 : // NS_NOTYETIMPLEMENTED("write me");
269 0 : return NS_ERROR_NOT_IMPLEMENTED;
270 : }
271 :
272 :
273 :
274 : NS_IMETHODIMP
275 0 : FileSystemDataSource::GetTarget(nsIRDFResource *source,
276 : nsIRDFResource *property,
277 : bool tv,
278 : nsIRDFNode **target /* out */)
279 : {
280 0 : NS_PRECONDITION(source != nsnull, "null ptr");
281 0 : if (! source)
282 0 : return NS_ERROR_NULL_POINTER;
283 :
284 0 : NS_PRECONDITION(property != nsnull, "null ptr");
285 0 : if (! property)
286 0 : return NS_ERROR_NULL_POINTER;
287 :
288 0 : NS_PRECONDITION(target != nsnull, "null ptr");
289 0 : if (! target)
290 0 : return NS_ERROR_NULL_POINTER;
291 :
292 0 : *target = nsnull;
293 :
294 0 : nsresult rv = NS_RDF_NO_VALUE;
295 :
296 : // we only have positive assertions in the file system data source.
297 0 : if (! tv)
298 0 : return NS_RDF_NO_VALUE;
299 :
300 0 : if (source == mNC_FileSystemRoot)
301 : {
302 0 : if (property == mNC_pulse)
303 : {
304 : nsIRDFLiteral *pulseLiteral;
305 0 : mRDFService->GetLiteral(NS_LITERAL_STRING("12").get(), &pulseLiteral);
306 0 : *target = pulseLiteral;
307 0 : return NS_OK;
308 : }
309 : }
310 0 : else if (isFileURI(source))
311 : {
312 0 : if (property == mNC_Name)
313 : {
314 0 : nsCOMPtr<nsIRDFLiteral> name;
315 0 : rv = GetName(source, getter_AddRefs(name));
316 0 : if (NS_FAILED(rv)) return(rv);
317 0 : if (!name) rv = NS_RDF_NO_VALUE;
318 0 : if (rv == NS_RDF_NO_VALUE) return(rv);
319 0 : return name->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
320 : }
321 0 : else if (property == mNC_URL)
322 : {
323 0 : nsCOMPtr<nsIRDFLiteral> url;
324 0 : rv = GetURL(source, nsnull, getter_AddRefs(url));
325 0 : if (NS_FAILED(rv)) return(rv);
326 0 : if (!url) rv = NS_RDF_NO_VALUE;
327 0 : if (rv == NS_RDF_NO_VALUE) return(rv);
328 :
329 0 : return url->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
330 : }
331 0 : else if (property == mNC_Icon)
332 : {
333 0 : nsCOMPtr<nsIRDFLiteral> url;
334 0 : bool isFavorite = false;
335 0 : rv = GetURL(source, &isFavorite, getter_AddRefs(url));
336 0 : if (NS_FAILED(rv)) return(rv);
337 0 : if (isFavorite || !url) rv = NS_RDF_NO_VALUE;
338 0 : if (rv == NS_RDF_NO_VALUE) return(rv);
339 :
340 0 : const PRUnichar *uni = nsnull;
341 0 : url->GetValueConst(&uni);
342 0 : if (!uni) return(NS_RDF_NO_VALUE);
343 0 : nsAutoString urlStr;
344 0 : urlStr.Assign(NS_LITERAL_STRING(NS_MOZICON_SCHEME).get());
345 0 : urlStr.Append(uni);
346 :
347 0 : rv = mRDFService->GetLiteral(urlStr.get(), getter_AddRefs(url));
348 0 : if (NS_FAILED(rv) || !url) return(NS_RDF_NO_VALUE);
349 0 : return url->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
350 : }
351 0 : else if (property == mNC_Length)
352 : {
353 0 : nsCOMPtr<nsIRDFInt> fileSize;
354 0 : rv = GetFileSize(source, getter_AddRefs(fileSize));
355 0 : if (NS_FAILED(rv)) return(rv);
356 0 : if (!fileSize) rv = NS_RDF_NO_VALUE;
357 0 : if (rv == NS_RDF_NO_VALUE) return(rv);
358 :
359 0 : return fileSize->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
360 : }
361 0 : else if (property == mNC_IsDirectory)
362 : {
363 0 : *target = (isDirURI(source)) ? mLiteralTrue : mLiteralFalse;
364 0 : NS_ADDREF(*target);
365 0 : return NS_OK;
366 : }
367 0 : else if (property == mWEB_LastMod)
368 : {
369 0 : nsCOMPtr<nsIRDFDate> lastMod;
370 0 : rv = GetLastMod(source, getter_AddRefs(lastMod));
371 0 : if (NS_FAILED(rv)) return(rv);
372 0 : if (!lastMod) rv = NS_RDF_NO_VALUE;
373 0 : if (rv == NS_RDF_NO_VALUE) return(rv);
374 :
375 0 : return lastMod->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
376 : }
377 0 : else if (property == mRDF_type)
378 : {
379 0 : nsCString type;
380 0 : rv = mNC_FileSystemObject->GetValueUTF8(type);
381 0 : if (NS_FAILED(rv)) return(rv);
382 :
383 : #ifdef XP_WIN
384 : // under Windows, if its an IE favorite, return that type
385 : if (!ieFavoritesDir.IsEmpty())
386 : {
387 : nsCString uri;
388 : rv = source->GetValueUTF8(uri);
389 : if (NS_FAILED(rv)) return(rv);
390 :
391 : NS_ConvertUTF8toUTF16 theURI(uri);
392 :
393 : if (theURI.Find(ieFavoritesDir) == 0)
394 : {
395 : if (theURI[theURI.Length() - 1] == '/')
396 : {
397 : rv = mNC_IEFavoriteFolder->GetValueUTF8(type);
398 : }
399 : else
400 : {
401 : rv = mNC_IEFavoriteObject->GetValueUTF8(type);
402 : }
403 : if (NS_FAILED(rv)) return(rv);
404 : }
405 : }
406 : #endif
407 :
408 0 : NS_ConvertUTF8toUTF16 url(type);
409 0 : nsCOMPtr<nsIRDFLiteral> literal;
410 0 : mRDFService->GetLiteral(url.get(), getter_AddRefs(literal));
411 0 : rv = literal->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
412 0 : return(rv);
413 : }
414 0 : else if (property == mNC_pulse)
415 : {
416 0 : nsCOMPtr<nsIRDFLiteral> pulseLiteral;
417 0 : mRDFService->GetLiteral(NS_LITERAL_STRING("12").get(), getter_AddRefs(pulseLiteral));
418 0 : rv = pulseLiteral->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
419 0 : return(rv);
420 : }
421 0 : else if (property == mNC_Child)
422 : {
423 : // Oh this is evil. Somebody kill me now.
424 0 : nsCOMPtr<nsISimpleEnumerator> children;
425 0 : rv = GetFolderList(source, false, true, getter_AddRefs(children));
426 0 : if (NS_FAILED(rv) || (rv == NS_RDF_NO_VALUE)) return(rv);
427 :
428 : bool hasMore;
429 0 : rv = children->HasMoreElements(&hasMore);
430 0 : if (NS_FAILED(rv)) return(rv);
431 :
432 0 : if (hasMore)
433 : {
434 0 : nsCOMPtr<nsISupports> isupports;
435 0 : rv = children->GetNext(getter_AddRefs(isupports));
436 0 : if (NS_FAILED(rv)) return(rv);
437 :
438 0 : return isupports->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
439 : }
440 : }
441 : #ifdef USE_NC_EXTENSION
442 0 : else if (property == mNC_extension)
443 : {
444 0 : nsCOMPtr<nsIRDFLiteral> extension;
445 0 : rv = GetExtension(source, getter_AddRefs(extension));
446 0 : if (!extension) rv = NS_RDF_NO_VALUE;
447 0 : if (rv == NS_RDF_NO_VALUE) return(rv);
448 0 : return extension->QueryInterface(NS_GET_IID(nsIRDFNode), (void**) target);
449 : }
450 : #endif
451 : }
452 :
453 0 : return(NS_RDF_NO_VALUE);
454 : }
455 :
456 :
457 :
458 : NS_IMETHODIMP
459 0 : FileSystemDataSource::GetTargets(nsIRDFResource *source,
460 : nsIRDFResource *property,
461 : bool tv,
462 : nsISimpleEnumerator **targets /* out */)
463 : {
464 0 : NS_PRECONDITION(source != nsnull, "null ptr");
465 0 : if (! source)
466 0 : return NS_ERROR_NULL_POINTER;
467 :
468 0 : NS_PRECONDITION(property != nsnull, "null ptr");
469 0 : if (! property)
470 0 : return NS_ERROR_NULL_POINTER;
471 :
472 0 : NS_PRECONDITION(targets != nsnull, "null ptr");
473 0 : if (! targets)
474 0 : return NS_ERROR_NULL_POINTER;
475 :
476 0 : *targets = nsnull;
477 :
478 : // we only have positive assertions in the file system data source.
479 0 : if (! tv)
480 0 : return NS_RDF_NO_VALUE;
481 :
482 : nsresult rv;
483 :
484 0 : if (source == mNC_FileSystemRoot)
485 : {
486 0 : if (property == mNC_Child)
487 : {
488 0 : return GetVolumeList(targets);
489 : }
490 0 : else if (property == mNC_pulse)
491 : {
492 0 : nsCOMPtr<nsIRDFLiteral> pulseLiteral;
493 0 : mRDFService->GetLiteral(NS_LITERAL_STRING("12").get(),
494 0 : getter_AddRefs(pulseLiteral));
495 0 : return NS_NewSingletonEnumerator(targets, pulseLiteral);
496 : }
497 : }
498 0 : else if (isFileURI(source))
499 : {
500 0 : if (property == mNC_Child)
501 : {
502 0 : return GetFolderList(source, false, false, targets);
503 : }
504 0 : else if (property == mNC_Name)
505 : {
506 0 : nsCOMPtr<nsIRDFLiteral> name;
507 0 : rv = GetName(source, getter_AddRefs(name));
508 0 : if (NS_FAILED(rv)) return rv;
509 :
510 0 : return NS_NewSingletonEnumerator(targets, name);
511 : }
512 0 : else if (property == mNC_URL)
513 : {
514 0 : nsCOMPtr<nsIRDFLiteral> url;
515 0 : rv = GetURL(source, nsnull, getter_AddRefs(url));
516 0 : if (NS_FAILED(rv)) return rv;
517 :
518 0 : return NS_NewSingletonEnumerator(targets, url);
519 : }
520 0 : else if (property == mRDF_type)
521 : {
522 0 : nsCString uri;
523 0 : rv = mNC_FileSystemObject->GetValueUTF8(uri);
524 0 : if (NS_FAILED(rv)) return rv;
525 :
526 0 : NS_ConvertUTF8toUTF16 url(uri);
527 :
528 0 : nsCOMPtr<nsIRDFLiteral> literal;
529 0 : rv = mRDFService->GetLiteral(url.get(), getter_AddRefs(literal));
530 0 : if (NS_FAILED(rv)) return rv;
531 :
532 0 : return NS_NewSingletonEnumerator(targets, literal);
533 : }
534 0 : else if (property == mNC_pulse)
535 : {
536 0 : nsCOMPtr<nsIRDFLiteral> pulseLiteral;
537 0 : rv = mRDFService->GetLiteral(NS_LITERAL_STRING("12").get(),
538 0 : getter_AddRefs(pulseLiteral));
539 0 : if (NS_FAILED(rv)) return rv;
540 :
541 0 : return NS_NewSingletonEnumerator(targets, pulseLiteral);
542 : }
543 : }
544 :
545 0 : return NS_NewEmptyEnumerator(targets);
546 : }
547 :
548 :
549 :
550 : NS_IMETHODIMP
551 0 : FileSystemDataSource::Assert(nsIRDFResource *source,
552 : nsIRDFResource *property,
553 : nsIRDFNode *target,
554 : bool tv)
555 : {
556 0 : return NS_RDF_ASSERTION_REJECTED;
557 : }
558 :
559 :
560 :
561 : NS_IMETHODIMP
562 0 : FileSystemDataSource::Unassert(nsIRDFResource *source,
563 : nsIRDFResource *property,
564 : nsIRDFNode *target)
565 : {
566 0 : return NS_RDF_ASSERTION_REJECTED;
567 : }
568 :
569 :
570 :
571 : NS_IMETHODIMP
572 0 : FileSystemDataSource::Change(nsIRDFResource* aSource,
573 : nsIRDFResource* aProperty,
574 : nsIRDFNode* aOldTarget,
575 : nsIRDFNode* aNewTarget)
576 : {
577 0 : return NS_RDF_ASSERTION_REJECTED;
578 : }
579 :
580 :
581 :
582 : NS_IMETHODIMP
583 0 : FileSystemDataSource::Move(nsIRDFResource* aOldSource,
584 : nsIRDFResource* aNewSource,
585 : nsIRDFResource* aProperty,
586 : nsIRDFNode* aTarget)
587 : {
588 0 : return NS_RDF_ASSERTION_REJECTED;
589 : }
590 :
591 :
592 :
593 : NS_IMETHODIMP
594 0 : FileSystemDataSource::HasAssertion(nsIRDFResource *source,
595 : nsIRDFResource *property,
596 : nsIRDFNode *target,
597 : bool tv,
598 : bool *hasAssertion /* out */)
599 : {
600 0 : NS_PRECONDITION(source != nsnull, "null ptr");
601 0 : if (! source)
602 0 : return NS_ERROR_NULL_POINTER;
603 :
604 0 : NS_PRECONDITION(property != nsnull, "null ptr");
605 0 : if (! property)
606 0 : return NS_ERROR_NULL_POINTER;
607 :
608 0 : NS_PRECONDITION(target != nsnull, "null ptr");
609 0 : if (! target)
610 0 : return NS_ERROR_NULL_POINTER;
611 :
612 0 : NS_PRECONDITION(hasAssertion != nsnull, "null ptr");
613 0 : if (! hasAssertion)
614 0 : return NS_ERROR_NULL_POINTER;
615 :
616 : // we only have positive assertions in the file system data source.
617 0 : *hasAssertion = false;
618 :
619 0 : if (! tv) {
620 0 : return NS_OK;
621 : }
622 :
623 0 : if ((source == mNC_FileSystemRoot) || isFileURI(source))
624 : {
625 0 : if (property == mRDF_type)
626 : {
627 0 : nsCOMPtr<nsIRDFResource> resource( do_QueryInterface(target) );
628 0 : if (resource.get() == mRDF_type)
629 : {
630 0 : *hasAssertion = true;
631 : }
632 : }
633 : #ifdef USE_NC_EXTENSION
634 0 : else if (property == mNC_extension)
635 : {
636 : // Cheat just a little here by making dirs always match
637 0 : if (isDirURI(source))
638 : {
639 0 : *hasAssertion = true;
640 : }
641 : else
642 : {
643 0 : nsCOMPtr<nsIRDFLiteral> extension;
644 0 : GetExtension(source, getter_AddRefs(extension));
645 0 : if (extension.get() == target)
646 : {
647 0 : *hasAssertion = true;
648 : }
649 : }
650 : }
651 : #endif
652 0 : else if (property == mNC_IsDirectory)
653 : {
654 0 : bool isDir = isDirURI(source);
655 0 : bool isEqual = false;
656 0 : target->EqualsNode(mLiteralTrue, &isEqual);
657 0 : if (isEqual)
658 : {
659 0 : *hasAssertion = isDir;
660 : }
661 : else
662 : {
663 0 : target->EqualsNode(mLiteralFalse, &isEqual);
664 0 : if (isEqual)
665 0 : *hasAssertion = !isDir;
666 : }
667 : }
668 : }
669 :
670 0 : return NS_OK;
671 : }
672 :
673 :
674 :
675 : NS_IMETHODIMP
676 0 : FileSystemDataSource::HasArcIn(nsIRDFNode *aNode, nsIRDFResource *aArc, bool *result)
677 : {
678 0 : return NS_ERROR_NOT_IMPLEMENTED;
679 : }
680 :
681 :
682 :
683 : NS_IMETHODIMP
684 0 : FileSystemDataSource::HasArcOut(nsIRDFResource *aSource, nsIRDFResource *aArc, bool *result)
685 : {
686 0 : *result = false;
687 :
688 0 : if (aSource == mNC_FileSystemRoot)
689 : {
690 0 : *result = (aArc == mNC_Child || aArc == mNC_pulse);
691 : }
692 0 : else if (isFileURI(aSource))
693 : {
694 0 : if (aArc == mNC_pulse)
695 : {
696 0 : *result = true;
697 : }
698 0 : else if (isDirURI(aSource))
699 : {
700 : #ifdef XP_WIN
701 : *result = isValidFolder(aSource);
702 : #else
703 0 : *result = true;
704 : #endif
705 : }
706 0 : else if (aArc == mNC_pulse || aArc == mNC_Name || aArc == mNC_Icon ||
707 0 : aArc == mNC_URL || aArc == mNC_Length || aArc == mWEB_LastMod ||
708 0 : aArc == mNC_FileSystemObject || aArc == mRDF_InstanceOf ||
709 0 : aArc == mRDF_type)
710 : {
711 0 : *result = true;
712 : }
713 : }
714 0 : return NS_OK;
715 : }
716 :
717 :
718 :
719 : NS_IMETHODIMP
720 0 : FileSystemDataSource::ArcLabelsIn(nsIRDFNode *node,
721 : nsISimpleEnumerator ** labels /* out */)
722 : {
723 : // NS_NOTYETIMPLEMENTED("write me");
724 0 : return NS_ERROR_NOT_IMPLEMENTED;
725 : }
726 :
727 :
728 :
729 : NS_IMETHODIMP
730 0 : FileSystemDataSource::ArcLabelsOut(nsIRDFResource *source,
731 : nsISimpleEnumerator **labels /* out */)
732 : {
733 0 : NS_PRECONDITION(source != nsnull, "null ptr");
734 0 : if (! source)
735 0 : return NS_ERROR_NULL_POINTER;
736 :
737 0 : NS_PRECONDITION(labels != nsnull, "null ptr");
738 0 : if (! labels)
739 0 : return NS_ERROR_NULL_POINTER;
740 :
741 : nsresult rv;
742 :
743 0 : if (source == mNC_FileSystemRoot)
744 : {
745 0 : nsCOMPtr<nsISupportsArray> array;
746 0 : rv = NS_NewISupportsArray(getter_AddRefs(array));
747 0 : if (NS_FAILED(rv)) return rv;
748 :
749 0 : array->AppendElement(mNC_Child);
750 0 : array->AppendElement(mNC_pulse);
751 :
752 0 : return NS_NewArrayEnumerator(labels, array);
753 : }
754 0 : else if (isFileURI(source))
755 : {
756 0 : nsCOMPtr<nsISupportsArray> array;
757 0 : rv = NS_NewISupportsArray(getter_AddRefs(array));
758 0 : if (NS_FAILED(rv)) return rv;
759 :
760 0 : if (isDirURI(source))
761 : {
762 : #ifdef XP_WIN
763 : if (isValidFolder(source))
764 : {
765 : array->AppendElement(mNC_Child);
766 : }
767 : #else
768 0 : array->AppendElement(mNC_Child);
769 : #endif
770 0 : array->AppendElement(mNC_pulse);
771 : }
772 :
773 0 : return NS_NewArrayEnumerator(labels, array);
774 : }
775 :
776 0 : return NS_NewEmptyEnumerator(labels);
777 : }
778 :
779 :
780 :
781 : NS_IMETHODIMP
782 0 : FileSystemDataSource::GetAllResources(nsISimpleEnumerator** aCursor)
783 : {
784 0 : NS_NOTYETIMPLEMENTED("sorry!");
785 0 : return NS_ERROR_NOT_IMPLEMENTED;
786 : }
787 :
788 :
789 :
790 : NS_IMETHODIMP
791 0 : FileSystemDataSource::AddObserver(nsIRDFObserver *n)
792 : {
793 0 : return NS_ERROR_NOT_IMPLEMENTED;
794 : }
795 :
796 :
797 :
798 : NS_IMETHODIMP
799 0 : FileSystemDataSource::RemoveObserver(nsIRDFObserver *n)
800 : {
801 0 : return NS_ERROR_NOT_IMPLEMENTED;
802 : }
803 :
804 :
805 :
806 : NS_IMETHODIMP
807 0 : FileSystemDataSource::GetAllCmds(nsIRDFResource* source,
808 : nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
809 : {
810 0 : return(NS_NewEmptyEnumerator(commands));
811 : }
812 :
813 :
814 :
815 : NS_IMETHODIMP
816 0 : FileSystemDataSource::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
817 : nsIRDFResource* aCommand,
818 : nsISupportsArray/*<nsIRDFResource>*/* aArguments,
819 : bool* aResult)
820 : {
821 0 : return(NS_ERROR_NOT_IMPLEMENTED);
822 : }
823 :
824 :
825 :
826 : NS_IMETHODIMP
827 0 : FileSystemDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
828 : nsIRDFResource* aCommand,
829 : nsISupportsArray/*<nsIRDFResource>*/* aArguments)
830 : {
831 0 : return(NS_ERROR_NOT_IMPLEMENTED);
832 : }
833 :
834 :
835 :
836 : NS_IMETHODIMP
837 0 : FileSystemDataSource::BeginUpdateBatch()
838 : {
839 0 : return NS_OK;
840 : }
841 :
842 :
843 :
844 : NS_IMETHODIMP
845 0 : FileSystemDataSource::EndUpdateBatch()
846 : {
847 0 : return NS_OK;
848 : }
849 :
850 :
851 :
852 : nsresult
853 0 : FileSystemDataSource::GetVolumeList(nsISimpleEnumerator** aResult)
854 : {
855 : nsresult rv;
856 0 : nsCOMPtr<nsISupportsArray> volumes;
857 :
858 0 : rv = NS_NewISupportsArray(getter_AddRefs(volumes));
859 0 : if (NS_FAILED(rv)) return rv;
860 :
861 0 : nsCOMPtr<nsIRDFResource> vol;
862 :
863 : #ifdef XP_WIN
864 :
865 : PRInt32 driveType;
866 : PRUnichar drive[32];
867 : PRInt32 volNum;
868 : char *url;
869 :
870 : for (volNum = 0; volNum < 26; volNum++)
871 : {
872 : swprintf( drive, L"%c:\\", volNum + (PRUnichar)'A');
873 :
874 : driveType = GetDriveTypeW(drive);
875 : if (driveType != DRIVE_UNKNOWN && driveType != DRIVE_NO_ROOT_DIR)
876 : {
877 : if (nsnull != (url = PR_smprintf("file:///%c|/", volNum + 'A')))
878 : {
879 : rv = mRDFService->GetResource(nsDependentCString(url),
880 : getter_AddRefs(vol));
881 : PR_Free(url);
882 :
883 : if (NS_FAILED(rv)) return rv;
884 : volumes->AppendElement(vol);
885 : }
886 : }
887 : }
888 : #endif
889 :
890 : #ifdef XP_UNIX
891 0 : mRDFService->GetResource(NS_LITERAL_CSTRING("file:///"), getter_AddRefs(vol));
892 0 : volumes->AppendElement(vol);
893 : #endif
894 :
895 : #ifdef XP_OS2
896 : ULONG ulDriveNo = 0;
897 : ULONG ulDriveMap = 0;
898 : char *url;
899 :
900 : rv = DosQueryCurrentDisk(&ulDriveNo, &ulDriveMap);
901 : if (NS_FAILED(rv))
902 : return rv;
903 :
904 : for (int volNum = 0; volNum < 26; volNum++)
905 : {
906 : if (((ulDriveMap << (31 - volNum)) >> 31))
907 : {
908 : if (nsnull != (url = PR_smprintf("file:///%c|/", volNum + 'A')))
909 : {
910 : rv = mRDFService->GetResource(nsDependentCString(url), getter_AddRefs(vol));
911 : PR_Free(url);
912 :
913 : if (NS_FAILED(rv)) return rv;
914 : volumes->AppendElement(vol);
915 : }
916 : }
917 :
918 : }
919 : #endif
920 :
921 0 : return NS_NewArrayEnumerator(aResult, volumes);
922 : }
923 :
924 :
925 :
926 : #ifdef XP_WIN
927 : bool
928 : FileSystemDataSource::isValidFolder(nsIRDFResource *source)
929 : {
930 : bool isValid = true;
931 : if (ieFavoritesDir.IsEmpty()) return(isValid);
932 :
933 : nsresult rv;
934 : nsCString uri;
935 : rv = source->GetValueUTF8(uri);
936 : if (NS_FAILED(rv)) return(isValid);
937 :
938 : NS_ConvertUTF8toUTF16 theURI(uri);
939 : if (theURI.Find(ieFavoritesDir) == 0)
940 : {
941 : isValid = false;
942 :
943 : nsCOMPtr<nsISimpleEnumerator> folderEnum;
944 : if (NS_SUCCEEDED(rv = GetFolderList(source, true, false, getter_AddRefs(folderEnum))))
945 : {
946 : bool hasAny = false, hasMore;
947 : while (NS_SUCCEEDED(folderEnum->HasMoreElements(&hasMore)) &&
948 : hasMore)
949 : {
950 : hasAny = true;
951 :
952 : nsCOMPtr<nsISupports> isupports;
953 : if (NS_FAILED(rv = folderEnum->GetNext(getter_AddRefs(isupports))))
954 : break;
955 : nsCOMPtr<nsIRDFResource> res = do_QueryInterface(isupports);
956 : if (!res) break;
957 :
958 : nsCOMPtr<nsIRDFLiteral> nameLiteral;
959 : if (NS_FAILED(rv = GetName(res, getter_AddRefs(nameLiteral))))
960 : break;
961 :
962 : const PRUnichar *uniName;
963 : if (NS_FAILED(rv = nameLiteral->GetValueConst(&uniName)))
964 : break;
965 : nsAutoString name(uniName);
966 :
967 : // An empty folder, or a folder that contains just "desktop.ini",
968 : // is considered to be a IE Favorite; otherwise, its a folder
969 : if (!name.LowerCaseEqualsLiteral("desktop.ini"))
970 : {
971 : isValid = true;
972 : break;
973 : }
974 : }
975 : if (!hasAny) isValid = true;
976 : }
977 : }
978 : return(isValid);
979 : }
980 : #endif
981 :
982 :
983 :
984 : nsresult
985 0 : FileSystemDataSource::GetFolderList(nsIRDFResource *source, bool allowHidden,
986 : bool onlyFirst, nsISimpleEnumerator** aResult)
987 : {
988 0 : if (!isDirURI(source))
989 0 : return(NS_RDF_NO_VALUE);
990 :
991 : nsresult rv;
992 0 : nsCOMPtr<nsISupportsArray> nameArray;
993 :
994 0 : rv = NS_NewISupportsArray(getter_AddRefs(nameArray));
995 0 : if (NS_FAILED(rv))
996 0 : return(rv);
997 :
998 0 : const char *parentURI = nsnull;
999 0 : rv = source->GetValueConst(&parentURI);
1000 0 : if (NS_FAILED(rv))
1001 0 : return(rv);
1002 0 : if (!parentURI)
1003 0 : return(NS_ERROR_UNEXPECTED);
1004 :
1005 0 : nsCOMPtr<nsIURI> aIURI;
1006 0 : if (NS_FAILED(rv = NS_NewURI(getter_AddRefs(aIURI), nsDependentCString(parentURI))))
1007 0 : return(rv);
1008 :
1009 0 : nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aIURI);
1010 0 : if (!fileURL)
1011 0 : return(false);
1012 :
1013 0 : nsCOMPtr<nsIFile> aDir;
1014 0 : if (NS_FAILED(rv = fileURL->GetFile(getter_AddRefs(aDir))))
1015 0 : return(rv);
1016 :
1017 : // ensure that we DO NOT resolve aliases
1018 0 : nsCOMPtr<nsILocalFile> aDirLocal = do_QueryInterface(aDir);
1019 0 : if (aDirLocal)
1020 0 : aDirLocal->SetFollowLinks(false);
1021 :
1022 0 : nsCOMPtr<nsISimpleEnumerator> dirContents;
1023 0 : if (NS_FAILED(rv = aDir->GetDirectoryEntries(getter_AddRefs(dirContents))))
1024 0 : return(rv);
1025 0 : if (!dirContents)
1026 0 : return(NS_ERROR_UNEXPECTED);
1027 :
1028 : bool hasMore;
1029 0 : while(NS_SUCCEEDED(rv = dirContents->HasMoreElements(&hasMore)) &&
1030 : hasMore)
1031 : {
1032 0 : nsCOMPtr<nsISupports> isupports;
1033 0 : if (NS_FAILED(rv = dirContents->GetNext(getter_AddRefs(isupports))))
1034 : break;
1035 :
1036 0 : nsCOMPtr<nsIFile> aFile = do_QueryInterface(isupports);
1037 0 : if (!aFile)
1038 : break;
1039 :
1040 0 : if (!allowHidden)
1041 : {
1042 0 : bool hiddenFlag = false;
1043 0 : if (NS_FAILED(rv = aFile->IsHidden(&hiddenFlag)))
1044 : break;
1045 0 : if (hiddenFlag)
1046 0 : continue;
1047 : }
1048 :
1049 0 : nsAutoString leafStr;
1050 0 : if (NS_FAILED(rv = aFile->GetLeafName(leafStr)))
1051 : break;
1052 0 : if (leafStr.IsEmpty())
1053 0 : continue;
1054 :
1055 0 : nsCAutoString fullURI;
1056 0 : fullURI.Assign(parentURI);
1057 0 : if (fullURI.Last() != '/')
1058 : {
1059 0 : fullURI.Append('/');
1060 : }
1061 :
1062 0 : char *escLeafStr = nsEscape(NS_ConvertUTF16toUTF8(leafStr).get(), url_Path);
1063 0 : leafStr.Truncate();
1064 :
1065 0 : if (!escLeafStr)
1066 0 : continue;
1067 :
1068 0 : nsCAutoString leaf(escLeafStr);
1069 0 : NS_Free(escLeafStr);
1070 0 : escLeafStr = nsnull;
1071 :
1072 : // using nsEscape() [above] doesn't escape slashes, so do that by hand
1073 : PRInt32 aOffset;
1074 0 : while ((aOffset = leaf.FindChar('/')) >= 0)
1075 : {
1076 0 : leaf.Cut((PRUint32)aOffset, 1);
1077 0 : leaf.Insert("%2F", (PRUint32)aOffset);
1078 : }
1079 :
1080 : // append the encoded name
1081 0 : fullURI.Append(leaf);
1082 :
1083 0 : bool dirFlag = false;
1084 0 : rv = aFile->IsDirectory(&dirFlag);
1085 0 : if (NS_SUCCEEDED(rv) && dirFlag)
1086 : {
1087 0 : fullURI.Append('/');
1088 : }
1089 :
1090 0 : nsCOMPtr<nsIRDFResource> fileRes;
1091 0 : mRDFService->GetResource(fullURI, getter_AddRefs(fileRes));
1092 :
1093 0 : nameArray->AppendElement(fileRes);
1094 :
1095 0 : if (onlyFirst)
1096 : break;
1097 : }
1098 :
1099 0 : return NS_NewArrayEnumerator(aResult, nameArray);
1100 : }
1101 :
1102 : nsresult
1103 0 : FileSystemDataSource::GetLastMod(nsIRDFResource *source, nsIRDFDate **aResult)
1104 : {
1105 0 : *aResult = nsnull;
1106 :
1107 : nsresult rv;
1108 0 : const char *uri = nsnull;
1109 :
1110 0 : rv = source->GetValueConst(&uri);
1111 0 : if (NS_FAILED(rv)) return(rv);
1112 0 : if (!uri)
1113 0 : return(NS_ERROR_UNEXPECTED);
1114 :
1115 0 : nsCOMPtr<nsIURI> aIURI;
1116 0 : if (NS_FAILED(rv = NS_NewURI(getter_AddRefs(aIURI), nsDependentCString(uri))))
1117 0 : return(rv);
1118 :
1119 0 : nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aIURI);
1120 0 : if (!fileURL)
1121 0 : return(false);
1122 :
1123 0 : nsCOMPtr<nsIFile> aFile;
1124 0 : if (NS_FAILED(rv = fileURL->GetFile(getter_AddRefs(aFile))))
1125 0 : return(rv);
1126 0 : if (!aFile)
1127 0 : return(NS_ERROR_UNEXPECTED);
1128 :
1129 : // ensure that we DO NOT resolve aliases
1130 0 : nsCOMPtr<nsILocalFile> aFileLocal = do_QueryInterface(aFile);
1131 0 : if (aFileLocal)
1132 0 : aFileLocal->SetFollowLinks(false);
1133 :
1134 : PRInt64 lastModDate;
1135 0 : if (NS_FAILED(rv = aFile->GetLastModifiedTime(&lastModDate)))
1136 0 : return(rv);
1137 :
1138 : // convert from milliseconds to seconds
1139 : PRTime temp64, thousand;
1140 0 : LL_I2L(thousand, PR_MSEC_PER_SEC);
1141 0 : LL_MUL(temp64, lastModDate, thousand);
1142 :
1143 0 : mRDFService->GetDateLiteral(temp64, aResult);
1144 :
1145 0 : return(NS_OK);
1146 : }
1147 :
1148 :
1149 :
1150 : nsresult
1151 0 : FileSystemDataSource::GetFileSize(nsIRDFResource *source, nsIRDFInt **aResult)
1152 : {
1153 0 : *aResult = nsnull;
1154 :
1155 : nsresult rv;
1156 0 : const char *uri = nsnull;
1157 :
1158 0 : rv = source->GetValueConst(&uri);
1159 0 : if (NS_FAILED(rv))
1160 0 : return(rv);
1161 0 : if (!uri)
1162 0 : return(NS_ERROR_UNEXPECTED);
1163 :
1164 0 : nsCOMPtr<nsIURI> aIURI;
1165 0 : if (NS_FAILED(rv = NS_NewURI(getter_AddRefs(aIURI), nsDependentCString(uri))))
1166 0 : return(rv);
1167 :
1168 0 : nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aIURI);
1169 0 : if (!fileURL)
1170 0 : return(false);
1171 :
1172 0 : nsCOMPtr<nsIFile> aFile;
1173 0 : if (NS_FAILED(rv = fileURL->GetFile(getter_AddRefs(aFile))))
1174 0 : return(rv);
1175 0 : if (!aFile)
1176 0 : return(NS_ERROR_UNEXPECTED);
1177 :
1178 : // ensure that we DO NOT resolve aliases
1179 0 : nsCOMPtr<nsILocalFile> aFileLocal = do_QueryInterface(aFile);
1180 0 : if (aFileLocal)
1181 0 : aFileLocal->SetFollowLinks(false);
1182 :
1183 : // don't do anything with directories
1184 0 : bool isDir = false;
1185 0 : if (NS_FAILED(rv = aFile->IsDirectory(&isDir)))
1186 0 : return(rv);
1187 0 : if (isDir)
1188 0 : return(NS_RDF_NO_VALUE);
1189 :
1190 : PRInt64 aFileSize64;
1191 0 : if (NS_FAILED(rv = aFile->GetFileSize(&aFileSize64)))
1192 0 : return(rv);
1193 :
1194 : // convert 64bits to 32bits
1195 0 : PRInt32 aFileSize32 = 0;
1196 0 : LL_L2I(aFileSize32, aFileSize64);
1197 :
1198 0 : mRDFService->GetIntLiteral(aFileSize32, aResult);
1199 :
1200 0 : return(NS_OK);
1201 : }
1202 :
1203 :
1204 :
1205 : nsresult
1206 0 : FileSystemDataSource::GetName(nsIRDFResource *source, nsIRDFLiteral **aResult)
1207 : {
1208 : nsresult rv;
1209 0 : const char *uri = nsnull;
1210 :
1211 0 : rv = source->GetValueConst(&uri);
1212 0 : if (NS_FAILED(rv))
1213 0 : return(rv);
1214 0 : if (!uri)
1215 0 : return(NS_ERROR_UNEXPECTED);
1216 :
1217 0 : nsCOMPtr<nsIURI> aIURI;
1218 0 : if (NS_FAILED(rv = NS_NewURI(getter_AddRefs(aIURI), nsDependentCString(uri))))
1219 0 : return(rv);
1220 :
1221 0 : nsCOMPtr<nsIFileURL> fileURL = do_QueryInterface(aIURI);
1222 0 : if (!fileURL)
1223 0 : return(false);
1224 :
1225 0 : nsCOMPtr<nsIFile> aFile;
1226 0 : if (NS_FAILED(rv = fileURL->GetFile(getter_AddRefs(aFile))))
1227 0 : return(rv);
1228 0 : if (!aFile)
1229 0 : return(NS_ERROR_UNEXPECTED);
1230 :
1231 : // ensure that we DO NOT resolve aliases
1232 0 : nsCOMPtr<nsILocalFile> aFileLocal = do_QueryInterface(aFile);
1233 0 : if (aFileLocal)
1234 0 : aFileLocal->SetFollowLinks(false);
1235 :
1236 0 : nsAutoString name;
1237 0 : if (NS_FAILED(rv = aFile->GetLeafName(name)))
1238 0 : return(rv);
1239 0 : if (name.IsEmpty())
1240 0 : return(NS_ERROR_UNEXPECTED);
1241 :
1242 : #ifdef XP_WIN
1243 : // special hack for IE favorites under Windows; strip off the
1244 : // trailing ".url" or ".lnk" at the end of IE favorites names
1245 : PRInt32 nameLen = name.Length();
1246 : if ((strncmp(uri, ieFavoritesDir.get(), ieFavoritesDir.Length()) == 0) && (nameLen > 4))
1247 : {
1248 : nsAutoString extension;
1249 : name.Right(extension, 4);
1250 : if (extension.LowerCaseEqualsLiteral(".url") ||
1251 : extension.LowerCaseEqualsLiteral(".lnk"))
1252 : {
1253 : name.Truncate(nameLen - 4);
1254 : }
1255 : }
1256 : #endif
1257 :
1258 0 : mRDFService->GetLiteral(name.get(), aResult);
1259 :
1260 0 : return NS_OK;
1261 : }
1262 :
1263 :
1264 :
1265 : #ifdef USE_NC_EXTENSION
1266 : nsresult
1267 0 : FileSystemDataSource::GetExtension(nsIRDFResource *source, nsIRDFLiteral **aResult)
1268 : {
1269 0 : nsCOMPtr<nsIRDFLiteral> name;
1270 0 : nsresult rv = GetName(source, getter_AddRefs(name));
1271 0 : if (NS_FAILED(rv))
1272 0 : return rv;
1273 :
1274 : const PRUnichar* unicodeLeafName;
1275 0 : rv = name->GetValueConst(&unicodeLeafName);
1276 0 : if (NS_FAILED(rv))
1277 0 : return rv;
1278 :
1279 0 : nsAutoString filename(unicodeLeafName);
1280 0 : PRInt32 lastDot = filename.RFindChar('.');
1281 0 : if (lastDot == -1)
1282 : {
1283 0 : mRDFService->GetLiteral(EmptyString().get(), aResult);
1284 : }
1285 : else
1286 : {
1287 0 : nsAutoString extension;
1288 0 : filename.Right(extension, (filename.Length() - lastDot));
1289 0 : mRDFService->GetLiteral(extension.get(), aResult);
1290 : }
1291 :
1292 0 : return NS_OK;
1293 : }
1294 : #endif
1295 :
1296 : #ifdef XP_WIN
1297 : nsresult
1298 : FileSystemDataSource::getIEFavoriteURL(nsIRDFResource *source, nsString aFileURL, nsIRDFLiteral **urlLiteral)
1299 : {
1300 : nsresult rv = NS_OK;
1301 :
1302 : *urlLiteral = nsnull;
1303 :
1304 : nsCOMPtr<nsIFile> f;
1305 : NS_GetFileFromURLSpec(NS_ConvertUTF16toUTF8(aFileURL), getter_AddRefs(f));
1306 :
1307 : bool value;
1308 :
1309 : if (NS_SUCCEEDED(f->IsDirectory(&value)) && value)
1310 : {
1311 : if (isValidFolder(source))
1312 : return(NS_RDF_NO_VALUE);
1313 : aFileURL.AppendLiteral("desktop.ini");
1314 : }
1315 : else if (aFileURL.Length() > 4)
1316 : {
1317 : nsAutoString extension;
1318 :
1319 : aFileURL.Right(extension, 4);
1320 : if (!extension.LowerCaseEqualsLiteral(".url"))
1321 : {
1322 : return(NS_RDF_NO_VALUE);
1323 : }
1324 : }
1325 :
1326 : nsCOMPtr<nsIInputStream> strm;
1327 : NS_NewLocalFileInputStream(getter_AddRefs(strm),f);
1328 : nsCOMPtr<nsILineInputStream> linereader = do_QueryInterface(strm, &rv);
1329 :
1330 : nsAutoString line;
1331 : nsCAutoString cLine;
1332 : while(NS_SUCCEEDED(rv))
1333 : {
1334 : bool isEOF;
1335 : rv = linereader->ReadLine(cLine, &isEOF);
1336 : CopyASCIItoUTF16(cLine, line);
1337 :
1338 : if (isEOF)
1339 : {
1340 : if (line.Find("URL=", true) == 0)
1341 : {
1342 : line.Cut(0, 4);
1343 : rv = mRDFService->GetLiteral(line.get(), urlLiteral);
1344 : break;
1345 : }
1346 : else if (line.Find("CDFURL=", true) == 0)
1347 : {
1348 : line.Cut(0, 7);
1349 : rv = mRDFService->GetLiteral(line.get(), urlLiteral);
1350 : break;
1351 : }
1352 : line.Truncate();
1353 : }
1354 : }
1355 :
1356 : return(rv);
1357 : }
1358 : #endif
1359 :
1360 :
1361 :
1362 : nsresult
1363 0 : FileSystemDataSource::GetURL(nsIRDFResource *source, bool *isFavorite, nsIRDFLiteral** aResult)
1364 : {
1365 0 : if (isFavorite) *isFavorite = false;
1366 :
1367 : nsresult rv;
1368 0 : nsCString uri;
1369 :
1370 0 : rv = source->GetValueUTF8(uri);
1371 0 : if (NS_FAILED(rv))
1372 0 : return(rv);
1373 :
1374 0 : NS_ConvertUTF8toUTF16 url(uri);
1375 :
1376 : #ifdef XP_WIN
1377 : // under Windows, if its an IE favorite, munge the URL
1378 : if (!ieFavoritesDir.IsEmpty())
1379 : {
1380 : if (url.Find(ieFavoritesDir) == 0)
1381 : {
1382 : if (isFavorite) *isFavorite = true;
1383 : rv = getIEFavoriteURL(source, url, aResult);
1384 : return(rv);
1385 : }
1386 : }
1387 : #endif
1388 :
1389 : // if we fall through to here, its not any type of bookmark
1390 : // stored in the platform native file system, so just set the URL
1391 :
1392 0 : mRDFService->GetLiteral(url.get(), aResult);
1393 :
1394 0 : return(NS_OK);
1395 4392 : }
|