1 /*****************************************************************************
2 *
3 * Copyright (c) 2008-2010, CoreCodec, Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * * Neither the name of CoreCodec, Inc. nor the
14 * names of its contributors may be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY CoreCodec, Inc. ``AS IS'' AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL CoreCodec, Inc. BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 ****************************************************************************/
29
30 #include "file.h"
31
SetFileExt(tchar_t * URL,size_t URLLen,const tchar_t * Ext)32 bool_t SetFileExt(tchar_t* URL, size_t URLLen, const tchar_t* Ext)
33 {
34 tchar_t *p,*q,*p2;
35 bool_t HasHost;
36
37 p = (tchar_t*) GetProtocol(URL,NULL,0,&HasHost);
38 q = p;
39
40 p = tcsrchr(q,'\\');
41 p2 = tcsrchr(q,'/');
42 if (!p || (p2 && p2>p))
43 p=p2;
44 if (p)
45 q = p+1;
46 else
47 if (HasHost) // only hostname
48 return 0;
49
50 if (!q[0]) // no filename at all?
51 return 0;
52
53 p = tcsrchr(q,'.');
54 if (p)
55 *p = 0;
56
57 tcscat_s(URL,URLLen,T("."));
58 tcscat_s(URL,URLLen,Ext);
59 return 1;
60 }
61
AddPathDelimiter(tchar_t * Path,size_t PathLen)62 void AddPathDelimiter(tchar_t* Path,size_t PathLen)
63 {
64 size_t n = tcslen(Path);
65 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
66 bool_t HasProtocol = GetProtocol(Path,NULL,0,NULL)==Path;
67 if (!n || (n>0 && (HasProtocol || Path[n-1] != '/') && (!HasProtocol || Path[n-1] != '\\')))
68 {
69 if (HasProtocol)
70 tcscat_s(Path,PathLen,T("\\"));
71 else
72 tcscat_s(Path,PathLen,T("/"));
73 }
74 #elif defined(TARGET_PS2SDK)
75 if (!n || (n>0 && Path[n-1] != '/' && Path[n-1] != '\\' && Path[n-1] != ':'))
76 tcscat_s(Path,PathLen,T("/"));
77 #else
78 if (!n || (n>0 && Path[n-1] != '/'))
79 tcscat_s(Path,PathLen,T("/"));
80 #endif
81 }
82
RemovePathDelimiter(tchar_t * Path)83 void RemovePathDelimiter(tchar_t* Path)
84 {
85 size_t n = tcslen(Path);
86 const tchar_t* s = GetProtocol(Path,NULL,0,NULL);
87 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
88 bool_t HasProtocol = s==Path;
89 if (s[0] && n>0 && ((HasProtocol && Path[n-1] == '\\') || (!HasProtocol && Path[n-1] == '/')))
90 #else
91 if (s[0] && n>0 && Path[n-1] == '/' && n > 1)
92 #endif
93 Path[n-1] = 0;
94 }
95
GetProtocol(const tchar_t * URL,tchar_t * Proto,int ProtoLen,bool_t * HasHost)96 const tchar_t* GetProtocol(const tchar_t* URL, tchar_t* Proto, int ProtoLen, bool_t* HasHost)
97 {
98 const tchar_t* s = tcschr(URL,':');
99 if (s && s[1] == '/' && s[2] == '/')
100 {
101 while (URL<s && IsSpace(*URL)) ++URL;
102 if (Proto)
103 tcsncpy_s(Proto,ProtoLen,URL,s-URL);
104 if (HasHost)
105 {
106 if (tcsnicmp(URL,T("urlpart"),7)==0)
107 // skip this protocol for the Host checking
108 GetProtocol(URL+10,NULL,0,HasHost);
109 else
110 *HasHost = tcsnicmp(URL,T("file"),4)!=0 &&
111 tcsnicmp(URL,T("conf"),3)!=0 &&
112 tcsnicmp(URL,T("res"),3)!=0 &&
113 tcsnicmp(URL,T("root"),4)!=0 &&
114 tcsnicmp(URL,T("mem"),3)!=0 &&
115 tcsnicmp(URL,T("pose"),4)!=0 &&
116 tcsnicmp(URL,T("vol"),3)!=0 &&
117 tcsnicmp(URL,T("slot"),4)!=0 &&
118 tcsnicmp(URL,T("simu"),4)!=0 &&
119 tcsnicmp(URL,T("local"),5)!=0 &&
120 tcsnicmp(URL,T("sdcard"),6)!=0;
121 }
122 s += 3;
123 }
124 else
125 {
126 if (HasHost)
127 *HasHost = 0;
128 if (Proto)
129 tcscpy_s(Proto,ProtoLen,T("file"));
130 s = URL;
131 }
132 return s;
133 }
134
GetProtocolKind(anynode * AnyNode,tchar_t * Protocol)135 fourcc_t GetProtocolKind(anynode* AnyNode, tchar_t *Protocol)
136 {
137 fourcc_t Class = NodeEnumClassStr(AnyNode,NULL,STREAM_CLASS,NODE_PROTOCOL,Protocol);
138 if (Class)
139 {
140 const nodeclass *NodeClass = NodeContext_FindClass(AnyNode,Class);
141 if (NodeClass)
142 return (fourcc_t)NodeClass_Meta(NodeClass,STREAM_KIND,META_PARAM_CUSTOM);
143 }
144 return 0;
145 }
146
SplitAddr(const tchar_t * URL,tchar_t * Peer,int PeerLen,tchar_t * Local,int LocalLen)147 bool_t SplitAddr(const tchar_t* URL, tchar_t* Peer, int PeerLen, tchar_t* Local, int LocalLen)
148 {
149 const tchar_t* p = NULL;
150 const tchar_t* p2;
151 const tchar_t* Addr;
152 bool_t HasHost;
153 bool_t Result = 0;
154
155 Addr = GetProtocol(URL,NULL,0,&HasHost);
156
157 if (HasHost)
158 {
159 p = tcschr(Addr,'\\');
160 p2 = tcschr(Addr,'/');
161 if (!p || (p2 && p2>p))
162 p=p2;
163 }
164 if (!p)
165 p = Addr+tcslen(Addr);
166
167 p2 = tcschr(Addr,'@');
168 if (!p2 || p2>p)
169 p2 = p;
170 else
171 Result = 1;
172
173 if (Peer)
174 tcsncpy_s(Peer,PeerLen,URL,p2-URL);
175
176 if (Local)
177 {
178 if (p2<p)
179 ++p2;
180 tcsncpy_s(Local,LocalLen,URL,Addr-URL);
181 tcsncat_s(Local,LocalLen,p2,p-p2);
182 }
183 return Result;
184 }
185
SplitURL(const tchar_t * URL,tchar_t * Protocol,int ProtocolLen,tchar_t * Host,int HostLen,int * Port,tchar_t * Path,int PathLen)186 void SplitURL(const tchar_t* URL, tchar_t* Protocol, int ProtocolLen, tchar_t* Host, int HostLen, int* Port, tchar_t* Path, int PathLen)
187 {
188 bool_t HasHost;
189 URL = GetProtocol(URL,Protocol,ProtocolLen,&HasHost);
190
191 if (HasHost)
192 {
193 const tchar_t* p;
194 const tchar_t* p2;
195
196 p = tcschr(URL,'\\');
197 p2 = tcschr(URL,'/');
198 if (!p || (p2 && p2>p))
199 p=p2;
200 if (!p)
201 p = URL+tcslen(URL);
202
203 p2 = tcschr(URL,':');
204 if (p2 && p2<p)
205 {
206 if (Port)
207 stscanf(p2+1,T("%d"),Port);
208 }
209 else
210 p2 = p;
211
212 if (Host)
213 tcsncpy_s(Host,HostLen,URL,p2-URL);
214
215 URL = p;
216 }
217 else
218 {
219 if (Host && HostLen>0)
220 *Host = 0;
221 }
222
223 if (Path)
224 {
225 if (URL[0])
226 {
227 tchar_t* p;
228 tcscpy_s(Path,PathLen,URL);
229 for (p=Path;*p;++p)
230 if (*p == '\\')
231 *p = '/';
232 }
233 else
234 tcscpy_s(Path,PathLen,T("/"));
235 }
236 }
237
SplitPath(const tchar_t * URL,tchar_t * Dir,int DirLen,tchar_t * Name,int NameLen,tchar_t * Ext,int ExtLen)238 void SplitPath(const tchar_t* URL, tchar_t* Dir, int DirLen, tchar_t* Name, int NameLen, tchar_t* Ext, int ExtLen)
239 {
240 const tchar_t *p,*p2,*p3;
241 bool_t HasHost;
242 tchar_t LocalURL[MAXPATH];
243 tchar_t Protocol[MAXPATH];
244
245 // mime
246 p = GetProtocol(URL,Protocol,TSIZEOF(Protocol),&HasHost);
247
248 // dir
249 p2 = tcsrchr(p,'\\');
250 p3 = tcsrchr(p,'/');
251 if (!p2 || (p3 && p3>p2))
252 p2 = p3;
253
254 #ifdef TARGET_PS2SDK
255 // "host:test.elf" -> "host:"
256 // "host:/test.elf" -> "host:/" (keeping end delimiter)
257 if ((p2 && p2>p && p2[-1]==':') || (!p2 && (p2 = tcschr(p,':'))!=NULL))
258 {
259 if (Dir)
260 tcsncpy_s(Dir,DirLen,URL,p2-URL+1);
261 URL = p2+1;
262 }
263 else
264 #endif
265 if (p2)
266 {
267 if (Dir)
268 tcsncpy_s(Dir,DirLen,URL,p2-URL);
269 URL = p2+1;
270 }
271 else
272 if (HasHost) // no filename, only host
273 {
274 if (Dir)
275 tcscpy_s(Dir,DirLen,URL);
276 URL += tcslen(URL);
277 }
278 else // no directory
279 {
280 if (Dir)
281 tcsncpy_s(Dir,DirLen,URL,p-URL);
282 URL = p;
283 }
284
285 // name
286 if (tcsicmp(Protocol,T("http"))==0 && tcsrchr(URL,T('#')))
287 {
288 tchar_t *NulChar;
289 tcscpy_s(LocalURL,TSIZEOF(LocalURL),URL);
290 URL = LocalURL;
291 NulChar = tcsrchr(LocalURL,T('#'));
292 *NulChar = 0;
293 }
294
295 if (Name && Name == Ext)
296 tcscpy_s(Name,NameLen,URL);
297 else
298 {
299 p = tcsrchr(URL,'.');
300 if (p)
301 {
302 if (Name)
303 tcsncpy_s(Name,NameLen,URL,p-URL);
304 if (Ext)
305 {
306 if (p[1]) ++p; // remove '.', but only if there is a real extension
307 tcscpy_s(Ext,ExtLen,p);
308 }
309 }
310 else
311 {
312 if (Name)
313 tcscpy_s(Name,NameLen,URL);
314 if (Ext)
315 Ext[0] = 0;
316 }
317 }
318 }
319
RelPath(tchar_t * Rel,int RelLen,const tchar_t * Path,const tchar_t * Base)320 void RelPath(tchar_t* Rel, int RelLen, const tchar_t* Path, const tchar_t* Base)
321 {
322 size_t n;
323 bool_t HasHost;
324 const tchar_t* p = GetProtocol(Base,NULL,0,&HasHost);
325 if (p != Base)
326 {
327 if (HasHost)
328 {
329 // include host name too
330 tchar_t *a,*b;
331 a = tcschr(p,'\\');
332 b = tcschr(p,'/');
333 if (!a || (b && b<a))
334 a=b;
335 if (a)
336 p=a;
337 else
338 p+=tcslen(p);
339 }
340
341 // check if mime and host is the same
342 n = p-Base;
343 if (n>0 && n<tcslen(Path) && (Path[n]=='\\' || Path[n]=='/') && tcsnicmp(Path,Base,n)==0)
344 {
345 Base += n;
346 Path += n;
347 }
348 }
349
350 n = tcslen(Base);
351 if (n>0 && n<tcslen(Path) && (Path[n]=='\\' || Path[n]=='/') && tcsnicmp(Path,Base,n)==0)
352 Path += n+1;
353
354 tcscpy_s(Rel,RelLen,Path);
355 }
356
UpperPath(tchar_t * Path,tchar_t * Last,size_t LastLen)357 bool_t UpperPath(tchar_t* Path, tchar_t* Last, size_t LastLen)
358 {
359 tchar_t *a,*b,*c;
360 bool_t HasHost;
361 tchar_t Mime[32];
362
363 if (!*Path)
364 return 0;
365
366 RemovePathDelimiter(Path);
367 c = (tchar_t*)GetProtocol(Path,Mime,TSIZEOF(Mime),&HasHost);
368
369 a = tcsrchr(c,'\\');
370 b = tcsrchr(c,'/');
371 if (!a || (b && b>a))
372 a=b;
373
374 #ifdef TARGET_PS2SDK
375 if (!a && (a = tcschr(c,':'))!=NULL)
376 if (a[1]==0)
377 a = NULL;
378 #endif
379
380 if (!a)
381 {
382 if (tcsicmp(Mime, T("smb")) == 0) {
383 *c = 0;
384 tcscpy_s(Last, LastLen, Path);
385 return 1;
386 }
387
388 if (HasHost && tcsicmp(Mime, T("upnp"))!=0)
389 return 0;
390 a=c;
391 if (!a[0]) // only mime left
392 a=c=Path;
393 }
394 else
395 ++a;
396
397 if (Last)
398 tcscpy_s(Last,LastLen,a);
399
400 if (a==c)
401 *a = 0;
402
403 #ifdef TARGET_PS2SDK
404 if (a>c && a[-1]==':')
405 *a = 0;
406 #endif
407
408 while (--a>=c && (*a=='\\' || *a=='/'))
409 *a = 0;
410
411 return 1;
412 }
413
AbsPath(tchar_t * Abs,int AbsLen,const tchar_t * Path,const tchar_t * Base)414 void AbsPath(tchar_t* Abs, int AbsLen, const tchar_t* Path, const tchar_t* Base)
415 {
416 if (Base && GetProtocol(Base,NULL,0,NULL)!=Base && (Path[0] == '/' || Path[0] == '\\') &&
417 (Path[1] != '/' && Path[1] != '\\'))
418 {
419 tchar_t* s;
420 bool_t HasHost;
421
422 tcscpy_s(Abs,AbsLen,Base);
423 s = (tchar_t*)GetProtocol(Abs,NULL,0,&HasHost);
424 if (!HasHost)
425 {
426 // keep "mime://" from Base
427 ++Path;
428 *s = 0;
429 }
430 else
431 {
432 // keep "mime://host" from Base
433 tchar_t *a,*b;
434 a = tcschr(s,'\\');
435 b = tcschr(s,'/');
436 if (!a || (b && b<a))
437 a=b;
438 if (a)
439 *a=0;
440 }
441 }
442 else
443 if (Base && GetProtocol(Path,NULL,0,NULL)==Path && Path[0] != '/' && Path[0] != '\\' &&
444 !(Path[0] && Path[1]==':' && (Path[2]=='\\' || Path[2]=='\0')))
445 {
446 // doesn't have mime or drive letter or pathdelimiter at the start
447 const tchar_t* MimeEnd = GetProtocol(Base,NULL,0,NULL);
448 tcscpy_s(Abs,AbsLen,Base);
449
450 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
451 if (MimeEnd==Base)
452 AddPathDelimiter(Abs,AbsLen);
453 else
454 #endif
455 if (MimeEnd[0])
456 AddPathDelimiter(Abs,AbsLen);
457 }
458 else
459 Abs[0] = 0;
460
461 tcscat_s(Abs,AbsLen,Path);
462 AbsPathNormalize(Abs,AbsLen);
463 }
464
AbsPathNormalize(tchar_t * Abs,size_t AbsLen)465 void AbsPathNormalize(tchar_t* Abs,size_t AbsLen)
466 {
467 if (GetProtocol(Abs,NULL,0,NULL)!=Abs)
468 {
469 tchar_t *i;
470 for (i=Abs;*i;++i)
471 if (*i == '\\')
472 *i = '/';
473 }
474 else
475 {
476 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
477 tchar_t *i;
478 for (i=Abs;*i;++i)
479 if (*i == '/')
480 *i = '\\';
481
482 #if defined(TARGET_WINCE)
483 if (Abs[0]!='\\')
484 {
485 size_t n = tcslen(Abs)+1;
486 if (n>=AbsLen)
487 {
488 n=AbsLen-1;
489 Abs[n-1]=0;
490 }
491 memmove(Abs+1,Abs,n*sizeof(tchar_t));
492 Abs[0]='\\';
493 }
494 #endif
495 #endif
496 }
497 }
498
ReduceLocalPath(tchar_t * Abs,size_t UNUSED_PARAM (AbsLen))499 void ReduceLocalPath(tchar_t* Abs,size_t UNUSED_PARAM(AbsLen))
500 {
501 tchar_t *Folder,*Back;
502 Folder = tcsstr(Abs,T("://")); // skip the protocol
503 if (Folder)
504 Abs = Folder+3;
505 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
506 Back = tcsstr(Abs,T("\\\\"));
507 #else
508 Back = tcsstr(Abs,T("//"));
509 #endif
510 while (Back)
511 {
512 memmove(Back,Back+1,tcsbytes(Back+1));
513 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
514 Back = tcsstr(Abs,T("\\\\"));
515 #else
516 Back = tcsstr(Abs,T("//"));
517 #endif
518 }
519
520 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
521 Back = tcsstr(Abs,T("\\.."));
522 #else
523 Back = tcsstr(Abs,T("/.."));
524 #endif
525 while (Back)
526 {
527 Folder = Back;
528 while (--Folder >= Abs)
529 {
530 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
531 if (*Folder == T('\\'))
532 #else
533 if (*Folder == T('/'))
534 #endif
535 {
536 memmove(Folder,Back+3,tcsbytes(Back+3));
537 break;
538 }
539 }
540 #if defined(TARGET_WIN) || defined(TARGET_SYMBIAN)
541 Back = tcsstr(Abs,T("\\.."));
542 #else
543 Back = tcsstr(Abs,T("/.."));
544 #endif
545 }
546 }
547
CheckExts(const tchar_t * URL,const tchar_t * Exts)548 int CheckExts(const tchar_t* URL, const tchar_t* Exts)
549 {
550 tchar_t Ext[MAXPATH];
551 tchar_t* Tail;
552 intptr_t ExtLen;
553
554 SplitPath(URL,NULL,0,NULL,0,Ext,TSIZEOF(Ext));
555 Tail = tcschr(Ext,'?');
556 if (Tail) *Tail = 0;
557 ExtLen = tcslen(Ext);
558
559 while (Exts)
560 {
561 const tchar_t* p = tcschr(Exts,':');
562 if (p && (ExtLen == p-Exts) && tcsnicmp(Ext,Exts,p-Exts)==0)
563 return p[1]; // return type char
564 Exts = tcschr(Exts,';');
565 if (Exts) ++Exts;
566 }
567 return 0;
568 }
569
ScaleRound(int_fast32_t v,int_fast32_t Num,int_fast32_t Den)570 int ScaleRound(int_fast32_t v,int_fast32_t Num,int_fast32_t Den)
571 {
572 int64_t i;
573 if (!Den)
574 return 0;
575 i = (int64_t)v * Num;
576 if (i<0)
577 i-=Den/2;
578 else
579 i+=Den/2;
580 i/=Den;
581 return (int)i;
582 }
583
StreamLoginInfo(node * p,tchar_t * URL,bool_t Proxy)584 void StreamLoginInfo(node* p, tchar_t* URL, bool_t Proxy)
585 {
586 tchar_t LoginPass[MAXPATH];
587 if (SplitAddr(URL,LoginPass,TSIZEOF(LoginPass),NULL,0))
588 {
589 // extract the login:pass from the URL as there seems to be one
590 tchar_t *s,*t;
591 if (!Proxy)
592 {
593 Node_SetData(p,STREAM_FULL_URL,TYPE_STRING,URL);
594
595 t = (tchar_t*)GetProtocol(URL,NULL,0,NULL);
596 s = tcschr(t,T('@'));
597 assert(s!=NULL);
598 ++s;
599 memmove(t, s, tcsbytes(s));
600 }
601
602 t = (tchar_t*)GetProtocol(LoginPass,NULL,0,NULL);
603 s=tcschr(t,T(':'));
604 if (s)
605 *s++ = 0;
606
607 if (Proxy)
608 {
609 Node_SetData(p,STREAM_PROXY_PASSWORD,TYPE_STRING,s);
610 Node_SetData(p,STREAM_PROXY_USERNAME,TYPE_STRING,t);
611 }
612 else
613 {
614 Node_SetData(p,STREAM_PASSWORD,TYPE_STRING,s);
615 Node_SetData(p,STREAM_USERNAME,TYPE_STRING,t);
616 }
617 }
618 else
619 Node_RemoveData(p,STREAM_FULL_URL,TYPE_STRING);
620 }
621
FirstSepar(const tchar_t * Path)622 tchar_t* FirstSepar(const tchar_t *Path)
623 {
624 tchar_t *s1, *s2;
625 s1 = tcschr(Path, '\\');
626 s2 = tcschr(Path, '/');
627 if (!s1 || (s2 && s2 < s1))
628 s1 = s2;
629 return s1;
630 }
631
SplitURLLogin(const tchar_t * URL,tchar_t * UserName,size_t UserNameLen,tchar_t * Password,size_t PasswordLen,tchar_t * URL2,size_t URL2Len)632 void SplitURLLogin(const tchar_t *URL, tchar_t *UserName, size_t UserNameLen, tchar_t *Password, size_t PasswordLen, tchar_t *URL2, size_t URL2Len)
633 {
634 tchar_t LoginPass[MAXPATH];
635 if (SplitAddr(URL, LoginPass, TSIZEOF(LoginPass), NULL, 0))
636 {
637 tchar_t *s,*t;
638 if (URL2)
639 {
640 tcscpy_s(URL2, URL2Len, URL);
641 t = (tchar_t*)GetProtocol(URL2,NULL,0,NULL);
642 s = tcschr(t,T('@'));
643 assert(s!=NULL);
644 ++s;
645 memmove(t, s, tcsbytes(s));
646 }
647
648 t = (tchar_t*)GetProtocol(LoginPass,NULL,0,NULL);
649 s=tcschr(t,T(':'));
650 if (s)
651 {
652 *s++ = 0;
653 // missing: resolving escape sequences
654 if (Password)
655 tcscpy_s(Password, PasswordLen, s);
656 }
657 else
658 tcsclr_s(Password, PasswordLen);
659 if (UserName)
660 tcscpy_s(UserName, UserNameLen, t);
661 } else {
662 tcsclr_s(UserName, UserNameLen);
663 tcsclr_s(Password, PasswordLen);
664 if (URL2)
665 tcscpy_s(URL2, URL2Len, URL);
666 }
667 }
668
SplitShare(const tchar_t * Path,tchar_t * Share,size_t ShareLen,tchar_t * Path2,size_t Path2Len)669 void SplitShare(const tchar_t *Path, tchar_t *Share, size_t ShareLen, tchar_t *Path2, size_t Path2Len)
670 {
671 tchar_t *s1;
672 s1 = FirstSepar(Path);
673 if (s1 == Path)
674 {
675 Path++;
676 s1 = FirstSepar(Path);
677 }
678 if (s1) {
679 if (Share)
680 tcsncpy_s(Share, ShareLen, Path, s1 - Path);
681 if (Path2)
682 tcscpy_s(Path2, Path2Len, s1);
683 } else
684 {
685 if (Share)
686 tcscpy_s(Share, ShareLen, Path);
687 tcsclr_s(Path2, Path2Len);
688 }
689 }
690
MergeURL(tchar_t * URL,size_t URLLen,const tchar_t * Protocol,const tchar_t * Host,int Port,const tchar_t * Path)691 tchar_t *MergeURL(tchar_t *URL, size_t URLLen, const tchar_t *Protocol, const tchar_t *Host, int Port, const tchar_t *Path)
692 {
693 *URL = 0;
694 if (Protocol && *Protocol)
695 stcatprintf_s(URL, URLLen, T("%s://"), Protocol);
696 if (Host && *Host)
697 {
698 stcatprintf_s(URL, URLLen, T("%s"), Host);
699 if (Port > 0)
700 stcatprintf_s(URL, URLLen, T(":%d"), Port);
701 }
702 if (Path && *Path)
703 {
704 if (FirstSepar(Path) == Path)
705 stcatprintf_s(URL, URLLen, T("%s"), Path);
706 else
707 stcatprintf_s(URL, URLLen, T("/%s"), Path);
708 }
709 return URL;
710 }
711
GetIP(tchar_t * sIP,size_t IPLen,long IP)712 tchar_t *GetIP(tchar_t *sIP, size_t IPLen, long IP)
713 {
714 stprintf_s(sIP, IPLen, T("%d.%d.%d.%d"), (IP >> 24) & 0xFF, (IP >> 16) & 0xFF, (IP >> 8) & 0xFF, IP & 0xFF);
715 return sIP;
716 }
717
SplitURLParams(const tchar_t * URL,tchar_t * URL2,int URL2Len,tchar_t * Params,int ParamsLen)718 void SplitURLParams(const tchar_t* URL, tchar_t* URL2, int URL2Len, tchar_t* Params, int ParamsLen)
719 {
720 tchar_t* p;
721 p = tcschr(URL, '?');
722 if (p)
723 {
724 if (URL2)
725 tcsncpy_s(URL2, URL2Len, URL, p-URL);
726 if (Params)
727 tcscpy_s(Params, ParamsLen, p);
728 } else
729 {
730 if (URL2)
731 tcscpy_s(URL2, URL2Len, URL);
732 if (Params)
733 *Params = 0;
734 }
735 }
736
AddCacheURL(tchar_t * Out,size_t Len,const tchar_t * In)737 tchar_t *AddCacheURL(tchar_t* Out, size_t Len, const tchar_t *In)
738 {
739 CheckRemoveCacheURL(&In);
740 if (!In || !*In) {
741 if (Out && Len)
742 *Out = 0;
743 }
744 else
745 stprintf_s(Out, Len, T("cache://%s"), In);
746 return Out;
747 }
748
CheckRemoveCacheURL(const tchar_t ** URL)749 bool_t CheckRemoveCacheURL(const tchar_t** URL)
750 {
751 if (*URL && !tcsncmp(*URL, T("cache://"), 8))
752 {
753 *URL += 8;
754 return 1;
755 }
756 return 0;
757 }
758
RemoveURLParam(tchar_t * URL,const tchar_t * Param)759 bool_t RemoveURLParam(tchar_t* URL, const tchar_t* Param)
760 {
761 size_t l;
762 tchar_t *s1, *s2;
763 l = tcslen(Param);
764 if (!l)
765 return 0;
766 s1 = tcschr(URL, '?');
767 if (!s1)
768 s1 = tcschr(URL, ';');
769 while (s1)
770 {
771 s2 = tcschr(s1+1, '&');
772 if (!s2)
773 s2 = tcschr(s1+1, ';');
774 if (tcsncmp(s1+1, Param, l) == 0 && s1[l+1] == '=')
775 {
776 if (s2)
777 memcpy(s1+1, s2+1, (tcslen(s2)+1)*sizeof(tchar_t));
778 else
779 *s1 = 0;
780 return 1;
781 }
782 s1 = s2;
783 }
784 return 0;
785 }
786
FileStat(nodecontext * p,const tchar_t * Path,streamdir * Item)787 err_t FileStat(nodecontext* p, const tchar_t* Path, streamdir* Item)
788 {
789 err_t Result;
790 stream *s;
791 tchar_t Dir[MAXPATH];
792 tchar_t NameExt[MAXPATH];
793 tchar_t Ext[MAXPATH+2];
794 size_t l;
795 SplitPath(Path, Dir, MAXPATH, NameExt, MAXPATH, Ext, MAXPATH);
796 if (*Ext)
797 {
798 if (!tcschr(NameExt,T('.')))
799 SetFileExt(NameExt, MAXPATH, Ext);
800 else
801 {
802 tcscat_s(NameExt,TSIZEOF(NameExt),T("."));
803 tcscat_s(NameExt,TSIZEOF(NameExt),Ext);
804 }
805 }
806 l = tcslen(Ext);
807 Ext[l] = ':';
808 Ext[l + 1] = '1';
809 Ext[l + 2] = '\0';
810 s = GetStream(p, Dir, SFLAG_SILENT);
811 if (!s)
812 return ERR_FILE_NOT_FOUND;
813 Result = Stream_OpenDir(s, Dir, SFLAG_SILENT);
814 if (Result == ERR_NONE) {
815 do {
816 Result = Stream_EnumDir(s, Ext, 1, Item);
817 if (Result == ERR_NONE && tcscmp(Item->FileName, NameExt) == 0)
818 break;
819 } while (Result == ERR_NONE);
820 }
821 NodeDelete((node *) s);
822 if (Result != ERR_NONE)
823 Result = ERR_FILE_NOT_FOUND;
824 return Result;
825 }
826
827