Fossil

Hex Artifact Content
Login

Artifact e79fccbe92a2f46f83b7b817804f6f17ecfd48a7:


0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68  (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 53 69 6d 70 6c 69 66 69 65 64 20 42 53 44 20   Simplified BSD 
00a0: 4c 69 63 65 6e 73 65 20 28 61 6c 73 6f 0a 2a 2a  License (also.**
00b0: 20 6b 6e 6f 77 6e 20 61 73 20 74 68 65 20 22 32   known as the "2
00c0: 2d 43 6c 61 75 73 65 20 4c 69 63 65 6e 73 65 22  -Clause License"
00d0: 20 6f 72 20 22 46 72 65 65 42 53 44 20 4c 69 63   or "FreeBSD Lic
00e0: 65 6e 73 65 22 2e 29 0a 0a 2a 2a 20 54 68 69 73  ense".)..** This
00f0: 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73 74   program is dist
0100: 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20 68  ributed in the h
0110: 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c 6c  ope that it will
0120: 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20 62   be useful,.** b
0130: 75 74 20 77 69 74 68 6f 75 74 20 61 6e 79 20 77  ut without any w
0140: 61 72 72 61 6e 74 79 3b 20 77 69 74 68 6f 75 74  arranty; without
0150: 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69 65   even the implie
0160: 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a 2a  d warranty of.**
0170: 20 6d 65 72 63 68 61 6e 74 61 62 69 6c 69 74 79   merchantability
0180: 20 6f 72 20 66 69 74 6e 65 73 73 20 66 6f 72 20   or fitness for 
0190: 61 20 70 61 72 74 69 63 75 6c 61 72 20 70 75 72  a particular pur
01a0: 70 6f 73 65 2e 0a 2a 2a 0a 2a 2a 20 41 75 74 68  pose..**.** Auth
01b0: 6f 72 20 63 6f 6e 74 61 63 74 20 69 6e 66 6f 72  or contact infor
01c0: 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20 20 64 72 68  mation:.**   drh
01d0: 40 68 77 61 63 69 2e 63 6f 6d 0a 2a 2a 20 20 20  @hwaci.com.**   
01e0: 68 74 74 70 3a 2f 2f 77 77 77 2e 68 77 61 63 69  http://www.hwaci
01f0: 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a 0a 2a 2a 2a  .com/drh/.**.***
0200: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0210: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0220: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a  ************.**.
0250: 2a 2a 20 46 69 6c 65 20 75 74 69 6c 69 74 69 65  ** File utilitie
0260: 73 2e 0a 2a 2a 0a 2a 2a 20 46 75 6e 63 74 69 6f  s..**.** Functio
0270: 6e 73 20 6e 61 6d 65 64 20 66 69 6c 65 5f 2a 20  ns named file_* 
0280: 61 72 65 20 67 65 6e 65 72 69 63 20 66 75 6e 63  are generic func
0290: 74 69 6f 6e 73 20 74 68 61 74 20 61 6c 77 61 79  tions that alway
02a0: 73 20 66 6f 6c 6c 6f 77 20 73 79 6d 6c 69 6e 6b  s follow symlink
02b0: 73 2e 0a 2a 2a 0a 2a 2a 20 46 75 6e 63 74 69 6f  s..**.** Functio
02c0: 6e 73 20 6e 61 6d 65 64 20 66 69 6c 65 5f 77 64  ns named file_wd
02d0: 5f 2a 20 61 72 65 20 74 6f 20 62 65 20 75 73 65  _* are to be use
02e0: 64 20 66 6f 72 20 66 69 6c 65 73 20 69 6e 73 69  d for files insi
02f0: 64 65 20 77 6f 72 6b 69 6e 67 0a 2a 2a 20 64 69  de working.** di
0300: 72 65 63 74 6f 72 69 65 73 2e 20 54 68 65 79 20  rectories. They 
0310: 66 6f 6c 6c 6f 77 20 73 79 6d 6c 69 6e 6b 73 20  follow symlinks 
0320: 64 65 70 65 6e 64 69 6e 67 20 6f 6e 20 27 61 6c  depending on 'al
0330: 6c 6f 77 2d 73 79 6d 6c 69 6e 6b 73 27 20 73 65  low-symlinks' se
0340: 74 74 69 6e 67 2e 0a 2a 2f 0a 23 69 6e 63 6c 75  tting..*/.#inclu
0350: 64 65 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69  de "config.h".#i
0360: 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 79 70 65  nclude <sys/type
0370: 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  s.h>.#include <s
0380: 79 73 2f 73 74 61 74 2e 68 3e 0a 23 69 6e 63 6c  ys/stat.h>.#incl
0390: 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e 0a 23  ude <unistd.h>.#
03a0: 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e  include <string.
03b0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 65 72 72  h>.#include <err
03c0: 6e 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 22  no.h>.#include "
03d0: 66 69 6c 65 2e 68 22 0a 0a 2f 2a 0a 2a 2a 20 4f  file.h"../*.** O
03e0: 6e 20 57 69 6e 64 6f 77 73 2c 20 69 6e 63 6c 75  n Windows, inclu
03f0: 64 65 20 74 68 65 20 50 6c 61 74 66 6f 72 6d 20  de the Platform 
0400: 53 44 4b 20 68 65 61 64 65 72 20 66 69 6c 65 2e  SDK header file.
0410: 0a 2a 2f 0a 23 69 66 64 65 66 20 5f 57 49 4e 33  .*/.#ifdef _WIN3
0420: 32 0a 23 20 69 6e 63 6c 75 64 65 20 3c 77 69 6e  2.# include <win
0430: 64 6f 77 73 2e 68 3e 0a 23 65 6e 64 69 66 0a 0a  dows.h>.#endif..
0440: 2f 2a 0a 2a 2a 20 54 68 65 20 66 69 6c 65 20 73  /*.** The file s
0450: 74 61 74 75 73 20 69 6e 66 6f 72 6d 61 74 69 6f  tatus informatio
0460: 6e 20 66 72 6f 6d 20 74 68 65 20 6d 6f 73 74 20  n from the most 
0470: 72 65 63 65 6e 74 20 73 74 61 74 28 29 20 63 61  recent stat() ca
0480: 6c 6c 2e 0a 2a 2a 0a 2a 2a 20 55 73 65 20 5f 73  ll..**.** Use _s
0490: 74 61 74 69 36 34 20 72 61 74 68 65 72 20 74 68  tati64 rather th
04a0: 61 6e 20 73 74 61 74 20 6f 6e 20 77 69 6e 64 6f  an stat on windo
04b0: 77 73 2c 20 69 6e 20 6f 72 64 65 72 20 74 6f 20  ws, in order to 
04c0: 68 61 6e 64 6c 65 20 66 69 6c 65 73 0a 2a 2a 20  handle files.** 
04d0: 6c 61 72 67 65 72 20 74 68 61 6e 20 32 47 42 2e  larger than 2GB.
04e0: 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28  .*/.#if defined(
04f0: 5f 57 49 4e 33 32 29 20 26 26 20 28 64 65 66 69  _WIN32) && (defi
0500: 6e 65 64 28 5f 5f 4d 53 56 43 52 54 5f 5f 29 20  ned(__MSVCRT__) 
0510: 7c 7c 20 64 65 66 69 6e 65 64 28 5f 4d 53 43 5f  || defined(_MSC_
0520: 56 45 52 29 29 0a 23 20 64 65 66 69 6e 65 20 73  VER)).# define s
0530: 74 61 74 20 5f 73 74 61 74 69 36 34 0a 23 65 6e  tat _stati64.#en
0540: 64 69 66 0a 2f 2a 0a 2a 2a 20 4f 6e 20 57 69 6e  dif./*.** On Win
0550: 64 6f 77 73 20 53 5f 49 53 4c 4e 4b 20 61 6c 77  dows S_ISLNK alw
0560: 61 79 73 20 72 65 74 75 72 6e 73 20 46 41 4c 53  ays returns FALS
0570: 45 2e 0a 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65  E..*/.#if define
0580: 64 28 5f 57 49 4e 33 32 29 0a 23 20 64 65 66 69  d(_WIN32).# defi
0590: 6e 65 20 53 5f 49 53 4c 4e 4b 28 78 29 20 28 30  ne S_ISLNK(x) (0
05a0: 29 0a 23 65 6e 64 69 66 0a 73 74 61 74 69 63 20  ).#endif.static 
05b0: 69 6e 74 20 66 69 6c 65 53 74 61 74 56 61 6c 69  int fileStatVali
05c0: 64 20 3d 20 30 3b 0a 73 74 61 74 69 63 20 73 74  d = 0;.static st
05d0: 72 75 63 74 20 73 74 61 74 20 66 69 6c 65 53 74  ruct stat fileSt
05e0: 61 74 3b 0a 0a 2f 2a 0a 2a 2a 20 46 69 6c 6c 20  at;../*.** Fill 
05f0: 73 74 61 74 20 62 75 66 20 77 69 74 68 20 69 6e  stat buf with in
0600: 66 6f 72 6d 61 74 69 6f 6e 20 72 65 63 65 69 76  formation receiv
0610: 65 64 20 66 72 6f 6d 20 73 74 61 74 28 29 20 6f  ed from stat() o
0620: 72 20 6c 73 74 61 74 28 29 2e 0a 2a 2a 20 6c 73  r lstat()..** ls
0630: 74 61 74 28 29 20 69 73 20 63 61 6c 6c 65 64 20  tat() is called 
0640: 6f 6e 20 55 6e 69 78 20 69 66 20 69 73 57 64 20  on Unix if isWd 
0650: 69 73 20 54 52 55 45 20 61 6e 64 20 61 6c 6c 6f  is TRUE and allo
0660: 77 2d 73 79 6d 6c 69 6e 6b 73 20 73 65 74 74 69  w-symlinks setti
0670: 6e 67 20 69 73 20 6f 6e 2e 0a 2a 2a 0a 2a 2f 0a  ng is on..**.*/.
0680: 73 74 61 74 69 63 20 69 6e 74 20 66 6f 73 73 69  static int fossi
0690: 6c 5f 73 74 61 74 28 63 6f 6e 73 74 20 63 68 61  l_stat(const cha
06a0: 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 73 74  r *zFilename, st
06b0: 72 75 63 74 20 73 74 61 74 20 2a 62 75 66 2c 20  ruct stat *buf, 
06c0: 69 6e 74 20 69 73 57 64 29 7b 0a 23 69 66 20 21  int isWd){.#if !
06d0: 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a  defined(_WIN32).
06e0: 20 20 69 66 28 20 69 73 57 64 20 26 26 20 67 2e    if( isWd && g.
06f0: 61 6c 6c 6f 77 53 79 6d 6c 69 6e 6b 73 20 29 7b  allowSymlinks ){
0700: 0a 20 20 20 20 72 65 74 75 72 6e 20 6c 73 74 61  .    return lsta
0710: 74 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 62 75 66  t(zFilename, buf
0720: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
0730: 72 65 74 75 72 6e 20 73 74 61 74 28 7a 46 69 6c  return stat(zFil
0740: 65 6e 61 6d 65 2c 20 62 75 66 29 3b 0a 20 20 7d  ename, buf);.  }
0750: 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20 72 63 20  .#else.  int rc 
0760: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 7a 4d 62  = 0;.  char *zMb
0770: 63 73 20 3d 20 66 6f 73 73 69 6c 5f 75 74 66 38  cs = fossil_utf8
0780: 5f 74 6f 5f 6d 62 63 73 28 7a 46 69 6c 65 6e 61  _to_mbcs(zFilena
0790: 6d 65 29 3b 0a 20 20 72 63 20 3d 20 73 74 61 74  me);.  rc = stat
07a0: 28 7a 4d 62 63 73 2c 20 62 75 66 29 3b 0a 20 20  (zMbcs, buf);.  
07b0: 66 6f 73 73 69 6c 5f 6d 62 63 73 5f 66 72 65 65  fossil_mbcs_free
07c0: 28 7a 4d 62 63 73 29 3b 0a 20 20 72 65 74 75 72  (zMbcs);.  retur
07d0: 6e 20 72 63 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a  n rc;.#endif.}..
07e0: 2f 2a 0a 2a 2a 20 46 69 6c 6c 20 69 6e 20 74 68  /*.** Fill in th
07f0: 65 20 66 69 6c 65 53 74 61 74 20 76 61 72 69 61  e fileStat varia
0800: 62 6c 65 20 66 6f 72 20 74 68 65 20 66 69 6c 65  ble for the file
0810: 20 6e 61 6d 65 64 20 7a 46 69 6c 65 6e 61 6d 65   named zFilename
0820: 2e 0a 2a 2a 20 49 66 20 7a 46 69 6c 65 6e 61 6d  ..** If zFilenam
0830: 65 3d 3d 30 2c 20 74 68 65 6e 20 75 73 65 20 74  e==0, then use t
0840: 68 65 20 70 72 65 76 69 6f 75 73 20 76 61 6c 75  he previous valu
0850: 65 20 6f 66 20 66 69 6c 65 53 74 61 74 20 69 66  e of fileStat if
0860: 0a 2a 2a 20 74 68 65 72 65 20 69 73 20 61 20 70  .** there is a p
0870: 72 65 76 69 6f 75 73 20 76 61 6c 75 65 2e 0a 2a  revious value..*
0880: 2a 0a 2a 2a 20 49 66 20 69 73 57 64 20 69 73 20  *.** If isWd is 
0890: 54 52 55 45 2c 20 64 6f 20 6c 73 74 61 74 28 29  TRUE, do lstat()
08a0: 20 69 6e 73 74 65 61 64 20 6f 66 20 73 74 61 74   instead of stat
08b0: 28 29 20 69 66 20 61 6c 6c 6f 77 2d 73 79 6d 6c  () if allow-syml
08c0: 69 6e 6b 73 20 69 73 20 6f 6e 2e 0a 2a 2a 0a 2a  inks is on..**.*
08d0: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d  * Return the num
08e0: 62 65 72 20 6f 66 20 65 72 72 6f 72 73 2e 20 20  ber of errors.  
08f0: 4e 6f 20 65 72 72 6f 72 20 6d 65 73 73 61 67 65  No error message
0900: 73 20 61 72 65 20 67 65 6e 65 72 61 74 65 64 2e  s are generated.
0910: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 67  .*/.static int g
0920: 65 74 53 74 61 74 28 63 6f 6e 73 74 20 63 68 61  etStat(const cha
0930: 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 69 6e  r *zFilename, in
0940: 74 20 69 73 57 64 29 7b 0a 20 20 69 6e 74 20 72  t isWd){.  int r
0950: 63 20 3d 20 30 3b 0a 20 20 69 66 28 20 7a 46 69  c = 0;.  if( zFi
0960: 6c 65 6e 61 6d 65 3d 3d 30 20 29 7b 0a 20 20 20  lename==0 ){.   
0970: 20 69 66 28 20 66 69 6c 65 53 74 61 74 56 61 6c   if( fileStatVal
0980: 69 64 3d 3d 30 20 29 20 72 63 20 3d 20 31 3b 0a  id==0 ) rc = 1;.
0990: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28    }else{.    if(
09a0: 20 66 6f 73 73 69 6c 5f 73 74 61 74 28 7a 46 69   fossil_stat(zFi
09b0: 6c 65 6e 61 6d 65 2c 20 26 66 69 6c 65 53 74 61  lename, &fileSta
09c0: 74 2c 20 69 73 57 64 29 21 3d 30 20 29 7b 0a 20  t, isWd)!=0 ){. 
09d0: 20 20 20 20 20 66 69 6c 65 53 74 61 74 56 61 6c       fileStatVal
09e0: 69 64 20 3d 20 30 3b 0a 20 20 20 20 20 20 72 63  id = 0;.      rc
09f0: 20 3d 20 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b   = 1;.    }else{
0a00: 0a 20 20 20 20 20 20 66 69 6c 65 53 74 61 74 56  .      fileStatV
0a10: 61 6c 69 64 20 3d 20 31 3b 0a 20 20 20 20 20 20  alid = 1;.      
0a20: 72 63 20 3d 20 30 3b 0a 20 20 20 20 7d 0a 20 20  rc = 0;.    }.  
0a30: 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d  }.  return rc;.}
0a40: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
0a50: 68 65 20 73 69 7a 65 20 6f 66 20 61 20 66 69 6c  he size of a fil
0a60: 65 20 69 6e 20 62 79 74 65 73 2e 20 20 52 65 74  e in bytes.  Ret
0a70: 75 72 6e 20 2d 31 20 69 66 20 74 68 65 20 66 69  urn -1 if the fi
0a80: 6c 65 20 64 6f 65 73 20 6e 6f 74 0a 2a 2a 20 65  le does not.** e
0a90: 78 69 73 74 2e 20 20 49 66 20 7a 46 69 6c 65 6e  xist.  If zFilen
0aa0: 61 6d 65 20 69 73 20 4e 55 4c 4c 2c 20 72 65 74  ame is NULL, ret
0ab0: 75 72 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20  urn the size of 
0ac0: 74 68 65 20 6d 6f 73 74 20 72 65 63 65 6e 74 6c  the most recentl
0ad0: 79 0a 2a 2a 20 73 74 61 74 2d 65 64 20 66 69 6c  y.** stat-ed fil
0ae0: 65 2e 0a 2a 2f 0a 69 36 34 20 66 69 6c 65 5f 73  e..*/.i64 file_s
0af0: 69 7a 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ize(const char *
0b00: 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 72 65  zFilename){.  re
0b10: 74 75 72 6e 20 67 65 74 53 74 61 74 28 7a 46 69  turn getStat(zFi
0b20: 6c 65 6e 61 6d 65 2c 20 30 29 20 3f 20 2d 31 20  lename, 0) ? -1 
0b30: 3a 20 66 69 6c 65 53 74 61 74 2e 73 74 5f 73 69  : fileStat.st_si
0b40: 7a 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 61 6d  ze;.}../*.** Sam
0b50: 65 20 61 73 20 66 69 6c 65 5f 73 69 7a 65 28 29  e as file_size()
0b60: 2c 20 62 75 74 20 74 61 6b 65 73 20 69 6e 74 6f  , but takes into
0b70: 20 61 63 63 6f 75 6e 74 20 73 79 6d 6c 69 6e 6b   account symlink
0b80: 73 2e 0a 2a 2f 0a 69 36 34 20 66 69 6c 65 5f 77  s..*/.i64 file_w
0b90: 64 5f 73 69 7a 65 28 63 6f 6e 73 74 20 63 68 61  d_size(const cha
0ba0: 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20  r *zFilename){. 
0bb0: 20 72 65 74 75 72 6e 20 67 65 74 53 74 61 74 28   return getStat(
0bc0: 7a 46 69 6c 65 6e 61 6d 65 2c 20 31 29 20 3f 20  zFilename, 1) ? 
0bd0: 2d 31 20 3a 20 66 69 6c 65 53 74 61 74 2e 73 74  -1 : fileStat.st
0be0: 5f 73 69 7a 65 3b 20 20 0a 7d 0a 0a 2f 2a 0a 2a  _size;  .}../*.*
0bf0: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6d 6f 64  * Return the mod
0c00: 69 66 69 63 61 74 69 6f 6e 20 74 69 6d 65 20 66  ification time f
0c10: 6f 72 20 61 20 66 69 6c 65 2e 20 20 52 65 74 75  or a file.  Retu
0c20: 72 6e 20 2d 31 20 69 66 20 74 68 65 20 66 69 6c  rn -1 if the fil
0c30: 65 0a 2a 2a 20 64 6f 65 73 20 6e 6f 74 20 65 78  e.** does not ex
0c40: 69 73 74 2e 20 20 49 66 20 7a 46 69 6c 65 6e 61  ist.  If zFilena
0c50: 6d 65 20 69 73 20 4e 55 4c 4c 20 72 65 74 75 72  me is NULL retur
0c60: 6e 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68  n the size of th
0c70: 65 20 6d 6f 73 74 0a 2a 2a 20 72 65 63 65 6e 74  e most.** recent
0c80: 6c 79 20 73 74 61 74 2d 65 64 20 66 69 6c 65 2e  ly stat-ed file.
0c90: 0a 2a 2f 0a 69 36 34 20 66 69 6c 65 5f 6d 74 69  .*/.i64 file_mti
0ca0: 6d 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  me(const char *z
0cb0: 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 72 65 74  Filename){.  ret
0cc0: 75 72 6e 20 67 65 74 53 74 61 74 28 7a 46 69 6c  urn getStat(zFil
0cd0: 65 6e 61 6d 65 2c 20 30 29 20 3f 20 2d 31 20 3a  ename, 0) ? -1 :
0ce0: 20 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 74 69   fileStat.st_mti
0cf0: 6d 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 61 6d  me;.}../*.** Sam
0d00: 65 20 61 73 20 66 69 6c 65 5f 6d 74 69 6d 65 28  e as file_mtime(
0d10: 29 2c 20 62 75 74 20 74 61 6b 65 73 20 69 6e 74  ), but takes int
0d20: 6f 20 61 63 63 6f 75 6e 74 20 73 79 6d 6c 69 6e  o account symlin
0d30: 6b 73 2e 0a 2a 2f 0a 69 36 34 20 66 69 6c 65 5f  ks..*/.i64 file_
0d40: 77 64 5f 6d 74 69 6d 65 28 63 6f 6e 73 74 20 63  wd_mtime(const c
0d50: 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b  har *zFilename){
0d60: 0a 20 20 72 65 74 75 72 6e 20 67 65 74 53 74 61  .  return getSta
0d70: 74 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 31 29 20  t(zFilename, 1) 
0d80: 3f 20 2d 31 20 3a 20 66 69 6c 65 53 74 61 74 2e  ? -1 : fileStat.
0d90: 73 74 5f 6d 74 69 6d 65 3b 0a 7d 0a 0a 2f 2a 0a  st_mtime;.}../*.
0da0: 2a 2a 20 52 65 74 75 72 6e 20 54 52 55 45 20 69  ** Return TRUE i
0db0: 66 20 74 68 65 20 6e 61 6d 65 64 20 66 69 6c 65  f the named file
0dc0: 20 69 73 20 61 6e 20 6f 72 64 69 6e 61 72 79 20   is an ordinary 
0dd0: 66 69 6c 65 20 6f 72 20 73 79 6d 6c 69 6e 6b 20  file or symlink 
0de0: 0a 2a 2a 20 61 6e 64 20 73 79 6d 6c 69 6e 6b 73  .** and symlinks
0df0: 20 61 72 65 20 61 6c 6c 6f 77 65 64 2e 0a 2a 2a   are allowed..**
0e00: 20 52 65 74 75 72 6e 20 66 61 6c 73 65 20 66 6f   Return false fo
0e10: 72 20 64 69 72 65 63 74 6f 72 69 65 73 2c 20 64  r directories, d
0e20: 65 76 69 63 65 73 2c 20 66 69 66 6f 73 2c 20 65  evices, fifos, e
0e30: 74 63 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f  tc..*/.int file_
0e40: 77 64 5f 69 73 66 69 6c 65 5f 6f 72 5f 6c 69 6e  wd_isfile_or_lin
0e50: 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46  k(const char *zF
0e60: 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 72 65 74 75  ilename){.  retu
0e70: 72 6e 20 67 65 74 53 74 61 74 28 7a 46 69 6c 65  rn getStat(zFile
0e80: 6e 61 6d 65 2c 20 31 29 20 3f 20 30 20 3a 20 53  name, 1) ? 0 : S
0e90: 5f 49 53 52 45 47 28 66 69 6c 65 53 74 61 74 2e  _ISREG(fileStat.
0ea0: 73 74 5f 6d 6f 64 65 29 20 7c 7c 0a 20 20 20 20  st_mode) ||.    
0eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ed0: 20 53 5f 49 53 4c 4e 4b 28 66 69 6c 65 53 74 61   S_ISLNK(fileSta
0ee0: 74 2e 73 74 5f 6d 6f 64 65 29 3b 0a 7d 0a 0a 2f  t.st_mode);.}../
0ef0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 54 52 55 45  *.** Return TRUE
0f00: 20 69 66 20 74 68 65 20 6e 61 6d 65 64 20 66 69   if the named fi
0f10: 6c 65 20 69 73 20 61 6e 20 6f 72 64 69 6e 61 72  le is an ordinar
0f20: 79 20 66 69 6c 65 2e 20 20 52 65 74 75 72 6e 20  y file.  Return 
0f30: 66 61 6c 73 65 0a 2a 2a 20 66 6f 72 20 64 69 72  false.** for dir
0f40: 65 63 74 6f 72 69 65 73 2c 20 64 65 76 69 63 65  ectories, device
0f50: 73 2c 20 66 69 66 6f 73 2c 20 73 79 6d 6c 69 6e  s, fifos, symlin
0f60: 6b 73 2c 20 65 74 63 2e 0a 2a 2f 0a 69 6e 74 20  ks, etc..*/.int 
0f70: 66 69 6c 65 5f 69 73 66 69 6c 65 28 63 6f 6e 73  file_isfile(cons
0f80: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d  t char *zFilenam
0f90: 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 67 65 74  e){.  return get
0fa0: 53 74 61 74 28 7a 46 69 6c 65 6e 61 6d 65 2c 20  Stat(zFilename, 
0fb0: 30 29 20 3f 20 30 20 3a 20 53 5f 49 53 52 45 47  0) ? 0 : S_ISREG
0fc0: 28 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 6f 64  (fileStat.st_mod
0fd0: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 61 6d  e);.}../*.** Sam
0fe0: 65 20 61 73 20 66 69 6c 65 5f 69 73 66 69 6c 65  e as file_isfile
0ff0: 28 29 2c 20 62 75 74 20 74 61 6b 65 73 20 69 6e  (), but takes in
1000: 74 6f 20 61 63 63 6f 75 6e 74 20 73 79 6d 6c 69  to account symli
1010: 6e 6b 73 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65  nks..*/.int file
1020: 5f 77 64 5f 69 73 66 69 6c 65 28 63 6f 6e 73 74  _wd_isfile(const
1030: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
1040: 29 7b 0a 20 20 72 65 74 75 72 6e 20 67 65 74 53  ){.  return getS
1050: 74 61 74 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 31  tat(zFilename, 1
1060: 29 20 3f 20 30 20 3a 20 53 5f 49 53 52 45 47 28  ) ? 0 : S_ISREG(
1070: 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 6f 64 65  fileStat.st_mode
1080: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61  );.}../*.** Crea
1090: 74 65 20 73 79 6d 6c 69 6e 6b 20 74 6f 20 66 69  te symlink to fi
10a0: 6c 65 20 6f 6e 20 55 6e 69 78 2c 20 6f 72 20 70  le on Unix, or p
10b0: 6c 61 69 6e 2d 74 65 78 74 20 66 69 6c 65 20 77  lain-text file w
10c0: 69 74 68 0a 2a 2a 20 73 79 6d 6c 69 6e 6b 20 74  ith.** symlink t
10d0: 61 72 67 65 74 20 69 66 20 22 61 6c 6c 6f 77 2d  arget if "allow-
10e0: 73 79 6d 6c 69 6e 6b 73 22 20 69 73 20 6f 66 66  symlinks" is off
10f0: 20 6f 72 20 77 65 27 72 65 20 6f 6e 20 57 69 6e   or we're on Win
1100: 64 6f 77 73 2e 0a 2a 2a 0a 2a 2a 20 41 72 67 75  dows..**.** Argu
1110: 6d 65 6e 74 73 3a 20 74 61 72 67 65 74 20 66 69  ments: target fi
1120: 6c 65 20 28 73 79 6d 6c 69 6e 6b 20 77 69 6c 6c  le (symlink will
1130: 20 70 6f 69 6e 74 20 74 6f 20 69 74 29 2c 20 6c   point to it), l
1140: 69 6e 6b 20 66 69 6c 65 0a 2a 2a 2f 0a 76 6f 69  ink file.**/.voi
1150: 64 20 73 79 6d 6c 69 6e 6b 5f 63 72 65 61 74 65  d symlink_create
1160: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 61  (const char *zTa
1170: 72 67 65 74 46 69 6c 65 2c 20 63 6f 6e 73 74 20  rgetFile, const 
1180: 63 68 61 72 20 2a 7a 4c 69 6e 6b 46 69 6c 65 29  char *zLinkFile)
1190: 7b 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28 5f  {.#if !defined(_
11a0: 57 49 4e 33 32 29 0a 20 20 69 66 28 20 67 2e 61  WIN32).  if( g.a
11b0: 6c 6c 6f 77 53 79 6d 6c 69 6e 6b 73 20 29 7b 0a  llowSymlinks ){.
11c0: 20 20 20 20 69 6e 74 20 69 2c 20 6e 4e 61 6d 65      int i, nName
11d0: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d  ;.    char *zNam
11e0: 65 2c 20 7a 42 75 66 5b 31 30 30 30 5d 3b 0a 0a  e, zBuf[1000];..
11f0: 20 20 20 20 6e 4e 61 6d 65 20 3d 20 73 74 72 6c      nName = strl
1200: 65 6e 28 7a 4c 69 6e 6b 46 69 6c 65 29 3b 0a 20  en(zLinkFile);. 
1210: 20 20 20 69 66 28 20 6e 4e 61 6d 65 3e 3d 73 69     if( nName>=si
1220: 7a 65 6f 66 28 7a 42 75 66 29 20 29 7b 0a 20 20  zeof(zBuf) ){.  
1230: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 6d 70 72 69      zName = mpri
1240: 6e 74 66 28 22 25 73 22 2c 20 7a 4c 69 6e 6b 46  ntf("%s", zLinkF
1250: 69 6c 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ile);.    }else{
1260: 0a 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 7a  .      zName = z
1270: 42 75 66 3b 0a 20 20 20 20 20 20 6d 65 6d 63 70  Buf;.      memcp
1280: 79 28 7a 4e 61 6d 65 2c 20 7a 4c 69 6e 6b 46 69  y(zName, zLinkFi
1290: 6c 65 2c 20 6e 4e 61 6d 65 2b 31 29 3b 0a 20 20  le, nName+1);.  
12a0: 20 20 7d 0a 20 20 20 20 6e 4e 61 6d 65 20 3d 20    }.    nName = 
12b0: 66 69 6c 65 5f 73 69 6d 70 6c 69 66 79 5f 6e 61  file_simplify_na
12c0: 6d 65 28 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 2c  me(zName, nName,
12d0: 20 30 29 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31   0);.    for(i=1
12e0: 3b 20 69 3c 6e 4e 61 6d 65 3b 20 69 2b 2b 29 7b  ; i<nName; i++){
12f0: 0a 20 20 20 20 20 20 69 66 28 20 7a 4e 61 6d 65  .      if( zName
1300: 5b 69 5d 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20  [i]=='/' ){.    
1310: 20 20 20 20 7a 4e 61 6d 65 5b 69 5d 20 3d 20 30      zName[i] = 0
1320: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
1330: 66 69 6c 65 5f 6d 6b 64 69 72 28 7a 4e 61 6d 65  file_mkdir(zName
1340: 2c 20 31 29 20 29 7b 0a 20 20 20 20 20 20 20 20  , 1) ){.        
1350: 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c      fossil_fatal
1360: 5f 72 65 63 75 72 73 69 76 65 28 22 75 6e 61 62  _recursive("unab
1370: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 64 69 72  le to create dir
1380: 65 63 74 6f 72 79 20 25 73 22 2c 20 7a 4e 61 6d  ectory %s", zNam
1390: 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20  e);.            
13a0: 72 65 74 75 72 6e 3b 0a 20 20 20 20 20 20 20 20  return;.        
13b0: 20 20 7d 0a 20 20 20 20 20 20 20 20 7a 4e 61 6d    }.        zNam
13c0: 65 5b 69 5d 20 3d 20 27 2f 27 3b 0a 20 20 20 20  e[i] = '/';.    
13d0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
13e0: 28 20 7a 4e 61 6d 65 21 3d 7a 42 75 66 20 29 20  ( zName!=zBuf ) 
13f0: 66 72 65 65 28 7a 4e 61 6d 65 29 3b 0a 0a 20 20  free(zName);..  
1400: 20 20 69 66 28 20 73 79 6d 6c 69 6e 6b 28 7a 54    if( symlink(zT
1410: 61 72 67 65 74 46 69 6c 65 2c 20 7a 4e 61 6d 65  argetFile, zName
1420: 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 66 6f  )!=0 ){.      fo
1430: 73 73 69 6c 5f 66 61 74 61 6c 5f 72 65 63 75 72  ssil_fatal_recur
1440: 73 69 76 65 28 22 75 6e 61 62 6c 65 20 74 6f 20  sive("unable to 
1450: 63 72 65 61 74 65 20 73 79 6d 6c 69 6e 6b 20 5c  create symlink \
1460: 22 25 73 5c 22 22 2c 20 7a 4e 61 6d 65 29 3b 20  "%s\"", zName); 
1470: 20 20 20 20 20 0a 20 20 20 20 7d 0a 20 20 7d 65       .    }.  }e
1480: 6c 73 65 0a 23 65 6e 64 69 66 20 0a 20 20 7b 0a  lse.#endif .  {.
1490: 20 20 20 20 42 6c 6f 62 20 63 6f 6e 74 65 6e 74      Blob content
14a0: 3b 0a 20 20 20 20 62 6c 6f 62 5f 73 65 74 28 26  ;.    blob_set(&
14b0: 63 6f 6e 74 65 6e 74 2c 20 7a 54 61 72 67 65 74  content, zTarget
14c0: 46 69 6c 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  File);.    blob_
14d0: 77 72 69 74 65 5f 74 6f 5f 66 69 6c 65 28 26 63  write_to_file(&c
14e0: 6f 6e 74 65 6e 74 2c 20 7a 4c 69 6e 6b 46 69 6c  ontent, zLinkFil
14f0: 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73  e);.    blob_res
1500: 65 74 28 26 63 6f 6e 74 65 6e 74 29 3b 0a 20 20  et(&content);.  
1510: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20  }.}../*.** Copy 
1520: 73 79 6d 62 6f 6c 69 63 20 6c 69 6e 6b 20 66 72  symbolic link fr
1530: 6f 6d 20 7a 46 72 6f 6d 20 74 6f 20 7a 54 6f 2e  om zFrom to zTo.
1540: 0a 2a 2f 0a 76 6f 69 64 20 73 79 6d 6c 69 6e 6b  .*/.void symlink
1550: 5f 63 6f 70 79 28 63 6f 6e 73 74 20 63 68 61 72  _copy(const char
1560: 20 2a 7a 46 72 6f 6d 2c 20 63 6f 6e 73 74 20 63   *zFrom, const c
1570: 68 61 72 20 2a 7a 54 6f 29 7b 0a 20 20 42 6c 6f  har *zTo){.  Blo
1580: 62 20 63 6f 6e 74 65 6e 74 3b 0a 20 20 62 6c 6f  b content;.  blo
1590: 62 5f 72 65 61 64 5f 6c 69 6e 6b 28 26 63 6f 6e  b_read_link(&con
15a0: 74 65 6e 74 2c 20 7a 46 72 6f 6d 29 3b 0a 20 20  tent, zFrom);.  
15b0: 73 79 6d 6c 69 6e 6b 5f 63 72 65 61 74 65 28 62  symlink_create(b
15c0: 6c 6f 62 5f 73 74 72 28 26 63 6f 6e 74 65 6e 74  lob_str(&content
15d0: 29 2c 20 7a 54 6f 29 3b 0a 20 20 62 6c 6f 62 5f  ), zTo);.  blob_
15e0: 72 65 73 65 74 28 26 63 6f 6e 74 65 6e 74 29 3b  reset(&content);
15f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
1600: 20 66 69 6c 65 20 70 65 72 6d 69 73 73 69 6f 6e   file permission
1610: 73 20 28 6e 6f 72 6d 61 6c 2c 20 65 78 65 63 75  s (normal, execu
1620: 74 61 62 6c 65 2c 20 6f 72 20 73 79 6d 6c 69 6e  table, or symlin
1630: 6b 29 3a 0a 2a 2a 20 20 20 2d 20 50 45 52 4d 5f  k):.**   - PERM_
1640: 45 58 45 20 69 66 20 66 69 6c 65 20 69 73 20 65  EXE if file is e
1650: 78 65 63 75 74 61 62 6c 65 3b 0a 2a 2a 20 20 20  xecutable;.**   
1660: 2d 20 50 45 52 4d 5f 4c 4e 4b 20 6f 6e 20 55 6e  - PERM_LNK on Un
1670: 69 78 20 69 66 20 66 69 6c 65 20 69 73 20 73 79  ix if file is sy
1680: 6d 6c 69 6e 6b 20 61 6e 64 20 61 6c 6c 6f 77 2d  mlink and allow-
1690: 73 79 6d 6c 69 6e 6b 73 20 6f 70 74 69 6f 6e 20  symlinks option 
16a0: 69 73 20 6f 6e 3b 0a 2a 2a 20 20 20 2d 20 50 45  is on;.**   - PE
16b0: 52 4d 5f 52 45 47 20 66 6f 72 20 61 6c 6c 20 6f  RM_REG for all o
16c0: 74 68 65 72 20 63 61 73 65 73 20 28 72 65 67 75  ther cases (regu
16d0: 6c 61 72 20 66 69 6c 65 2c 20 64 69 72 65 63 74  lar file, direct
16e0: 6f 72 79 2c 20 66 69 66 6f 2c 20 65 74 63 29 2e  ory, fifo, etc).
16f0: 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 77 64 5f  .*/.int file_wd_
1700: 70 65 72 6d 28 63 6f 6e 73 74 20 63 68 61 72 20  perm(const char 
1710: 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 69  *zFilename){.  i
1720: 66 28 20 67 65 74 53 74 61 74 28 7a 46 69 6c 65  f( getStat(zFile
1730: 6e 61 6d 65 2c 20 31 29 20 29 20 72 65 74 75 72  name, 1) ) retur
1740: 6e 20 50 45 52 4d 5f 52 45 47 3b 0a 23 69 66 20  n PERM_REG;.#if 
1750: 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a  defined(_WIN32).
1760: 23 20 20 69 66 20 64 65 66 69 6e 65 64 28 5f 5f  #  if defined(__
1770: 44 4d 43 5f 5f 29 20 7c 7c 20 64 65 66 69 6e 65  DMC__) || define
1780: 64 28 5f 4d 53 43 5f 56 45 52 29 0a 23 20 20 20  d(_MSC_VER).#   
1790: 20 64 65 66 69 6e 65 20 53 5f 49 58 55 53 52 20   define S_IXUSR 
17a0: 20 5f 53 5f 49 45 58 45 43 0a 23 20 20 65 6e 64   _S_IEXEC.#  end
17b0: 69 66 0a 20 20 69 66 28 20 53 5f 49 53 52 45 47  if.  if( S_ISREG
17c0: 28 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 6f 64  (fileStat.st_mod
17d0: 65 29 20 26 26 20 28 28 53 5f 49 58 55 53 52 29  e) && ((S_IXUSR)
17e0: 26 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 6f 64  &fileStat.st_mod
17f0: 65 29 21 3d 30 20 29 0a 20 20 20 20 72 65 74 75  e)!=0 ).    retu
1800: 72 6e 20 50 45 52 4d 5f 45 58 45 3b 0a 20 20 65  rn PERM_EXE;.  e
1810: 6c 73 65 0a 20 20 20 20 72 65 74 75 72 6e 20 50  lse.    return P
1820: 45 52 4d 5f 52 45 47 3b 0a 23 65 6c 73 65 0a 20  ERM_REG;.#else. 
1830: 20 69 66 28 20 53 5f 49 53 52 45 47 28 66 69 6c   if( S_ISREG(fil
1840: 65 53 74 61 74 2e 73 74 5f 6d 6f 64 65 29 20 26  eStat.st_mode) &
1850: 26 20 0a 20 20 20 20 20 20 28 28 53 5f 49 58 55  & .      ((S_IXU
1860: 53 52 7c 53 5f 49 58 47 52 50 7c 53 5f 49 58 4f  SR|S_IXGRP|S_IXO
1870: 54 48 29 26 66 69 6c 65 53 74 61 74 2e 73 74 5f  TH)&fileStat.st_
1880: 6d 6f 64 65 29 21 3d 30 20 29 0a 20 20 20 20 72  mode)!=0 ).    r
1890: 65 74 75 72 6e 20 50 45 52 4d 5f 45 58 45 3b 0a  eturn PERM_EXE;.
18a0: 20 20 65 6c 73 65 20 69 66 28 20 67 2e 61 6c 6c    else if( g.all
18b0: 6f 77 53 79 6d 6c 69 6e 6b 73 20 26 26 20 53 5f  owSymlinks && S_
18c0: 49 53 4c 4e 4b 28 66 69 6c 65 53 74 61 74 2e 73  ISLNK(fileStat.s
18d0: 74 5f 6d 6f 64 65 29 20 29 0a 20 20 20 20 72 65  t_mode) ).    re
18e0: 74 75 72 6e 20 50 45 52 4d 5f 4c 4e 4b 3b 0a 20  turn PERM_LNK;. 
18f0: 20 65 6c 73 65 0a 20 20 20 20 72 65 74 75 72 6e   else.    return
1900: 20 50 45 52 4d 5f 52 45 47 3b 0a 23 65 6e 64 69   PERM_REG;.#endi
1910: 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  f.}../*.** Retur
1920: 6e 20 54 52 55 45 20 69 66 20 74 68 65 20 6e 61  n TRUE if the na
1930: 6d 65 64 20 66 69 6c 65 20 69 73 20 61 6e 20 65  med file is an e
1940: 78 65 63 75 74 61 62 6c 65 2e 20 20 52 65 74 75  xecutable.  Retu
1950: 72 6e 20 66 61 6c 73 65 0a 2a 2a 20 66 6f 72 20  rn false.** for 
1960: 64 69 72 65 63 74 6f 72 69 65 73 2c 20 64 65 76  directories, dev
1970: 69 63 65 73 2c 20 66 69 66 6f 73 2c 20 73 79 6d  ices, fifos, sym
1980: 6c 69 6e 6b 73 2c 20 65 74 63 2e 0a 2a 2f 0a 69  links, etc..*/.i
1990: 6e 74 20 66 69 6c 65 5f 77 64 5f 69 73 65 78 65  nt file_wd_isexe
19a0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69  (const char *zFi
19b0: 6c 65 6e 61 6d 65 29 7b 0a 20 20 72 65 74 75 72  lename){.  retur
19c0: 6e 20 66 69 6c 65 5f 77 64 5f 70 65 72 6d 28 7a  n file_wd_perm(z
19d0: 46 69 6c 65 6e 61 6d 65 29 3d 3d 50 45 52 4d 5f  Filename)==PERM_
19e0: 45 58 45 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  EXE;.}../*.** Re
19f0: 74 75 72 6e 20 54 52 55 45 20 69 66 20 74 68 65  turn TRUE if the
1a00: 20 6e 61 6d 65 64 20 66 69 6c 65 20 69 73 20 61   named file is a
1a10: 20 73 79 6d 6c 69 6e 6b 20 61 6e 64 20 73 79 6d   symlink and sym
1a20: 6c 69 6e 6b 73 20 61 72 65 20 61 6c 6c 6f 77 65  links are allowe
1a30: 64 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 66 61 6c  d..** Return fal
1a40: 73 65 20 66 6f 72 20 61 6c 6c 20 6f 74 68 65 72  se for all other
1a50: 20 63 61 73 65 73 2e 0a 2a 2a 0a 2a 2a 20 4f 6e   cases..**.** On
1a60: 20 57 69 6e 64 6f 77 73 2c 20 61 6c 77 61 79 73   Windows, always
1a70: 20 72 65 74 75 72 6e 20 46 61 6c 73 65 2e 0a 2a   return False..*
1a80: 2f 0a 69 6e 74 20 66 69 6c 65 5f 77 64 5f 69 73  /.int file_wd_is
1a90: 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20  link(const char 
1aa0: 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 72  *zFilename){.  r
1ab0: 65 74 75 72 6e 20 66 69 6c 65 5f 77 64 5f 70 65  eturn file_wd_pe
1ac0: 72 6d 28 7a 46 69 6c 65 6e 61 6d 65 29 3d 3d 50  rm(zFilename)==P
1ad0: 45 52 4d 5f 4c 4e 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a  ERM_LNK;.}../*.*
1ae0: 2a 20 52 65 74 75 72 6e 20 31 20 69 66 20 7a 46  * Return 1 if zF
1af0: 69 6c 65 6e 61 6d 65 20 69 73 20 61 20 64 69 72  ilename is a dir
1b00: 65 63 74 6f 72 79 2e 20 20 52 65 74 75 72 6e 20  ectory.  Return 
1b10: 30 20 69 66 20 7a 46 69 6c 65 6e 61 6d 65 0a 2a  0 if zFilename.*
1b20: 2a 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74  * does not exist
1b30: 2e 20 20 52 65 74 75 72 6e 20 32 20 69 66 20 7a  .  Return 2 if z
1b40: 46 69 6c 65 6e 61 6d 65 20 65 78 69 73 74 73 20  Filename exists 
1b50: 62 75 74 20 69 73 20 73 6f 6d 65 74 68 69 6e 67  but is something
1b60: 0a 2a 2a 20 6f 74 68 65 72 20 74 68 61 6e 20 61  .** other than a
1b70: 20 64 69 72 65 63 74 6f 72 79 2e 0a 2a 2f 0a 69   directory..*/.i
1b80: 6e 74 20 66 69 6c 65 5f 69 73 64 69 72 28 63 6f  nt file_isdir(co
1b90: 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e  nst char *zFilen
1ba0: 61 6d 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a  ame){.  int rc;.
1bb0: 0a 20 20 69 66 28 20 7a 46 69 6c 65 6e 61 6d 65  .  if( zFilename
1bc0: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 46   ){.    char *zF
1bd0: 4e 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22  N = mprintf("%s"
1be0: 2c 20 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20  , zFilename);.  
1bf0: 20 20 66 69 6c 65 5f 73 69 6d 70 6c 69 66 79 5f    file_simplify_
1c00: 6e 61 6d 65 28 7a 46 4e 2c 20 2d 31 2c 20 30 29  name(zFN, -1, 0)
1c10: 3b 0a 20 20 20 20 72 63 20 3d 20 67 65 74 53 74  ;.    rc = getSt
1c20: 61 74 28 7a 46 4e 2c 20 30 29 3b 0a 20 20 20 20  at(zFN, 0);.    
1c30: 66 72 65 65 28 7a 46 4e 29 3b 0a 20 20 7d 65 6c  free(zFN);.  }el
1c40: 73 65 7b 0a 20 20 20 20 72 63 20 3d 20 67 65 74  se{.    rc = get
1c50: 53 74 61 74 28 30 2c 20 30 29 3b 0a 20 20 7d 0a  Stat(0, 0);.  }.
1c60: 20 20 72 65 74 75 72 6e 20 72 63 20 3f 20 30 20    return rc ? 0 
1c70: 3a 20 28 53 5f 49 53 44 49 52 28 66 69 6c 65 53  : (S_ISDIR(fileS
1c80: 74 61 74 2e 73 74 5f 6d 6f 64 65 29 20 3f 20 31  tat.st_mode) ? 1
1c90: 20 3a 20 32 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20   : 2);.}../*.** 
1ca0: 53 61 6d 65 20 61 73 20 66 69 6c 65 5f 69 73 64  Same as file_isd
1cb0: 69 72 28 29 2c 20 62 75 74 20 74 61 6b 65 73 20  ir(), but takes 
1cc0: 69 6e 74 6f 20 61 63 63 6f 75 6e 74 20 73 79 6d  into account sym
1cd0: 6c 69 6e 6b 73 2e 0a 2a 2f 0a 69 6e 74 20 66 69  links..*/.int fi
1ce0: 6c 65 5f 77 64 5f 69 73 64 69 72 28 63 6f 6e 73  le_wd_isdir(cons
1cf0: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d  t char *zFilenam
1d00: 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20  e){.  int rc;.. 
1d10: 20 69 66 28 20 7a 46 69 6c 65 6e 61 6d 65 20 29   if( zFilename )
1d20: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 46 4e 20  {.    char *zFN 
1d30: 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20  = mprintf("%s", 
1d40: 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 20 20  zFilename);.    
1d50: 66 69 6c 65 5f 73 69 6d 70 6c 69 66 79 5f 6e 61  file_simplify_na
1d60: 6d 65 28 7a 46 4e 2c 20 2d 31 2c 20 30 29 3b 0a  me(zFN, -1, 0);.
1d70: 20 20 20 20 72 63 20 3d 20 67 65 74 53 74 61 74      rc = getStat
1d80: 28 7a 46 4e 2c 20 31 29 3b 0a 20 20 20 20 66 72  (zFN, 1);.    fr
1d90: 65 65 28 7a 46 4e 29 3b 0a 20 20 7d 65 6c 73 65  ee(zFN);.  }else
1da0: 7b 0a 20 20 20 20 72 63 20 3d 20 67 65 74 53 74  {.    rc = getSt
1db0: 61 74 28 30 2c 20 31 29 3b 0a 20 20 7d 0a 20 20  at(0, 1);.  }.  
1dc0: 72 65 74 75 72 6e 20 72 63 20 3f 20 30 20 3a 20  return rc ? 0 : 
1dd0: 28 53 5f 49 53 44 49 52 28 66 69 6c 65 53 74 61  (S_ISDIR(fileSta
1de0: 74 2e 73 74 5f 6d 6f 64 65 29 20 3f 20 31 20 3a  t.st_mode) ? 1 :
1df0: 20 32 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 57   2);.}.../*.** W
1e00: 72 61 70 70 65 72 20 61 72 6f 75 6e 64 20 74 68  rapper around th
1e10: 65 20 61 63 63 65 73 73 28 29 20 73 79 73 74 65  e access() syste
1e20: 6d 20 63 61 6c 6c 2e 0a 2a 2f 0a 69 6e 74 20 66  m call..*/.int f
1e30: 69 6c 65 5f 61 63 63 65 73 73 28 63 6f 6e 73 74  ile_access(const
1e40: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
1e50: 2c 20 69 6e 74 20 66 6c 61 67 73 29 7b 0a 20 20  , int flags){.  
1e60: 63 68 61 72 20 2a 7a 4d 62 63 73 20 3d 20 66 6f  char *zMbcs = fo
1e70: 73 73 69 6c 5f 75 74 66 38 5f 74 6f 5f 6d 62 63  ssil_utf8_to_mbc
1e80: 73 28 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20  s(zFilename);.  
1e90: 69 6e 74 20 72 63 20 3d 20 61 63 63 65 73 73 28  int rc = access(
1ea0: 7a 4d 62 63 73 2c 20 66 6c 61 67 73 29 3b 0a 20  zMbcs, flags);. 
1eb0: 20 66 6f 73 73 69 6c 5f 6d 62 63 73 5f 66 72 65   fossil_mbcs_fre
1ec0: 65 28 7a 4d 62 63 73 29 3b 0a 20 20 72 65 74 75  e(zMbcs);.  retu
1ed0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
1ee0: 46 69 6e 64 20 61 6e 20 75 6e 75 73 65 64 20 66  Find an unused f
1ef0: 69 6c 65 6e 61 6d 65 20 73 69 6d 69 6c 61 72 20  ilename similar 
1f00: 74 6f 20 7a 42 61 73 65 20 77 69 74 68 20 7a 53  to zBase with zS
1f10: 75 66 66 69 78 20 61 70 70 65 6e 64 65 64 2e 0a  uffix appended..
1f20: 2a 2a 0a 2a 2a 20 4d 61 6b 65 20 74 68 65 20 6e  **.** Make the n
1f30: 61 6d 65 20 72 65 6c 61 74 69 76 65 20 74 6f 20  ame relative to 
1f40: 74 68 65 20 77 6f 72 6b 69 6e 67 20 64 69 72 65  the working dire
1f50: 63 74 6f 72 79 20 69 66 20 72 65 6c 46 6c 61 67  ctory if relFlag
1f60: 20 69 73 20 74 72 75 65 2e 0a 2a 2a 0a 2a 2a 20   is true..**.** 
1f70: 53 70 61 63 65 20 74 6f 20 68 6f 6c 64 20 74 68  Space to hold th
1f80: 65 20 6e 65 77 20 66 69 6c 65 6e 61 6d 65 20 69  e new filename i
1f90: 73 20 6f 62 74 61 69 6e 65 64 20 66 6f 72 6d 20  s obtained form 
1fa0: 6d 70 72 69 6e 74 66 28 29 20 61 6e 64 20 73 68  mprintf() and sh
1fb0: 6f 75 6c 64 0a 2a 2a 20 62 65 20 66 72 65 65 64  ould.** be freed
1fc0: 20 62 79 20 74 68 65 20 63 61 6c 6c 65 72 2e 0a   by the caller..
1fd0: 2a 2f 0a 63 68 61 72 20 2a 66 69 6c 65 5f 6e 65  */.char *file_ne
1fe0: 77 6e 61 6d 65 28 63 6f 6e 73 74 20 63 68 61 72  wname(const char
1ff0: 20 2a 7a 42 61 73 65 2c 20 63 6f 6e 73 74 20 63   *zBase, const c
2000: 68 61 72 20 2a 7a 53 75 66 66 69 78 2c 20 69 6e  har *zSuffix, in
2010: 74 20 72 65 6c 46 6c 61 67 29 7b 0a 20 20 63 68  t relFlag){.  ch
2020: 61 72 20 2a 7a 20 3d 20 30 3b 0a 20 20 69 6e 74  ar *z = 0;.  int
2030: 20 63 6e 74 20 3d 20 30 3b 0a 20 20 7a 20 3d 20   cnt = 0;.  z = 
2040: 6d 70 72 69 6e 74 66 28 22 25 73 2d 25 73 22 2c  mprintf("%s-%s",
2050: 20 7a 42 61 73 65 2c 20 7a 53 75 66 66 69 78 29   zBase, zSuffix)
2060: 3b 0a 20 20 77 68 69 6c 65 28 20 66 69 6c 65 5f  ;.  while( file_
2070: 73 69 7a 65 28 7a 29 3e 3d 30 20 29 7b 0a 20 20  size(z)>=0 ){.  
2080: 20 20 66 6f 73 73 69 6c 5f 66 72 65 65 28 7a 29    fossil_free(z)
2090: 3b 0a 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e 74  ;.    z = mprint
20a0: 66 28 22 25 73 2d 25 73 2d 25 64 22 2c 20 7a 42  f("%s-%s-%d", zB
20b0: 61 73 65 2c 20 7a 53 75 66 66 69 78 2c 20 63 6e  ase, zSuffix, cn
20c0: 74 2b 2b 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20  t++);.  }.  if( 
20d0: 72 65 6c 46 6c 61 67 20 29 7b 0a 20 20 20 20 42  relFlag ){.    B
20e0: 6c 6f 62 20 78 3b 0a 20 20 20 20 66 69 6c 65 5f  lob x;.    file_
20f0: 72 65 6c 61 74 69 76 65 5f 6e 61 6d 65 28 7a 2c  relative_name(z,
2100: 20 26 78 2c 20 30 29 3b 0a 20 20 20 20 66 6f 73   &x, 0);.    fos
2110: 73 69 6c 5f 66 72 65 65 28 7a 29 3b 0a 20 20 20  sil_free(z);.   
2120: 20 7a 20 3d 20 62 6c 6f 62 5f 73 74 72 28 26 78   z = blob_str(&x
2130: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
2140: 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  z;.}../*.** Retu
2150: 72 6e 20 74 68 65 20 74 61 69 6c 20 6f 66 20 61  rn the tail of a
2160: 20 66 69 6c 65 20 70 61 74 68 6e 61 6d 65 2e 20   file pathname. 
2170: 20 54 68 65 20 74 61 69 6c 20 69 73 20 74 68 65   The tail is the
2180: 20 6c 61 73 74 20 63 6f 6d 70 6f 6e 65 6e 74 0a   last component.
2190: 2a 2a 20 6f 66 20 74 68 65 20 70 61 74 68 2e 20  ** of the path. 
21a0: 20 46 6f 72 20 65 78 61 6d 70 6c 65 2c 20 74 68   For example, th
21b0: 65 20 74 61 69 6c 20 6f 66 20 22 2f 61 2f 62 2f  e tail of "/a/b/
21c0: 63 2e 64 22 20 69 73 20 22 63 2e 64 22 2e 0a 2a  c.d" is "c.d"..*
21d0: 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20 2a 66 69  /.const char *fi
21e0: 6c 65 5f 74 61 69 6c 28 63 6f 6e 73 74 20 63 68  le_tail(const ch
21f0: 61 72 20 2a 7a 29 7b 0a 20 20 63 6f 6e 73 74 20  ar *z){.  const 
2200: 63 68 61 72 20 2a 7a 54 61 69 6c 20 3d 20 7a 3b  char *zTail = z;
2210: 0a 20 20 77 68 69 6c 65 28 20 7a 5b 30 5d 20 29  .  while( z[0] )
2220: 7b 0a 20 20 20 20 69 66 28 20 7a 5b 30 5d 3d 3d  {.    if( z[0]==
2230: 27 2f 27 20 29 20 7a 54 61 69 6c 20 3d 20 26 7a  '/' ) zTail = &z
2240: 5b 31 5d 3b 0a 20 20 20 20 7a 2b 2b 3b 0a 20 20  [1];.    z++;.  
2250: 7d 0a 20 20 72 65 74 75 72 6e 20 7a 54 61 69 6c  }.  return zTail
2260: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20  ;.}../*.** Copy 
2270: 74 68 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61  the content of a
2280: 20 66 69 6c 65 20 66 72 6f 6d 20 6f 6e 65 20 70   file from one p
2290: 6c 61 63 65 20 74 6f 20 61 6e 6f 74 68 65 72 2e  lace to another.
22a0: 0a 2a 2f 0a 76 6f 69 64 20 66 69 6c 65 5f 63 6f  .*/.void file_co
22b0: 70 79 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  py(const char *z
22c0: 46 72 6f 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72  From, const char
22d0: 20 2a 7a 54 6f 29 7b 0a 20 20 46 49 4c 45 20 2a   *zTo){.  FILE *
22e0: 69 6e 2c 20 2a 6f 75 74 3b 0a 20 20 69 6e 74 20  in, *out;.  int 
22f0: 67 6f 74 3b 0a 20 20 63 68 61 72 20 7a 42 75 66  got;.  char zBuf
2300: 5b 38 31 39 32 5d 3b 0a 20 20 69 6e 20 3d 20 66  [8192];.  in = f
2310: 6f 73 73 69 6c 5f 66 6f 70 65 6e 28 7a 46 72 6f  ossil_fopen(zFro
2320: 6d 2c 20 22 72 62 22 29 3b 0a 20 20 69 66 28 20  m, "rb");.  if( 
2330: 69 6e 3d 3d 30 20 29 20 66 6f 73 73 69 6c 5f 66  in==0 ) fossil_f
2340: 61 74 61 6c 28 22 63 61 6e 6e 6f 74 20 6f 70 65  atal("cannot ope
2350: 6e 20 5c 22 25 73 5c 22 20 66 6f 72 20 72 65 61  n \"%s\" for rea
2360: 64 69 6e 67 22 2c 20 7a 46 72 6f 6d 29 3b 0a 20  ding", zFrom);. 
2370: 20 6f 75 74 20 3d 20 66 6f 73 73 69 6c 5f 66 6f   out = fossil_fo
2380: 70 65 6e 28 7a 54 6f 2c 20 22 77 62 22 29 3b 0a  pen(zTo, "wb");.
2390: 20 20 69 66 28 20 6f 75 74 3d 3d 30 20 29 20 66    if( out==0 ) f
23a0: 6f 73 73 69 6c 5f 66 61 74 61 6c 28 22 63 61 6e  ossil_fatal("can
23b0: 6e 6f 74 20 6f 70 65 6e 20 5c 22 25 73 5c 22 20  not open \"%s\" 
23c0: 66 6f 72 20 77 72 69 74 69 6e 67 22 2c 20 7a 54  for writing", zT
23d0: 6f 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 67 6f  o);.  while( (go
23e0: 74 3d 66 72 65 61 64 28 7a 42 75 66 2c 20 31 2c  t=fread(zBuf, 1,
23f0: 20 73 69 7a 65 6f 66 28 7a 42 75 66 29 2c 20 69   sizeof(zBuf), i
2400: 6e 29 29 3e 30 20 29 7b 0a 20 20 20 20 66 77 72  n))>0 ){.    fwr
2410: 69 74 65 28 7a 42 75 66 2c 20 31 2c 20 67 6f 74  ite(zBuf, 1, got
2420: 2c 20 6f 75 74 29 3b 0a 20 20 7d 0a 20 20 66 63  , out);.  }.  fc
2430: 6c 6f 73 65 28 69 6e 29 3b 0a 20 20 66 63 6c 6f  lose(in);.  fclo
2440: 73 65 28 6f 75 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  se(out);.}../*.*
2450: 2a 20 53 65 74 20 6f 72 20 63 6c 65 61 72 20 74  * Set or clear t
2460: 68 65 20 65 78 65 63 75 74 65 20 62 69 74 20 6f  he execute bit o
2470: 6e 20 61 20 66 69 6c 65 2e 20 20 52 65 74 75 72  n a file.  Retur
2480: 6e 20 74 72 75 65 20 69 66 20 61 20 63 68 61 6e  n true if a chan
2490: 67 65 0a 2a 2a 20 6f 63 63 75 72 72 65 64 20 61  ge.** occurred a
24a0: 6e 64 20 66 61 6c 73 65 20 69 66 20 74 68 69 73  nd false if this
24b0: 20 72 6f 75 74 69 6e 65 20 69 73 20 61 20 6e 6f   routine is a no
24c0: 2d 6f 70 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65  -op..*/.int file
24d0: 5f 77 64 5f 73 65 74 65 78 65 28 63 6f 6e 73 74  _wd_setexe(const
24e0: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
24f0: 2c 20 69 6e 74 20 6f 6e 6f 66 66 29 7b 0a 20 20  , int onoff){.  
2500: 69 6e 74 20 72 63 20 3d 20 30 3b 0a 23 69 66 20  int rc = 0;.#if 
2510: 21 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29  !defined(_WIN32)
2520: 0a 20 20 73 74 72 75 63 74 20 73 74 61 74 20 62  .  struct stat b
2530: 75 66 3b 0a 20 20 69 66 28 20 66 6f 73 73 69 6c  uf;.  if( fossil
2540: 5f 73 74 61 74 28 7a 46 69 6c 65 6e 61 6d 65 2c  _stat(zFilename,
2550: 20 26 62 75 66 2c 20 31 29 21 3d 30 20 7c 7c 20   &buf, 1)!=0 || 
2560: 53 5f 49 53 4c 4e 4b 28 62 75 66 2e 73 74 5f 6d  S_ISLNK(buf.st_m
2570: 6f 64 65 29 20 29 20 72 65 74 75 72 6e 20 30 3b  ode) ) return 0;
2580: 0a 20 20 69 66 28 20 6f 6e 6f 66 66 20 29 7b 0a  .  if( onoff ){.
2590: 20 20 20 20 69 6e 74 20 74 61 72 67 65 74 4d 6f      int targetMo
25a0: 64 65 20 3d 20 28 62 75 66 2e 73 74 5f 6d 6f 64  de = (buf.st_mod
25b0: 65 20 26 20 30 34 34 34 29 3e 3e 32 3b 0a 20 20  e & 0444)>>2;.  
25c0: 20 20 69 66 28 20 28 62 75 66 2e 73 74 5f 6d 6f    if( (buf.st_mo
25d0: 64 65 20 26 20 30 31 31 31 29 21 3d 74 61 72 67  de & 0111)!=targ
25e0: 65 74 4d 6f 64 65 20 29 7b 0a 20 20 20 20 20 20  etMode ){.      
25f0: 63 68 6d 6f 64 28 7a 46 69 6c 65 6e 61 6d 65 2c  chmod(zFilename,
2600: 20 62 75 66 2e 73 74 5f 6d 6f 64 65 20 7c 20 74   buf.st_mode | t
2610: 61 72 67 65 74 4d 6f 64 65 29 3b 0a 20 20 20 20  argetMode);.    
2620: 20 20 72 63 20 3d 20 31 3b 0a 20 20 20 20 7d 0a    rc = 1;.    }.
2630: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 66 28    }else{.    if(
2640: 20 28 62 75 66 2e 73 74 5f 6d 6f 64 65 20 26 20   (buf.st_mode & 
2650: 30 31 31 31 29 21 3d 30 20 29 7b 0a 20 20 20 20  0111)!=0 ){.    
2660: 20 20 63 68 6d 6f 64 28 7a 46 69 6c 65 6e 61 6d    chmod(zFilenam
2670: 65 2c 20 62 75 66 2e 73 74 5f 6d 6f 64 65 20 26  e, buf.st_mode &
2680: 20 7e 30 31 31 31 29 3b 0a 20 20 20 20 20 20 72   ~0111);.      r
2690: 63 20 3d 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d  c = 1;.    }.  }
26a0: 0a 23 65 6e 64 69 66 20 2f 2a 20 5f 57 49 4e 33  .#endif /* _WIN3
26b0: 32 20 2a 2f 0a 20 20 72 65 74 75 72 6e 20 72 63  2 */.  return rc
26c0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 6c 65 74  ;.}../*.** Delet
26d0: 65 20 61 20 66 69 6c 65 2e 0a 2a 2f 0a 76 6f 69  e a file..*/.voi
26e0: 64 20 66 69 6c 65 5f 64 65 6c 65 74 65 28 63 6f  d file_delete(co
26f0: 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e  nst char *zFilen
2700: 61 6d 65 29 7b 0a 20 20 63 68 61 72 20 2a 7a 20  ame){.  char *z 
2710: 3d 20 66 6f 73 73 69 6c 5f 75 74 66 38 5f 74 6f  = fossil_utf8_to
2720: 5f 6d 62 63 73 28 7a 46 69 6c 65 6e 61 6d 65 29  _mbcs(zFilename)
2730: 3b 0a 20 20 75 6e 6c 69 6e 6b 28 7a 29 3b 0a 20  ;.  unlink(z);. 
2740: 20 66 6f 73 73 69 6c 5f 6d 62 63 73 5f 66 72 65   fossil_mbcs_fre
2750: 65 28 7a 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  e(z);.}../*.** C
2760: 72 65 61 74 65 20 74 68 65 20 64 69 72 65 63 74  reate the direct
2770: 6f 72 79 20 6e 61 6d 65 64 20 69 6e 20 74 68 65  ory named in the
2780: 20 61 72 67 75 6d 65 6e 74 2c 20 69 66 20 69 74   argument, if it
2790: 20 64 6f 65 73 20 6e 6f 74 20 61 6c 72 65 61 64   does not alread
27a0: 79 0a 2a 2a 20 65 78 69 73 74 2e 20 20 49 66 20  y.** exist.  If 
27b0: 66 6f 72 63 65 46 6c 61 67 20 69 73 20 31 2c 20  forceFlag is 1, 
27c0: 64 65 6c 65 74 65 20 61 6e 79 20 70 72 69 6f 72  delete any prior
27d0: 20 6e 6f 6e 2d 64 69 72 65 63 74 6f 72 79 20 6f   non-directory o
27e0: 62 6a 65 63 74 20 0a 2a 2a 20 77 69 74 68 20 74  bject .** with t
27f0: 68 65 20 73 61 6d 65 20 6e 61 6d 65 2e 0a 2a 2a  he same name..**
2800: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e  .** Return the n
2810: 75 6d 62 65 72 20 6f 66 20 65 72 72 6f 72 73 2e  umber of errors.
2820: 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 6d 6b 64  .*/.int file_mkd
2830: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  ir(const char *z
2840: 4e 61 6d 65 2c 20 69 6e 74 20 66 6f 72 63 65 46  Name, int forceF
2850: 6c 61 67 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  lag){.  int rc =
2860: 20 66 69 6c 65 5f 77 64 5f 69 73 64 69 72 28 7a   file_wd_isdir(z
2870: 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 72 63 3d  Name);.  if( rc=
2880: 3d 32 20 29 7b 0a 20 20 20 20 69 66 28 20 21 66  =2 ){.    if( !f
2890: 6f 72 63 65 46 6c 61 67 20 29 20 72 65 74 75 72  orceFlag ) retur
28a0: 6e 20 31 3b 0a 20 20 20 20 66 69 6c 65 5f 64 65  n 1;.    file_de
28b0: 6c 65 74 65 28 7a 4e 61 6d 65 29 3b 0a 20 20 7d  lete(zName);.  }
28c0: 0a 20 20 69 66 28 20 72 63 21 3d 31 20 29 7b 0a  .  if( rc!=1 ){.
28d0: 23 69 66 20 64 65 66 69 6e 65 64 28 5f 57 49 4e  #if defined(_WIN
28e0: 33 32 29 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a  32).    int rc;.
28f0: 20 20 20 20 63 68 61 72 20 2a 7a 4d 62 63 73 20      char *zMbcs 
2900: 3d 20 66 6f 73 73 69 6c 5f 75 74 66 38 5f 74 6f  = fossil_utf8_to
2910: 5f 6d 62 63 73 28 7a 4e 61 6d 65 29 3b 0a 20 20  _mbcs(zName);.  
2920: 20 20 72 63 20 3d 20 6d 6b 64 69 72 28 7a 4d 62    rc = mkdir(zMb
2930: 63 73 29 3b 0a 20 20 20 20 66 6f 73 73 69 6c 5f  cs);.    fossil_
2940: 6d 62 63 73 5f 66 72 65 65 28 7a 4d 62 63 73 29  mbcs_free(zMbcs)
2950: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 72 63 3b  ;.    return rc;
2960: 0a 23 65 6c 73 65 0a 20 20 20 20 72 65 74 75 72  .#else.    retur
2970: 6e 20 6d 6b 64 69 72 28 7a 4e 61 6d 65 2c 20 30  n mkdir(zName, 0
2980: 37 35 35 29 3b 0a 23 65 6e 64 69 66 0a 20 20 7d  755);.#endif.  }
2990: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
29a0: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75  /*.** Return tru
29b0: 65 20 69 66 20 74 68 65 20 66 69 6c 65 6e 61 6d  e if the filenam
29c0: 65 20 67 69 76 65 6e 20 69 73 20 61 20 76 61 6c  e given is a val
29d0: 69 64 20 66 69 6c 65 6e 61 6d 65 20 66 6f 72 0a  id filename for.
29e0: 2a 2a 20 61 20 66 69 6c 65 20 69 6e 20 61 20 72  ** a file in a r
29f0: 65 70 6f 73 69 74 6f 72 79 2e 20 20 56 61 6c 69  epository.  Vali
2a00: 64 20 66 69 6c 65 6e 61 6d 65 73 20 66 6f 6c 6c  d filenames foll
2a10: 6f 77 20 61 6c 6c 20 6f 66 20 74 68 65 0a 2a 2a  ow all of the.**
2a20: 20 66 6f 6c 6c 6f 77 69 6e 67 20 72 75 6c 65 73   following rules
2a30: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2a 20 20 44  :.**.**     *  D
2a40: 6f 65 73 20 6e 6f 74 20 62 65 67 69 6e 20 77 69  oes not begin wi
2a50: 74 68 20 22 2f 22 0a 2a 2a 20 20 20 20 20 2a 20  th "/".**     * 
2a60: 20 44 6f 65 73 20 6e 6f 74 20 63 6f 6e 74 61 69   Does not contai
2a70: 6e 20 61 6e 79 20 70 61 74 68 20 65 6c 65 6d 65  n any path eleme
2a80: 6e 74 20 6e 61 6d 65 64 20 22 2e 22 20 6f 72 20  nt named "." or 
2a90: 22 2e 2e 22 0a 2a 2a 20 20 20 20 20 2a 20 20 44  "..".**     *  D
2aa0: 6f 65 73 20 6e 6f 74 20 63 6f 6e 74 61 69 6e 20  oes not contain 
2ab0: 61 6e 79 20 6f 66 20 74 68 65 73 65 20 63 68 61  any of these cha
2ac0: 72 61 63 74 65 72 73 20 69 6e 20 74 68 65 20 70  racters in the p
2ad0: 61 74 68 3a 20 22 5c 2a 5b 5d 3f 22 0a 2a 2a 20  ath: "\*[]?".** 
2ae0: 20 20 20 20 2a 20 20 44 6f 65 73 20 6e 6f 74 20      *  Does not 
2af0: 65 6e 64 20 77 69 74 68 20 22 2f 22 2e 0a 2a 2a  end with "/"..**
2b00: 20 20 20 20 20 2a 20 20 44 6f 65 73 20 6e 6f 74       *  Does not
2b10: 20 63 6f 6e 74 61 69 6e 20 74 77 6f 20 6f 72 20   contain two or 
2b20: 6d 6f 72 65 20 22 2f 22 20 63 68 61 72 61 63 74  more "/" charact
2b30: 65 72 73 20 69 6e 20 61 20 72 6f 77 2e 0a 2a 2a  ers in a row..**
2b40: 20 20 20 20 20 2a 20 20 43 6f 6e 74 61 69 6e 73       *  Contains
2b50: 20 61 74 20 6c 65 61 73 74 20 6f 6e 65 20 63 68   at least one ch
2b60: 61 72 61 63 74 65 72 0a 2a 2f 0a 69 6e 74 20 66  aracter.*/.int f
2b70: 69 6c 65 5f 69 73 5f 73 69 6d 70 6c 65 5f 70 61  ile_is_simple_pa
2b80: 74 68 6e 61 6d 65 28 63 6f 6e 73 74 20 63 68 61  thname(const cha
2b90: 72 20 2a 7a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a  r *z){.  int i;.
2ba0: 20 20 63 68 61 72 20 63 20 3d 20 7a 5b 30 5d 3b    char c = z[0];
2bb0: 0a 20 20 69 66 28 20 63 3d 3d 27 2f 27 20 7c 7c  .  if( c=='/' ||
2bc0: 20 63 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30   c==0 ) return 0
2bd0: 3b 0a 20 20 69 66 28 20 63 3d 3d 27 2e 27 20 29  ;.  if( c=='.' )
2be0: 7b 0a 20 20 20 20 69 66 28 20 7a 5b 31 5d 3d 3d  {.    if( z[1]==
2bf0: 27 2f 27 20 7c 7c 20 7a 5b 31 5d 3d 3d 30 20 29  '/' || z[1]==0 )
2c00: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 69   return 0;.    i
2c10: 66 28 20 7a 5b 31 5d 3d 3d 27 2e 27 20 26 26 20  f( z[1]=='.' && 
2c20: 28 7a 5b 32 5d 3d 3d 27 2f 27 20 7c 7c 20 7a 5b  (z[2]=='/' || z[
2c30: 32 5d 3d 3d 30 29 20 29 20 72 65 74 75 72 6e 20  2]==0) ) return 
2c40: 30 3b 0a 20 20 7d 0a 20 20 66 6f 72 28 69 3d 30  0;.  }.  for(i=0
2c50: 3b 20 28 63 3d 7a 5b 69 5d 29 21 3d 30 3b 20 69  ; (c=z[i])!=0; i
2c60: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 63 3d 3d  ++){.    if( c==
2c70: 27 5c 5c 27 20 7c 7c 20 63 3d 3d 27 2a 27 20 7c  '\\' || c=='*' |
2c80: 7c 20 63 3d 3d 27 5b 27 20 7c 7c 20 63 3d 3d 27  | c=='[' || c=='
2c90: 5d 27 20 7c 7c 20 63 3d 3d 27 3f 27 20 29 7b 0a  ]' || c=='?' ){.
2ca0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a        return 0;.
2cb0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 63 3d      }.    if( c=
2cc0: 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 69 66  ='/' ){.      if
2cd0: 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2f 27 20 29 20  ( z[i+1]=='/' ) 
2ce0: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20  return 0;.      
2cf0: 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20  if( z[i+1]=='.' 
2d00: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a  ){.        if( z
2d10: 5b 69 2b 32 5d 3d 3d 27 2f 27 20 7c 7c 20 7a 5b  [i+2]=='/' || z[
2d20: 69 2b 32 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e  i+2]==0 ) return
2d30: 20 30 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20   0;.        if( 
2d40: 7a 5b 69 2b 32 5d 3d 3d 27 2e 27 20 26 26 20 28  z[i+2]=='.' && (
2d50: 7a 5b 69 2b 33 5d 3d 3d 27 2f 27 20 7c 7c 20 7a  z[i+3]=='/' || z
2d60: 5b 69 2b 33 5d 3d 3d 30 29 20 29 20 72 65 74 75  [i+3]==0) ) retu
2d70: 72 6e 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20  rn 0;.      }.  
2d80: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 7a 5b    }.  }.  if( z[
2d90: 69 2d 31 5d 3d 3d 27 2f 27 20 29 20 72 65 74 75  i-1]=='/' ) retu
2da0: 72 6e 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 31  rn 0;.  return 1
2db0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68  ;.}../*.** If th
2dc0: 65 20 6c 61 73 74 20 63 6f 6d 70 6f 6e 65 6e 74  e last component
2dd0: 20 6f 66 20 74 68 65 20 70 61 74 68 6e 61 6d 65   of the pathname
2de0: 20 69 6e 20 7a 5b 30 5d 2e 2e 7a 5b 6a 2d 31 5d   in z[0]..z[j-1]
2df0: 20 69 73 20 73 6f 6d 65 74 68 69 6e 67 0a 2a 2a   is something.**
2e00: 20 6f 74 68 65 72 20 74 68 61 6e 20 22 2e 2e 22   other than ".."
2e10: 20 74 68 65 6e 20 62 61 63 6b 20 69 74 20 6f 75   then back it ou
2e20: 74 20 61 6e 64 20 72 65 74 75 72 6e 20 74 72 75  t and return tru
2e30: 65 2e 20 20 49 66 20 74 68 65 20 6c 61 73 74 0a  e.  If the last.
2e40: 2a 2a 20 63 6f 6d 70 6f 6e 65 6e 74 20 69 73 20  ** component is 
2e50: 65 6d 70 74 79 20 6f 72 20 69 66 20 69 74 20 69  empty or if it i
2e60: 73 20 22 2e 2e 22 20 74 68 65 6e 20 72 65 74 75  s ".." then retu
2e70: 72 6e 20 66 61 6c 73 65 2e 0a 2a 2f 0a 73 74 61  rn false..*/.sta
2e80: 74 69 63 20 69 6e 74 20 62 61 63 6b 75 70 5f 64  tic int backup_d
2e90: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  ir(const char *z
2ea0: 2c 20 69 6e 74 20 2a 70 4a 29 7b 0a 20 20 69 6e  , int *pJ){.  in
2eb0: 74 20 6a 20 3d 20 2a 70 4a 3b 0a 20 20 69 6e 74  t j = *pJ;.  int
2ec0: 20 69 3b 0a 20 20 69 66 28 20 6a 3c 3d 30 20 29   i;.  if( j<=0 )
2ed0: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 66 6f 72   return 0;.  for
2ee0: 28 69 3d 6a 2d 31 3b 20 69 3e 30 20 26 26 20 7a  (i=j-1; i>0 && z
2ef0: 5b 69 2d 31 5d 21 3d 27 2f 27 3b 20 69 2d 2d 29  [i-1]!='/'; i--)
2f00: 7b 7d 0a 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27  {}.  if( z[i]=='
2f10: 2e 27 20 26 26 20 69 3d 3d 6a 2d 32 20 26 26 20  .' && i==j-2 && 
2f20: 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 29 20 72 65  z[i+1]=='.' ) re
2f30: 74 75 72 6e 20 30 3b 0a 20 20 2a 70 4a 20 3d 20  turn 0;.  *pJ = 
2f40: 69 2d 31 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b  i-1;.  return 1;
2f50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 69 6d 70 6c 69  .}../*.** Simpli
2f60: 66 79 20 61 20 66 69 6c 65 6e 61 6d 65 20 62 79  fy a filename by
2f70: 0a 2a 2a 0a 2a 2a 20 20 2a 20 43 6f 6e 76 65 72  .**.**  * Conver
2f80: 74 20 61 6c 6c 20 5c 20 69 6e 74 6f 20 2f 20 6f  t all \ into / o
2f90: 6e 20 77 69 6e 64 6f 77 73 0a 2a 2a 20 20 2a 20  n windows.**  * 
2fa0: 72 65 6d 6f 76 69 6e 67 20 61 6e 79 20 74 72 61  removing any tra
2fb0: 69 6c 69 6e 67 20 61 6e 64 20 64 75 70 6c 69 63  iling and duplic
2fc0: 61 74 65 20 2f 0a 2a 2a 20 20 2a 20 72 65 6d 6f  ate /.**  * remo
2fd0: 76 69 6e 67 20 2f 2e 2f 0a 2a 2a 20 20 2a 20 72  ving /./.**  * r
2fe0: 65 6d 6f 76 69 6e 67 20 2f 41 2f 2e 2e 2f 0a 2a  emoving /A/../.*
2ff0: 2a 0a 2a 2a 20 43 68 61 6e 67 65 73 20 61 72 65  *.** Changes are
3000: 20 6d 61 64 65 20 69 6e 2d 70 6c 61 63 65 2e 20   made in-place. 
3010: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 65 77 20   Return the new 
3020: 6e 61 6d 65 20 6c 65 6e 67 74 68 2e 0a 2a 2a 20  name length..** 
3030: 49 66 20 74 68 65 20 73 6c 61 73 68 20 70 61 72  If the slash par
3040: 61 6d 65 74 65 72 20 69 73 20 6e 6f 6e 2d 7a 65  ameter is non-ze
3050: 72 6f 2c 20 74 68 65 20 74 72 61 69 6c 69 6e 67  ro, the trailing
3060: 20 73 6c 61 73 68 2c 20 69 66 20 61 6e 79 2c 0a   slash, if any,.
3070: 2a 2a 20 69 73 20 72 65 74 61 69 6e 65 64 2e 0a  ** is retained..
3080: 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 73 69 6d 70  */.int file_simp
3090: 6c 69 66 79 5f 6e 61 6d 65 28 63 68 61 72 20 2a  lify_name(char *
30a0: 7a 2c 20 69 6e 74 20 6e 2c 20 69 6e 74 20 73 6c  z, int n, int sl
30b0: 61 73 68 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6a  ash){.  int i, j
30c0: 3b 0a 20 20 69 66 28 20 6e 3c 30 20 29 20 6e 20  ;.  if( n<0 ) n 
30d0: 3d 20 73 74 72 6c 65 6e 28 7a 29 3b 0a 0a 20 20  = strlen(z);..  
30e0: 2f 2a 20 4f 6e 20 77 69 6e 64 6f 77 73 20 63 6f  /* On windows co
30f0: 6e 76 65 72 74 20 61 6c 6c 20 5c 20 63 68 61 72  nvert all \ char
3100: 61 63 74 65 72 73 20 74 6f 20 2f 20 2a 2f 0a 23  acters to / */.#
3110: 69 66 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33  if defined(_WIN3
3120: 32 29 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  2).  for(i=0; i<
3130: 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  n; i++){.    if(
3140: 20 7a 5b 69 5d 3d 3d 27 5c 5c 27 20 29 20 7a 5b   z[i]=='\\' ) z[
3150: 69 5d 20 3d 20 27 2f 27 3b 0a 20 20 7d 0a 23 65  i] = '/';.  }.#e
3160: 6e 64 69 66 0a 0a 20 20 2f 2a 20 52 65 6d 6f 76  ndif..  /* Remov
3170: 69 6e 67 20 74 72 61 69 6c 69 6e 67 20 22 2f 22  ing trailing "/"
3180: 20 63 68 61 72 61 63 74 65 72 73 20 2a 2f 0a 20   characters */. 
3190: 20 69 66 20 28 20 21 73 6c 61 73 68 20 29 7b 0a   if ( !slash ){.
31a0: 20 20 20 20 77 68 69 6c 65 28 20 6e 3e 31 20 26      while( n>1 &
31b0: 26 20 7a 5b 6e 2d 31 5d 3d 3d 27 2f 27 20 29 7b  & z[n-1]=='/' ){
31c0: 20 6e 2d 2d 3b 20 7d 0a 20 20 7d 0a 0a 20 20 2f   n--; }.  }..  /
31d0: 2a 20 52 65 6d 6f 76 65 20 64 75 70 6c 69 63 61  * Remove duplica
31e0: 74 65 20 27 2f 27 20 63 68 61 72 61 63 74 65 72  te '/' character
31f0: 73 2e 20 20 45 78 63 65 70 74 2c 20 74 77 6f 20  s.  Except, two 
3200: 2f 2f 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e  // at the beginn
3210: 69 6e 67 0a 20 20 2a 2a 20 6f 66 20 61 20 70 61  ing.  ** of a pa
3220: 74 68 6e 61 6d 65 20 69 73 20 61 6c 6c 6f 77 65  thname is allowe
3230: 64 20 73 69 6e 63 65 20 74 68 69 73 20 69 73 20  d since this is 
3240: 69 6d 70 6f 72 74 61 6e 74 20 6f 6e 20 77 69 6e  important on win
3250: 64 6f 77 73 2e 20 2a 2f 0a 20 20 66 6f 72 28 69  dows. */.  for(i
3260: 3d 6a 3d 31 3b 20 69 3c 6e 3b 20 69 2b 2b 29 7b  =j=1; i<n; i++){
3270: 0a 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b  .    z[j++] = z[
3280: 69 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 7a  i];.    while( z
3290: 5b 69 5d 3d 3d 27 2f 27 20 26 26 20 69 3c 6e 2d  [i]=='/' && i<n-
32a0: 31 20 26 26 20 7a 5b 69 2b 31 5d 3d 3d 27 2f 27  1 && z[i+1]=='/'
32b0: 20 29 20 69 2b 2b 3b 0a 20 20 7d 0a 20 20 6e 20   ) i++;.  }.  n 
32c0: 3d 20 6a 3b 0a 0a 20 20 2f 2a 20 53 6b 69 70 20  = j;..  /* Skip 
32d0: 6f 76 65 72 20 7a 65 72 6f 20 6f 72 20 6d 6f 72  over zero or mor
32e0: 65 20 69 6e 69 74 69 61 6c 20 22 2e 2f 22 20 73  e initial "./" s
32f0: 65 71 75 65 6e 63 65 73 20 2a 2f 0a 20 20 66 6f  equences */.  fo
3300: 72 28 69 3d 30 3b 20 69 3c 6e 2d 31 20 26 26 20  r(i=0; i<n-1 && 
3310: 7a 5b 69 5d 3d 3d 27 2e 27 20 26 26 20 7a 5b 69  z[i]=='.' && z[i
3320: 2b 31 5d 3d 3d 27 2f 27 3b 20 69 2b 3d 32 29 7b  +1]=='/'; i+=2){
3330: 7d 0a 0a 20 20 2f 2a 20 42 65 67 69 6e 20 63 6f  }..  /* Begin co
3340: 70 79 69 6e 67 20 66 72 6f 6d 20 7a 5b 69 5d 20  pying from z[i] 
3350: 62 61 63 6b 20 74 6f 20 7a 5b 6a 5d 2e 2e 2e 20  back to z[j]... 
3360: 2a 2f 0a 20 20 66 6f 72 28 6a 3d 30 3b 20 69 3c  */.  for(j=0; i<
3370: 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  n; i++){.    if(
3380: 20 7a 5b 69 5d 3d 3d 27 2f 27 20 29 7b 0a 20 20   z[i]=='/' ){.  
3390: 20 20 20 20 2f 2a 20 53 6b 69 70 20 6f 76 65 72      /* Skip over
33a0: 20 69 6e 74 65 72 6e 61 6c 20 22 2f 2e 22 20 64   internal "/." d
33b0: 69 72 65 63 74 6f 72 79 20 63 6f 6d 70 6f 6e 65  irectory compone
33c0: 6e 74 73 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  nts */.      if(
33d0: 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 26 26 20   z[i+1]=='.' && 
33e0: 28 69 2b 32 3d 3d 6e 20 7c 7c 20 7a 5b 69 2b 32  (i+2==n || z[i+2
33f0: 5d 3d 3d 27 2f 27 29 20 29 7b 0a 20 20 20 20 20  ]=='/') ){.     
3400: 20 20 20 69 20 2b 3d 20 31 3b 0a 20 20 20 20 20     i += 1;.     
3410: 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20     continue;.   
3420: 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 49     }..      /* I
3430: 66 20 74 68 69 73 20 69 73 20 61 20 22 2f 2e 2e  f this is a "/..
3440: 22 20 64 69 72 65 63 74 6f 72 79 20 63 6f 6d 70  " directory comp
3450: 6f 6e 65 6e 74 20 74 68 65 6e 20 62 61 63 6b 20  onent then back 
3460: 6f 75 74 20 74 68 65 0a 20 20 20 20 20 20 2a 2a  out the.      **
3470: 20 70 72 65 76 69 6f 75 73 20 74 65 72 6d 20 6f   previous term o
3480: 66 20 74 68 65 20 64 69 72 65 63 74 6f 72 79 20  f the directory 
3490: 69 66 20 69 74 20 69 73 20 73 6f 6d 65 74 68 69  if it is somethi
34a0: 6e 67 20 6f 74 68 65 72 20 74 68 61 6e 20 22 2e  ng other than ".
34b0: 2e 22 0a 20 20 20 20 20 20 2a 2a 20 6f 72 20 22  .".      ** or "
34c0: 2e 22 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  .".      */.    
34d0: 20 20 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2e    if( z[i+1]=='.
34e0: 27 20 26 26 20 69 2b 32 3c 6e 20 26 26 20 7a 5b  ' && i+2<n && z[
34f0: 69 2b 32 5d 3d 3d 27 2e 27 20 26 26 20 28 69 2b  i+2]=='.' && (i+
3500: 33 3d 3d 6e 20 7c 7c 20 7a 5b 69 2b 33 5d 3d 3d  3==n || z[i+3]==
3510: 27 2f 27 29 0a 20 20 20 20 20 20 20 26 26 20 62  '/').       && b
3520: 61 63 6b 75 70 5f 64 69 72 28 7a 2c 20 26 6a 29  ackup_dir(z, &j)
3530: 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20  .      ){.      
3540: 20 20 69 20 2b 3d 20 32 3b 0a 20 20 20 20 20 20    i += 2;.      
3550: 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20    continue;.    
3560: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
3570: 28 20 6a 3e 3d 30 20 29 20 7a 5b 6a 5d 20 3d 20  ( j>=0 ) z[j] = 
3580: 7a 5b 69 5d 3b 0a 20 20 20 20 6a 2b 2b 3b 0a 20  z[i];.    j++;. 
3590: 20 7d 0a 20 20 69 66 28 20 6a 3d 3d 30 20 29 20   }.  if( j==0 ) 
35a0: 7a 5b 6a 2b 2b 5d 20 3d 20 27 2e 27 3b 0a 20 20  z[j++] = '.';.  
35b0: 7a 5b 6a 5d 20 3d 20 30 3b 0a 20 20 72 65 74 75  z[j] = 0;.  retu
35c0: 72 6e 20 6a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  rn j;.}../*.** C
35d0: 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 73 69 6d  OMMAND: test-sim
35e0: 70 6c 69 66 79 2d 6e 61 6d 65 0a 2a 2a 0a 2a 2a  plify-name.**.**
35f0: 20 25 66 6f 73 73 69 6c 20 74 65 73 74 2d 73 69   %fossil test-si
3600: 6d 70 6c 69 66 79 2d 6e 61 6d 65 20 46 49 4c 45  mplify-name FILE
3610: 4e 41 4d 45 2e 2e 2e 0a 2a 2a 0a 2a 2a 20 50 72  NAME....**.** Pr
3620: 69 6e 74 20 74 68 65 20 73 69 6d 70 6c 69 66 69  int the simplifi
3630: 65 64 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 65  ed versions of e
3640: 61 63 68 20 46 49 4c 45 4e 41 4d 45 2e 0a 2a 2f  ach FILENAME..*/
3650: 0a 76 6f 69 64 20 63 6d 64 5f 74 65 73 74 5f 73  .void cmd_test_s
3660: 69 6d 70 6c 69 66 79 5f 6e 61 6d 65 28 76 6f 69  implify_name(voi
3670: 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63  d){.  int i;.  c
3680: 68 61 72 20 2a 7a 3b 0a 20 20 66 6f 72 28 69 3d  har *z;.  for(i=
3690: 32 3b 20 69 3c 67 2e 61 72 67 63 3b 20 69 2b 2b  2; i<g.argc; i++
36a0: 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e  ){.    z = mprin
36b0: 74 66 28 22 25 73 22 2c 20 67 2e 61 72 67 76 5b  tf("%s", g.argv[
36c0: 69 5d 29 3b 0a 20 20 20 20 66 6f 73 73 69 6c 5f  i]);.    fossil_
36d0: 70 72 69 6e 74 28 22 5b 25 73 5d 20 2d 3e 20 22  print("[%s] -> "
36e0: 2c 20 7a 29 3b 0a 20 20 20 20 66 69 6c 65 5f 73  , z);.    file_s
36f0: 69 6d 70 6c 69 66 79 5f 6e 61 6d 65 28 7a 2c 20  implify_name(z, 
3700: 2d 31 2c 20 30 29 3b 0a 20 20 20 20 66 6f 73 73  -1, 0);.    foss
3710: 69 6c 5f 70 72 69 6e 74 28 22 5b 25 73 5d 5c 6e  il_print("[%s]\n
3720: 22 2c 20 7a 29 3b 0a 20 20 20 20 66 6f 73 73 69  ", z);.    fossi
3730: 6c 5f 66 72 65 65 28 7a 29 3b 0a 20 20 7d 0a 7d  l_free(z);.  }.}
3740: 0a 0a 2f 2a 0a 2a 2a 20 47 65 74 20 74 68 65 20  ../*.** Get the 
3750: 63 75 72 72 65 6e 74 20 77 6f 72 6b 69 6e 67 20  current working 
3760: 64 69 72 65 63 74 6f 72 79 2e 0a 2a 2a 0a 2a 2a  directory..**.**
3770: 20 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 74 68 65   On windows, the
3780: 20 6e 61 6d 65 20 69 73 20 63 6f 6e 76 65 72 74   name is convert
3790: 65 64 20 66 72 6f 6d 20 4d 42 43 53 20 74 6f 20  ed from MBCS to 
37a0: 55 54 46 38 20 61 6e 64 20 61 6c 6c 20 27 5c 5c  UTF8 and all '\\
37b0: 27 0a 2a 2a 20 63 68 61 72 61 63 74 65 72 73 20  '.** characters 
37c0: 61 72 65 20 63 6f 6e 76 65 72 74 65 64 20 74 6f  are converted to
37d0: 20 27 2f 27 2e 20 20 4e 6f 20 63 6f 6e 76 65 72   '/'.  No conver
37e0: 73 69 6f 6e 73 20 61 72 65 20 6e 65 65 64 65 64  sions are needed
37f0: 20 6f 6e 0a 2a 2a 20 75 6e 69 78 2e 0a 2a 2f 0a   on.** unix..*/.
3800: 76 6f 69 64 20 66 69 6c 65 5f 67 65 74 63 77 64  void file_getcwd
3810: 28 63 68 61 72 20 2a 7a 42 75 66 2c 20 69 6e 74  (char *zBuf, int
3820: 20 6e 42 75 66 29 7b 0a 23 69 66 64 65 66 20 5f   nBuf){.#ifdef _
3830: 57 49 4e 33 32 0a 20 20 63 68 61 72 20 2a 7a 50  WIN32.  char *zP
3840: 77 64 55 74 66 38 3b 0a 20 20 69 6e 74 20 6e 50  wdUtf8;.  int nP
3850: 77 64 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63  wd;.  int i;.  c
3860: 68 61 72 20 7a 50 77 64 5b 32 30 30 30 5d 3b 0a  har zPwd[2000];.
3870: 20 20 69 66 28 20 67 65 74 63 77 64 28 7a 50 77    if( getcwd(zPw
3880: 64 2c 20 73 69 7a 65 6f 66 28 7a 50 77 64 29 2d  d, sizeof(zPwd)-
3890: 31 29 3d 3d 30 20 29 7b 0a 20 20 20 20 66 6f 73  1)==0 ){.    fos
38a0: 73 69 6c 5f 66 61 74 61 6c 28 22 63 61 6e 6e 6f  sil_fatal("canno
38b0: 74 20 66 69 6e 64 20 74 68 65 20 63 75 72 72 65  t find the curre
38c0: 6e 74 20 77 6f 72 6b 69 6e 67 20 64 69 72 65 63  nt working direc
38d0: 74 6f 72 79 2e 22 29 3b 0a 20 20 7d 0a 20 20 7a  tory.");.  }.  z
38e0: 50 77 64 55 74 66 38 20 3d 20 66 6f 73 73 69 6c  PwdUtf8 = fossil
38f0: 5f 6d 62 63 73 5f 74 6f 5f 75 74 66 38 28 7a 50  _mbcs_to_utf8(zP
3900: 77 64 29 3b 0a 20 20 6e 50 77 64 20 3d 20 73 74  wd);.  nPwd = st
3910: 72 6c 65 6e 28 7a 50 77 64 55 74 66 38 29 3b 0a  rlen(zPwdUtf8);.
3920: 20 20 69 66 28 20 6e 50 77 64 20 3e 20 6e 42 75    if( nPwd > nBu
3930: 66 2d 31 20 29 7b 0a 20 20 20 20 66 6f 73 73 69  f-1 ){.    fossi
3940: 6c 5f 66 61 74 61 6c 28 22 70 77 64 20 74 6f 6f  l_fatal("pwd too
3950: 20 62 69 67 3a 20 6d 61 78 20 25 64 5c 6e 22 2c   big: max %d\n",
3960: 20 6e 42 75 66 2d 31 29 3b 0a 20 20 7d 0a 20 20   nBuf-1);.  }.  
3970: 66 6f 72 28 69 3d 30 3b 20 7a 50 77 64 55 74 66  for(i=0; zPwdUtf
3980: 38 5b 69 5d 3b 20 69 2b 2b 29 20 69 66 28 20 7a  8[i]; i++) if( z
3990: 50 77 64 55 74 66 38 5b 69 5d 3d 3d 27 5c 5c 27  PwdUtf8[i]=='\\'
39a0: 20 29 20 7a 50 77 64 55 74 66 38 5b 69 5d 20 3d   ) zPwdUtf8[i] =
39b0: 20 27 2f 27 3b 0a 20 20 6d 65 6d 63 70 79 28 7a   '/';.  memcpy(z
39c0: 42 75 66 2c 20 7a 50 77 64 55 74 66 38 2c 20 6e  Buf, zPwdUtf8, n
39d0: 50 77 64 2b 31 29 3b 0a 20 20 66 6f 73 73 69 6c  Pwd+1);.  fossil
39e0: 5f 6d 62 63 73 5f 66 72 65 65 28 7a 50 77 64 55  _mbcs_free(zPwdU
39f0: 74 66 38 29 3b 0a 23 65 6c 73 65 0a 20 20 69 66  tf8);.#else.  if
3a00: 28 20 67 65 74 63 77 64 28 7a 42 75 66 2c 20 6e  ( getcwd(zBuf, n
3a10: 42 75 66 2d 31 29 3d 3d 30 20 29 7b 0a 20 20 20  Buf-1)==0 ){.   
3a20: 20 69 66 28 20 65 72 72 6e 6f 3d 3d 45 52 41 4e   if( errno==ERAN
3a30: 47 45 20 29 7b 0a 20 20 20 20 20 20 66 6f 73 73  GE ){.      foss
3a40: 69 6c 5f 66 61 74 61 6c 28 22 70 77 64 20 74 6f  il_fatal("pwd to
3a50: 6f 20 62 69 67 3a 20 6d 61 78 20 25 64 5c 6e 22  o big: max %d\n"
3a60: 2c 20 6e 42 75 66 2d 31 29 3b 0a 20 20 20 20 7d  , nBuf-1);.    }
3a70: 65 6c 73 65 7b 0a 20 20 20 20 20 20 66 6f 73 73  else{.      foss
3a80: 69 6c 5f 66 61 74 61 6c 28 22 63 61 6e 6e 6f 74  il_fatal("cannot
3a90: 20 66 69 6e 64 20 63 75 72 72 65 6e 74 20 77 6f   find current wo
3aa0: 72 6b 69 6e 67 20 64 69 72 65 63 74 6f 72 79 3b  rking directory;
3ab0: 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20 20   %s",.          
3ac0: 20 20 20 20 20 20 20 20 20 73 74 72 65 72 72 6f           strerro
3ad0: 72 28 65 72 72 6e 6f 29 29 3b 0a 20 20 20 20 7d  r(errno));.    }
3ae0: 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f  .  }.#endif.}../
3af0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65  *.** Return true
3b00: 20 69 66 20 7a 50 61 74 68 20 69 73 20 61 6e 20   if zPath is an 
3b10: 61 62 73 6f 6c 75 74 65 20 70 61 74 68 6e 61 6d  absolute pathnam
3b20: 65 2e 20 20 52 65 74 75 72 6e 20 66 61 6c 73 65  e.  Return false
3b30: 0a 2a 2a 20 69 66 20 69 74 20 69 73 20 72 65 6c  .** if it is rel
3b40: 61 74 69 76 65 2e 0a 2a 2f 0a 69 6e 74 20 66 69  ative..*/.int fi
3b50: 6c 65 5f 69 73 5f 61 62 73 6f 6c 75 74 65 5f 70  le_is_absolute_p
3b60: 61 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ath(const char *
3b70: 7a 50 61 74 68 29 7b 0a 20 20 69 66 28 20 7a 50  zPath){.  if( zP
3b80: 61 74 68 5b 30 5d 3d 3d 27 2f 27 0a 23 69 66 20  ath[0]=='/'.#if 
3b90: 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a  defined(_WIN32).
3ba0: 20 20 20 20 20 20 7c 7c 20 7a 50 61 74 68 5b 30        || zPath[0
3bb0: 5d 3d 3d 27 5c 5c 27 0a 20 20 20 20 20 20 7c 7c  ]=='\\'.      ||
3bc0: 20 28 73 74 72 6c 65 6e 28 7a 50 61 74 68 29 3e   (strlen(zPath)>
3bd0: 33 20 26 26 20 7a 50 61 74 68 5b 31 5d 3d 3d 27  3 && zPath[1]=='
3be0: 3a 27 0a 20 20 20 20 20 20 20 20 20 20 20 26 26  :'.           &&
3bf0: 20 28 7a 50 61 74 68 5b 32 5d 3d 3d 27 5c 5c 27   (zPath[2]=='\\'
3c00: 20 7c 7c 20 7a 50 61 74 68 5b 32 5d 3d 3d 27 2f   || zPath[2]=='/
3c10: 27 29 29 0a 23 65 6e 64 69 66 0a 20 20 29 7b 0a  ')).#endif.  ){.
3c20: 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
3c30: 7d 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72  }else{.    retur
3c40: 6e 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  n 0;.  }.}../*.*
3c50: 2a 20 43 6f 6d 70 75 74 65 20 61 20 63 61 6e 6f  * Compute a cano
3c60: 6e 69 63 61 6c 20 70 61 74 68 6e 61 6d 65 20 66  nical pathname f
3c70: 6f 72 20 61 20 66 69 6c 65 20 6f 72 20 64 69 72  or a file or dir
3c80: 65 63 74 6f 72 79 2e 0a 2a 2a 20 4d 61 6b 65 20  ectory..** Make 
3c90: 74 68 65 20 6e 61 6d 65 20 61 62 73 6f 6c 75 74  the name absolut
3ca0: 65 20 69 66 20 69 74 20 69 73 20 72 65 6c 61 74  e if it is relat
3cb0: 69 76 65 2e 0a 2a 2a 20 52 65 6d 6f 76 65 20 72  ive..** Remove r
3cc0: 65 64 75 6e 64 61 6e 74 20 2f 20 63 68 61 72 61  edundant / chara
3cd0: 63 74 65 72 73 0a 2a 2a 20 52 65 6d 6f 76 65 20  cters.** Remove 
3ce0: 61 6c 6c 20 2f 2e 2f 20 70 61 74 68 20 65 6c 65  all /./ path ele
3cf0: 6d 65 6e 74 73 2e 0a 2a 2a 20 43 6f 6e 76 65 72  ments..** Conver
3d00: 74 20 2f 41 2f 2e 2e 2f 20 74 6f 20 6a 75 73 74  t /A/../ to just
3d10: 20 2f 0a 2a 2a 20 49 66 20 74 68 65 20 73 6c 61   /.** If the sla
3d20: 73 68 20 70 61 72 61 6d 65 74 65 72 20 69 73 20  sh parameter is 
3d30: 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 20 74 72  non-zero, the tr
3d40: 61 69 6c 69 6e 67 20 73 6c 61 73 68 2c 20 69 66  ailing slash, if
3d50: 20 61 6e 79 2c 0a 2a 2a 20 69 73 20 72 65 74 61   any,.** is reta
3d60: 69 6e 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 66 69  ined..*/.void fi
3d70: 6c 65 5f 63 61 6e 6f 6e 69 63 61 6c 5f 6e 61 6d  le_canonical_nam
3d80: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4f  e(const char *zO
3d90: 72 69 67 4e 61 6d 65 2c 20 42 6c 6f 62 20 2a 70  rigName, Blob *p
3da0: 4f 75 74 2c 20 69 6e 74 20 73 6c 61 73 68 29 7b  Out, int slash){
3db0: 0a 20 20 69 66 28 20 66 69 6c 65 5f 69 73 5f 61  .  if( file_is_a
3dc0: 62 73 6f 6c 75 74 65 5f 70 61 74 68 28 7a 4f 72  bsolute_path(zOr
3dd0: 69 67 4e 61 6d 65 29 20 29 7b 0a 23 69 66 20 64  igName) ){.#if d
3de0: 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20  efined(_WIN32). 
3df0: 20 20 20 63 68 61 72 20 2a 7a 4f 75 74 3b 0a 23     char *zOut;.#
3e00: 65 6e 64 69 66 0a 20 20 20 20 62 6c 6f 62 5f 73  endif.    blob_s
3e10: 65 74 28 70 4f 75 74 2c 20 7a 4f 72 69 67 4e 61  et(pOut, zOrigNa
3e20: 6d 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 6d 61  me);.    blob_ma
3e30: 74 65 72 69 61 6c 69 7a 65 28 70 4f 75 74 29 3b  terialize(pOut);
3e40: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 5f 57 49  .#if defined(_WI
3e50: 4e 33 32 29 0a 20 20 20 20 2f 2a 0a 20 20 20 20  N32).    /*.    
3e60: 2a 2a 20 4f 6e 20 57 69 6e 64 6f 77 73 2c 20 6e  ** On Windows, n
3e70: 6f 72 6d 61 6c 69 7a 65 20 74 68 65 20 64 72 69  ormalize the dri
3e80: 76 65 20 6c 65 74 74 65 72 20 74 6f 20 75 70 70  ve letter to upp
3e90: 65 72 20 63 61 73 65 2e 0a 20 20 20 20 2a 2f 0a  er case..    */.
3ea0: 20 20 20 20 7a 4f 75 74 20 3d 20 62 6c 6f 62 5f      zOut = blob_
3eb0: 73 74 72 28 70 4f 75 74 29 3b 0a 20 20 20 20 69  str(pOut);.    i
3ec0: 66 28 20 66 6f 73 73 69 6c 5f 69 73 61 6c 70 68  f( fossil_isalph
3ed0: 61 28 7a 4f 75 74 5b 30 5d 29 20 26 26 20 7a 4f  a(zOut[0]) && zO
3ee0: 75 74 5b 31 5d 3d 3d 27 3a 27 20 29 7b 0a 20 20  ut[1]==':' ){.  
3ef0: 20 20 20 20 7a 4f 75 74 5b 30 5d 20 3d 20 66 6f      zOut[0] = fo
3f00: 73 73 69 6c 5f 74 6f 75 70 70 65 72 28 7a 4f 75  ssil_toupper(zOu
3f10: 74 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 23 65 6e  t[0]);.    }.#en
3f20: 64 69 66 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  dif.  }else{.   
3f30: 20 63 68 61 72 20 7a 50 77 64 5b 32 30 30 30 5d   char zPwd[2000]
3f40: 3b 0a 20 20 20 20 66 69 6c 65 5f 67 65 74 63 77  ;.    file_getcw
3f50: 64 28 7a 50 77 64 2c 20 73 69 7a 65 6f 66 28 7a  d(zPwd, sizeof(z
3f60: 50 77 64 29 2d 73 74 72 6c 65 6e 28 7a 4f 72 69  Pwd)-strlen(zOri
3f70: 67 4e 61 6d 65 29 29 3b 0a 23 69 66 20 64 65 66  gName));.#if def
3f80: 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20 20 20  ined(_WIN32).   
3f90: 20 2f 2a 0a 20 20 20 20 2a 2a 20 4f 6e 20 57 69   /*.    ** On Wi
3fa0: 6e 64 6f 77 73 2c 20 6e 6f 72 6d 61 6c 69 7a 65  ndows, normalize
3fb0: 20 74 68 65 20 64 72 69 76 65 20 6c 65 74 74 65   the drive lette
3fc0: 72 20 74 6f 20 75 70 70 65 72 20 63 61 73 65 2e  r to upper case.
3fd0: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20  .    */.    if( 
3fe0: 66 6f 73 73 69 6c 5f 69 73 61 6c 70 68 61 28 7a  fossil_isalpha(z
3ff0: 50 77 64 5b 30 5d 29 20 26 26 20 7a 50 77 64 5b  Pwd[0]) && zPwd[
4000: 31 5d 3d 3d 27 3a 27 20 29 7b 0a 20 20 20 20 20  1]==':' ){.     
4010: 20 7a 50 77 64 5b 30 5d 20 3d 20 66 6f 73 73 69   zPwd[0] = fossi
4020: 6c 5f 74 6f 75 70 70 65 72 28 7a 50 77 64 5b 30  l_toupper(zPwd[0
4030: 5d 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66  ]);.    }.#endif
4040: 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 70  .    blob_zero(p
4050: 4f 75 74 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61  Out);.    blob_a
4060: 70 70 65 6e 64 66 28 70 4f 75 74 2c 20 22 25 2f  ppendf(pOut, "%/
4070: 2f 25 2f 22 2c 20 7a 50 77 64 2c 20 7a 4f 72 69  /%/", zPwd, zOri
4080: 67 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20 62 6c  gName);.  }.  bl
4090: 6f 62 5f 72 65 73 69 7a 65 28 70 4f 75 74 2c 20  ob_resize(pOut, 
40a0: 66 69 6c 65 5f 73 69 6d 70 6c 69 66 79 5f 6e 61  file_simplify_na
40b0: 6d 65 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 70  me(blob_buffer(p
40c0: 4f 75 74 29 2c 0a 20 20 20 20 20 20 20 20 20 20  Out),.          
40d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 62 6c 6f               blo
40f0: 62 5f 73 69 7a 65 28 70 4f 75 74 29 2c 20 73 6c  b_size(pOut), sl
4100: 61 73 68 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ash));.}../*.** 
4110: 43 4f 4d 4d 41 4e 44 3a 20 20 74 65 73 74 2d 63  COMMAND:  test-c
4120: 61 6e 6f 6e 69 63 61 6c 2d 6e 61 6d 65 0a 2a 2a  anonical-name.**
4130: 20 55 73 61 67 65 3a 20 25 66 6f 73 73 69 6c 20   Usage: %fossil 
4140: 74 65 73 74 2d 63 61 6e 6f 6e 69 63 61 6c 2d 6e  test-canonical-n
4150: 61 6d 65 20 46 49 4c 45 4e 41 4d 45 2e 2e 2e 0a  ame FILENAME....
4160: 2a 2a 0a 2a 2a 20 54 65 73 74 20 74 68 65 20 6f  **.** Test the o
4170: 70 65 72 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  peration of the 
4180: 63 61 6e 6f 6e 69 63 61 6c 20 6e 61 6d 65 20 67  canonical name g
4190: 65 6e 65 72 61 74 6f 72 2e 0a 2a 2a 20 41 6c 73  enerator..** Als
41a0: 6f 20 74 65 73 74 20 46 6f 73 73 69 6c 27 73 20  o test Fossil's 
41b0: 61 62 69 6c 69 74 79 20 74 6f 20 6d 65 61 73 75  ability to measu
41c0: 72 65 20 61 74 74 72 69 62 75 74 65 73 20 6f 66  re attributes of
41d0: 20 61 20 66 69 6c 65 2e 0a 2a 2f 0a 76 6f 69 64   a file..*/.void
41e0: 20 63 6d 64 5f 74 65 73 74 5f 63 61 6e 6f 6e 69   cmd_test_canoni
41f0: 63 61 6c 5f 6e 61 6d 65 28 76 6f 69 64 29 7b 0a  cal_name(void){.
4200: 20 20 69 6e 74 20 69 3b 0a 20 20 42 6c 6f 62 20    int i;.  Blob 
4210: 78 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26  x;.  blob_zero(&
4220: 78 29 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20 69  x);.  for(i=2; i
4230: 3c 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20  <g.argc; i++){. 
4240: 20 20 20 63 68 61 72 20 7a 42 75 66 5b 31 30 30     char zBuf[100
4250: 5d 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61  ];.    const cha
4260: 72 20 2a 7a 4e 61 6d 65 20 3d 20 67 2e 61 72 67  r *zName = g.arg
4270: 76 5b 69 5d 3b 0a 20 20 20 20 66 69 6c 65 5f 63  v[i];.    file_c
4280: 61 6e 6f 6e 69 63 61 6c 5f 6e 61 6d 65 28 7a 4e  anonical_name(zN
4290: 61 6d 65 2c 20 26 78 2c 20 30 29 3b 0a 20 20 20  ame, &x, 0);.   
42a0: 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 5b   fossil_print("[
42b0: 25 73 5d 20 2d 3e 20 5b 25 73 5d 5c 6e 22 2c 20  %s] -> [%s]\n", 
42c0: 7a 4e 61 6d 65 2c 20 62 6c 6f 62 5f 62 75 66 66  zName, blob_buff
42d0: 65 72 28 26 78 29 29 3b 0a 20 20 20 20 62 6c 6f  er(&x));.    blo
42e0: 62 5f 72 65 73 65 74 28 26 78 29 3b 0a 20 20 20  b_reset(&x);.   
42f0: 20 73 71 6c 69 74 65 34 5f 73 6e 70 72 69 6e 74   sqlite4_snprint
4300: 66 28 7a 42 75 66 2c 20 73 69 7a 65 6f 66 28 7a  f(zBuf, sizeof(z
4310: 42 75 66 29 2c 20 22 25 6c 6c 64 22 2c 20 66 69  Buf), "%lld", fi
4320: 6c 65 5f 77 64 5f 73 69 7a 65 28 7a 4e 61 6d 65  le_wd_size(zName
4330: 29 29 3b 0a 20 20 20 20 66 6f 73 73 69 6c 5f 70  ));.    fossil_p
4340: 72 69 6e 74 28 22 20 20 66 69 6c 65 5f 73 69 7a  rint("  file_siz
4350: 65 20 20 20 3d 20 25 73 5c 6e 22 2c 20 7a 42 75  e   = %s\n", zBu
4360: 66 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 34 5f  f);.    sqlite4_
4370: 73 6e 70 72 69 6e 74 66 28 7a 42 75 66 2c 20 73  snprintf(zBuf, s
4380: 69 7a 65 6f 66 28 7a 42 75 66 29 2c 20 22 25 6c  izeof(zBuf), "%l
4390: 6c 64 22 2c 20 66 69 6c 65 5f 77 64 5f 6d 74 69  ld", file_wd_mti
43a0: 6d 65 28 7a 4e 61 6d 65 29 29 3b 0a 20 20 20 20  me(zName));.    
43b0: 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 20 20  fossil_print("  
43c0: 66 69 6c 65 5f 6d 74 69 6d 65 20 20 3d 20 25 73  file_mtime  = %s
43d0: 5c 6e 22 2c 20 7a 42 75 66 29 3b 0a 20 20 20 20  \n", zBuf);.    
43e0: 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 20 20  fossil_print("  
43f0: 66 69 6c 65 5f 69 73 66 69 6c 65 20 3d 20 25 64  file_isfile = %d
4400: 5c 6e 22 2c 20 66 69 6c 65 5f 77 64 5f 69 73 66  \n", file_wd_isf
4410: 69 6c 65 28 7a 4e 61 6d 65 29 29 3b 0a 20 20 20  ile(zName));.   
4420: 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 20   fossil_print(" 
4430: 20 66 69 6c 65 5f 69 73 66 69 6c 65 5f 6f 72 5f   file_isfile_or_
4440: 6c 69 6e 6b 20 3d 20 25 64 5c 6e 22 2c 66 69 6c  link = %d\n",fil
4450: 65 5f 77 64 5f 69 73 66 69 6c 65 5f 6f 72 5f 6c  e_wd_isfile_or_l
4460: 69 6e 6b 28 7a 4e 61 6d 65 29 29 3b 0a 20 20 20  ink(zName));.   
4470: 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 20   fossil_print(" 
4480: 20 66 69 6c 65 5f 69 73 6c 69 6e 6b 20 3d 20 25   file_islink = %
4490: 64 5c 6e 22 2c 20 66 69 6c 65 5f 77 64 5f 69 73  d\n", file_wd_is
44a0: 6c 69 6e 6b 28 7a 4e 61 6d 65 29 29 3b 0a 20 20  link(zName));.  
44b0: 20 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22    fossil_print("
44c0: 20 20 66 69 6c 65 5f 69 73 65 78 65 20 20 3d 20    file_isexe  = 
44d0: 25 64 5c 6e 22 2c 20 66 69 6c 65 5f 77 64 5f 69  %d\n", file_wd_i
44e0: 73 65 78 65 28 7a 4e 61 6d 65 29 29 3b 0a 20 20  sexe(zName));.  
44f0: 20 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22    fossil_print("
4500: 20 20 66 69 6c 65 5f 69 73 64 69 72 20 20 3d 20    file_isdir  = 
4510: 25 64 5c 6e 22 2c 20 66 69 6c 65 5f 77 64 5f 69  %d\n", file_wd_i
4520: 73 64 69 72 28 7a 4e 61 6d 65 29 29 3b 0a 20 20  sdir(zName));.  
4530: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  }.}../*.** Retur
4540: 6e 20 54 52 55 45 20 69 66 20 74 68 65 20 67 69  n TRUE if the gi
4550: 76 65 6e 20 66 69 6c 65 6e 61 6d 65 20 69 73 20  ven filename is 
4560: 63 61 6e 6f 6e 69 63 61 6c 2e 0a 2a 2a 0a 2a 2a  canonical..**.**
4570: 20 43 61 6e 6f 6e 69 63 61 6c 20 6e 61 6d 65 73   Canonical names
4580: 20 61 72 65 20 66 75 6c 6c 20 70 61 74 68 6e 61   are full pathna
4590: 6d 65 73 20 75 73 69 6e 67 20 22 2f 22 20 6e 6f  mes using "/" no
45a0: 74 20 22 5c 22 20 61 6e 64 20 77 68 69 63 68 0a  t "\" and which.
45b0: 2a 2a 20 63 6f 6e 74 61 69 6e 20 6e 6f 20 22 2f  ** contain no "/
45c0: 2e 2f 22 20 6f 72 20 22 2f 2e 2e 2f 22 20 74 65  ./" or "/../" te
45d0: 72 6d 73 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65  rms..*/.int file
45e0: 5f 69 73 5f 63 61 6e 6f 6e 69 63 61 6c 28 63 6f  _is_canonical(co
45f0: 6e 73 74 20 63 68 61 72 20 2a 7a 29 7b 0a 20 20  nst char *z){.  
4600: 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 7a 5b 30  int i;.  if( z[0
4610: 5d 21 3d 27 2f 27 0a 23 69 66 20 64 65 66 69 6e  ]!='/'.#if defin
4620: 65 64 28 5f 57 49 4e 33 32 29 0a 20 20 20 20 26  ed(_WIN32).    &
4630: 26 20 28 7a 5b 30 5d 3d 3d 30 20 7c 7c 20 7a 5b  & (z[0]==0 || z[
4640: 31 5d 21 3d 27 3a 27 20 7c 7c 20 7a 5b 32 5d 21  1]!=':' || z[2]!
4650: 3d 27 2f 27 29 0a 23 65 6e 64 69 66 0a 20 20 29  ='/').#endif.  )
4660: 20 72 65 74 75 72 6e 20 30 3b 0a 0a 20 20 66 6f   return 0;..  fo
4670: 72 28 69 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b  r(i=0; z[i]; i++
4680: 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d  ){.    if( z[i]=
4690: 3d 27 5c 5c 27 20 29 20 72 65 74 75 72 6e 20 30  ='\\' ) return 0
46a0: 3b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d  ;.    if( z[i]==
46b0: 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 69 66 28  '/' ){.      if(
46c0: 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 29 7b 0a   z[i+1]=='.' ){.
46d0: 20 20 20 20 20 20 20 20 69 66 28 20 7a 5b 69 2b          if( z[i+
46e0: 32 5d 3d 3d 27 2f 27 20 7c 7c 20 7a 5b 69 2b 32  2]=='/' || z[i+2
46f0: 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b  ]==0 ) return 0;
4700: 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a 5b 69  .        if( z[i
4710: 2b 32 5d 3d 3d 27 2e 27 20 26 26 20 28 7a 5b 69  +2]=='.' && (z[i
4720: 2b 33 5d 3d 3d 27 2f 27 20 7c 7c 20 7a 5b 69 2b  +3]=='/' || z[i+
4730: 33 5d 3d 3d 30 29 20 29 20 72 65 74 75 72 6e 20  3]==0) ) return 
4740: 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  0;.      }.    }
4750: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 31 3b  .  }.  return 1;
4760: 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 52 65 74 75 72  .}../* .** Retur
4770: 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74  n a pointer to t
4780: 68 65 20 66 69 72 73 74 20 63 68 61 72 61 63 74  he first charact
4790: 65 72 20 69 6e 20 61 20 70 61 74 68 6e 61 6d 65  er in a pathname
47a0: 20 70 61 73 74 20 74 68 65 0a 2a 2a 20 64 72 69   past the.** dri
47b0: 76 65 20 6c 65 74 74 65 72 2e 20 20 54 68 69 73  ve letter.  This
47c0: 20 72 6f 75 74 69 6e 65 20 69 73 20 61 20 6e 6f   routine is a no
47d0: 2d 6f 70 20 6f 6e 20 75 6e 69 78 2e 0a 2a 2f 0a  -op on unix..*/.
47e0: 63 68 61 72 20 2a 66 69 6c 65 5f 77 69 74 68 6f  char *file_witho
47f0: 75 74 5f 64 72 69 76 65 5f 6c 65 74 74 65 72 28  ut_drive_letter(
4800: 63 68 61 72 20 2a 7a 49 6e 29 7b 0a 23 69 66 64  char *zIn){.#ifd
4810: 65 66 20 5f 57 49 4e 33 32 0a 20 20 69 66 28 20  ef _WIN32.  if( 
4820: 66 6f 73 73 69 6c 5f 69 73 61 6c 70 68 61 28 7a  fossil_isalpha(z
4830: 49 6e 5b 30 5d 29 20 26 26 20 7a 49 6e 5b 31 5d  In[0]) && zIn[1]
4840: 3d 3d 27 3a 27 20 29 20 7a 49 6e 20 2b 3d 20 32  ==':' ) zIn += 2
4850: 3b 0a 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72  ;.#endif.  retur
4860: 6e 20 7a 49 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  n zIn;.}../*.** 
4870: 43 6f 6d 70 75 74 65 20 61 20 70 61 74 68 6e 61  Compute a pathna
4880: 6d 65 20 66 6f 72 20 61 20 66 69 6c 65 20 6f 72  me for a file or
4890: 20 64 69 72 65 63 74 6f 72 79 20 74 68 61 74 20   directory that 
48a0: 69 73 20 72 65 6c 61 74 69 76 65 0a 2a 2a 20 74  is relative.** t
48b0: 6f 20 74 68 65 20 63 75 72 72 65 6e 74 20 64 69  o the current di
48c0: 72 65 63 74 6f 72 79 2e 20 20 49 66 20 74 68 65  rectory.  If the
48d0: 20 73 6c 61 73 68 20 70 61 72 61 6d 65 74 65 72   slash parameter
48e0: 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 0a 2a 2a   is non-zero,.**
48f0: 20 74 68 65 20 74 72 61 69 6c 69 6e 67 20 73 6c   the trailing sl
4900: 61 73 68 2c 20 69 66 20 61 6e 79 2c 20 69 73 20  ash, if any, is 
4910: 72 65 74 61 69 6e 65 64 2e 0a 2a 2f 0a 76 6f 69  retained..*/.voi
4920: 64 20 66 69 6c 65 5f 72 65 6c 61 74 69 76 65 5f  d file_relative_
4930: 6e 61 6d 65 28 63 6f 6e 73 74 20 63 68 61 72 20  name(const char 
4940: 2a 7a 4f 72 69 67 4e 61 6d 65 2c 20 42 6c 6f 62  *zOrigName, Blob
4950: 20 2a 70 4f 75 74 2c 20 69 6e 74 20 73 6c 61 73   *pOut, int slas
4960: 68 29 7b 0a 20 20 63 68 61 72 20 2a 7a 50 61 74  h){.  char *zPat
4970: 68 3b 0a 20 20 62 6c 6f 62 5f 73 65 74 28 70 4f  h;.  blob_set(pO
4980: 75 74 2c 20 7a 4f 72 69 67 4e 61 6d 65 29 3b 0a  ut, zOrigName);.
4990: 20 20 62 6c 6f 62 5f 72 65 73 69 7a 65 28 70 4f    blob_resize(pO
49a0: 75 74 2c 20 66 69 6c 65 5f 73 69 6d 70 6c 69 66  ut, file_simplif
49b0: 79 5f 6e 61 6d 65 28 62 6c 6f 62 5f 62 75 66 66  y_name(blob_buff
49c0: 65 72 28 70 4f 75 74 29 2c 0a 20 20 20 20 20 20  er(pOut),.      
49d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
49e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
49f0: 20 62 6c 6f 62 5f 73 69 7a 65 28 70 4f 75 74 29   blob_size(pOut)
4a00: 2c 20 73 6c 61 73 68 29 29 3b 0a 20 20 7a 50 61  , slash));.  zPa
4a10: 74 68 20 3d 20 66 69 6c 65 5f 77 69 74 68 6f 75  th = file_withou
4a20: 74 5f 64 72 69 76 65 5f 6c 65 74 74 65 72 28 62  t_drive_letter(b
4a30: 6c 6f 62 5f 62 75 66 66 65 72 28 70 4f 75 74 29  lob_buffer(pOut)
4a40: 29 3b 0a 20 20 69 66 28 20 7a 50 61 74 68 5b 30  );.  if( zPath[0
4a50: 5d 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 69 6e  ]=='/' ){.    in
4a60: 74 20 69 2c 20 6a 3b 0a 20 20 20 20 42 6c 6f 62  t i, j;.    Blob
4a70: 20 74 6d 70 3b 0a 20 20 20 20 63 68 61 72 20 2a   tmp;.    char *
4a80: 7a 50 77 64 3b 0a 20 20 20 20 63 68 61 72 20 7a  zPwd;.    char z
4a90: 42 75 66 5b 32 30 30 30 5d 3b 0a 20 20 20 20 7a  Buf[2000];.    z
4aa0: 50 77 64 20 3d 20 7a 42 75 66 3b 0a 20 20 20 20  Pwd = zBuf;.    
4ab0: 66 69 6c 65 5f 67 65 74 63 77 64 28 7a 42 75 66  file_getcwd(zBuf
4ac0: 2c 20 73 69 7a 65 6f 66 28 7a 42 75 66 29 2d 32  , sizeof(zBuf)-2
4ad0: 30 29 3b 0a 20 20 20 20 7a 50 77 64 20 3d 20 66  0);.    zPwd = f
4ae0: 69 6c 65 5f 77 69 74 68 6f 75 74 5f 64 72 69 76  ile_without_driv
4af0: 65 5f 6c 65 74 74 65 72 28 7a 42 75 66 29 3b 0a  e_letter(zBuf);.
4b00: 20 20 20 20 69 20 3d 20 31 3b 0a 23 69 66 64 65      i = 1;.#ifde
4b10: 66 20 5f 57 49 4e 33 32 0a 20 20 20 20 77 68 69  f _WIN32.    whi
4b20: 6c 65 28 20 7a 50 61 74 68 5b 69 5d 20 26 26 20  le( zPath[i] && 
4b30: 66 6f 73 73 69 6c 5f 74 6f 6c 6f 77 65 72 28 7a  fossil_tolower(z
4b40: 50 77 64 5b 69 5d 29 3d 3d 66 6f 73 73 69 6c 5f  Pwd[i])==fossil_
4b50: 74 6f 6c 6f 77 65 72 28 7a 50 61 74 68 5b 69 5d  tolower(zPath[i]
4b60: 29 20 29 20 69 2b 2b 3b 0a 23 65 6c 73 65 0a 20  ) ) i++;.#else. 
4b70: 20 20 20 77 68 69 6c 65 28 20 7a 50 61 74 68 5b     while( zPath[
4b80: 69 5d 20 26 26 20 7a 50 77 64 5b 69 5d 3d 3d 7a  i] && zPwd[i]==z
4b90: 50 61 74 68 5b 69 5d 20 29 20 69 2b 2b 3b 0a 23  Path[i] ) i++;.#
4ba0: 65 6e 64 69 66 0a 20 20 20 20 69 66 28 20 7a 50  endif.    if( zP
4bb0: 61 74 68 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20  ath[i]==0 ){.   
4bc0: 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 70 4f     blob_reset(pO
4bd0: 75 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a  ut);.      if( z
4be0: 50 77 64 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20  Pwd[i]==0 ){.   
4bf0: 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64       blob_append
4c00: 28 70 4f 75 74 2c 20 22 2e 22 2c 20 31 29 3b 0a  (pOut, ".", 1);.
4c10: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20        }else{.   
4c20: 20 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64       blob_append
4c30: 28 70 4f 75 74 2c 20 22 2e 2e 22 2c 20 32 29 3b  (pOut, "..", 2);
4c40: 0a 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 69  .        for(j=i
4c50: 2b 31 3b 20 7a 50 77 64 5b 6a 5d 3b 20 6a 2b 2b  +1; zPwd[j]; j++
4c60: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ){.          if(
4c70: 20 7a 50 77 64 5b 6a 5d 3d 3d 27 2f 27 20 29 20   zPwd[j]=='/' ) 
4c80: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 6c  {.            bl
4c90: 6f 62 5f 61 70 70 65 6e 64 28 70 4f 75 74 2c 20  ob_append(pOut, 
4ca0: 22 2f 2e 2e 22 2c 20 33 29 3b 0a 20 20 20 20 20  "/..", 3);.     
4cb0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d       }.        }
4cc0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72  .      }.      r
4cd0: 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20  eturn;.    }.   
4ce0: 20 69 66 28 20 7a 50 77 64 5b 69 5d 3d 3d 30 20   if( zPwd[i]==0 
4cf0: 26 26 20 7a 50 61 74 68 5b 69 5d 3d 3d 27 2f 27  && zPath[i]=='/'
4d00: 20 29 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79   ){.      memcpy
4d10: 28 26 74 6d 70 2c 20 70 4f 75 74 2c 20 73 69 7a  (&tmp, pOut, siz
4d20: 65 6f 66 28 74 6d 70 29 29 3b 0a 20 20 20 20 20  eof(tmp));.     
4d30: 20 62 6c 6f 62 5f 73 65 74 28 70 4f 75 74 2c 20   blob_set(pOut, 
4d40: 22 2e 2f 22 29 3b 0a 20 20 20 20 20 20 62 6c 6f  "./");.      blo
4d50: 62 5f 61 70 70 65 6e 64 28 70 4f 75 74 2c 20 26  b_append(pOut, &
4d60: 7a 50 61 74 68 5b 69 2b 31 5d 2c 20 2d 31 29 3b  zPath[i+1], -1);
4d70: 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  .      blob_rese
4d80: 74 28 26 74 6d 70 29 3b 0a 20 20 20 20 20 20 72  t(&tmp);.      r
4d90: 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20  eturn;.    }.   
4da0: 20 77 68 69 6c 65 28 20 7a 50 61 74 68 5b 69 2d   while( zPath[i-
4db0: 31 5d 21 3d 27 2f 27 20 29 7b 20 69 2d 2d 3b 20  1]!='/' ){ i--; 
4dc0: 7d 0a 20 20 20 20 62 6c 6f 62 5f 73 65 74 28 26  }.    blob_set(&
4dd0: 74 6d 70 2c 20 22 2e 2e 2f 22 29 3b 0a 20 20 20  tmp, "../");.   
4de0: 20 66 6f 72 28 6a 3d 69 3b 20 7a 50 77 64 5b 6a   for(j=i; zPwd[j
4df0: 5d 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 69  ]; j++){.      i
4e00: 66 28 20 7a 50 77 64 5b 6a 5d 3d 3d 27 2f 27 20  f( zPwd[j]=='/' 
4e10: 29 20 7b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62  ) {.        blob
4e20: 5f 61 70 70 65 6e 64 28 26 74 6d 70 2c 20 22 2e  _append(&tmp, ".
4e30: 2e 2f 22 2c 20 33 29 3b 0a 20 20 20 20 20 20 7d  ./", 3);.      }
4e40: 0a 20 20 20 20 7d 0a 20 20 20 20 62 6c 6f 62 5f  .    }.    blob_
4e50: 61 70 70 65 6e 64 28 26 74 6d 70 2c 20 26 7a 50  append(&tmp, &zP
4e60: 61 74 68 5b 69 5d 2c 20 2d 31 29 3b 0a 20 20 20  ath[i], -1);.   
4e70: 20 62 6c 6f 62 5f 72 65 73 65 74 28 70 4f 75 74   blob_reset(pOut
4e80: 29 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 4f  );.    memcpy(pO
4e90: 75 74 2c 20 26 74 6d 70 2c 20 73 69 7a 65 6f 66  ut, &tmp, sizeof
4ea0: 28 74 6d 70 29 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  (tmp));.  }.}../
4eb0: 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 20 74  *.** COMMAND:  t
4ec0: 65 73 74 2d 72 65 6c 61 74 69 76 65 2d 6e 61 6d  est-relative-nam
4ed0: 65 0a 2a 2a 0a 2a 2a 20 54 65 73 74 20 74 68 65  e.**.** Test the
4ee0: 20 6f 70 65 72 61 74 69 6f 6e 20 6f 66 20 74 68   operation of th
4ef0: 65 20 72 65 6c 61 74 69 76 65 20 6e 61 6d 65 20  e relative name 
4f00: 67 65 6e 65 72 61 74 6f 72 2e 0a 2a 2f 0a 76 6f  generator..*/.vo
4f10: 69 64 20 63 6d 64 5f 74 65 73 74 5f 72 65 6c 61  id cmd_test_rela
4f20: 74 69 76 65 5f 6e 61 6d 65 28 76 6f 69 64 29 7b  tive_name(void){
4f30: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 42 6c 6f 62  .  int i;.  Blob
4f40: 20 78 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28   x;.  blob_zero(
4f50: 26 78 29 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20  &x);.  for(i=2; 
4f60: 69 3c 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a  i<g.argc; i++){.
4f70: 20 20 20 20 66 69 6c 65 5f 72 65 6c 61 74 69 76      file_relativ
4f80: 65 5f 6e 61 6d 65 28 67 2e 61 72 67 76 5b 69 5d  e_name(g.argv[i]
4f90: 2c 20 26 78 2c 20 30 29 3b 0a 20 20 20 20 66 6f  , &x, 0);.    fo
4fa0: 73 73 69 6c 5f 70 72 69 6e 74 28 22 25 73 5c 6e  ssil_print("%s\n
4fb0: 22 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26  ", blob_buffer(&
4fc0: 78 29 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65  x));.    blob_re
4fd0: 73 65 74 28 26 78 29 3b 0a 20 20 7d 0a 7d 0a 0a  set(&x);.  }.}..
4fe0: 2f 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20  /*.** Compute a 
4ff0: 70 61 74 68 6e 61 6d 65 20 66 6f 72 20 61 20 66  pathname for a f
5000: 69 6c 65 20 72 65 6c 61 74 69 76 65 20 74 6f 20  ile relative to 
5010: 74 68 65 20 72 6f 6f 74 20 6f 66 20 74 68 65 20  the root of the 
5020: 6c 6f 63 61 6c 0a 2a 2a 20 74 72 65 65 2e 20 20  local.** tree.  
5030: 52 65 74 75 72 6e 20 54 52 55 45 20 6f 6e 20 73  Return TRUE on s
5040: 75 63 63 65 73 73 2e 20 20 4f 6e 20 66 61 69 6c  uccess.  On fail
5050: 75 72 65 2c 20 70 72 69 6e 74 20 61 6e 64 20 65  ure, print and e
5060: 72 72 6f 72 0a 2a 2a 20 6d 65 73 73 61 67 65 20  rror.** message 
5070: 61 6e 64 20 71 75 69 74 20 69 66 20 74 68 65 20  and quit if the 
5080: 65 72 72 46 61 74 61 6c 20 66 6c 61 67 20 69 73  errFatal flag is
5090: 20 74 72 75 65 2e 20 20 49 66 20 65 72 72 46 61   true.  If errFa
50a0: 74 61 6c 20 69 73 0a 2a 2a 20 66 61 6c 73 65 2c  tal is.** false,
50b0: 20 74 68 65 6e 20 73 69 6d 70 6c 79 20 72 65 74   then simply ret
50c0: 75 72 6e 20 30 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  urn 0..**.** The
50d0: 20 72 6f 6f 74 20 6f 66 20 74 68 65 20 74 72 65   root of the tre
50e0: 65 20 69 73 20 64 65 66 69 6e 65 64 20 62 79 20  e is defined by 
50f0: 74 68 65 20 67 2e 7a 4c 6f 63 61 6c 52 6f 6f 74  the g.zLocalRoot
5100: 20 76 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a 69 6e   variable..*/.in
5110: 74 20 66 69 6c 65 5f 74 72 65 65 5f 6e 61 6d 65  t file_tree_name
5120: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4f 72  (const char *zOr
5130: 69 67 4e 61 6d 65 2c 20 42 6c 6f 62 20 2a 70 4f  igName, Blob *pO
5140: 75 74 2c 20 69 6e 74 20 65 72 72 46 61 74 61 6c  ut, int errFatal
5150: 29 7b 0a 20 20 42 6c 6f 62 20 6c 6f 63 61 6c 52  ){.  Blob localR
5160: 6f 6f 74 3b 0a 20 20 69 6e 74 20 6e 4c 6f 63 61  oot;.  int nLoca
5170: 6c 52 6f 6f 74 3b 0a 20 20 63 68 61 72 20 2a 7a  lRoot;.  char *z
5180: 4c 6f 63 61 6c 52 6f 6f 74 3b 0a 20 20 42 6c 6f  LocalRoot;.  Blo
5190: 62 20 66 75 6c 6c 3b 0a 20 20 69 6e 74 20 6e 46  b full;.  int nF
51a0: 75 6c 6c 3b 0a 20 20 63 68 61 72 20 2a 7a 46 75  ull;.  char *zFu
51b0: 6c 6c 3b 0a 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f  ll;..  blob_zero
51c0: 28 70 4f 75 74 29 3b 0a 20 20 64 62 5f 6d 75 73  (pOut);.  db_mus
51d0: 74 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72 65 65  t_be_within_tree
51e0: 28 29 3b 0a 20 20 66 69 6c 65 5f 63 61 6e 6f 6e  ();.  file_canon
51f0: 69 63 61 6c 5f 6e 61 6d 65 28 67 2e 7a 4c 6f 63  ical_name(g.zLoc
5200: 61 6c 52 6f 6f 74 2c 20 26 6c 6f 63 61 6c 52 6f  alRoot, &localRo
5210: 6f 74 2c 20 31 29 3b 0a 20 20 6e 4c 6f 63 61 6c  ot, 1);.  nLocal
5220: 52 6f 6f 74 20 3d 20 62 6c 6f 62 5f 73 69 7a 65  Root = blob_size
5230: 28 26 6c 6f 63 61 6c 52 6f 6f 74 29 3b 0a 20 20  (&localRoot);.  
5240: 7a 4c 6f 63 61 6c 52 6f 6f 74 20 3d 20 62 6c 6f  zLocalRoot = blo
5250: 62 5f 62 75 66 66 65 72 28 26 6c 6f 63 61 6c 52  b_buffer(&localR
5260: 6f 6f 74 29 3b 0a 20 20 61 73 73 65 72 74 28 20  oot);.  assert( 
5270: 6e 4c 6f 63 61 6c 52 6f 6f 74 3e 30 20 26 26 20  nLocalRoot>0 && 
5280: 7a 4c 6f 63 61 6c 52 6f 6f 74 5b 6e 4c 6f 63 61  zLocalRoot[nLoca
5290: 6c 52 6f 6f 74 2d 31 5d 3d 3d 27 2f 27 20 29 3b  lRoot-1]=='/' );
52a0: 0a 20 20 66 69 6c 65 5f 63 61 6e 6f 6e 69 63 61  .  file_canonica
52b0: 6c 5f 6e 61 6d 65 28 7a 4f 72 69 67 4e 61 6d 65  l_name(zOrigName
52c0: 2c 20 26 66 75 6c 6c 2c 20 30 29 3b 0a 20 20 6e  , &full, 0);.  n
52d0: 46 75 6c 6c 20 3d 20 62 6c 6f 62 5f 73 69 7a 65  Full = blob_size
52e0: 28 26 66 75 6c 6c 29 3b 0a 20 20 7a 46 75 6c 6c  (&full);.  zFull
52f0: 20 3d 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26   = blob_buffer(&
5300: 66 75 6c 6c 29 3b 0a 0a 20 20 2f 2a 20 53 70 65  full);..  /* Spe
5310: 63 69 61 6c 20 63 61 73 65 2e 20 20 7a 4f 72 69  cial case.  zOri
5320: 67 4e 61 6d 65 20 72 65 66 65 72 73 20 74 6f 20  gName refers to 
5330: 67 2e 7a 4c 6f 63 61 6c 52 6f 6f 74 20 64 69 72  g.zLocalRoot dir
5340: 65 63 74 6f 72 79 2e 20 2a 2f 0a 20 20 69 66 28  ectory. */.  if(
5350: 20 6e 46 75 6c 6c 3d 3d 6e 4c 6f 63 61 6c 52 6f   nFull==nLocalRo
5360: 6f 74 2d 31 20 26 26 20 6d 65 6d 63 6d 70 28 7a  ot-1 && memcmp(z
5370: 4c 6f 63 61 6c 52 6f 6f 74 2c 20 7a 46 75 6c 6c  LocalRoot, zFull
5380: 2c 20 6e 46 75 6c 6c 29 3d 3d 30 20 29 7b 0a 20  , nFull)==0 ){. 
5390: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70     blob_append(p
53a0: 4f 75 74 2c 20 22 2e 22 2c 20 31 29 3b 0a 20 20  Out, ".", 1);.  
53b0: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 6c 6f    blob_reset(&lo
53c0: 63 61 6c 52 6f 6f 74 29 3b 0a 20 20 20 20 62 6c  calRoot);.    bl
53d0: 6f 62 5f 72 65 73 65 74 28 26 66 75 6c 6c 29 3b  ob_reset(&full);
53e0: 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20  .    return 1;. 
53f0: 20 7d 0a 0a 20 20 69 66 28 20 6e 46 75 6c 6c 3c   }..  if( nFull<
5400: 3d 6e 4c 6f 63 61 6c 52 6f 6f 74 20 7c 7c 20 6d  =nLocalRoot || m
5410: 65 6d 63 6d 70 28 7a 4c 6f 63 61 6c 52 6f 6f 74  emcmp(zLocalRoot
5420: 2c 20 7a 46 75 6c 6c 2c 20 6e 4c 6f 63 61 6c 52  , zFull, nLocalR
5430: 6f 6f 74 29 20 29 7b 0a 20 20 20 20 62 6c 6f 62  oot) ){.    blob
5440: 5f 72 65 73 65 74 28 26 6c 6f 63 61 6c 52 6f 6f  _reset(&localRoo
5450: 74 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73  t);.    blob_res
5460: 65 74 28 26 66 75 6c 6c 29 3b 0a 20 20 20 20 69  et(&full);.    i
5470: 66 28 20 65 72 72 46 61 74 61 6c 20 29 7b 0a 20  f( errFatal ){. 
5480: 20 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61       fossil_fata
5490: 6c 28 22 66 69 6c 65 20 6f 75 74 73 69 64 65 20  l("file outside 
54a0: 6f 66 20 63 68 65 63 6b 6f 75 74 20 74 72 65 65  of checkout tree
54b0: 3a 20 25 73 22 2c 20 7a 4f 72 69 67 4e 61 6d 65  : %s", zOrigName
54c0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74  );.    }.    ret
54d0: 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 62 6c 6f  urn 0;.  }.  blo
54e0: 62 5f 61 70 70 65 6e 64 28 70 4f 75 74 2c 20 26  b_append(pOut, &
54f0: 7a 46 75 6c 6c 5b 6e 4c 6f 63 61 6c 52 6f 6f 74  zFull[nLocalRoot
5500: 5d 2c 20 6e 46 75 6c 6c 2d 6e 4c 6f 63 61 6c 52  ], nFull-nLocalR
5510: 6f 6f 74 29 3b 0a 20 20 62 6c 6f 62 5f 72 65 73  oot);.  blob_res
5520: 65 74 28 26 6c 6f 63 61 6c 52 6f 6f 74 29 3b 0a  et(&localRoot);.
5530: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 66 75    blob_reset(&fu
5540: 6c 6c 29 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b  ll);.  return 1;
5550: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e  .}../*.** COMMAN
5560: 44 3a 20 20 74 65 73 74 2d 74 72 65 65 2d 6e 61  D:  test-tree-na
5570: 6d 65 0a 2a 2a 0a 2a 2a 20 54 65 73 74 20 74 68  me.**.** Test th
5580: 65 20 6f 70 65 72 61 74 69 6f 6e 20 6f 66 20 74  e operation of t
5590: 68 65 20 74 72 65 65 20 6e 61 6d 65 20 67 65 6e  he tree name gen
55a0: 65 72 61 74 6f 72 2e 0a 2a 2f 0a 76 6f 69 64 20  erator..*/.void 
55b0: 63 6d 64 5f 74 65 73 74 5f 74 72 65 65 5f 6e 61  cmd_test_tree_na
55c0: 6d 65 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20  me(void){.  int 
55d0: 69 3b 0a 20 20 42 6c 6f 62 20 78 3b 0a 20 20 62  i;.  Blob x;.  b
55e0: 6c 6f 62 5f 7a 65 72 6f 28 26 78 29 3b 0a 20 20  lob_zero(&x);.  
55f0: 66 6f 72 28 69 3d 32 3b 20 69 3c 67 2e 61 72 67  for(i=2; i<g.arg
5600: 63 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  c; i++){.    if(
5610: 20 66 69 6c 65 5f 74 72 65 65 5f 6e 61 6d 65 28   file_tree_name(
5620: 67 2e 61 72 67 76 5b 69 5d 2c 20 26 78 2c 20 31  g.argv[i], &x, 1
5630: 29 20 29 7b 0a 20 20 20 20 20 20 66 6f 73 73 69  ) ){.      fossi
5640: 6c 5f 70 72 69 6e 74 28 22 25 73 5c 6e 22 2c 20  l_print("%s\n", 
5650: 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 78 29 29  blob_buffer(&x))
5660: 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73  ;.      blob_res
5670: 65 74 28 26 78 29 3b 0a 20 20 20 20 7d 0a 20 20  et(&x);.    }.  
5680: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 73 65  }.}../*.** Parse
5690: 20 61 20 55 52 49 20 69 6e 74 6f 20 73 63 68 65   a URI into sche
56a0: 6d 65 2c 20 68 6f 73 74 2c 20 70 6f 72 74 2c 20  me, host, port, 
56b0: 61 6e 64 20 70 61 74 68 2e 0a 2a 2f 0a 76 6f 69  and path..*/.voi
56c0: 64 20 66 69 6c 65 5f 70 61 72 73 65 5f 75 72 69  d file_parse_uri
56d0: 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  (.  const char *
56e0: 7a 55 72 69 2c 0a 20 20 42 6c 6f 62 20 2a 70 53  zUri,.  Blob *pS
56f0: 63 68 65 6d 65 2c 0a 20 20 42 6c 6f 62 20 2a 70  cheme,.  Blob *p
5700: 48 6f 73 74 2c 0a 20 20 69 6e 74 20 2a 70 50 6f  Host,.  int *pPo
5710: 72 74 2c 0a 20 20 42 6c 6f 62 20 2a 70 50 61 74  rt,.  Blob *pPat
5720: 68 0a 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b  h.){.  int i, j;
5730: 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 55 72  ..  for(i=0; zUr
5740: 69 5b 69 5d 20 26 26 20 7a 55 72 69 5b 69 5d 3e  i[i] && zUri[i]>
5750: 3d 27 61 27 20 26 26 20 7a 55 72 69 5b 69 5d 3c  ='a' && zUri[i]<
5760: 3d 27 7a 27 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69  ='z'; i++){}.  i
5770: 66 28 20 7a 55 72 69 5b 69 5d 21 3d 27 3a 27 20  f( zUri[i]!=':' 
5780: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f  ){.    blob_zero
5790: 28 70 53 63 68 65 6d 65 29 3b 0a 20 20 20 20 62  (pScheme);.    b
57a0: 6c 6f 62 5f 7a 65 72 6f 28 70 48 6f 73 74 29 3b  lob_zero(pHost);
57b0: 0a 20 20 20 20 62 6c 6f 62 5f 73 65 74 28 70 50  .    blob_set(pP
57c0: 61 74 68 2c 20 7a 55 72 69 29 3b 0a 20 20 20 20  ath, zUri);.    
57d0: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 62 6c  return;.  }.  bl
57e0: 6f 62 5f 69 6e 69 74 28 70 53 63 68 65 6d 65 2c  ob_init(pScheme,
57f0: 20 7a 55 72 69 2c 20 69 29 3b 0a 20 20 69 2b 2b   zUri, i);.  i++
5800: 3b 0a 20 20 69 66 28 20 7a 55 72 69 5b 69 5d 3d  ;.  if( zUri[i]=
5810: 3d 27 2f 27 20 26 26 20 7a 55 72 69 5b 69 2b 31  ='/' && zUri[i+1
5820: 5d 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 69 20  ]=='/' ){.    i 
5830: 2b 3d 20 32 3b 0a 20 20 20 20 6a 20 3d 20 69 3b  += 2;.    j = i;
5840: 0a 20 20 20 20 77 68 69 6c 65 28 20 7a 55 72 69  .    while( zUri
5850: 5b 69 5d 20 26 26 20 7a 55 72 69 5b 69 5d 21 3d  [i] && zUri[i]!=
5860: 27 2f 27 20 26 26 20 7a 55 72 69 5b 69 5d 21 3d  '/' && zUri[i]!=
5870: 27 3a 27 20 29 7b 20 69 2b 2b 3b 20 7d 0a 20 20  ':' ){ i++; }.  
5880: 20 20 62 6c 6f 62 5f 69 6e 69 74 28 70 48 6f 73    blob_init(pHos
5890: 74 2c 20 26 7a 55 72 69 5b 6a 5d 2c 20 69 2d 6a  t, &zUri[j], i-j
58a0: 29 3b 0a 20 20 20 20 69 66 28 20 7a 55 72 69 5b  );.    if( zUri[
58b0: 69 5d 3d 3d 27 3a 27 20 29 7b 0a 20 20 20 20 20  i]==':' ){.     
58c0: 20 69 2b 2b 3b 0a 20 20 20 20 20 20 2a 70 50 6f   i++;.      *pPo
58d0: 72 74 20 3d 20 61 74 6f 69 28 26 7a 55 72 69 5b  rt = atoi(&zUri[
58e0: 69 5d 29 3b 0a 20 20 20 20 20 20 77 68 69 6c 65  i]);.      while
58f0: 28 20 7a 55 72 69 5b 69 5d 20 26 26 20 7a 55 72  ( zUri[i] && zUr
5900: 69 5b 69 5d 21 3d 27 2f 27 20 29 7b 20 69 2b 2b  i[i]!='/' ){ i++
5910: 3b 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73  ; }.    }.  }els
5920: 65 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f  e{.    blob_zero
5930: 28 70 48 6f 73 74 29 3b 0a 20 20 7d 0a 20 20 69  (pHost);.  }.  i
5940: 66 28 20 7a 55 72 69 5b 69 5d 3d 3d 27 2f 27 20  f( zUri[i]=='/' 
5950: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 73 65 74 28  ){.    blob_set(
5960: 70 50 61 74 68 2c 20 26 7a 55 72 69 5b 69 5d 29  pPath, &zUri[i])
5970: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 62  ;.  }else{.    b
5980: 6c 6f 62 5f 73 65 74 28 70 50 61 74 68 2c 20 22  lob_set(pPath, "
5990: 2f 22 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  /");.  }.}../*.*
59a0: 2a 20 43 6f 6e 73 74 72 75 63 74 20 61 20 72 61  * Construct a ra
59b0: 6e 64 6f 6d 20 74 65 6d 70 6f 72 61 72 79 20 66  ndom temporary f
59c0: 69 6c 65 6e 61 6d 65 20 69 6e 74 6f 20 7a 42 75  ilename into zBu
59d0: 66 5b 5d 2e 0a 2a 2f 0a 76 6f 69 64 20 66 69 6c  f[]..*/.void fil
59e0: 65 5f 74 65 6d 70 6e 61 6d 65 28 69 6e 74 20 6e  e_tempname(int n
59f0: 42 75 66 2c 20 63 68 61 72 20 2a 7a 42 75 66 29  Buf, char *zBuf)
5a00: 7b 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74  {.  static const
5a10: 20 63 68 61 72 20 2a 61 7a 44 69 72 73 5b 5d 20   char *azDirs[] 
5a20: 3d 20 7b 0a 23 69 66 20 64 65 66 69 6e 65 64 28  = {.#if defined(
5a30: 5f 57 49 4e 33 32 29 0a 20 20 20 20 20 30 2c 20  _WIN32).     0, 
5a40: 2f 2a 20 47 65 74 54 65 6d 70 50 61 74 68 20 2a  /* GetTempPath *
5a50: 2f 0a 20 20 20 20 20 30 2c 20 2f 2a 20 54 45 4d  /.     0, /* TEM
5a60: 50 20 2a 2f 0a 20 20 20 20 20 30 2c 20 2f 2a 20  P */.     0, /* 
5a70: 54 4d 50 20 2a 2f 0a 23 65 6c 73 65 0a 20 20 20  TMP */.#else.   
5a80: 20 20 22 2f 76 61 72 2f 74 6d 70 22 2c 0a 20 20    "/var/tmp",.  
5a90: 20 20 20 22 2f 75 73 72 2f 74 6d 70 22 2c 0a 20     "/usr/tmp",. 
5aa0: 20 20 20 20 22 2f 74 6d 70 22 2c 0a 20 20 20 20      "/tmp",.    
5ab0: 20 22 2f 74 65 6d 70 22 2c 0a 23 65 6e 64 69 66   "/temp",.#endif
5ac0: 0a 20 20 20 20 20 22 2e 22 2c 0a 20 20 7d 3b 0a  .     ".",.  };.
5ad0: 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 75    static const u
5ae0: 6e 73 69 67 6e 65 64 20 63 68 61 72 20 7a 43 68  nsigned char zCh
5af0: 61 72 73 5b 5d 20 3d 0a 20 20 20 20 22 61 62 63  ars[] =.    "abc
5b00: 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73  defghijklmnopqrs
5b10: 74 75 76 77 78 79 7a 22 0a 20 20 20 20 22 41 42  tuvwxyz".    "AB
5b20: 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52  CDEFGHIJKLMNOPQR
5b30: 53 54 55 56 57 58 59 5a 22 0a 20 20 20 20 22 30  STUVWXYZ".    "0
5b40: 31 32 33 34 35 36 37 38 39 22 3b 0a 20 20 75 6e  123456789";.  un
5b50: 73 69 67 6e 65 64 20 69 6e 74 20 69 2c 20 6a 3b  signed int i, j;
5b60: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5b70: 44 69 72 20 3d 20 22 2e 22 3b 0a 20 20 69 6e 74  Dir = ".";.  int
5b80: 20 63 6e 74 20 3d 20 30 3b 0a 0a 23 69 66 20 64   cnt = 0;..#if d
5b90: 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20  efined(_WIN32). 
5ba0: 20 63 68 61 72 20 7a 54 6d 70 50 61 74 68 5b 4d   char zTmpPath[M
5bb0: 41 58 5f 50 41 54 48 5d 3b 0a 0a 20 20 69 66 28  AX_PATH];..  if(
5bc0: 20 47 65 74 54 65 6d 70 50 61 74 68 28 73 69 7a   GetTempPath(siz
5bd0: 65 6f 66 28 7a 54 6d 70 50 61 74 68 29 2c 20 7a  eof(zTmpPath), z
5be0: 54 6d 70 50 61 74 68 29 20 29 7b 0a 20 20 20 20  TmpPath) ){.    
5bf0: 61 7a 44 69 72 73 5b 30 5d 20 3d 20 7a 54 6d 70  azDirs[0] = zTmp
5c00: 50 61 74 68 3b 0a 20 20 7d 0a 0a 20 20 61 7a 44  Path;.  }..  azD
5c10: 69 72 73 5b 31 5d 20 3d 20 66 6f 73 73 69 6c 5f  irs[1] = fossil_
5c20: 67 65 74 65 6e 76 28 22 54 45 4d 50 22 29 3b 0a  getenv("TEMP");.
5c30: 20 20 61 7a 44 69 72 73 5b 32 5d 20 3d 20 66 6f    azDirs[2] = fo
5c40: 73 73 69 6c 5f 67 65 74 65 6e 76 28 22 54 4d 50  ssil_getenv("TMP
5c50: 22 29 3b 0a 23 65 6e 64 69 66 0a 0a 20 20 0a 20  ");.#endif..  . 
5c60: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a 65   for(i=0; i<size
5c70: 6f 66 28 61 7a 44 69 72 73 29 2f 73 69 7a 65 6f  of(azDirs)/sizeo
5c80: 66 28 61 7a 44 69 72 73 5b 30 5d 29 3b 20 69 2b  f(azDirs[0]); i+
5c90: 2b 29 7b 0a 20 20 20 20 69 66 28 20 61 7a 44 69  +){.    if( azDi
5ca0: 72 73 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e 74 69  rs[i]==0 ) conti
5cb0: 6e 75 65 3b 0a 20 20 20 20 69 66 28 20 21 66 69  nue;.    if( !fi
5cc0: 6c 65 5f 69 73 64 69 72 28 61 7a 44 69 72 73 5b  le_isdir(azDirs[
5cd0: 69 5d 29 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a  i]) ) continue;.
5ce0: 20 20 20 20 7a 44 69 72 20 3d 20 61 7a 44 69 72      zDir = azDir
5cf0: 73 5b 69 5d 3b 0a 20 20 20 20 62 72 65 61 6b 3b  s[i];.    break;
5d00: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 68 65 63 6b  .  }..  /* Check
5d10: 20 74 68 61 74 20 74 68 65 20 6f 75 74 70 75 74   that the output
5d20: 20 62 75 66 66 65 72 20 69 73 20 6c 61 72 67 65   buffer is large
5d30: 20 65 6e 6f 75 67 68 20 66 6f 72 20 74 68 65 20   enough for the 
5d40: 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65 20 0a  temporary file .
5d50: 20 20 2a 2a 20 6e 61 6d 65 2e 20 49 66 20 69 74    ** name. If it
5d60: 20 69 73 20 6e 6f 74 2c 20 72 65 74 75 72 6e 20   is not, return 
5d70: 53 51 4c 49 54 45 5f 45 52 52 4f 52 2e 0a 20 20  SQLITE_ERROR..  
5d80: 2a 2f 0a 20 20 69 66 28 20 28 73 74 72 6c 65 6e  */.  if( (strlen
5d90: 28 7a 44 69 72 29 20 2b 20 31 37 29 20 3e 3d 20  (zDir) + 17) >= 
5da0: 28 73 69 7a 65 5f 74 29 6e 42 75 66 20 29 7b 0a  (size_t)nBuf ){.
5db0: 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c      fossil_fatal
5dc0: 28 22 69 6e 73 75 66 66 69 63 69 65 6e 74 20 73  ("insufficient s
5dd0: 70 61 63 65 20 66 6f 72 20 74 65 6d 70 6f 72 61  pace for tempora
5de0: 72 79 20 66 69 6c 65 6e 61 6d 65 22 29 3b 0a 20  ry filename");. 
5df0: 20 7d 0a 0a 20 20 64 6f 7b 0a 20 20 20 20 69 66   }..  do{.    if
5e00: 28 20 63 6e 74 2b 2b 3e 32 30 20 29 20 66 6f 73  ( cnt++>20 ) fos
5e10: 73 69 6c 5f 70 61 6e 69 63 28 22 63 61 6e 6e 6f  sil_panic("canno
5e20: 74 20 67 65 6e 65 72 61 74 65 20 61 20 74 65 6d  t generate a tem
5e30: 70 6f 72 61 72 79 20 66 69 6c 65 6e 61 6d 65 22  porary filename"
5e40: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 34 5f 73  );.    sqlite4_s
5e50: 6e 70 72 69 6e 74 66 28 7a 42 75 66 2c 20 6e 42  nprintf(zBuf, nB
5e60: 75 66 2d 31 37 2c 20 22 25 73 2f 22 2c 20 7a 44  uf-17, "%s/", zD
5e70: 69 72 29 3b 0a 20 20 20 20 6a 20 3d 20 28 69 6e  ir);.    j = (in
5e80: 74 29 73 74 72 6c 65 6e 28 7a 42 75 66 29 3b 0a  t)strlen(zBuf);.
5e90: 20 20 20 20 73 71 6c 69 74 65 34 5f 72 61 6e 64      sqlite4_rand
5ea0: 6f 6d 6e 65 73 73 28 30 2c 20 31 35 2c 20 26 7a  omness(0, 15, &z
5eb0: 42 75 66 5b 6a 5d 29 3b 0a 20 20 20 20 66 6f 72  Buf[j]);.    for
5ec0: 28 69 3d 30 3b 20 69 3c 31 35 3b 20 69 2b 2b 2c  (i=0; i<15; i++,
5ed0: 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 7a 42 75   j++){.      zBu
5ee0: 66 5b 6a 5d 20 3d 20 28 63 68 61 72 29 7a 43 68  f[j] = (char)zCh
5ef0: 61 72 73 5b 20 28 28 75 6e 73 69 67 6e 65 64 20  ars[ ((unsigned 
5f00: 63 68 61 72 29 7a 42 75 66 5b 6a 5d 29 25 28 73  char)zBuf[j])%(s
5f10: 69 7a 65 6f 66 28 7a 43 68 61 72 73 29 2d 31 29  izeof(zChars)-1)
5f20: 20 5d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 42   ];.    }.    zB
5f30: 75 66 5b 6a 5d 20 3d 20 30 3b 0a 20 20 7d 77 68  uf[j] = 0;.  }wh
5f40: 69 6c 65 28 20 66 69 6c 65 5f 73 69 7a 65 28 7a  ile( file_size(z
5f50: 42 75 66 29 3e 3d 30 20 29 3b 0a 0a 23 69 66 20  Buf)>=0 );..#if 
5f60: 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a  defined(_WIN32).
5f70: 20 20 66 6f 73 73 69 6c 5f 6d 62 63 73 5f 66 72    fossil_mbcs_fr
5f80: 65 65 28 28 63 68 61 72 20 2a 29 61 7a 44 69 72  ee((char *)azDir
5f90: 73 5b 31 5d 29 3b 0a 20 20 66 6f 73 73 69 6c 5f  s[1]);.  fossil_
5fa0: 6d 62 63 73 5f 66 72 65 65 28 28 63 68 61 72 20  mbcs_free((char 
5fb0: 2a 29 61 7a 44 69 72 73 5b 32 5d 29 3b 0a 23 65  *)azDirs[2]);.#e
5fc0: 6e 64 69 66 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 52  ndif.}.../*.** R
5fd0: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 61 20  eturn true if a 
5fe0: 66 69 6c 65 20 6e 61 6d 65 64 20 7a 4e 61 6d 65  file named zName
5ff0: 20 65 78 69 73 74 73 20 61 6e 64 20 68 61 73 20   exists and has 
6000: 69 64 65 6e 74 69 63 61 6c 20 63 6f 6e 74 65 6e  identical conten
6010: 74 0a 2a 2a 20 74 6f 20 74 68 65 20 62 6c 6f 62  t.** to the blob
6020: 20 70 43 6f 6e 74 65 6e 74 2e 20 20 49 66 20 7a   pContent.  If z
6030: 4e 61 6d 65 20 64 6f 65 73 20 6e 6f 74 20 65 78  Name does not ex
6040: 69 73 74 20 6f 72 20 69 66 20 74 68 65 20 63 6f  ist or if the co
6050: 6e 74 65 6e 74 20 69 73 0a 2a 2a 20 64 69 66 66  ntent is.** diff
6060: 65 72 65 6e 74 20 69 6e 20 61 6e 79 20 77 61 79  erent in any way
6070: 2c 20 74 68 65 6e 20 72 65 74 75 72 6e 20 66 61  , then return fa
6080: 6c 73 65 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65  lse..*/.int file
6090: 5f 69 73 5f 74 68 65 5f 73 61 6d 65 28 42 6c 6f  _is_the_same(Blo
60a0: 62 20 2a 70 43 6f 6e 74 65 6e 74 2c 20 63 6f 6e  b *pContent, con
60b0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b  st char *zName){
60c0: 0a 20 20 69 36 34 20 69 53 69 7a 65 3b 0a 20 20  .  i64 iSize;.  
60d0: 69 6e 74 20 72 63 3b 0a 20 20 42 6c 6f 62 20 6f  int rc;.  Blob o
60e0: 6e 44 69 73 6b 3b 0a 0a 20 20 69 53 69 7a 65 20  nDisk;..  iSize 
60f0: 3d 20 66 69 6c 65 5f 77 64 5f 73 69 7a 65 28 7a  = file_wd_size(z
6100: 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 69 53 69  Name);.  if( iSi
6110: 7a 65 3c 30 20 29 20 72 65 74 75 72 6e 20 30 3b  ze<0 ) return 0;
6120: 0a 20 20 69 66 28 20 69 53 69 7a 65 21 3d 62 6c  .  if( iSize!=bl
6130: 6f 62 5f 73 69 7a 65 28 70 43 6f 6e 74 65 6e 74  ob_size(pContent
6140: 29 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  ) ) return 0;.  
6150: 69 66 28 20 66 69 6c 65 5f 77 64 5f 69 73 6c 69  if( file_wd_isli
6160: 6e 6b 28 7a 4e 61 6d 65 29 20 29 7b 0a 20 20 20  nk(zName) ){.   
6170: 20 62 6c 6f 62 5f 72 65 61 64 5f 6c 69 6e 6b 28   blob_read_link(
6180: 26 6f 6e 44 69 73 6b 2c 20 7a 4e 61 6d 65 29 3b  &onDisk, zName);
6190: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 62 6c  .  }else{.    bl
61a0: 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c  ob_read_from_fil
61b0: 65 28 26 6f 6e 44 69 73 6b 2c 20 7a 4e 61 6d 65  e(&onDisk, zName
61c0: 29 3b 0a 20 20 7d 0a 20 20 72 63 20 3d 20 62 6c  );.  }.  rc = bl
61d0: 6f 62 5f 63 6f 6d 70 61 72 65 28 26 6f 6e 44 69  ob_compare(&onDi
61e0: 73 6b 2c 20 70 43 6f 6e 74 65 6e 74 29 3b 0a 20  sk, pContent);. 
61f0: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 6f 6e 44   blob_reset(&onD
6200: 69 73 6b 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  isk);.  return r
6210: 63 3d 3d 30 3b 0a 7d 0a 0a 0a 2f 2a 2a 2a 2a 2a  c==0;.}.../*****
6220: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6230: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6240: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6250: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6260: 2a 2a 2a 2a 2a 0a 2a 2a 20 54 68 65 20 66 6f 6c  *****.** The fol
6270: 6c 6f 77 69 6e 67 20 72 6f 75 74 69 6e 65 73 20  lowing routines 
6280: 74 72 61 6e 73 6c 61 74 65 20 62 65 74 77 65 65  translate betwee
6290: 6e 20 4d 42 43 53 20 61 6e 64 20 55 54 46 38 20  n MBCS and UTF8 
62a0: 6f 6e 20 77 69 6e 64 6f 77 73 2e 0a 2a 2a 20 53  on windows..** S
62b0: 69 6e 63 65 20 65 76 65 72 79 74 68 69 6e 67 20  ince everything 
62c0: 69 73 20 61 6c 77 61 79 73 20 55 54 46 38 20 6f  is always UTF8 o
62d0: 6e 20 75 6e 69 78 2c 20 74 68 65 73 65 20 72 6f  n unix, these ro
62e0: 75 74 69 6e 65 73 20 61 72 65 20 6e 6f 2d 6f 70  utines are no-op
62f0: 73 0a 2a 2a 20 74 68 65 72 65 2e 0a 2a 2f 0a 0a  s.** there..*/..
6300: 2f 2a 0a 2a 2a 20 54 72 61 6e 73 6c 61 74 65 20  /*.** Translate 
6310: 4d 42 43 53 20 74 6f 20 55 54 46 38 2e 20 20 52  MBCS to UTF8.  R
6320: 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20  eturn a pointer 
6330: 74 6f 20 74 68 65 20 74 72 61 6e 73 6c 61 74 65  to the translate
6340: 64 20 74 65 78 74 2e 20 20 0a 2a 2a 20 43 61 6c  d text.  .** Cal
6350: 6c 20 66 6f 73 73 69 6c 5f 6d 62 63 73 5f 66 72  l fossil_mbcs_fr
6360: 65 65 28 29 20 74 6f 20 64 65 61 6c 6c 6f 63 61  ee() to dealloca
6370: 74 65 20 61 6e 79 20 6d 65 6d 6f 72 79 20 75 73  te any memory us
6380: 65 64 20 74 6f 20 73 74 6f 72 65 20 74 68 65 0a  ed to store the.
6390: 2a 2a 20 72 65 74 75 72 6e 65 64 20 70 6f 69 6e  ** returned poin
63a0: 74 65 72 20 77 68 65 6e 20 64 6f 6e 65 2e 0a 2a  ter when done..*
63b0: 2f 0a 63 68 61 72 20 2a 66 6f 73 73 69 6c 5f 6d  /.char *fossil_m
63c0: 62 63 73 5f 74 6f 5f 75 74 66 38 28 63 6f 6e 73  bcs_to_utf8(cons
63d0: 74 20 63 68 61 72 20 2a 7a 4d 62 63 73 29 7b 0a  t char *zMbcs){.
63e0: 23 69 66 64 65 66 20 5f 57 49 4e 33 32 0a 20 20  #ifdef _WIN32.  
63f0: 65 78 74 65 72 6e 20 63 68 61 72 20 2a 73 71 6c  extern char *sql
6400: 69 74 65 34 5f 77 69 6e 33 32 5f 6d 62 63 73 5f  ite4_win32_mbcs_
6410: 74 6f 5f 75 74 66 38 28 63 6f 6e 73 74 20 63 68  to_utf8(const ch
6420: 61 72 2a 29 3b 0a 20 20 72 65 74 75 72 6e 20 73  ar*);.  return s
6430: 71 6c 69 74 65 34 5f 77 69 6e 33 32 5f 6d 62 63  qlite4_win32_mbc
6440: 73 5f 74 6f 5f 75 74 66 38 28 7a 4d 62 63 73 29  s_to_utf8(zMbcs)
6450: 3b 0a 23 65 6c 73 65 0a 20 20 72 65 74 75 72 6e  ;.#else.  return
6460: 20 28 63 68 61 72 2a 29 7a 4d 62 63 73 3b 20 20   (char*)zMbcs;  
6470: 2f 2a 20 4e 6f 2d 6f 70 20 6f 6e 20 75 6e 69 78  /* No-op on unix
6480: 20 2a 2f 0a 23 65 6e 64 69 66 20 20 0a 7d 0a 0a   */.#endif  .}..
6490: 2f 2a 0a 2a 2a 20 54 72 61 6e 73 6c 61 74 65 20  /*.** Translate 
64a0: 55 54 46 38 20 74 6f 20 4d 42 43 53 20 66 6f 72  UTF8 to MBCS for
64b0: 20 75 73 65 20 69 6e 20 73 79 73 74 65 6d 20 63   use in system c
64c0: 61 6c 6c 73 2e 20 20 52 65 74 75 72 6e 20 61 20  alls.  Return a 
64d0: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 0a 2a  pointer to the.*
64e0: 2a 20 74 72 61 6e 73 6c 61 74 65 64 20 74 65 78  * translated tex
64f0: 74 2e 2e 20 20 43 61 6c 6c 20 66 6f 73 73 69 6c  t..  Call fossil
6500: 5f 6d 62 63 73 5f 66 72 65 65 28 29 20 74 6f 20  _mbcs_free() to 
6510: 64 65 61 6c 6c 6f 63 61 74 65 20 61 6e 79 20 6d  deallocate any m
6520: 65 6d 6f 72 79 0a 2a 2a 20 75 73 65 64 20 74 6f  emory.** used to
6530: 20 73 74 6f 72 65 20 74 68 65 20 72 65 74 75 72   store the retur
6540: 6e 65 64 20 70 6f 69 6e 74 65 72 20 77 68 65 6e  ned pointer when
6550: 20 64 6f 6e 65 2e 0a 2a 2f 0a 63 68 61 72 20 2a   done..*/.char *
6560: 66 6f 73 73 69 6c 5f 75 74 66 38 5f 74 6f 5f 6d  fossil_utf8_to_m
6570: 62 63 73 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  bcs(const char *
6580: 7a 55 74 66 38 29 7b 0a 23 69 66 64 65 66 20 5f  zUtf8){.#ifdef _
6590: 57 49 4e 33 32 0a 20 20 65 78 74 65 72 6e 20 63  WIN32.  extern c
65a0: 68 61 72 20 2a 73 71 6c 69 74 65 34 5f 77 69 6e  har *sqlite4_win
65b0: 33 32 5f 75 74 66 38 5f 74 6f 5f 6d 62 63 73 28  32_utf8_to_mbcs(
65c0: 63 6f 6e 73 74 20 63 68 61 72 2a 29 3b 0a 20 20  const char*);.  
65d0: 72 65 74 75 72 6e 20 73 71 6c 69 74 65 34 5f 77  return sqlite4_w
65e0: 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f 6d 62 63  in32_utf8_to_mbc
65f0: 73 28 7a 55 74 66 38 29 3b 0a 23 65 6c 73 65 0a  s(zUtf8);.#else.
6600: 20 20 72 65 74 75 72 6e 20 28 63 68 61 72 2a 29    return (char*)
6610: 7a 55 74 66 38 3b 20 20 2f 2a 20 4e 6f 2d 6f 70  zUtf8;  /* No-op
6620: 20 6f 6e 20 75 6e 69 78 20 2a 2f 0a 23 65 6e 64   on unix */.#end
6630: 69 66 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  if  .}../*.** Re
6640: 74 75 72 6e 20 74 68 65 20 76 61 6c 75 65 20 6f  turn the value o
6650: 66 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e 74  f an environment
6660: 20 76 61 72 69 61 62 6c 65 20 61 73 20 55 54 46   variable as UTF
6670: 38 2e 0a 2a 2f 0a 63 68 61 72 20 2a 66 6f 73 73  8..*/.char *foss
6680: 69 6c 5f 67 65 74 65 6e 76 28 63 6f 6e 73 74 20  il_getenv(const 
6690: 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b 0a 20 20  char *zName){.  
66a0: 63 68 61 72 20 2a 7a 56 61 6c 75 65 20 3d 20 67  char *zValue = g
66b0: 65 74 65 6e 76 28 7a 4e 61 6d 65 29 3b 0a 23 69  etenv(zName);.#i
66c0: 66 64 65 66 20 5f 57 49 4e 33 32 0a 20 20 69 66  fdef _WIN32.  if
66d0: 28 20 7a 56 61 6c 75 65 20 29 20 7a 56 61 6c 75  ( zValue ) zValu
66e0: 65 20 3d 20 66 6f 73 73 69 6c 5f 6d 62 63 73 5f  e = fossil_mbcs_
66f0: 74 6f 5f 75 74 66 38 28 7a 56 61 6c 75 65 29 3b  to_utf8(zValue);
6700: 0a 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e  .#endif.  return
6710: 20 7a 56 61 6c 75 65 3b 0a 7d 0a 0a 2f 2a 0a 2a   zValue;.}../*.*
6720: 2a 20 54 72 61 6e 73 6c 61 74 65 20 55 54 46 38  * Translate UTF8
6730: 20 74 6f 20 4d 42 43 53 20 66 6f 72 20 64 69 73   to MBCS for dis
6740: 70 6c 61 79 20 6f 6e 20 74 68 65 20 63 6f 6e 73  play on the cons
6750: 6f 6c 65 2e 20 20 52 65 74 75 72 6e 20 61 20 70  ole.  Return a p
6760: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 0a 2a 2a  ointer to the.**
6770: 20 74 72 61 6e 73 6c 61 74 65 64 20 74 65 78 74   translated text
6780: 2e 2e 20 20 43 61 6c 6c 20 66 6f 73 73 69 6c 5f  ..  Call fossil_
6790: 6d 62 63 73 5f 66 72 65 65 28 29 20 74 6f 20 64  mbcs_free() to d
67a0: 65 61 6c 6c 6f 63 61 74 65 20 61 6e 79 20 6d 65  eallocate any me
67b0: 6d 6f 72 79 0a 2a 2a 20 75 73 65 64 20 74 6f 20  mory.** used to 
67c0: 73 74 6f 72 65 20 74 68 65 20 72 65 74 75 72 6e  store the return
67d0: 65 64 20 70 6f 69 6e 74 65 72 20 77 68 65 6e 20  ed pointer when 
67e0: 64 6f 6e 65 2e 0a 2a 2f 0a 63 68 61 72 20 2a 66  done..*/.char *f
67f0: 6f 73 73 69 6c 5f 75 74 66 38 5f 74 6f 5f 63 6f  ossil_utf8_to_co
6800: 6e 73 6f 6c 65 28 63 6f 6e 73 74 20 63 68 61 72  nsole(const char
6810: 20 2a 7a 55 74 66 38 29 7b 0a 23 69 66 64 65 66   *zUtf8){.#ifdef
6820: 20 5f 57 49 4e 33 32 0a 20 20 69 6e 74 20 6e 43   _WIN32.  int nC
6830: 68 61 72 2c 20 6e 42 79 74 65 3b 0a 20 20 57 43  har, nByte;.  WC
6840: 48 41 52 20 2a 7a 55 6e 69 63 6f 64 65 3b 20 20  HAR *zUnicode;  
6850: 20 2f 2a 20 55 6e 69 63 6f 64 65 20 76 65 72 73   /* Unicode vers
6860: 69 6f 6e 20 6f 66 20 7a 55 74 66 38 20 2a 2f 0a  ion of zUtf8 */.
6870: 20 20 63 68 61 72 20 2a 7a 43 6f 6e 73 6f 6c 65    char *zConsole
6880: 3b 20 20 20 20 2f 2a 20 43 6f 6e 73 6f 6c 65 20  ;    /* Console 
6890: 76 65 72 73 69 6f 6e 20 6f 66 20 7a 55 74 66 38  version of zUtf8
68a0: 20 2a 2f 0a 20 20 69 6e 74 20 63 6f 64 65 70 61   */.  int codepa
68b0: 67 65 3b 20 20 20 20 20 20 2f 2a 20 43 6f 6e 73  ge;      /* Cons
68c0: 6f 6c 65 20 63 6f 64 65 20 70 61 67 65 20 2a 2f  ole code page */
68d0: 0a 0a 20 20 6e 43 68 61 72 20 3d 20 4d 75 6c 74  ..  nChar = Mult
68e0: 69 42 79 74 65 54 6f 57 69 64 65 43 68 61 72 28  iByteToWideChar(
68f0: 43 50 5f 55 54 46 38 2c 20 30 2c 20 7a 55 74 66  CP_UTF8, 0, zUtf
6900: 38 2c 20 2d 31 2c 20 4e 55 4c 4c 2c 20 30 29 3b  8, -1, NULL, 0);
6910: 0a 20 20 7a 55 6e 69 63 6f 64 65 20 3d 20 6d 61  .  zUnicode = ma
6920: 6c 6c 6f 63 28 20 6e 43 68 61 72 2a 73 69 7a 65  lloc( nChar*size
6930: 6f 66 28 7a 55 6e 69 63 6f 64 65 5b 30 5d 29 20  of(zUnicode[0]) 
6940: 29 3b 0a 20 20 69 66 28 20 7a 55 6e 69 63 6f 64  );.  if( zUnicod
6950: 65 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  e==0 ){.    retu
6960: 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 6e 43 68 61  rn 0;.  }.  nCha
6970: 72 20 3d 20 4d 75 6c 74 69 42 79 74 65 54 6f 57  r = MultiByteToW
6980: 69 64 65 43 68 61 72 28 43 50 5f 55 54 46 38 2c  ideChar(CP_UTF8,
6990: 20 30 2c 20 7a 55 74 66 38 2c 20 2d 31 2c 20 7a   0, zUtf8, -1, z
69a0: 55 6e 69 63 6f 64 65 2c 20 6e 43 68 61 72 29 3b  Unicode, nChar);
69b0: 0a 20 20 69 66 28 20 6e 43 68 61 72 3d 3d 30 20  .  if( nChar==0 
69c0: 29 7b 0a 20 20 20 20 66 72 65 65 28 7a 55 6e 69  ){.    free(zUni
69d0: 63 6f 64 65 29 3b 0a 20 20 20 20 72 65 74 75 72  code);.    retur
69e0: 6e 20 30 3b 0a 20 20 7d 0a 20 20 63 6f 64 65 70  n 0;.  }.  codep
69f0: 61 67 65 20 3d 20 47 65 74 43 6f 6e 73 6f 6c 65  age = GetConsole
6a00: 43 50 28 29 3b 0a 20 20 6e 42 79 74 65 20 3d 20  CP();.  nByte = 
6a10: 57 69 64 65 43 68 61 72 54 6f 4d 75 6c 74 69 42  WideCharToMultiB
6a20: 79 74 65 28 63 6f 64 65 70 61 67 65 2c 20 30 2c  yte(codepage, 0,
6a30: 20 7a 55 6e 69 63 6f 64 65 2c 20 2d 31 2c 20 30   zUnicode, -1, 0
6a40: 2c 20 30 2c 20 30 2c 20 30 29 3b 0a 20 20 7a 43  , 0, 0, 0);.  zC
6a50: 6f 6e 73 6f 6c 65 20 3d 20 6d 61 6c 6c 6f 63 28  onsole = malloc(
6a60: 20 6e 42 79 74 65 20 29 3b 0a 20 20 69 66 28 20   nByte );.  if( 
6a70: 7a 43 6f 6e 73 6f 6c 65 3d 3d 30 20 29 7b 0a 20  zConsole==0 ){. 
6a80: 20 20 20 66 72 65 65 28 7a 55 6e 69 63 6f 64 65     free(zUnicode
6a90: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b  );.    return 0;
6aa0: 0a 20 20 7d 0a 20 20 6e 42 79 74 65 20 3d 20 57  .  }.  nByte = W
6ab0: 69 64 65 43 68 61 72 54 6f 4d 75 6c 74 69 42 79  ideCharToMultiBy
6ac0: 74 65 28 63 6f 64 65 70 61 67 65 2c 20 30 2c 20  te(codepage, 0, 
6ad0: 7a 55 6e 69 63 6f 64 65 2c 20 2d 31 2c 20 7a 43  zUnicode, -1, zC
6ae0: 6f 6e 73 6f 6c 65 2c 20 6e 42 79 74 65 2c 20 30  onsole, nByte, 0
6af0: 2c 20 30 29 3b 0a 20 20 66 72 65 65 28 7a 55 6e  , 0);.  free(zUn
6b00: 69 63 6f 64 65 29 3b 0a 20 20 69 66 28 20 6e 42  icode);.  if( nB
6b10: 79 74 65 20 3d 3d 20 30 20 29 7b 0a 20 20 20 20  yte == 0 ){.    
6b20: 66 72 65 65 28 7a 43 6f 6e 73 6f 6c 65 29 3b 0a  free(zConsole);.
6b30: 20 20 20 20 7a 43 6f 6e 73 6f 6c 65 20 3d 20 30      zConsole = 0
6b40: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 7a  ;.  }.  return z
6b50: 43 6f 6e 73 6f 6c 65 3b 0a 23 65 6c 73 65 0a 20  Console;.#else. 
6b60: 20 72 65 74 75 72 6e 20 28 63 68 61 72 2a 29 7a   return (char*)z
6b70: 55 74 66 38 3b 20 20 2f 2a 20 4e 6f 2d 6f 70 20  Utf8;  /* No-op 
6b80: 6f 6e 20 75 6e 69 78 20 2a 2f 0a 23 65 6e 64 69  on unix */.#endi
6b90: 66 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 61  f  .}../*.** Tra
6ba0: 6e 73 6c 61 74 65 20 4d 42 43 53 20 74 6f 20 55  nslate MBCS to U
6bb0: 54 46 38 2e 20 20 52 65 74 75 72 6e 20 61 20 70  TF8.  Return a p
6bc0: 6f 69 6e 74 65 72 2e 20 20 43 61 6c 6c 20 66 6f  ointer.  Call fo
6bd0: 73 73 69 6c 5f 6d 62 63 73 5f 66 72 65 65 28 29  ssil_mbcs_free()
6be0: 0a 2a 2a 20 74 6f 20 64 65 61 6c 6c 6f 63 61 74  .** to deallocat
6bf0: 65 20 61 6e 79 20 6d 65 6d 6f 72 79 20 75 73 65  e any memory use
6c00: 64 20 74 6f 20 73 74 6f 72 65 20 74 68 65 20 72  d to store the r
6c10: 65 74 75 72 6e 65 64 20 70 6f 69 6e 74 65 72 20  eturned pointer 
6c20: 77 68 65 6e 20 64 6f 6e 65 2e 0a 2a 2f 0a 76 6f  when done..*/.vo
6c30: 69 64 20 66 6f 73 73 69 6c 5f 6d 62 63 73 5f 66  id fossil_mbcs_f
6c40: 72 65 65 28 63 68 61 72 20 2a 7a 4f 6c 64 29 7b  ree(char *zOld){
6c50: 0a 23 69 66 64 65 66 20 5f 57 49 4e 33 32 0a 20  .#ifdef _WIN32. 
6c60: 20 65 78 74 65 72 6e 20 76 6f 69 64 20 73 71 6c   extern void sql
6c70: 69 74 65 34 5f 66 72 65 65 28 76 6f 69 64 2a 29  ite4_free(void*)
6c80: 3b 0a 20 20 73 71 6c 69 74 65 34 5f 66 72 65 65  ;.  sqlite4_free
6c90: 28 30 2c 20 7a 4f 6c 64 29 3b 0a 23 65 6c 73 65  (0, zOld);.#else
6ca0: 0a 20 20 2f 2a 20 4e 6f 2d 6f 70 20 6f 6e 20 75  .  /* No-op on u
6cb0: 6e 69 78 20 2a 2f 0a 23 65 6e 64 69 66 20 20 0a  nix */.#endif  .
6cc0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 69 6b 65 20 66 6f  }../*.** Like fo
6cd0: 70 65 6e 28 29 20 62 75 74 20 61 6c 77 61 79 73  pen() but always
6ce0: 20 74 61 6b 65 73 20 61 20 55 54 46 38 20 61 72   takes a UTF8 ar
6cf0: 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 46 49 4c 45 20  gument..*/.FILE 
6d00: 2a 66 6f 73 73 69 6c 5f 66 6f 70 65 6e 28 63 6f  *fossil_fopen(co
6d10: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c  nst char *zName,
6d20: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4d 6f   const char *zMo
6d30: 64 65 29 7b 0a 20 20 63 68 61 72 20 2a 7a 4d 62  de){.  char *zMb
6d40: 63 73 20 3d 20 66 6f 73 73 69 6c 5f 75 74 66 38  cs = fossil_utf8
6d50: 5f 74 6f 5f 6d 62 63 73 28 7a 4e 61 6d 65 29 3b  _to_mbcs(zName);
6d60: 0a 20 20 46 49 4c 45 20 2a 66 20 3d 20 66 6f 70  .  FILE *f = fop
6d70: 65 6e 28 7a 4d 62 63 73 2c 20 7a 4d 6f 64 65 29  en(zMbcs, zMode)
6d80: 3b 0a 20 20 66 6f 73 73 69 6c 5f 6d 62 63 73 5f  ;.  fossil_mbcs_
6d90: 66 72 65 65 28 7a 4d 62 63 73 29 3b 0a 20 20 72  free(zMbcs);.  r
6da0: 65 74 75 72 6e 20 66 3b 0a 7d 0a                 eturn f;.}.