Fossil with Commonmark

Hex Artifact Content
Login

Artifact 3889ef1e34e0ad864aa932617cb9d9d01fc56d10:


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 64 69 72  2.# include <dir
0430: 65 63 74 2e 68 3e 0a 23 20 69 6e 63 6c 75 64 65  ect.h>.# include
0440: 20 3c 77 69 6e 64 6f 77 73 2e 68 3e 0a 23 20 69   <windows.h>.# i
0450: 6e 63 6c 75 64 65 20 3c 73 79 73 2f 75 74 69 6d  nclude <sys/utim
0460: 65 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69 66 64  e.h>.#endif.#ifd
0470: 65 66 20 5f 5f 43 59 47 57 49 4e 5f 5f 0a 23 20  ef __CYGWIN__.# 
0480: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d  include <sys/tim
0490: 65 2e 68 3e 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a  e.h>.#endif../*.
04a0: 2a 2a 20 54 68 65 20 66 69 6c 65 20 73 74 61 74  ** The file stat
04b0: 75 73 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 66  us information f
04c0: 72 6f 6d 20 74 68 65 20 6d 6f 73 74 20 72 65 63  rom the most rec
04d0: 65 6e 74 20 73 74 61 74 28 29 20 63 61 6c 6c 2e  ent stat() call.
04e0: 0a 2a 2a 0a 2a 2a 20 55 73 65 20 5f 73 74 61 74  .**.** Use _stat
04f0: 69 36 34 20 72 61 74 68 65 72 20 74 68 61 6e 20  i64 rather than 
0500: 73 74 61 74 20 6f 6e 20 77 69 6e 64 6f 77 73 2c  stat on windows,
0510: 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 68 61 6e   in order to han
0520: 64 6c 65 20 66 69 6c 65 73 0a 2a 2a 20 6c 61 72  dle files.** lar
0530: 67 65 72 20 74 68 61 6e 20 32 47 42 2e 0a 2a 2f  ger than 2GB..*/
0540: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 5f 57 49  .#if defined(_WI
0550: 4e 33 32 29 20 26 26 20 28 64 65 66 69 6e 65 64  N32) && (defined
0560: 28 5f 5f 4d 53 56 43 52 54 5f 5f 29 20 7c 7c 20  (__MSVCRT__) || 
0570: 64 65 66 69 6e 65 64 28 5f 4d 53 43 5f 56 45 52  defined(_MSC_VER
0580: 29 29 0a 23 20 75 6e 64 65 66 20 73 74 61 74 0a  )).# undef stat.
0590: 23 20 64 65 66 69 6e 65 20 73 74 61 74 20 5f 73  # define stat _s
05a0: 74 61 74 69 36 34 0a 23 65 6e 64 69 66 0a 2f 2a  tati64.#endif./*
05b0: 0a 2a 2a 20 4f 6e 20 57 69 6e 64 6f 77 73 20 53  .** On Windows S
05c0: 5f 49 53 4c 4e 4b 20 61 6c 77 61 79 73 20 72 65  _ISLNK always re
05d0: 74 75 72 6e 73 20 46 41 4c 53 45 2e 0a 2a 2f 0a  turns FALSE..*/.
05e0: 23 69 66 20 21 64 65 66 69 6e 65 64 28 53 5f 49  #if !defined(S_I
05f0: 53 4c 4e 4b 29 0a 23 20 64 65 66 69 6e 65 20 53  SLNK).# define S
0600: 5f 49 53 4c 4e 4b 28 78 29 20 28 30 29 0a 23 65  _ISLNK(x) (0).#e
0610: 6e 64 69 66 0a 73 74 61 74 69 63 20 69 6e 74 20  ndif.static int 
0620: 66 69 6c 65 53 74 61 74 56 61 6c 69 64 20 3d 20  fileStatValid = 
0630: 30 3b 0a 73 74 61 74 69 63 20 73 74 72 75 63 74  0;.static struct
0640: 20 73 74 61 74 20 66 69 6c 65 53 74 61 74 3b 0a   stat fileStat;.
0650: 0a 2f 2a 0a 2a 2a 20 46 69 6c 6c 20 73 74 61 74  ./*.** Fill stat
0660: 20 62 75 66 20 77 69 74 68 20 69 6e 66 6f 72 6d   buf with inform
0670: 61 74 69 6f 6e 20 72 65 63 65 69 76 65 64 20 66  ation received f
0680: 72 6f 6d 20 73 74 61 74 28 29 20 6f 72 20 6c 73  rom stat() or ls
0690: 74 61 74 28 29 2e 0a 2a 2a 20 6c 73 74 61 74 28  tat()..** lstat(
06a0: 29 20 69 73 20 63 61 6c 6c 65 64 20 6f 6e 20 55  ) is called on U
06b0: 6e 69 78 20 69 66 20 69 73 57 64 20 69 73 20 54  nix if isWd is T
06c0: 52 55 45 20 61 6e 64 20 61 6c 6c 6f 77 2d 73 79  RUE and allow-sy
06d0: 6d 6c 69 6e 6b 73 20 73 65 74 74 69 6e 67 20 69  mlinks setting i
06e0: 73 20 6f 6e 2e 0a 2a 2a 0a 2a 2f 0a 73 74 61 74  s on..**.*/.stat
06f0: 69 63 20 69 6e 74 20 66 6f 73 73 69 6c 5f 73 74  ic int fossil_st
0700: 61 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  at(const char *z
0710: 46 69 6c 65 6e 61 6d 65 2c 20 73 74 72 75 63 74  Filename, struct
0720: 20 73 74 61 74 20 2a 62 75 66 2c 20 69 6e 74 20   stat *buf, int 
0730: 69 73 57 64 29 7b 0a 23 69 66 20 21 64 65 66 69  isWd){.#if !defi
0740: 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20 20 69 66  ned(_WIN32).  if
0750: 28 20 69 73 57 64 20 26 26 20 67 2e 61 6c 6c 6f  ( isWd && g.allo
0760: 77 53 79 6d 6c 69 6e 6b 73 20 29 7b 0a 20 20 20  wSymlinks ){.   
0770: 20 72 65 74 75 72 6e 20 6c 73 74 61 74 28 7a 46   return lstat(zF
0780: 69 6c 65 6e 61 6d 65 2c 20 62 75 66 29 3b 0a 20  ilename, buf);. 
0790: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75   }else{.    retu
07a0: 72 6e 20 73 74 61 74 28 7a 46 69 6c 65 6e 61 6d  rn stat(zFilenam
07b0: 65 2c 20 62 75 66 29 3b 0a 20 20 7d 0a 23 65 6c  e, buf);.  }.#el
07c0: 73 65 0a 20 20 69 6e 74 20 72 63 20 3d 20 30 3b  se.  int rc = 0;
07d0: 0a 20 20 77 63 68 61 72 5f 74 20 2a 7a 4d 62 63  .  wchar_t *zMbc
07e0: 73 20 3d 20 66 6f 73 73 69 6c 5f 75 74 66 38 5f  s = fossil_utf8_
07f0: 74 6f 5f 66 69 6c 65 6e 61 6d 65 28 7a 46 69 6c  to_filename(zFil
0800: 65 6e 61 6d 65 29 3b 0a 20 20 72 63 20 3d 20 5f  ename);.  rc = _
0810: 77 73 74 61 74 69 36 34 28 7a 4d 62 63 73 2c 20  wstati64(zMbcs, 
0820: 62 75 66 29 3b 0a 20 20 66 6f 73 73 69 6c 5f 66  buf);.  fossil_f
0830: 69 6c 65 6e 61 6d 65 5f 66 72 65 65 28 7a 4d 62  ilename_free(zMb
0840: 63 73 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  cs);.  return rc
0850: 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a  ;.#endif.}../*.*
0860: 2a 20 46 69 6c 6c 20 69 6e 20 74 68 65 20 66 69  * Fill in the fi
0870: 6c 65 53 74 61 74 20 76 61 72 69 61 62 6c 65 20  leStat variable 
0880: 66 6f 72 20 74 68 65 20 66 69 6c 65 20 6e 61 6d  for the file nam
0890: 65 64 20 7a 46 69 6c 65 6e 61 6d 65 2e 0a 2a 2a  ed zFilename..**
08a0: 20 49 66 20 7a 46 69 6c 65 6e 61 6d 65 3d 3d 30   If zFilename==0
08b0: 2c 20 74 68 65 6e 20 75 73 65 20 74 68 65 20 70  , then use the p
08c0: 72 65 76 69 6f 75 73 20 76 61 6c 75 65 20 6f 66  revious value of
08d0: 20 66 69 6c 65 53 74 61 74 20 69 66 0a 2a 2a 20   fileStat if.** 
08e0: 74 68 65 72 65 20 69 73 20 61 20 70 72 65 76 69  there is a previ
08f0: 6f 75 73 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a  ous value..**.**
0900: 20 49 66 20 69 73 57 64 20 69 73 20 54 52 55 45   If isWd is TRUE
0910: 2c 20 64 6f 20 6c 73 74 61 74 28 29 20 69 6e 73  , do lstat() ins
0920: 74 65 61 64 20 6f 66 20 73 74 61 74 28 29 20 69  tead of stat() i
0930: 66 20 61 6c 6c 6f 77 2d 73 79 6d 6c 69 6e 6b 73  f allow-symlinks
0940: 20 69 73 20 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 52 65   is on..**.** Re
0950: 74 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20  turn the number 
0960: 6f 66 20 65 72 72 6f 72 73 2e 20 20 4e 6f 20 65  of errors.  No e
0970: 72 72 6f 72 20 6d 65 73 73 61 67 65 73 20 61 72  rror messages ar
0980: 65 20 67 65 6e 65 72 61 74 65 64 2e 0a 2a 2f 0a  e generated..*/.
0990: 73 74 61 74 69 63 20 69 6e 74 20 67 65 74 53 74  static int getSt
09a0: 61 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  at(const char *z
09b0: 46 69 6c 65 6e 61 6d 65 2c 20 69 6e 74 20 69 73  Filename, int is
09c0: 57 64 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20  Wd){.  int rc = 
09d0: 30 3b 0a 20 20 69 66 28 20 7a 46 69 6c 65 6e 61  0;.  if( zFilena
09e0: 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28  me==0 ){.    if(
09f0: 20 66 69 6c 65 53 74 61 74 56 61 6c 69 64 3d 3d   fileStatValid==
0a00: 30 20 29 20 72 63 20 3d 20 31 3b 0a 20 20 7d 65  0 ) rc = 1;.  }e
0a10: 6c 73 65 7b 0a 20 20 20 20 69 66 28 20 66 6f 73  lse{.    if( fos
0a20: 73 69 6c 5f 73 74 61 74 28 7a 46 69 6c 65 6e 61  sil_stat(zFilena
0a30: 6d 65 2c 20 26 66 69 6c 65 53 74 61 74 2c 20 69  me, &fileStat, i
0a40: 73 57 64 29 21 3d 30 20 29 7b 0a 20 20 20 20 20  sWd)!=0 ){.     
0a50: 20 66 69 6c 65 53 74 61 74 56 61 6c 69 64 20 3d   fileStatValid =
0a60: 20 30 3b 0a 20 20 20 20 20 20 72 63 20 3d 20 31   0;.      rc = 1
0a70: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
0a80: 20 20 20 66 69 6c 65 53 74 61 74 56 61 6c 69 64     fileStatValid
0a90: 20 3d 20 31 3b 0a 20 20 20 20 20 20 72 63 20 3d   = 1;.      rc =
0aa0: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20   0;.    }.  }.  
0ab0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
0ac0: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73  .** Return the s
0ad0: 69 7a 65 20 6f 66 20 61 20 66 69 6c 65 20 69 6e  ize of a file in
0ae0: 20 62 79 74 65 73 2e 20 20 52 65 74 75 72 6e 20   bytes.  Return 
0af0: 2d 31 20 69 66 20 74 68 65 20 66 69 6c 65 20 64  -1 if the file d
0b00: 6f 65 73 20 6e 6f 74 0a 2a 2a 20 65 78 69 73 74  oes not.** exist
0b10: 2e 20 20 49 66 20 7a 46 69 6c 65 6e 61 6d 65 20  .  If zFilename 
0b20: 69 73 20 4e 55 4c 4c 2c 20 72 65 74 75 72 6e 20  is NULL, return 
0b30: 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20  the size of the 
0b40: 6d 6f 73 74 20 72 65 63 65 6e 74 6c 79 0a 2a 2a  most recently.**
0b50: 20 73 74 61 74 2d 65 64 20 66 69 6c 65 2e 0a 2a   stat-ed file..*
0b60: 2f 0a 69 36 34 20 66 69 6c 65 5f 73 69 7a 65 28  /.i64 file_size(
0b70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c  const char *zFil
0b80: 65 6e 61 6d 65 29 7b 0a 20 20 72 65 74 75 72 6e  ename){.  return
0b90: 20 67 65 74 53 74 61 74 28 7a 46 69 6c 65 6e 61   getStat(zFilena
0ba0: 6d 65 2c 20 30 29 20 3f 20 2d 31 20 3a 20 66 69  me, 0) ? -1 : fi
0bb0: 6c 65 53 74 61 74 2e 73 74 5f 73 69 7a 65 3b 0a  leStat.st_size;.
0bc0: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 61 6d 65 20 61 73  }../*.** Same as
0bd0: 20 66 69 6c 65 5f 73 69 7a 65 28 29 2c 20 62 75   file_size(), bu
0be0: 74 20 74 61 6b 65 73 20 69 6e 74 6f 20 61 63 63  t takes into acc
0bf0: 6f 75 6e 74 20 73 79 6d 6c 69 6e 6b 73 2e 0a 2a  ount symlinks..*
0c00: 2f 0a 69 36 34 20 66 69 6c 65 5f 77 64 5f 73 69  /.i64 file_wd_si
0c10: 7a 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  ze(const char *z
0c20: 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 72 65 74  Filename){.  ret
0c30: 75 72 6e 20 67 65 74 53 74 61 74 28 7a 46 69 6c  urn getStat(zFil
0c40: 65 6e 61 6d 65 2c 20 31 29 20 3f 20 2d 31 20 3a  ename, 1) ? -1 :
0c50: 20 66 69 6c 65 53 74 61 74 2e 73 74 5f 73 69 7a   fileStat.st_siz
0c60: 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  e;.}../*.** Retu
0c70: 72 6e 20 74 68 65 20 6d 6f 64 69 66 69 63 61 74  rn the modificat
0c80: 69 6f 6e 20 74 69 6d 65 20 66 6f 72 20 61 20 66  ion time for a f
0c90: 69 6c 65 2e 20 20 52 65 74 75 72 6e 20 2d 31 20  ile.  Return -1 
0ca0: 69 66 20 74 68 65 20 66 69 6c 65 0a 2a 2a 20 64  if the file.** d
0cb0: 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 2e 20 20  oes not exist.  
0cc0: 49 66 20 7a 46 69 6c 65 6e 61 6d 65 20 69 73 20  If zFilename is 
0cd0: 4e 55 4c 4c 20 72 65 74 75 72 6e 20 74 68 65 20  NULL return the 
0ce0: 73 69 7a 65 20 6f 66 20 74 68 65 20 6d 6f 73 74  size of the most
0cf0: 0a 2a 2a 20 72 65 63 65 6e 74 6c 79 20 73 74 61  .** recently sta
0d00: 74 2d 65 64 20 66 69 6c 65 2e 0a 2a 2f 0a 69 36  t-ed file..*/.i6
0d10: 34 20 66 69 6c 65 5f 6d 74 69 6d 65 28 63 6f 6e  4 file_mtime(con
0d20: 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61  st char *zFilena
0d30: 6d 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 67 65  me){.  return ge
0d40: 74 53 74 61 74 28 7a 46 69 6c 65 6e 61 6d 65 2c  tStat(zFilename,
0d50: 20 30 29 20 3f 20 2d 31 20 3a 20 66 69 6c 65 53   0) ? -1 : fileS
0d60: 74 61 74 2e 73 74 5f 6d 74 69 6d 65 3b 0a 7d 0a  tat.st_mtime;.}.
0d70: 0a 2f 2a 0a 2a 2a 20 53 61 6d 65 20 61 73 20 66  ./*.** Same as f
0d80: 69 6c 65 5f 6d 74 69 6d 65 28 29 2c 20 62 75 74  ile_mtime(), but
0d90: 20 74 61 6b 65 73 20 69 6e 74 6f 20 61 63 63 6f   takes into acco
0da0: 75 6e 74 20 73 79 6d 6c 69 6e 6b 73 2e 0a 2a 2f  unt symlinks..*/
0db0: 0a 69 36 34 20 66 69 6c 65 5f 77 64 5f 6d 74 69  .i64 file_wd_mti
0dc0: 6d 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  me(const char *z
0dd0: 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 72 65 74  Filename){.  ret
0de0: 75 72 6e 20 67 65 74 53 74 61 74 28 7a 46 69 6c  urn getStat(zFil
0df0: 65 6e 61 6d 65 2c 20 31 29 20 3f 20 2d 31 20 3a  ename, 1) ? -1 :
0e00: 20 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 74 69   fileStat.st_mti
0e10: 6d 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  me;.}../*.** Ret
0e20: 75 72 6e 20 54 52 55 45 20 69 66 20 74 68 65 20  urn TRUE if the 
0e30: 6e 61 6d 65 64 20 66 69 6c 65 20 69 73 20 61 6e  named file is an
0e40: 20 6f 72 64 69 6e 61 72 79 20 66 69 6c 65 20 6f   ordinary file o
0e50: 72 20 73 79 6d 6c 69 6e 6b 0a 2a 2a 20 61 6e 64  r symlink.** and
0e60: 20 73 79 6d 6c 69 6e 6b 73 20 61 72 65 20 61 6c   symlinks are al
0e70: 6c 6f 77 65 64 2e 0a 2a 2a 20 52 65 74 75 72 6e  lowed..** Return
0e80: 20 66 61 6c 73 65 20 66 6f 72 20 64 69 72 65 63   false for direc
0e90: 74 6f 72 69 65 73 2c 20 64 65 76 69 63 65 73 2c  tories, devices,
0ea0: 20 66 69 66 6f 73 2c 20 65 74 63 2e 0a 2a 2f 0a   fifos, etc..*/.
0eb0: 69 6e 74 20 66 69 6c 65 5f 77 64 5f 69 73 66 69  int file_wd_isfi
0ec0: 6c 65 5f 6f 72 5f 6c 69 6e 6b 28 63 6f 6e 73 74  le_or_link(const
0ed0: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
0ee0: 29 7b 0a 20 20 72 65 74 75 72 6e 20 67 65 74 53  ){.  return getS
0ef0: 74 61 74 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 31  tat(zFilename, 1
0f00: 29 20 3f 20 30 20 3a 20 53 5f 49 53 52 45 47 28  ) ? 0 : S_ISREG(
0f10: 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 6f 64 65  fileStat.st_mode
0f20: 29 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20  ) ||.           
0f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0f40: 20 20 20 20 20 20 20 20 20 20 53 5f 49 53 4c 4e            S_ISLN
0f50: 4b 28 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 6f  K(fileStat.st_mo
0f60: 64 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  de);.}../*.** Re
0f70: 74 75 72 6e 20 54 52 55 45 20 69 66 20 74 68 65  turn TRUE if the
0f80: 20 6e 61 6d 65 64 20 66 69 6c 65 20 69 73 20 61   named file is a
0f90: 6e 20 6f 72 64 69 6e 61 72 79 20 66 69 6c 65 2e  n ordinary file.
0fa0: 20 20 52 65 74 75 72 6e 20 66 61 6c 73 65 0a 2a    Return false.*
0fb0: 2a 20 66 6f 72 20 64 69 72 65 63 74 6f 72 69 65  * for directorie
0fc0: 73 2c 20 64 65 76 69 63 65 73 2c 20 66 69 66 6f  s, devices, fifo
0fd0: 73 2c 20 73 79 6d 6c 69 6e 6b 73 2c 20 65 74 63  s, symlinks, etc
0fe0: 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 69 73  ..*/.int file_is
0ff0: 66 69 6c 65 28 63 6f 6e 73 74 20 63 68 61 72 20  file(const char 
1000: 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 72  *zFilename){.  r
1010: 65 74 75 72 6e 20 67 65 74 53 74 61 74 28 7a 46  eturn getStat(zF
1020: 69 6c 65 6e 61 6d 65 2c 20 30 29 20 3f 20 30 20  ilename, 0) ? 0 
1030: 3a 20 53 5f 49 53 52 45 47 28 66 69 6c 65 53 74  : S_ISREG(fileSt
1040: 61 74 2e 73 74 5f 6d 6f 64 65 29 3b 0a 7d 0a 0a  at.st_mode);.}..
1050: 2f 2a 0a 2a 2a 20 53 61 6d 65 20 61 73 20 66 69  /*.** Same as fi
1060: 6c 65 5f 69 73 66 69 6c 65 28 29 2c 20 62 75 74  le_isfile(), but
1070: 20 74 61 6b 65 73 20 69 6e 74 6f 20 61 63 63 6f   takes into acco
1080: 75 6e 74 20 73 79 6d 6c 69 6e 6b 73 2e 0a 2a 2f  unt symlinks..*/
1090: 0a 69 6e 74 20 66 69 6c 65 5f 77 64 5f 69 73 66  .int file_wd_isf
10a0: 69 6c 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ile(const char *
10b0: 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 72 65  zFilename){.  re
10c0: 74 75 72 6e 20 67 65 74 53 74 61 74 28 7a 46 69  turn getStat(zFi
10d0: 6c 65 6e 61 6d 65 2c 20 31 29 20 3f 20 30 20 3a  lename, 1) ? 0 :
10e0: 20 53 5f 49 53 52 45 47 28 66 69 6c 65 53 74 61   S_ISREG(fileSta
10f0: 74 2e 73 74 5f 6d 6f 64 65 29 3b 0a 7d 0a 0a 2f  t.st_mode);.}../
1100: 2a 0a 2a 2a 20 43 72 65 61 74 65 20 73 79 6d 6c  *.** Create syml
1110: 69 6e 6b 20 74 6f 20 66 69 6c 65 20 6f 6e 20 55  ink to file on U
1120: 6e 69 78 2c 20 6f 72 20 70 6c 61 69 6e 2d 74 65  nix, or plain-te
1130: 78 74 20 66 69 6c 65 20 77 69 74 68 0a 2a 2a 20  xt file with.** 
1140: 73 79 6d 6c 69 6e 6b 20 74 61 72 67 65 74 20 69  symlink target i
1150: 66 20 22 61 6c 6c 6f 77 2d 73 79 6d 6c 69 6e 6b  f "allow-symlink
1160: 73 22 20 69 73 20 6f 66 66 20 6f 72 20 77 65 27  s" is off or we'
1170: 72 65 20 6f 6e 20 57 69 6e 64 6f 77 73 2e 0a 2a  re on Windows..*
1180: 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 73 3a 20  *.** Arguments: 
1190: 74 61 72 67 65 74 20 66 69 6c 65 20 28 73 79 6d  target file (sym
11a0: 6c 69 6e 6b 20 77 69 6c 6c 20 70 6f 69 6e 74 20  link will point 
11b0: 74 6f 20 69 74 29 2c 20 6c 69 6e 6b 20 66 69 6c  to it), link fil
11c0: 65 0a 2a 2a 2f 0a 76 6f 69 64 20 73 79 6d 6c 69  e.**/.void symli
11d0: 6e 6b 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20  nk_create(const 
11e0: 63 68 61 72 20 2a 7a 54 61 72 67 65 74 46 69 6c  char *zTargetFil
11f0: 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  e, const char *z
1200: 4c 69 6e 6b 46 69 6c 65 29 7b 0a 23 69 66 20 21  LinkFile){.#if !
1210: 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a  defined(_WIN32).
1220: 20 20 69 66 28 20 67 2e 61 6c 6c 6f 77 53 79 6d    if( g.allowSym
1230: 6c 69 6e 6b 73 20 29 7b 0a 20 20 20 20 69 6e 74  links ){.    int
1240: 20 69 2c 20 6e 4e 61 6d 65 3b 0a 20 20 20 20 63   i, nName;.    c
1250: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 7a 42 75 66  har *zName, zBuf
1260: 5b 31 30 30 30 5d 3b 0a 0a 20 20 20 20 6e 4e 61  [1000];..    nNa
1270: 6d 65 20 3d 20 73 74 72 6c 65 6e 28 7a 4c 69 6e  me = strlen(zLin
1280: 6b 46 69 6c 65 29 3b 0a 20 20 20 20 69 66 28 20  kFile);.    if( 
1290: 6e 4e 61 6d 65 3e 3d 73 69 7a 65 6f 66 28 7a 42  nName>=sizeof(zB
12a0: 75 66 29 20 29 7b 0a 20 20 20 20 20 20 7a 4e 61  uf) ){.      zNa
12b0: 6d 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73  me = mprintf("%s
12c0: 22 2c 20 7a 4c 69 6e 6b 46 69 6c 65 29 3b 0a 20  ", zLinkFile);. 
12d0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
12e0: 7a 4e 61 6d 65 20 3d 20 7a 42 75 66 3b 0a 20 20  zName = zBuf;.  
12f0: 20 20 20 20 6d 65 6d 63 70 79 28 7a 4e 61 6d 65      memcpy(zName
1300: 2c 20 7a 4c 69 6e 6b 46 69 6c 65 2c 20 6e 4e 61  , zLinkFile, nNa
1310: 6d 65 2b 31 29 3b 0a 20 20 20 20 7d 0a 20 20 20  me+1);.    }.   
1320: 20 6e 4e 61 6d 65 20 3d 20 66 69 6c 65 5f 73 69   nName = file_si
1330: 6d 70 6c 69 66 79 5f 6e 61 6d 65 28 7a 4e 61 6d  mplify_name(zNam
1340: 65 2c 20 6e 4e 61 6d 65 2c 20 30 29 3b 0a 20 20  e, nName, 0);.  
1350: 20 20 66 6f 72 28 69 3d 31 3b 20 69 3c 6e 4e 61    for(i=1; i<nNa
1360: 6d 65 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  me; i++){.      
1370: 69 66 28 20 7a 4e 61 6d 65 5b 69 5d 3d 3d 27 2f  if( zName[i]=='/
1380: 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 4e 61  ' ){.        zNa
1390: 6d 65 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20  me[i] = 0;.     
13a0: 20 20 20 20 20 69 66 28 20 66 69 6c 65 5f 6d 6b       if( file_mk
13b0: 64 69 72 28 7a 4e 61 6d 65 2c 20 31 29 20 29 7b  dir(zName, 1) ){
13c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 66 6f 73  .            fos
13d0: 73 69 6c 5f 66 61 74 61 6c 5f 72 65 63 75 72 73  sil_fatal_recurs
13e0: 69 76 65 28 22 75 6e 61 62 6c 65 20 74 6f 20 63  ive("unable to c
13f0: 72 65 61 74 65 20 64 69 72 65 63 74 6f 72 79 20  reate directory 
1400: 25 73 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20  %s", zName);.   
1410: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b           return;
1420: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
1430: 20 20 20 20 20 7a 4e 61 6d 65 5b 69 5d 20 3d 20       zName[i] = 
1440: 27 2f 27 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  '/';.      }.   
1450: 20 7d 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65   }.    if( zName
1460: 21 3d 7a 42 75 66 20 29 20 66 72 65 65 28 7a 4e  !=zBuf ) free(zN
1470: 61 6d 65 29 3b 0a 0a 20 20 20 20 69 66 28 20 73  ame);..    if( s
1480: 79 6d 6c 69 6e 6b 28 7a 54 61 72 67 65 74 46 69  ymlink(zTargetFi
1490: 6c 65 2c 20 7a 4e 61 6d 65 29 21 3d 30 20 29 7b  le, zName)!=0 ){
14a0: 0a 20 20 20 20 20 20 66 6f 73 73 69 6c 5f 66 61  .      fossil_fa
14b0: 74 61 6c 5f 72 65 63 75 72 73 69 76 65 28 22 75  tal_recursive("u
14c0: 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20  nable to create 
14d0: 73 79 6d 6c 69 6e 6b 20 5c 22 25 73 5c 22 22 2c  symlink \"%s\"",
14e0: 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 7d 0a 20   zName);.    }. 
14f0: 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20   }else.#endif.  
1500: 7b 0a 20 20 20 20 42 6c 6f 62 20 63 6f 6e 74 65  {.    Blob conte
1510: 6e 74 3b 0a 20 20 20 20 62 6c 6f 62 5f 73 65 74  nt;.    blob_set
1520: 28 26 63 6f 6e 74 65 6e 74 2c 20 7a 54 61 72 67  (&content, zTarg
1530: 65 74 46 69 6c 65 29 3b 0a 20 20 20 20 62 6c 6f  etFile);.    blo
1540: 62 5f 77 72 69 74 65 5f 74 6f 5f 66 69 6c 65 28  b_write_to_file(
1550: 26 63 6f 6e 74 65 6e 74 2c 20 7a 4c 69 6e 6b 46  &content, zLinkF
1560: 69 6c 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72  ile);.    blob_r
1570: 65 73 65 74 28 26 63 6f 6e 74 65 6e 74 29 3b 0a  eset(&content);.
1580: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70    }.}../*.** Cop
1590: 79 20 73 79 6d 62 6f 6c 69 63 20 6c 69 6e 6b 20  y symbolic link 
15a0: 66 72 6f 6d 20 7a 46 72 6f 6d 20 74 6f 20 7a 54  from zFrom to zT
15b0: 6f 2e 0a 2a 2f 0a 76 6f 69 64 20 73 79 6d 6c 69  o..*/.void symli
15c0: 6e 6b 5f 63 6f 70 79 28 63 6f 6e 73 74 20 63 68  nk_copy(const ch
15d0: 61 72 20 2a 7a 46 72 6f 6d 2c 20 63 6f 6e 73 74  ar *zFrom, const
15e0: 20 63 68 61 72 20 2a 7a 54 6f 29 7b 0a 20 20 42   char *zTo){.  B
15f0: 6c 6f 62 20 63 6f 6e 74 65 6e 74 3b 0a 20 20 62  lob content;.  b
1600: 6c 6f 62 5f 72 65 61 64 5f 6c 69 6e 6b 28 26 63  lob_read_link(&c
1610: 6f 6e 74 65 6e 74 2c 20 7a 46 72 6f 6d 29 3b 0a  ontent, zFrom);.
1620: 20 20 73 79 6d 6c 69 6e 6b 5f 63 72 65 61 74 65    symlink_create
1630: 28 62 6c 6f 62 5f 73 74 72 28 26 63 6f 6e 74 65  (blob_str(&conte
1640: 6e 74 29 2c 20 7a 54 6f 29 3b 0a 20 20 62 6c 6f  nt), zTo);.  blo
1650: 62 5f 72 65 73 65 74 28 26 63 6f 6e 74 65 6e 74  b_reset(&content
1660: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  );.}../*.** Retu
1670: 72 6e 20 66 69 6c 65 20 70 65 72 6d 69 73 73 69  rn file permissi
1680: 6f 6e 73 20 28 6e 6f 72 6d 61 6c 2c 20 65 78 65  ons (normal, exe
1690: 63 75 74 61 62 6c 65 2c 20 6f 72 20 73 79 6d 6c  cutable, or syml
16a0: 69 6e 6b 29 3a 0a 2a 2a 20 20 20 2d 20 50 45 52  ink):.**   - PER
16b0: 4d 5f 45 58 45 20 69 66 20 66 69 6c 65 20 69 73  M_EXE if file is
16c0: 20 65 78 65 63 75 74 61 62 6c 65 3b 0a 2a 2a 20   executable;.** 
16d0: 20 20 2d 20 50 45 52 4d 5f 4c 4e 4b 20 6f 6e 20    - PERM_LNK on 
16e0: 55 6e 69 78 20 69 66 20 66 69 6c 65 20 69 73 20  Unix if file is 
16f0: 73 79 6d 6c 69 6e 6b 20 61 6e 64 20 61 6c 6c 6f  symlink and allo
1700: 77 2d 73 79 6d 6c 69 6e 6b 73 20 6f 70 74 69 6f  w-symlinks optio
1710: 6e 20 69 73 20 6f 6e 3b 0a 2a 2a 20 20 20 2d 20  n is on;.**   - 
1720: 50 45 52 4d 5f 52 45 47 20 66 6f 72 20 61 6c 6c  PERM_REG for all
1730: 20 6f 74 68 65 72 20 63 61 73 65 73 20 28 72 65   other cases (re
1740: 67 75 6c 61 72 20 66 69 6c 65 2c 20 64 69 72 65  gular file, dire
1750: 63 74 6f 72 79 2c 20 66 69 66 6f 2c 20 65 74 63  ctory, fifo, etc
1760: 29 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 77  )..*/.int file_w
1770: 64 5f 70 65 72 6d 28 63 6f 6e 73 74 20 63 68 61  d_perm(const cha
1780: 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20  r *zFilename){. 
1790: 20 69 66 28 20 67 65 74 53 74 61 74 28 7a 46 69   if( getStat(zFi
17a0: 6c 65 6e 61 6d 65 2c 20 31 29 20 29 20 72 65 74  lename, 1) ) ret
17b0: 75 72 6e 20 50 45 52 4d 5f 52 45 47 3b 0a 23 69  urn PERM_REG;.#i
17c0: 66 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32  f defined(_WIN32
17d0: 29 0a 23 20 20 69 66 6e 64 65 66 20 53 5f 49 58  ).#  ifndef S_IX
17e0: 55 53 52 0a 23 20 20 20 20 64 65 66 69 6e 65 20  USR.#    define 
17f0: 53 5f 49 58 55 53 52 20 20 5f 53 5f 49 45 58 45  S_IXUSR  _S_IEXE
1800: 43 0a 23 20 20 65 6e 64 69 66 0a 20 20 69 66 28  C.#  endif.  if(
1810: 20 53 5f 49 53 52 45 47 28 66 69 6c 65 53 74 61   S_ISREG(fileSta
1820: 74 2e 73 74 5f 6d 6f 64 65 29 20 26 26 20 28 28  t.st_mode) && ((
1830: 53 5f 49 58 55 53 52 29 26 66 69 6c 65 53 74 61  S_IXUSR)&fileSta
1840: 74 2e 73 74 5f 6d 6f 64 65 29 21 3d 30 20 29 0a  t.st_mode)!=0 ).
1850: 20 20 20 20 72 65 74 75 72 6e 20 50 45 52 4d 5f      return PERM_
1860: 45 58 45 3b 0a 20 20 65 6c 73 65 0a 20 20 20 20  EXE;.  else.    
1870: 72 65 74 75 72 6e 20 50 45 52 4d 5f 52 45 47 3b  return PERM_REG;
1880: 0a 23 65 6c 73 65 0a 20 20 69 66 28 20 53 5f 49  .#else.  if( S_I
1890: 53 52 45 47 28 66 69 6c 65 53 74 61 74 2e 73 74  SREG(fileStat.st
18a0: 5f 6d 6f 64 65 29 20 26 26 0a 20 20 20 20 20 20  _mode) &&.      
18b0: 28 28 53 5f 49 58 55 53 52 7c 53 5f 49 58 47 52  ((S_IXUSR|S_IXGR
18c0: 50 7c 53 5f 49 58 4f 54 48 29 26 66 69 6c 65 53  P|S_IXOTH)&fileS
18d0: 74 61 74 2e 73 74 5f 6d 6f 64 65 29 21 3d 30 20  tat.st_mode)!=0 
18e0: 29 0a 20 20 20 20 72 65 74 75 72 6e 20 50 45 52  ).    return PER
18f0: 4d 5f 45 58 45 3b 0a 20 20 65 6c 73 65 20 69 66  M_EXE;.  else if
1900: 28 20 67 2e 61 6c 6c 6f 77 53 79 6d 6c 69 6e 6b  ( g.allowSymlink
1910: 73 20 26 26 20 53 5f 49 53 4c 4e 4b 28 66 69 6c  s && S_ISLNK(fil
1920: 65 53 74 61 74 2e 73 74 5f 6d 6f 64 65 29 20 29  eStat.st_mode) )
1930: 0a 20 20 20 20 72 65 74 75 72 6e 20 50 45 52 4d  .    return PERM
1940: 5f 4c 4e 4b 3b 0a 20 20 65 6c 73 65 0a 20 20 20  _LNK;.  else.   
1950: 20 72 65 74 75 72 6e 20 50 45 52 4d 5f 52 45 47   return PERM_REG
1960: 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a  ;.#endif.}../*.*
1970: 2a 20 52 65 74 75 72 6e 20 54 52 55 45 20 69 66  * Return TRUE if
1980: 20 74 68 65 20 6e 61 6d 65 64 20 66 69 6c 65 20   the named file 
1990: 69 73 20 61 6e 20 65 78 65 63 75 74 61 62 6c 65  is an executable
19a0: 2e 20 20 52 65 74 75 72 6e 20 66 61 6c 73 65 0a  .  Return false.
19b0: 2a 2a 20 66 6f 72 20 64 69 72 65 63 74 6f 72 69  ** for directori
19c0: 65 73 2c 20 64 65 76 69 63 65 73 2c 20 66 69 66  es, devices, fif
19d0: 6f 73 2c 20 73 79 6d 6c 69 6e 6b 73 2c 20 65 74  os, symlinks, et
19e0: 63 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 77  c..*/.int file_w
19f0: 64 5f 69 73 65 78 65 28 63 6f 6e 73 74 20 63 68  d_isexe(const ch
1a00: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a  ar *zFilename){.
1a10: 20 20 72 65 74 75 72 6e 20 66 69 6c 65 5f 77 64    return file_wd
1a20: 5f 70 65 72 6d 28 7a 46 69 6c 65 6e 61 6d 65 29  _perm(zFilename)
1a30: 3d 3d 50 45 52 4d 5f 45 58 45 3b 0a 7d 0a 0a 2f  ==PERM_EXE;.}../
1a40: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 54 52 55 45  *.** Return TRUE
1a50: 20 69 66 20 74 68 65 20 6e 61 6d 65 64 20 66 69   if the named fi
1a60: 6c 65 20 69 73 20 61 20 73 79 6d 6c 69 6e 6b 20  le is a symlink 
1a70: 61 6e 64 20 73 79 6d 6c 69 6e 6b 73 20 61 72 65  and symlinks are
1a80: 20 61 6c 6c 6f 77 65 64 2e 0a 2a 2a 20 52 65 74   allowed..** Ret
1a90: 75 72 6e 20 66 61 6c 73 65 20 66 6f 72 20 61 6c  urn false for al
1aa0: 6c 20 6f 74 68 65 72 20 63 61 73 65 73 2e 0a 2a  l other cases..*
1ab0: 2a 0a 2a 2a 20 4f 6e 20 57 69 6e 64 6f 77 73 2c  *.** On Windows,
1ac0: 20 61 6c 77 61 79 73 20 72 65 74 75 72 6e 20 46   always return F
1ad0: 61 6c 73 65 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c  alse..*/.int fil
1ae0: 65 5f 77 64 5f 69 73 6c 69 6e 6b 28 63 6f 6e 73  e_wd_islink(cons
1af0: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d  t char *zFilenam
1b00: 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 66 69 6c  e){.  return fil
1b10: 65 5f 77 64 5f 70 65 72 6d 28 7a 46 69 6c 65 6e  e_wd_perm(zFilen
1b20: 61 6d 65 29 3d 3d 50 45 52 4d 5f 4c 4e 4b 3b 0a  ame)==PERM_LNK;.
1b30: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
1b40: 31 20 69 66 20 7a 46 69 6c 65 6e 61 6d 65 20 69  1 if zFilename i
1b50: 73 20 61 20 64 69 72 65 63 74 6f 72 79 2e 20 20  s a directory.  
1b60: 52 65 74 75 72 6e 20 30 20 69 66 20 7a 46 69 6c  Return 0 if zFil
1b70: 65 6e 61 6d 65 0a 2a 2a 20 64 6f 65 73 20 6e 6f  ename.** does no
1b80: 74 20 65 78 69 73 74 2e 20 20 52 65 74 75 72 6e  t exist.  Return
1b90: 20 32 20 69 66 20 7a 46 69 6c 65 6e 61 6d 65 20   2 if zFilename 
1ba0: 65 78 69 73 74 73 20 62 75 74 20 69 73 20 73 6f  exists but is so
1bb0: 6d 65 74 68 69 6e 67 0a 2a 2a 20 6f 74 68 65 72  mething.** other
1bc0: 20 74 68 61 6e 20 61 20 64 69 72 65 63 74 6f 72   than a director
1bd0: 79 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 69  y..*/.int file_i
1be0: 73 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20  sdir(const char 
1bf0: 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 69  *zFilename){.  i
1c00: 6e 74 20 72 63 3b 0a 0a 20 20 69 66 28 20 7a 46  nt rc;..  if( zF
1c10: 69 6c 65 6e 61 6d 65 20 29 7b 0a 20 20 20 20 63  ilename ){.    c
1c20: 68 61 72 20 2a 7a 46 4e 20 3d 20 6d 70 72 69 6e  har *zFN = mprin
1c30: 74 66 28 22 25 73 22 2c 20 7a 46 69 6c 65 6e 61  tf("%s", zFilena
1c40: 6d 65 29 3b 0a 20 20 20 20 66 69 6c 65 5f 73 69  me);.    file_si
1c50: 6d 70 6c 69 66 79 5f 6e 61 6d 65 28 7a 46 4e 2c  mplify_name(zFN,
1c60: 20 2d 31 2c 20 30 29 3b 0a 20 20 20 20 72 63 20   -1, 0);.    rc 
1c70: 3d 20 67 65 74 53 74 61 74 28 7a 46 4e 2c 20 30  = getStat(zFN, 0
1c80: 29 3b 0a 20 20 20 20 66 72 65 65 28 7a 46 4e 29  );.    free(zFN)
1c90: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72  ;.  }else{.    r
1ca0: 63 20 3d 20 67 65 74 53 74 61 74 28 30 2c 20 30  c = getStat(0, 0
1cb0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
1cc0: 72 63 20 3f 20 30 20 3a 20 28 53 5f 49 53 44 49  rc ? 0 : (S_ISDI
1cd0: 52 28 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 6f  R(fileStat.st_mo
1ce0: 64 65 29 20 3f 20 31 20 3a 20 32 29 3b 0a 7d 0a  de) ? 1 : 2);.}.
1cf0: 0a 2f 2a 0a 2a 2a 20 53 61 6d 65 20 61 73 20 66  ./*.** Same as f
1d00: 69 6c 65 5f 69 73 64 69 72 28 29 2c 20 62 75 74  ile_isdir(), but
1d10: 20 74 61 6b 65 73 20 69 6e 74 6f 20 61 63 63 6f   takes into acco
1d20: 75 6e 74 20 73 79 6d 6c 69 6e 6b 73 2e 0a 2a 2f  unt symlinks..*/
1d30: 0a 69 6e 74 20 66 69 6c 65 5f 77 64 5f 69 73 64  .int file_wd_isd
1d40: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  ir(const char *z
1d50: 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 69 6e 74  Filename){.  int
1d60: 20 72 63 3b 0a 0a 20 20 69 66 28 20 7a 46 69 6c   rc;..  if( zFil
1d70: 65 6e 61 6d 65 20 29 7b 0a 20 20 20 20 63 68 61  ename ){.    cha
1d80: 72 20 2a 7a 46 4e 20 3d 20 6d 70 72 69 6e 74 66  r *zFN = mprintf
1d90: 28 22 25 73 22 2c 20 7a 46 69 6c 65 6e 61 6d 65  ("%s", zFilename
1da0: 29 3b 0a 20 20 20 20 66 69 6c 65 5f 73 69 6d 70  );.    file_simp
1db0: 6c 69 66 79 5f 6e 61 6d 65 28 7a 46 4e 2c 20 2d  lify_name(zFN, -
1dc0: 31 2c 20 30 29 3b 0a 20 20 20 20 72 63 20 3d 20  1, 0);.    rc = 
1dd0: 67 65 74 53 74 61 74 28 7a 46 4e 2c 20 31 29 3b  getStat(zFN, 1);
1de0: 0a 20 20 20 20 66 72 65 65 28 7a 46 4e 29 3b 0a  .    free(zFN);.
1df0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 63 20    }else{.    rc 
1e00: 3d 20 67 65 74 53 74 61 74 28 30 2c 20 31 29 3b  = getStat(0, 1);
1e10: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
1e20: 20 3f 20 30 20 3a 20 28 53 5f 49 53 44 49 52 28   ? 0 : (S_ISDIR(
1e30: 66 69 6c 65 53 74 61 74 2e 73 74 5f 6d 6f 64 65  fileStat.st_mode
1e40: 29 20 3f 20 31 20 3a 20 32 29 3b 0a 7d 0a 0a 0a  ) ? 1 : 2);.}...
1e50: 2f 2a 0a 2a 2a 20 57 72 61 70 70 65 72 20 61 72  /*.** Wrapper ar
1e60: 6f 75 6e 64 20 74 68 65 20 61 63 63 65 73 73 28  ound the access(
1e70: 29 20 73 79 73 74 65 6d 20 63 61 6c 6c 2e 0a 2a  ) system call..*
1e80: 2f 0a 69 6e 74 20 66 69 6c 65 5f 61 63 63 65 73  /.int file_acces
1e90: 73 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46  s(const char *zF
1ea0: 69 6c 65 6e 61 6d 65 2c 20 69 6e 74 20 66 6c 61  ilename, int fla
1eb0: 67 73 29 7b 0a 23 69 66 64 65 66 20 5f 57 49 4e  gs){.#ifdef _WIN
1ec0: 33 32 0a 20 20 77 63 68 61 72 5f 74 20 2a 7a 4d  32.  wchar_t *zM
1ed0: 62 63 73 20 3d 20 66 6f 73 73 69 6c 5f 75 74 66  bcs = fossil_utf
1ee0: 38 5f 74 6f 5f 66 69 6c 65 6e 61 6d 65 28 7a 46  8_to_filename(zF
1ef0: 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 69 6e 74 20  ilename);.  int 
1f00: 72 63 20 3d 20 5f 77 61 63 63 65 73 73 28 7a 4d  rc = _waccess(zM
1f10: 62 63 73 2c 20 66 6c 61 67 73 29 3b 0a 20 20 66  bcs, flags);.  f
1f20: 6f 73 73 69 6c 5f 66 69 6c 65 6e 61 6d 65 5f 66  ossil_filename_f
1f30: 72 65 65 28 7a 4d 62 63 73 29 3b 0a 23 65 6c 73  ree(zMbcs);.#els
1f40: 65 0a 20 20 69 6e 74 20 72 63 20 3d 20 61 63 63  e.  int rc = acc
1f50: 65 73 73 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 66  ess(zFilename, f
1f60: 6c 61 67 73 29 3b 0a 23 65 6e 64 69 66 0a 20 20  lags);.#endif.  
1f70: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
1f80: 0a 2a 2a 20 46 69 6e 64 20 61 6e 20 75 6e 75 73  .** Find an unus
1f90: 65 64 20 66 69 6c 65 6e 61 6d 65 20 73 69 6d 69  ed filename simi
1fa0: 6c 61 72 20 74 6f 20 7a 42 61 73 65 20 77 69 74  lar to zBase wit
1fb0: 68 20 7a 53 75 66 66 69 78 20 61 70 70 65 6e 64  h zSuffix append
1fc0: 65 64 2e 0a 2a 2a 0a 2a 2a 20 4d 61 6b 65 20 74  ed..**.** Make t
1fd0: 68 65 20 6e 61 6d 65 20 72 65 6c 61 74 69 76 65  he name relative
1fe0: 20 74 6f 20 74 68 65 20 77 6f 72 6b 69 6e 67 20   to the working 
1ff0: 64 69 72 65 63 74 6f 72 79 20 69 66 20 72 65 6c  directory if rel
2000: 46 6c 61 67 20 69 73 20 74 72 75 65 2e 0a 2a 2a  Flag is true..**
2010: 0a 2a 2a 20 53 70 61 63 65 20 74 6f 20 68 6f 6c  .** Space to hol
2020: 64 20 74 68 65 20 6e 65 77 20 66 69 6c 65 6e 61  d the new filena
2030: 6d 65 20 69 73 20 6f 62 74 61 69 6e 65 64 20 66  me is obtained f
2040: 6f 72 6d 20 6d 70 72 69 6e 74 66 28 29 20 61 6e  orm mprintf() an
2050: 64 20 73 68 6f 75 6c 64 0a 2a 2a 20 62 65 20 66  d should.** be f
2060: 72 65 65 64 20 62 79 20 74 68 65 20 63 61 6c 6c  reed by the call
2070: 65 72 2e 0a 2a 2f 0a 63 68 61 72 20 2a 66 69 6c  er..*/.char *fil
2080: 65 5f 6e 65 77 6e 61 6d 65 28 63 6f 6e 73 74 20  e_newname(const 
2090: 63 68 61 72 20 2a 7a 42 61 73 65 2c 20 63 6f 6e  char *zBase, con
20a0: 73 74 20 63 68 61 72 20 2a 7a 53 75 66 66 69 78  st char *zSuffix
20b0: 2c 20 69 6e 74 20 72 65 6c 46 6c 61 67 29 7b 0a  , int relFlag){.
20c0: 20 20 63 68 61 72 20 2a 7a 20 3d 20 30 3b 0a 20    char *z = 0;. 
20d0: 20 69 6e 74 20 63 6e 74 20 3d 20 30 3b 0a 20 20   int cnt = 0;.  
20e0: 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 2d  z = mprintf("%s-
20f0: 25 73 22 2c 20 7a 42 61 73 65 2c 20 7a 53 75 66  %s", zBase, zSuf
2100: 66 69 78 29 3b 0a 20 20 77 68 69 6c 65 28 20 66  fix);.  while( f
2110: 69 6c 65 5f 73 69 7a 65 28 7a 29 3e 3d 30 20 29  ile_size(z)>=0 )
2120: 7b 0a 20 20 20 20 66 6f 73 73 69 6c 5f 66 72 65  {.    fossil_fre
2130: 65 28 7a 29 3b 0a 20 20 20 20 7a 20 3d 20 6d 70  e(z);.    z = mp
2140: 72 69 6e 74 66 28 22 25 73 2d 25 73 2d 25 64 22  rintf("%s-%s-%d"
2150: 2c 20 7a 42 61 73 65 2c 20 7a 53 75 66 66 69 78  , zBase, zSuffix
2160: 2c 20 63 6e 74 2b 2b 29 3b 0a 20 20 7d 0a 20 20  , cnt++);.  }.  
2170: 69 66 28 20 72 65 6c 46 6c 61 67 20 29 7b 0a 20  if( relFlag ){. 
2180: 20 20 20 42 6c 6f 62 20 78 3b 0a 20 20 20 20 66     Blob x;.    f
2190: 69 6c 65 5f 72 65 6c 61 74 69 76 65 5f 6e 61 6d  ile_relative_nam
21a0: 65 28 7a 2c 20 26 78 2c 20 30 29 3b 0a 20 20 20  e(z, &x, 0);.   
21b0: 20 66 6f 73 73 69 6c 5f 66 72 65 65 28 7a 29 3b   fossil_free(z);
21c0: 0a 20 20 20 20 7a 20 3d 20 62 6c 6f 62 5f 73 74  .    z = blob_st
21d0: 72 28 26 78 29 3b 0a 20 20 7d 0a 20 20 72 65 74  r(&x);.  }.  ret
21e0: 75 72 6e 20 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn z;.}../*.** 
21f0: 52 65 74 75 72 6e 20 74 68 65 20 74 61 69 6c 20  Return the tail 
2200: 6f 66 20 61 20 66 69 6c 65 20 70 61 74 68 6e 61  of a file pathna
2210: 6d 65 2e 20 20 54 68 65 20 74 61 69 6c 20 69 73  me.  The tail is
2220: 20 74 68 65 20 6c 61 73 74 20 63 6f 6d 70 6f 6e   the last compon
2230: 65 6e 74 0a 2a 2a 20 6f 66 20 74 68 65 20 70 61  ent.** of the pa
2240: 74 68 2e 20 20 46 6f 72 20 65 78 61 6d 70 6c 65  th.  For example
2250: 2c 20 74 68 65 20 74 61 69 6c 20 6f 66 20 22 2f  , the tail of "/
2260: 61 2f 62 2f 63 2e 64 22 20 69 73 20 22 63 2e 64  a/b/c.d" is "c.d
2270: 22 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72  "..*/.const char
2280: 20 2a 66 69 6c 65 5f 74 61 69 6c 28 63 6f 6e 73   *file_tail(cons
2290: 74 20 63 68 61 72 20 2a 7a 29 7b 0a 20 20 63 6f  t char *z){.  co
22a0: 6e 73 74 20 63 68 61 72 20 2a 7a 54 61 69 6c 20  nst char *zTail 
22b0: 3d 20 7a 3b 0a 20 20 77 68 69 6c 65 28 20 7a 5b  = z;.  while( z[
22c0: 30 5d 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b  0] ){.    if( z[
22d0: 30 5d 3d 3d 27 2f 27 20 29 20 7a 54 61 69 6c 20  0]=='/' ) zTail 
22e0: 3d 20 26 7a 5b 31 5d 3b 0a 20 20 20 20 7a 2b 2b  = &z[1];.    z++
22f0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 7a  ;.  }.  return z
2300: 54 61 69 6c 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  Tail;.}../*.** C
2310: 6f 70 79 20 74 68 65 20 63 6f 6e 74 65 6e 74 20  opy the content 
2320: 6f 66 20 61 20 66 69 6c 65 20 66 72 6f 6d 20 6f  of a file from o
2330: 6e 65 20 70 6c 61 63 65 20 74 6f 20 61 6e 6f 74  ne place to anot
2340: 68 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20 66 69 6c  her..*/.void fil
2350: 65 5f 63 6f 70 79 28 63 6f 6e 73 74 20 63 68 61  e_copy(const cha
2360: 72 20 2a 7a 46 72 6f 6d 2c 20 63 6f 6e 73 74 20  r *zFrom, const 
2370: 63 68 61 72 20 2a 7a 54 6f 29 7b 0a 20 20 46 49  char *zTo){.  FI
2380: 4c 45 20 2a 69 6e 2c 20 2a 6f 75 74 3b 0a 20 20  LE *in, *out;.  
2390: 69 6e 74 20 67 6f 74 3b 0a 20 20 63 68 61 72 20  int got;.  char 
23a0: 7a 42 75 66 5b 38 31 39 32 5d 3b 0a 20 20 69 6e  zBuf[8192];.  in
23b0: 20 3d 20 66 6f 73 73 69 6c 5f 66 6f 70 65 6e 28   = fossil_fopen(
23c0: 7a 46 72 6f 6d 2c 20 22 72 62 22 29 3b 0a 20 20  zFrom, "rb");.  
23d0: 69 66 28 20 69 6e 3d 3d 30 20 29 20 66 6f 73 73  if( in==0 ) foss
23e0: 69 6c 5f 66 61 74 61 6c 28 22 63 61 6e 6e 6f 74  il_fatal("cannot
23f0: 20 6f 70 65 6e 20 5c 22 25 73 5c 22 20 66 6f 72   open \"%s\" for
2400: 20 72 65 61 64 69 6e 67 22 2c 20 7a 46 72 6f 6d   reading", zFrom
2410: 29 3b 0a 20 20 6f 75 74 20 3d 20 66 6f 73 73 69  );.  out = fossi
2420: 6c 5f 66 6f 70 65 6e 28 7a 54 6f 2c 20 22 77 62  l_fopen(zTo, "wb
2430: 22 29 3b 0a 20 20 69 66 28 20 6f 75 74 3d 3d 30  ");.  if( out==0
2440: 20 29 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c 28   ) fossil_fatal(
2450: 22 63 61 6e 6e 6f 74 20 6f 70 65 6e 20 5c 22 25  "cannot open \"%
2460: 73 5c 22 20 66 6f 72 20 77 72 69 74 69 6e 67 22  s\" for writing"
2470: 2c 20 7a 54 6f 29 3b 0a 20 20 77 68 69 6c 65 28  , zTo);.  while(
2480: 20 28 67 6f 74 3d 66 72 65 61 64 28 7a 42 75 66   (got=fread(zBuf
2490: 2c 20 31 2c 20 73 69 7a 65 6f 66 28 7a 42 75 66  , 1, sizeof(zBuf
24a0: 29 2c 20 69 6e 29 29 3e 30 20 29 7b 0a 20 20 20  ), in))>0 ){.   
24b0: 20 66 77 72 69 74 65 28 7a 42 75 66 2c 20 31 2c   fwrite(zBuf, 1,
24c0: 20 67 6f 74 2c 20 6f 75 74 29 3b 0a 20 20 7d 0a   got, out);.  }.
24d0: 20 20 66 63 6c 6f 73 65 28 69 6e 29 3b 0a 20 20    fclose(in);.  
24e0: 66 63 6c 6f 73 65 28 6f 75 74 29 3b 0a 7d 0a 0a  fclose(out);.}..
24f0: 2f 2a 0a 2a 2a 20 53 65 74 20 6f 72 20 63 6c 65  /*.** Set or cle
2500: 61 72 20 74 68 65 20 65 78 65 63 75 74 65 20 62  ar the execute b
2510: 69 74 20 6f 6e 20 61 20 66 69 6c 65 2e 20 20 52  it on a file.  R
2520: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 61 20  eturn true if a 
2530: 63 68 61 6e 67 65 0a 2a 2a 20 6f 63 63 75 72 72  change.** occurr
2540: 65 64 20 61 6e 64 20 66 61 6c 73 65 20 69 66 20  ed and false if 
2550: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 69 73 20  this routine is 
2560: 61 20 6e 6f 2d 6f 70 2e 0a 2a 2f 0a 69 6e 74 20  a no-op..*/.int 
2570: 66 69 6c 65 5f 77 64 5f 73 65 74 65 78 65 28 63  file_wd_setexe(c
2580: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65  onst char *zFile
2590: 6e 61 6d 65 2c 20 69 6e 74 20 6f 6e 6f 66 66 29  name, int onoff)
25a0: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 30 3b 0a  {.  int rc = 0;.
25b0: 23 69 66 20 21 64 65 66 69 6e 65 64 28 5f 57 49  #if !defined(_WI
25c0: 4e 33 32 29 0a 20 20 73 74 72 75 63 74 20 73 74  N32).  struct st
25d0: 61 74 20 62 75 66 3b 0a 20 20 69 66 28 20 66 6f  at buf;.  if( fo
25e0: 73 73 69 6c 5f 73 74 61 74 28 7a 46 69 6c 65 6e  ssil_stat(zFilen
25f0: 61 6d 65 2c 20 26 62 75 66 2c 20 31 29 21 3d 30  ame, &buf, 1)!=0
2600: 20 7c 7c 20 53 5f 49 53 4c 4e 4b 28 62 75 66 2e   || S_ISLNK(buf.
2610: 73 74 5f 6d 6f 64 65 29 20 29 20 72 65 74 75 72  st_mode) ) retur
2620: 6e 20 30 3b 0a 20 20 69 66 28 20 6f 6e 6f 66 66  n 0;.  if( onoff
2630: 20 29 7b 0a 20 20 20 20 69 6e 74 20 74 61 72 67   ){.    int targ
2640: 65 74 4d 6f 64 65 20 3d 20 28 62 75 66 2e 73 74  etMode = (buf.st
2650: 5f 6d 6f 64 65 20 26 20 30 34 34 34 29 3e 3e 32  _mode & 0444)>>2
2660: 3b 0a 20 20 20 20 69 66 28 20 28 62 75 66 2e 73  ;.    if( (buf.s
2670: 74 5f 6d 6f 64 65 20 26 20 30 31 31 31 29 21 3d  t_mode & 0111)!=
2680: 74 61 72 67 65 74 4d 6f 64 65 20 29 7b 0a 20 20  targetMode ){.  
2690: 20 20 20 20 63 68 6d 6f 64 28 7a 46 69 6c 65 6e      chmod(zFilen
26a0: 61 6d 65 2c 20 62 75 66 2e 73 74 5f 6d 6f 64 65  ame, buf.st_mode
26b0: 20 7c 20 74 61 72 67 65 74 4d 6f 64 65 29 3b 0a   | targetMode);.
26c0: 20 20 20 20 20 20 72 63 20 3d 20 31 3b 0a 20 20        rc = 1;.  
26d0: 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20    }.  }else{.   
26e0: 20 69 66 28 20 28 62 75 66 2e 73 74 5f 6d 6f 64   if( (buf.st_mod
26f0: 65 20 26 20 30 31 31 31 29 21 3d 30 20 29 7b 0a  e & 0111)!=0 ){.
2700: 20 20 20 20 20 20 63 68 6d 6f 64 28 7a 46 69 6c        chmod(zFil
2710: 65 6e 61 6d 65 2c 20 62 75 66 2e 73 74 5f 6d 6f  ename, buf.st_mo
2720: 64 65 20 26 20 7e 30 31 31 31 29 3b 0a 20 20 20  de & ~0111);.   
2730: 20 20 20 72 63 20 3d 20 31 3b 0a 20 20 20 20 7d     rc = 1;.    }
2740: 0a 20 20 7d 0a 23 65 6e 64 69 66 20 2f 2a 20 5f  .  }.#endif /* _
2750: 57 49 4e 33 32 20 2a 2f 0a 20 20 72 65 74 75 72  WIN32 */.  retur
2760: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  n rc;.}../*.** S
2770: 65 74 20 74 68 65 20 6d 74 69 6d 65 20 66 6f 72  et the mtime for
2780: 20 61 20 66 69 6c 65 2e 0a 2a 2f 0a 76 6f 69 64   a file..*/.void
2790: 20 66 69 6c 65 5f 73 65 74 5f 6d 74 69 6d 65 28   file_set_mtime(
27a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c  const char *zFil
27b0: 65 6e 61 6d 65 2c 20 69 36 34 20 6e 65 77 4d 54  ename, i64 newMT
27c0: 69 6d 65 29 7b 0a 23 69 66 20 21 64 65 66 69 6e  ime){.#if !defin
27d0: 65 64 28 5f 57 49 4e 33 32 29 0a 20 20 73 74 72  ed(_WIN32).  str
27e0: 75 63 74 20 74 69 6d 65 76 61 6c 20 74 76 5b 32  uct timeval tv[2
27f0: 5d 3b 0a 20 20 6d 65 6d 73 65 74 28 74 76 2c 20  ];.  memset(tv, 
2800: 30 2c 20 73 69 7a 65 6f 66 28 74 76 5b 30 5d 29  0, sizeof(tv[0])
2810: 2a 32 29 3b 0a 20 20 74 76 5b 30 5d 2e 74 76 5f  *2);.  tv[0].tv_
2820: 73 65 63 20 3d 20 6e 65 77 4d 54 69 6d 65 3b 0a  sec = newMTime;.
2830: 20 20 74 76 5b 31 5d 2e 74 76 5f 73 65 63 20 3d    tv[1].tv_sec =
2840: 20 6e 65 77 4d 54 69 6d 65 3b 0a 20 20 75 74 69   newMTime;.  uti
2850: 6d 65 73 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 74  mes(zFilename, t
2860: 76 29 3b 0a 23 65 6c 73 65 0a 20 20 73 74 72 75  v);.#else.  stru
2870: 63 74 20 5f 75 74 69 6d 62 75 66 20 74 62 3b 0a  ct _utimbuf tb;.
2880: 20 20 77 63 68 61 72 5f 74 20 2a 7a 4d 62 63 73    wchar_t *zMbcs
2890: 20 3d 20 66 6f 73 73 69 6c 5f 75 74 66 38 5f 74   = fossil_utf8_t
28a0: 6f 5f 66 69 6c 65 6e 61 6d 65 28 7a 46 69 6c 65  o_filename(zFile
28b0: 6e 61 6d 65 29 3b 0a 20 20 74 62 2e 61 63 74 69  name);.  tb.acti
28c0: 6d 65 20 3d 20 6e 65 77 4d 54 69 6d 65 3b 0a 20  me = newMTime;. 
28d0: 20 74 62 2e 6d 6f 64 74 69 6d 65 20 3d 20 6e 65   tb.modtime = ne
28e0: 77 4d 54 69 6d 65 3b 0a 20 20 5f 77 75 74 69 6d  wMTime;.  _wutim
28f0: 65 28 7a 4d 62 63 73 2c 20 26 74 62 29 3b 0a 20  e(zMbcs, &tb);. 
2900: 20 66 6f 73 73 69 6c 5f 66 69 6c 65 6e 61 6d 65   fossil_filename
2910: 5f 66 72 65 65 28 7a 4d 62 63 73 29 3b 0a 23 65  _free(zMbcs);.#e
2920: 6e 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f  ndif.}../*.** CO
2930: 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 73 65 74 2d  MMAND: test-set-
2940: 6d 74 69 6d 65 0a 2a 2a 0a 2a 2a 20 55 73 61 67  mtime.**.** Usag
2950: 65 3a 20 25 66 6f 73 73 69 6c 20 74 65 73 74 2d  e: %fossil test-
2960: 73 65 74 2d 6d 74 69 6d 65 20 46 49 4c 45 4e 41  set-mtime FILENA
2970: 4d 45 20 44 41 54 45 2f 54 49 4d 45 0a 2a 2a 0a  ME DATE/TIME.**.
2980: 2a 2a 20 53 65 74 73 20 74 68 65 20 6d 74 69 6d  ** Sets the mtim
2990: 65 20 6f 66 20 74 68 65 20 6e 61 6d 65 64 20 66  e of the named f
29a0: 69 6c 65 20 74 6f 20 74 68 65 20 64 61 74 65 2f  ile to the date/
29b0: 74 69 6d 65 20 73 68 6f 77 6e 2e 0a 2a 2f 0a 76  time shown..*/.v
29c0: 6f 69 64 20 74 65 73 74 5f 73 65 74 5f 6d 74 69  oid test_set_mti
29d0: 6d 65 28 76 6f 69 64 29 7b 0a 20 20 63 6f 6e 73  me(void){.  cons
29e0: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 3b 0a 20  t char *zFile;. 
29f0: 20 63 68 61 72 20 2a 7a 44 61 74 65 3b 0a 20 20   char *zDate;.  
2a00: 69 36 34 20 69 4d 54 69 6d 65 3b 0a 20 20 69 66  i64 iMTime;.  if
2a10: 28 20 67 2e 61 72 67 63 21 3d 34 20 29 7b 0a 20  ( g.argc!=4 ){. 
2a20: 20 20 20 75 73 61 67 65 28 22 74 65 73 74 2d 73     usage("test-s
2a30: 65 74 2d 6d 74 69 6d 65 20 46 49 4c 45 4e 41 4d  et-mtime FILENAM
2a40: 45 20 44 41 54 45 2f 54 49 4d 45 22 29 3b 0a 20  E DATE/TIME");. 
2a50: 20 7d 0a 20 20 64 62 5f 6f 70 65 6e 5f 6f 72 5f   }.  db_open_or_
2a60: 61 74 74 61 63 68 28 22 3a 6d 65 6d 6f 72 79 3a  attach(":memory:
2a70: 22 2c 20 22 6d 65 6d 22 2c 20 30 29 3b 0a 20 20  ", "mem", 0);.  
2a80: 69 4d 54 69 6d 65 20 3d 20 64 62 5f 69 6e 74 36  iMTime = db_int6
2a90: 34 28 30 2c 20 22 53 45 4c 45 43 54 20 73 74 72  4(0, "SELECT str
2aa0: 66 74 69 6d 65 28 27 25 25 73 27 2c 25 51 29 22  ftime('%%s',%Q)"
2ab0: 2c 20 67 2e 61 72 67 76 5b 33 5d 29 3b 0a 20 20  , g.argv[3]);.  
2ac0: 7a 46 69 6c 65 20 3d 20 67 2e 61 72 67 76 5b 32  zFile = g.argv[2
2ad0: 5d 3b 0a 20 20 66 69 6c 65 5f 73 65 74 5f 6d 74  ];.  file_set_mt
2ae0: 69 6d 65 28 7a 46 69 6c 65 2c 20 69 4d 54 69 6d  ime(zFile, iMTim
2af0: 65 29 3b 0a 20 20 69 4d 54 69 6d 65 20 3d 20 66  e);.  iMTime = f
2b00: 69 6c 65 5f 77 64 5f 6d 74 69 6d 65 28 7a 46 69  ile_wd_mtime(zFi
2b10: 6c 65 29 3b 0a 20 20 7a 44 61 74 65 20 3d 20 64  le);.  zDate = d
2b20: 62 5f 74 65 78 74 28 30 2c 20 22 53 45 4c 45 43  b_text(0, "SELEC
2b30: 54 20 64 61 74 65 74 69 6d 65 28 25 6c 6c 64 2c  T datetime(%lld,
2b40: 20 27 75 6e 69 78 65 70 6f 63 68 27 29 22 2c 20   'unixepoch')", 
2b50: 69 4d 54 69 6d 65 29 3b 0a 20 20 66 6f 73 73 69  iMTime);.  fossi
2b60: 6c 5f 70 72 69 6e 74 28 22 53 65 74 20 6d 74 69  l_print("Set mti
2b70: 6d 65 20 6f 66 20 5c 22 25 73 5c 22 20 74 6f 20  me of \"%s\" to 
2b80: 25 73 20 28 25 6c 6c 64 29 5c 6e 22 2c 20 7a 46  %s (%lld)\n", zF
2b90: 69 6c 65 2c 20 7a 44 61 74 65 2c 20 69 4d 54 69  ile, zDate, iMTi
2ba0: 6d 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65  me);.}../*.** De
2bb0: 6c 65 74 65 20 61 20 66 69 6c 65 2e 0a 2a 2f 0a  lete a file..*/.
2bc0: 76 6f 69 64 20 66 69 6c 65 5f 64 65 6c 65 74 65  void file_delete
2bd0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69  (const char *zFi
2be0: 6c 65 6e 61 6d 65 29 7b 0a 23 69 66 64 65 66 20  lename){.#ifdef 
2bf0: 5f 57 49 4e 33 32 0a 20 20 77 63 68 61 72 5f 74  _WIN32.  wchar_t
2c00: 20 2a 7a 20 3d 20 66 6f 73 73 69 6c 5f 75 74 66   *z = fossil_utf
2c10: 38 5f 74 6f 5f 75 6e 69 63 6f 64 65 28 7a 46 69  8_to_unicode(zFi
2c20: 6c 65 6e 61 6d 65 29 3b 0a 20 20 5f 77 75 6e 6c  lename);.  _wunl
2c30: 69 6e 6b 28 7a 29 3b 0a 20 20 66 6f 73 73 69 6c  ink(z);.  fossil
2c40: 5f 75 6e 69 63 6f 64 65 5f 66 72 65 65 28 7a 29  _unicode_free(z)
2c50: 3b 0a 23 65 6c 73 65 0a 20 20 75 6e 6c 69 6e 6b  ;.#else.  unlink
2c60: 28 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 23 65 6e  (zFilename);.#en
2c70: 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 72 65  dif.}../*.** Cre
2c80: 61 74 65 20 74 68 65 20 64 69 72 65 63 74 6f 72  ate the director
2c90: 79 20 6e 61 6d 65 64 20 69 6e 20 74 68 65 20 61  y named in the a
2ca0: 72 67 75 6d 65 6e 74 2c 20 69 66 20 69 74 20 64  rgument, if it d
2cb0: 6f 65 73 20 6e 6f 74 20 61 6c 72 65 61 64 79 0a  oes not already.
2cc0: 2a 2a 20 65 78 69 73 74 2e 20 20 49 66 20 66 6f  ** exist.  If fo
2cd0: 72 63 65 46 6c 61 67 20 69 73 20 31 2c 20 64 65  rceFlag is 1, de
2ce0: 6c 65 74 65 20 61 6e 79 20 70 72 69 6f 72 20 6e  lete any prior n
2cf0: 6f 6e 2d 64 69 72 65 63 74 6f 72 79 20 6f 62 6a  on-directory obj
2d00: 65 63 74 0a 2a 2a 20 77 69 74 68 20 74 68 65 20  ect.** with the 
2d10: 73 61 6d 65 20 6e 61 6d 65 2e 0a 2a 2a 0a 2a 2a  same name..**.**
2d20: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
2d30: 65 72 20 6f 66 20 65 72 72 6f 72 73 2e 0a 2a 2f  er of errors..*/
2d40: 0a 69 6e 74 20 66 69 6c 65 5f 6d 6b 64 69 72 28  .int file_mkdir(
2d50: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
2d60: 65 2c 20 69 6e 74 20 66 6f 72 63 65 46 6c 61 67  e, int forceFlag
2d70: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 66 69  ){.  int rc = fi
2d80: 6c 65 5f 77 64 5f 69 73 64 69 72 28 7a 4e 61 6d  le_wd_isdir(zNam
2d90: 65 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 32 20  e);.  if( rc==2 
2da0: 29 7b 0a 20 20 20 20 69 66 28 20 21 66 6f 72 63  ){.    if( !forc
2db0: 65 46 6c 61 67 20 29 20 72 65 74 75 72 6e 20 31  eFlag ) return 1
2dc0: 3b 0a 20 20 20 20 66 69 6c 65 5f 64 65 6c 65 74  ;.    file_delet
2dd0: 65 28 7a 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20  e(zName);.  }.  
2de0: 69 66 28 20 72 63 21 3d 31 20 29 7b 0a 23 69 66  if( rc!=1 ){.#if
2df0: 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29   defined(_WIN32)
2e00: 0a 20 20 20 20 69 6e 74 20 72 63 3b 0a 20 20 20  .    int rc;.   
2e10: 20 77 63 68 61 72 5f 74 20 2a 7a 4d 62 63 73 20   wchar_t *zMbcs 
2e20: 3d 20 66 6f 73 73 69 6c 5f 75 74 66 38 5f 74 6f  = fossil_utf8_to
2e30: 5f 66 69 6c 65 6e 61 6d 65 28 7a 4e 61 6d 65 29  _filename(zName)
2e40: 3b 0a 20 20 20 20 72 63 20 3d 20 5f 77 6d 6b 64  ;.    rc = _wmkd
2e50: 69 72 28 7a 4d 62 63 73 29 3b 0a 20 20 20 20 66  ir(zMbcs);.    f
2e60: 6f 73 73 69 6c 5f 66 69 6c 65 6e 61 6d 65 5f 66  ossil_filename_f
2e70: 72 65 65 28 7a 4d 62 63 73 29 3b 0a 20 20 20 20  ree(zMbcs);.    
2e80: 72 65 74 75 72 6e 20 72 63 3b 0a 23 65 6c 73 65  return rc;.#else
2e90: 0a 20 20 20 20 72 65 74 75 72 6e 20 6d 6b 64 69  .    return mkdi
2ea0: 72 28 7a 4e 61 6d 65 2c 20 30 37 35 35 29 3b 0a  r(zName, 0755);.
2eb0: 23 65 6e 64 69 66 0a 20 20 7d 0a 20 20 72 65 74  #endif.  }.  ret
2ec0: 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 0;.}../*.** 
2ed0: 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 74  Return true if t
2ee0: 68 65 20 66 69 6c 65 6e 61 6d 65 20 67 69 76 65  he filename give
2ef0: 6e 20 69 73 20 61 20 76 61 6c 69 64 20 66 69 6c  n is a valid fil
2f00: 65 6e 61 6d 65 20 66 6f 72 0a 2a 2a 20 61 20 66  ename for.** a f
2f10: 69 6c 65 20 69 6e 20 61 20 72 65 70 6f 73 69 74  ile in a reposit
2f20: 6f 72 79 2e 20 20 56 61 6c 69 64 20 66 69 6c 65  ory.  Valid file
2f30: 6e 61 6d 65 73 20 66 6f 6c 6c 6f 77 20 61 6c 6c  names follow all
2f40: 20 6f 66 20 74 68 65 0a 2a 2a 20 66 6f 6c 6c 6f   of the.** follo
2f50: 77 69 6e 67 20 72 75 6c 65 73 3a 0a 2a 2a 0a 2a  wing rules:.**.*
2f60: 2a 20 20 20 20 20 2a 20 20 44 6f 65 73 20 6e 6f  *     *  Does no
2f70: 74 20 62 65 67 69 6e 20 77 69 74 68 20 22 2f 22  t begin with "/"
2f80: 0a 2a 2a 20 20 20 20 20 2a 20 20 44 6f 65 73 20  .**     *  Does 
2f90: 6e 6f 74 20 63 6f 6e 74 61 69 6e 20 61 6e 79 20  not contain any 
2fa0: 70 61 74 68 20 65 6c 65 6d 65 6e 74 20 6e 61 6d  path element nam
2fb0: 65 64 20 22 2e 22 20 6f 72 20 22 2e 2e 22 0a 2a  ed "." or "..".*
2fc0: 2a 20 20 20 20 20 2a 20 20 44 6f 65 73 20 6e 6f  *     *  Does no
2fd0: 74 20 63 6f 6e 74 61 69 6e 20 61 6e 79 20 6f 66  t contain any of
2fe0: 20 74 68 65 73 65 20 63 68 61 72 61 63 74 65 72   these character
2ff0: 73 20 69 6e 20 74 68 65 20 70 61 74 68 3a 20 22  s in the path: "
3000: 5c 2a 5b 5d 3f 22 0a 2a 2a 20 20 20 20 20 2a 20  \*[]?".**     * 
3010: 20 44 6f 65 73 20 6e 6f 74 20 65 6e 64 20 77 69   Does not end wi
3020: 74 68 20 22 2f 22 2e 0a 2a 2a 20 20 20 20 20 2a  th "/"..**     *
3030: 20 20 44 6f 65 73 20 6e 6f 74 20 63 6f 6e 74 61    Does not conta
3040: 69 6e 20 74 77 6f 20 6f 72 20 6d 6f 72 65 20 22  in two or more "
3050: 2f 22 20 63 68 61 72 61 63 74 65 72 73 20 69 6e  /" characters in
3060: 20 61 20 72 6f 77 2e 0a 2a 2a 20 20 20 20 20 2a   a row..**     *
3070: 20 20 43 6f 6e 74 61 69 6e 73 20 61 74 20 6c 65    Contains at le
3080: 61 73 74 20 6f 6e 65 20 63 68 61 72 61 63 74 65  ast one characte
3090: 72 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 69 73  r.*/.int file_is
30a0: 5f 73 69 6d 70 6c 65 5f 70 61 74 68 6e 61 6d 65  _simple_pathname
30b0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 29 7b  (const char *z){
30c0: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 68 61 72  .  int i;.  char
30d0: 20 63 20 3d 20 7a 5b 30 5d 3b 0a 20 20 69 66 28   c = z[0];.  if(
30e0: 20 63 3d 3d 27 2f 27 20 7c 7c 20 63 3d 3d 30 20   c=='/' || c==0 
30f0: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 69 66  ) return 0;.  if
3100: 28 20 63 3d 3d 27 2e 27 20 29 7b 0a 20 20 20 20  ( c=='.' ){.    
3110: 69 66 28 20 7a 5b 31 5d 3d 3d 27 2f 27 20 7c 7c  if( z[1]=='/' ||
3120: 20 7a 5b 31 5d 3d 3d 30 20 29 20 72 65 74 75 72   z[1]==0 ) retur
3130: 6e 20 30 3b 0a 20 20 20 20 69 66 28 20 7a 5b 31  n 0;.    if( z[1
3140: 5d 3d 3d 27 2e 27 20 26 26 20 28 7a 5b 32 5d 3d  ]=='.' && (z[2]=
3150: 3d 27 2f 27 20 7c 7c 20 7a 5b 32 5d 3d 3d 30 29  ='/' || z[2]==0)
3160: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d   ) return 0;.  }
3170: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 28 63 3d 7a  .  for(i=0; (c=z
3180: 5b 69 5d 29 21 3d 30 3b 20 69 2b 2b 29 7b 0a 20  [i])!=0; i++){. 
3190: 20 20 20 69 66 28 20 28 63 20 26 20 30 78 66 30     if( (c & 0xf0
31a0: 29 20 3d 3d 20 30 78 66 30 20 29 20 7b 0a 20 20  ) == 0xf0 ) {.  
31b0: 20 20 20 20 2f 2a 20 55 6e 69 63 6f 64 65 20 63      /* Unicode c
31c0: 68 61 72 61 63 74 65 72 73 20 3e 20 55 2b 46 46  haracters > U+FF
31d0: 46 46 20 61 72 65 20 6e 6f 74 20 73 75 70 70 6f  FF are not suppo
31e0: 72 74 65 64 2e 0a 20 20 20 20 20 20 20 2a 20 57  rted..       * W
31f0: 69 6e 64 6f 77 73 20 58 50 20 61 6e 64 20 65 61  indows XP and ea
3200: 72 6c 69 65 72 20 63 61 6e 6e 6f 74 20 68 61 6e  rlier cannot han
3210: 64 6c 65 20 74 68 65 6d 2e 0a 20 20 20 20 20 20  dle them..      
3220: 20 2a 2f 0a 20 20 20 20 20 20 72 65 74 75 72 6e   */.      return
3230: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66   0;.    }.    if
3240: 28 20 28 63 20 26 20 30 78 66 30 29 20 3d 3d 20  ( (c & 0xf0) == 
3250: 30 78 65 30 20 29 20 7b 0a 20 20 20 20 20 20 2f  0xe0 ) {.      /
3260: 2a 20 54 68 69 73 20 69 73 20 61 20 33 2d 62 79  * This is a 3-by
3270: 74 65 20 55 54 46 2d 38 20 63 68 61 72 61 63 74  te UTF-8 charact
3280: 65 72 20 2a 2f 0a 20 20 20 20 20 20 69 66 20 28  er */.      if (
3290: 20 28 63 20 26 20 30 78 66 65 29 20 3d 3d 20 30   (c & 0xfe) == 0
32a0: 78 65 65 20 29 7b 0a 20 20 20 20 20 20 20 20 2f  xee ){.        /
32b0: 2a 20 52 61 6e 67 65 20 55 2b 45 30 30 30 20 2d  * Range U+E000 -
32c0: 20 55 2b 46 46 46 46 20 28 53 74 61 72 74 69 6e   U+FFFF (Startin
32d0: 67 20 77 69 74 68 20 30 78 65 65 20 6f 72 20 30  g with 0xee or 0
32e0: 78 65 66 20 69 6e 20 55 54 46 2d 38 20 29 20 2a  xef in UTF-8 ) *
32f0: 2f 0a 20 20 20 20 20 20 20 20 69 66 20 28 20 28  /.        if ( (
3300: 63 20 26 20 31 29 20 26 26 20 28 28 7a 5b 69 2b  c & 1) && ((z[i+
3310: 31 5d 20 26 20 30 78 66 66 29 20 3e 3d 20 30 78  1] & 0xff) >= 0x
3320: 61 34 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  a4) ){.         
3330: 20 2f 2a 20 42 75 74 20 65 78 63 6c 75 64 65 20   /* But exclude 
3340: 55 2b 46 39 30 30 20 2d 20 55 2b 46 46 46 46 20  U+F900 - U+FFFF 
3350: 28 30 78 65 66 20 66 6f 6c 6c 6f 77 65 64 20 62  (0xef followed b
3360: 79 20 62 79 74 65 20 3e 3d 20 30 78 61 34 29 2c  y byte >= 0xa4),
3370: 0a 20 20 20 20 20 20 20 20 20 20 20 2a 20 77 68  .           * wh
3380: 69 63 68 20 63 6f 6e 74 61 69 6e 20 76 61 6c 69  ich contain vali
3390: 64 20 63 68 61 72 61 63 74 65 72 73 2e 20 2a 2f  d characters. */
33a0: 0a 20 20 20 20 20 20 20 20 20 20 63 6f 6e 74 69  .          conti
33b0: 6e 75 65 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  nue;.        }. 
33c0: 20 20 20 20 20 20 20 2f 2a 20 55 6e 69 63 6f 64         /* Unicod
33d0: 65 20 63 68 61 72 61 63 74 65 72 20 69 6e 20 74  e character in t
33e0: 68 65 20 72 61 6e 67 65 20 55 2b 45 30 30 30 20  he range U+E000 
33f0: 2d 20 55 2b 46 38 46 46 20 61 72 65 20 66 6f 72  - U+F8FF are for
3400: 0a 20 20 20 20 20 20 20 20 20 2a 20 70 72 69 76  .         * priv
3410: 61 74 65 20 75 73 65 2c 20 74 68 65 79 20 73 68  ate use, they sh
3420: 6f 75 6c 64 6e 27 74 20 6f 63 63 75 72 20 69 6e  ouldn't occur in
3430: 20 66 69 6c 65 6e 61 6d 65 73 2e 20 20 2a 2f 0a   filenames.  */.
3440: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 30          return 0
3450: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
3460: 69 66 28 20 28 28 63 20 26 20 30 78 66 66 29 20  if( ((c & 0xff) 
3470: 3d 3d 20 30 78 65 64 29 20 26 26 20 28 28 7a 5b  == 0xed) && ((z[
3480: 69 2b 31 5d 20 26 20 30 78 65 30 29 20 3d 3d 20  i+1] & 0xe0) == 
3490: 30 78 61 30 29 20 29 7b 0a 20 20 20 20 20 20 20  0xa0) ){.       
34a0: 20 2f 2a 20 55 6e 69 63 6f 64 65 20 63 68 61 72   /* Unicode char
34b0: 61 63 74 65 72 20 69 6e 20 74 68 65 20 72 61 6e  acter in the ran
34c0: 67 65 20 55 2b 44 38 30 30 20 2d 20 55 2b 44 46  ge U+D800 - U+DF
34d0: 46 46 20 61 72 65 20 66 6f 72 0a 20 20 20 20 20  FF are for.     
34e0: 20 20 20 20 2a 20 73 75 72 72 6f 67 61 74 65 20      * surrogate 
34f0: 70 61 69 72 73 2c 20 74 68 65 79 20 73 68 6f 75  pairs, they shou
3500: 6c 64 6e 27 74 20 6f 63 63 75 72 20 69 6e 20 66  ldn't occur in f
3510: 69 6c 65 6e 61 6d 65 73 2e 20 2a 2f 0a 20 20 20  ilenames. */.   
3520: 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20       return 0;. 
3530: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
3540: 20 69 66 28 20 63 3d 3d 27 5c 5c 27 20 29 7b 0a   if( c=='\\' ){.
3550: 20 20 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a        return 0;.
3560: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 63 3d      }.    if( c=
3570: 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 69 66  ='/' ){.      if
3580: 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2f 27 20 29 20  ( z[i+1]=='/' ) 
3590: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20  return 0;.      
35a0: 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20  if( z[i+1]=='.' 
35b0: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a  ){.        if( z
35c0: 5b 69 2b 32 5d 3d 3d 27 2f 27 20 7c 7c 20 7a 5b  [i+2]=='/' || z[
35d0: 69 2b 32 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e  i+2]==0 ) return
35e0: 20 30 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20   0;.        if( 
35f0: 7a 5b 69 2b 32 5d 3d 3d 27 2e 27 20 26 26 20 28  z[i+2]=='.' && (
3600: 7a 5b 69 2b 33 5d 3d 3d 27 2f 27 20 7c 7c 20 7a  z[i+3]=='/' || z
3610: 5b 69 2b 33 5d 3d 3d 30 29 20 29 20 72 65 74 75  [i+3]==0) ) retu
3620: 72 6e 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20  rn 0;.      }.  
3630: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 7a 5b    }.  }.  if( z[
3640: 69 2d 31 5d 3d 3d 27 2f 27 20 29 20 72 65 74 75  i-1]=='/' ) retu
3650: 72 6e 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 31  rn 0;.  return 1
3660: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 66 20 74 68  ;.}../*.** If th
3670: 65 20 6c 61 73 74 20 63 6f 6d 70 6f 6e 65 6e 74  e last component
3680: 20 6f 66 20 74 68 65 20 70 61 74 68 6e 61 6d 65   of the pathname
3690: 20 69 6e 20 7a 5b 30 5d 2e 2e 7a 5b 6a 2d 31 5d   in z[0]..z[j-1]
36a0: 20 69 73 20 73 6f 6d 65 74 68 69 6e 67 0a 2a 2a   is something.**
36b0: 20 6f 74 68 65 72 20 74 68 61 6e 20 22 2e 2e 22   other than ".."
36c0: 20 74 68 65 6e 20 62 61 63 6b 20 69 74 20 6f 75   then back it ou
36d0: 74 20 61 6e 64 20 72 65 74 75 72 6e 20 74 72 75  t and return tru
36e0: 65 2e 20 20 49 66 20 74 68 65 20 6c 61 73 74 0a  e.  If the last.
36f0: 2a 2a 20 63 6f 6d 70 6f 6e 65 6e 74 20 69 73 20  ** component is 
3700: 65 6d 70 74 79 20 6f 72 20 69 66 20 69 74 20 69  empty or if it i
3710: 73 20 22 2e 2e 22 20 74 68 65 6e 20 72 65 74 75  s ".." then retu
3720: 72 6e 20 66 61 6c 73 65 2e 0a 2a 2f 0a 73 74 61  rn false..*/.sta
3730: 74 69 63 20 69 6e 74 20 62 61 63 6b 75 70 5f 64  tic int backup_d
3740: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  ir(const char *z
3750: 2c 20 69 6e 74 20 2a 70 4a 29 7b 0a 20 20 69 6e  , int *pJ){.  in
3760: 74 20 6a 20 3d 20 2a 70 4a 3b 0a 20 20 69 6e 74  t j = *pJ;.  int
3770: 20 69 3b 0a 20 20 69 66 28 20 6a 3c 3d 30 20 29   i;.  if( j<=0 )
3780: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 66 6f 72   return 0;.  for
3790: 28 69 3d 6a 2d 31 3b 20 69 3e 30 20 26 26 20 7a  (i=j-1; i>0 && z
37a0: 5b 69 2d 31 5d 21 3d 27 2f 27 3b 20 69 2d 2d 29  [i-1]!='/'; i--)
37b0: 7b 7d 0a 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27  {}.  if( z[i]=='
37c0: 2e 27 20 26 26 20 69 3d 3d 6a 2d 32 20 26 26 20  .' && i==j-2 && 
37d0: 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 29 20 72 65  z[i+1]=='.' ) re
37e0: 74 75 72 6e 20 30 3b 0a 20 20 2a 70 4a 20 3d 20  turn 0;.  *pJ = 
37f0: 69 2d 31 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b  i-1;.  return 1;
3800: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 69 6d 70 6c 69  .}../*.** Simpli
3810: 66 79 20 61 20 66 69 6c 65 6e 61 6d 65 20 62 79  fy a filename by
3820: 0a 2a 2a 0a 2a 2a 20 20 2a 20 43 6f 6e 76 65 72  .**.**  * Conver
3830: 74 20 61 6c 6c 20 5c 20 69 6e 74 6f 20 2f 20 6f  t all \ into / o
3840: 6e 20 77 69 6e 64 6f 77 73 0a 2a 2a 20 20 2a 20  n windows.**  * 
3850: 72 65 6d 6f 76 69 6e 67 20 61 6e 79 20 74 72 61  removing any tra
3860: 69 6c 69 6e 67 20 61 6e 64 20 64 75 70 6c 69 63  iling and duplic
3870: 61 74 65 20 2f 0a 2a 2a 20 20 2a 20 72 65 6d 6f  ate /.**  * remo
3880: 76 69 6e 67 20 2f 2e 2f 0a 2a 2a 20 20 2a 20 72  ving /./.**  * r
3890: 65 6d 6f 76 69 6e 67 20 2f 41 2f 2e 2e 2f 0a 2a  emoving /A/../.*
38a0: 2a 0a 2a 2a 20 43 68 61 6e 67 65 73 20 61 72 65  *.** Changes are
38b0: 20 6d 61 64 65 20 69 6e 2d 70 6c 61 63 65 2e 20   made in-place. 
38c0: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 65 77 20   Return the new 
38d0: 6e 61 6d 65 20 6c 65 6e 67 74 68 2e 0a 2a 2a 20  name length..** 
38e0: 49 66 20 74 68 65 20 73 6c 61 73 68 20 70 61 72  If the slash par
38f0: 61 6d 65 74 65 72 20 69 73 20 6e 6f 6e 2d 7a 65  ameter is non-ze
3900: 72 6f 2c 20 74 68 65 20 74 72 61 69 6c 69 6e 67  ro, the trailing
3910: 20 73 6c 61 73 68 2c 20 69 66 20 61 6e 79 2c 0a   slash, if any,.
3920: 2a 2a 20 69 73 20 72 65 74 61 69 6e 65 64 2e 0a  ** is retained..
3930: 2a 2f 0a 69 6e 74 20 66 69 6c 65 5f 73 69 6d 70  */.int file_simp
3940: 6c 69 66 79 5f 6e 61 6d 65 28 63 68 61 72 20 2a  lify_name(char *
3950: 7a 2c 20 69 6e 74 20 6e 2c 20 69 6e 74 20 73 6c  z, int n, int sl
3960: 61 73 68 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6a  ash){.  int i, j
3970: 3b 0a 20 20 69 66 28 20 6e 3c 30 20 29 20 6e 20  ;.  if( n<0 ) n 
3980: 3d 20 73 74 72 6c 65 6e 28 7a 29 3b 0a 0a 20 20  = strlen(z);..  
3990: 2f 2a 20 4f 6e 20 77 69 6e 64 6f 77 73 20 63 6f  /* On windows co
39a0: 6e 76 65 72 74 20 61 6c 6c 20 5c 20 63 68 61 72  nvert all \ char
39b0: 61 63 74 65 72 73 20 74 6f 20 2f 20 2a 2f 0a 23  acters to / */.#
39c0: 69 66 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33  if defined(_WIN3
39d0: 32 29 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  2).  for(i=0; i<
39e0: 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  n; i++){.    if(
39f0: 20 7a 5b 69 5d 3d 3d 27 5c 5c 27 20 29 20 7a 5b   z[i]=='\\' ) z[
3a00: 69 5d 20 3d 20 27 2f 27 3b 0a 20 20 7d 0a 23 65  i] = '/';.  }.#e
3a10: 6e 64 69 66 0a 0a 20 20 2f 2a 20 52 65 6d 6f 76  ndif..  /* Remov
3a20: 69 6e 67 20 74 72 61 69 6c 69 6e 67 20 22 2f 22  ing trailing "/"
3a30: 20 63 68 61 72 61 63 74 65 72 73 20 2a 2f 0a 20   characters */. 
3a40: 20 69 66 20 28 20 21 73 6c 61 73 68 20 29 7b 0a   if ( !slash ){.
3a50: 20 20 20 20 77 68 69 6c 65 28 20 6e 3e 31 20 26      while( n>1 &
3a60: 26 20 7a 5b 6e 2d 31 5d 3d 3d 27 2f 27 20 29 7b  & z[n-1]=='/' ){
3a70: 20 6e 2d 2d 3b 20 7d 0a 20 20 7d 0a 0a 20 20 2f   n--; }.  }..  /
3a80: 2a 20 52 65 6d 6f 76 65 20 64 75 70 6c 69 63 61  * Remove duplica
3a90: 74 65 20 27 2f 27 20 63 68 61 72 61 63 74 65 72  te '/' character
3aa0: 73 2e 20 20 45 78 63 65 70 74 2c 20 74 77 6f 20  s.  Except, two 
3ab0: 2f 2f 20 61 74 20 74 68 65 20 62 65 67 69 6e 6e  // at the beginn
3ac0: 69 6e 67 0a 20 20 2a 2a 20 6f 66 20 61 20 70 61  ing.  ** of a pa
3ad0: 74 68 6e 61 6d 65 20 69 73 20 61 6c 6c 6f 77 65  thname is allowe
3ae0: 64 20 73 69 6e 63 65 20 74 68 69 73 20 69 73 20  d since this is 
3af0: 69 6d 70 6f 72 74 61 6e 74 20 6f 6e 20 77 69 6e  important on win
3b00: 64 6f 77 73 2e 20 2a 2f 0a 20 20 66 6f 72 28 69  dows. */.  for(i
3b10: 3d 6a 3d 31 3b 20 69 3c 6e 3b 20 69 2b 2b 29 7b  =j=1; i<n; i++){
3b20: 0a 20 20 20 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b  .    z[j++] = z[
3b30: 69 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 7a  i];.    while( z
3b40: 5b 69 5d 3d 3d 27 2f 27 20 26 26 20 69 3c 6e 2d  [i]=='/' && i<n-
3b50: 31 20 26 26 20 7a 5b 69 2b 31 5d 3d 3d 27 2f 27  1 && z[i+1]=='/'
3b60: 20 29 20 69 2b 2b 3b 0a 20 20 7d 0a 20 20 6e 20   ) i++;.  }.  n 
3b70: 3d 20 6a 3b 0a 0a 20 20 2f 2a 20 53 6b 69 70 20  = j;..  /* Skip 
3b80: 6f 76 65 72 20 7a 65 72 6f 20 6f 72 20 6d 6f 72  over zero or mor
3b90: 65 20 69 6e 69 74 69 61 6c 20 22 2e 2f 22 20 73  e initial "./" s
3ba0: 65 71 75 65 6e 63 65 73 20 2a 2f 0a 20 20 66 6f  equences */.  fo
3bb0: 72 28 69 3d 30 3b 20 69 3c 6e 2d 31 20 26 26 20  r(i=0; i<n-1 && 
3bc0: 7a 5b 69 5d 3d 3d 27 2e 27 20 26 26 20 7a 5b 69  z[i]=='.' && z[i
3bd0: 2b 31 5d 3d 3d 27 2f 27 3b 20 69 2b 3d 32 29 7b  +1]=='/'; i+=2){
3be0: 7d 0a 0a 20 20 2f 2a 20 42 65 67 69 6e 20 63 6f  }..  /* Begin co
3bf0: 70 79 69 6e 67 20 66 72 6f 6d 20 7a 5b 69 5d 20  pying from z[i] 
3c00: 62 61 63 6b 20 74 6f 20 7a 5b 6a 5d 2e 2e 2e 20  back to z[j]... 
3c10: 2a 2f 0a 20 20 66 6f 72 28 6a 3d 30 3b 20 69 3c  */.  for(j=0; i<
3c20: 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  n; i++){.    if(
3c30: 20 7a 5b 69 5d 3d 3d 27 2f 27 20 29 7b 0a 20 20   z[i]=='/' ){.  
3c40: 20 20 20 20 2f 2a 20 53 6b 69 70 20 6f 76 65 72      /* Skip over
3c50: 20 69 6e 74 65 72 6e 61 6c 20 22 2f 2e 22 20 64   internal "/." d
3c60: 69 72 65 63 74 6f 72 79 20 63 6f 6d 70 6f 6e 65  irectory compone
3c70: 6e 74 73 20 2a 2f 0a 20 20 20 20 20 20 69 66 28  nts */.      if(
3c80: 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 26 26 20   z[i+1]=='.' && 
3c90: 28 69 2b 32 3d 3d 6e 20 7c 7c 20 7a 5b 69 2b 32  (i+2==n || z[i+2
3ca0: 5d 3d 3d 27 2f 27 29 20 29 7b 0a 20 20 20 20 20  ]=='/') ){.     
3cb0: 20 20 20 69 20 2b 3d 20 31 3b 0a 20 20 20 20 20     i += 1;.     
3cc0: 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20     continue;.   
3cd0: 20 20 20 7d 0a 0a 20 20 20 20 20 20 2f 2a 20 49     }..      /* I
3ce0: 66 20 74 68 69 73 20 69 73 20 61 20 22 2f 2e 2e  f this is a "/..
3cf0: 22 20 64 69 72 65 63 74 6f 72 79 20 63 6f 6d 70  " directory comp
3d00: 6f 6e 65 6e 74 20 74 68 65 6e 20 62 61 63 6b 20  onent then back 
3d10: 6f 75 74 20 74 68 65 0a 20 20 20 20 20 20 2a 2a  out the.      **
3d20: 20 70 72 65 76 69 6f 75 73 20 74 65 72 6d 20 6f   previous term o
3d30: 66 20 74 68 65 20 64 69 72 65 63 74 6f 72 79 20  f the directory 
3d40: 69 66 20 69 74 20 69 73 20 73 6f 6d 65 74 68 69  if it is somethi
3d50: 6e 67 20 6f 74 68 65 72 20 74 68 61 6e 20 22 2e  ng other than ".
3d60: 2e 22 0a 20 20 20 20 20 20 2a 2a 20 6f 72 20 22  .".      ** or "
3d70: 2e 22 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20  .".      */.    
3d80: 20 20 69 66 28 20 7a 5b 69 2b 31 5d 3d 3d 27 2e    if( z[i+1]=='.
3d90: 27 20 26 26 20 69 2b 32 3c 6e 20 26 26 20 7a 5b  ' && i+2<n && z[
3da0: 69 2b 32 5d 3d 3d 27 2e 27 20 26 26 20 28 69 2b  i+2]=='.' && (i+
3db0: 33 3d 3d 6e 20 7c 7c 20 7a 5b 69 2b 33 5d 3d 3d  3==n || z[i+3]==
3dc0: 27 2f 27 29 0a 20 20 20 20 20 20 20 26 26 20 62  '/').       && b
3dd0: 61 63 6b 75 70 5f 64 69 72 28 7a 2c 20 26 6a 29  ackup_dir(z, &j)
3de0: 0a 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20 20  .      ){.      
3df0: 20 20 69 20 2b 3d 20 32 3b 0a 20 20 20 20 20 20    i += 2;.      
3e00: 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20    continue;.    
3e10: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69 66    }.    }.    if
3e20: 28 20 6a 3e 3d 30 20 29 20 7a 5b 6a 5d 20 3d 20  ( j>=0 ) z[j] = 
3e30: 7a 5b 69 5d 3b 0a 20 20 20 20 6a 2b 2b 3b 0a 20  z[i];.    j++;. 
3e40: 20 7d 0a 20 20 69 66 28 20 6a 3d 3d 30 20 29 20   }.  if( j==0 ) 
3e50: 7a 5b 6a 2b 2b 5d 20 3d 20 27 2e 27 3b 0a 20 20  z[j++] = '.';.  
3e60: 7a 5b 6a 5d 20 3d 20 30 3b 0a 20 20 72 65 74 75  z[j] = 0;.  retu
3e70: 72 6e 20 6a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  rn j;.}../*.** C
3e80: 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 73 69 6d  OMMAND: test-sim
3e90: 70 6c 69 66 79 2d 6e 61 6d 65 0a 2a 2a 0a 2a 2a  plify-name.**.**
3ea0: 20 25 66 6f 73 73 69 6c 20 74 65 73 74 2d 73 69   %fossil test-si
3eb0: 6d 70 6c 69 66 79 2d 6e 61 6d 65 20 46 49 4c 45  mplify-name FILE
3ec0: 4e 41 4d 45 2e 2e 2e 0a 2a 2a 0a 2a 2a 20 50 72  NAME....**.** Pr
3ed0: 69 6e 74 20 74 68 65 20 73 69 6d 70 6c 69 66 69  int the simplifi
3ee0: 65 64 20 76 65 72 73 69 6f 6e 73 20 6f 66 20 65  ed versions of e
3ef0: 61 63 68 20 46 49 4c 45 4e 41 4d 45 2e 0a 2a 2f  ach FILENAME..*/
3f00: 0a 76 6f 69 64 20 63 6d 64 5f 74 65 73 74 5f 73  .void cmd_test_s
3f10: 69 6d 70 6c 69 66 79 5f 6e 61 6d 65 28 76 6f 69  implify_name(voi
3f20: 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63  d){.  int i;.  c
3f30: 68 61 72 20 2a 7a 3b 0a 20 20 66 6f 72 28 69 3d  har *z;.  for(i=
3f40: 32 3b 20 69 3c 67 2e 61 72 67 63 3b 20 69 2b 2b  2; i<g.argc; i++
3f50: 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e  ){.    z = mprin
3f60: 74 66 28 22 25 73 22 2c 20 67 2e 61 72 67 76 5b  tf("%s", g.argv[
3f70: 69 5d 29 3b 0a 20 20 20 20 66 6f 73 73 69 6c 5f  i]);.    fossil_
3f80: 70 72 69 6e 74 28 22 5b 25 73 5d 20 2d 3e 20 22  print("[%s] -> "
3f90: 2c 20 7a 29 3b 0a 20 20 20 20 66 69 6c 65 5f 73  , z);.    file_s
3fa0: 69 6d 70 6c 69 66 79 5f 6e 61 6d 65 28 7a 2c 20  implify_name(z, 
3fb0: 2d 31 2c 20 30 29 3b 0a 20 20 20 20 66 6f 73 73  -1, 0);.    foss
3fc0: 69 6c 5f 70 72 69 6e 74 28 22 5b 25 73 5d 5c 6e  il_print("[%s]\n
3fd0: 22 2c 20 7a 29 3b 0a 20 20 20 20 66 6f 73 73 69  ", z);.    fossi
3fe0: 6c 5f 66 72 65 65 28 7a 29 3b 0a 20 20 7d 0a 7d  l_free(z);.  }.}
3ff0: 0a 0a 2f 2a 0a 2a 2a 20 47 65 74 20 74 68 65 20  ../*.** Get the 
4000: 63 75 72 72 65 6e 74 20 77 6f 72 6b 69 6e 67 20  current working 
4010: 64 69 72 65 63 74 6f 72 79 2e 0a 2a 2a 0a 2a 2a  directory..**.**
4020: 20 4f 6e 20 77 69 6e 64 6f 77 73 2c 20 74 68 65   On windows, the
4030: 20 6e 61 6d 65 20 69 73 20 63 6f 6e 76 65 72 74   name is convert
4040: 65 64 20 66 72 6f 6d 20 75 6e 69 63 6f 64 65 20  ed from unicode 
4050: 74 6f 20 55 54 46 38 20 61 6e 64 20 61 6c 6c 20  to UTF8 and all 
4060: 27 5c 5c 27 0a 2a 2a 20 63 68 61 72 61 63 74 65  '\\'.** characte
4070: 72 73 20 61 72 65 20 63 6f 6e 76 65 72 74 65 64  rs are converted
4080: 20 74 6f 20 27 2f 27 2e 20 20 4e 6f 20 63 6f 6e   to '/'.  No con
4090: 76 65 72 73 69 6f 6e 73 20 61 72 65 20 6e 65 65  versions are nee
40a0: 64 65 64 20 6f 6e 0a 2a 2a 20 75 6e 69 78 2e 0a  ded on.** unix..
40b0: 2a 2f 0a 76 6f 69 64 20 66 69 6c 65 5f 67 65 74  */.void file_get
40c0: 63 77 64 28 63 68 61 72 20 2a 7a 42 75 66 2c 20  cwd(char *zBuf, 
40d0: 69 6e 74 20 6e 42 75 66 29 7b 0a 23 69 66 64 65  int nBuf){.#ifde
40e0: 66 20 5f 57 49 4e 33 32 0a 20 20 63 68 61 72 20  f _WIN32.  char 
40f0: 2a 7a 50 77 64 55 74 66 38 3b 0a 20 20 69 6e 74  *zPwdUtf8;.  int
4100: 20 6e 50 77 64 3b 0a 20 20 69 6e 74 20 69 3b 0a   nPwd;.  int i;.
4110: 20 20 77 63 68 61 72 5f 74 20 7a 50 77 64 5b 32    wchar_t zPwd[2
4120: 30 30 30 5d 3b 0a 20 20 69 66 28 20 5f 77 67 65  000];.  if( _wge
4130: 74 63 77 64 28 7a 50 77 64 2c 20 73 69 7a 65 6f  tcwd(zPwd, sizeo
4140: 66 28 7a 50 77 64 29 2f 73 69 7a 65 6f 66 28 7a  f(zPwd)/sizeof(z
4150: 50 77 64 5b 30 5d 29 2d 31 29 3d 3d 30 20 29 7b  Pwd[0])-1)==0 ){
4160: 0a 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61  .    fossil_fata
4170: 6c 28 22 63 61 6e 6e 6f 74 20 66 69 6e 64 20 74  l("cannot find t
4180: 68 65 20 63 75 72 72 65 6e 74 20 77 6f 72 6b 69  he current worki
4190: 6e 67 20 64 69 72 65 63 74 6f 72 79 2e 22 29 3b  ng directory.");
41a0: 0a 20 20 7d 0a 20 20 7a 50 77 64 55 74 66 38 20  .  }.  zPwdUtf8 
41b0: 3d 20 66 6f 73 73 69 6c 5f 66 69 6c 65 6e 61 6d  = fossil_filenam
41c0: 65 5f 74 6f 5f 75 74 66 38 28 7a 50 77 64 29 3b  e_to_utf8(zPwd);
41d0: 0a 20 20 6e 50 77 64 20 3d 20 73 74 72 6c 65 6e  .  nPwd = strlen
41e0: 28 7a 50 77 64 55 74 66 38 29 3b 0a 20 20 69 66  (zPwdUtf8);.  if
41f0: 28 20 6e 50 77 64 20 3e 20 6e 42 75 66 2d 31 20  ( nPwd > nBuf-1 
4200: 29 7b 0a 20 20 20 20 66 6f 73 73 69 6c 5f 66 61  ){.    fossil_fa
4210: 74 61 6c 28 22 70 77 64 20 74 6f 6f 20 62 69 67  tal("pwd too big
4220: 3a 20 6d 61 78 20 25 64 5c 6e 22 2c 20 6e 42 75  : max %d\n", nBu
4230: 66 2d 31 29 3b 0a 20 20 7d 0a 20 20 66 6f 72 28  f-1);.  }.  for(
4240: 69 3d 30 3b 20 7a 50 77 64 55 74 66 38 5b 69 5d  i=0; zPwdUtf8[i]
4250: 3b 20 69 2b 2b 29 20 69 66 28 20 7a 50 77 64 55  ; i++) if( zPwdU
4260: 74 66 38 5b 69 5d 3d 3d 27 5c 5c 27 20 29 20 7a  tf8[i]=='\\' ) z
4270: 50 77 64 55 74 66 38 5b 69 5d 20 3d 20 27 2f 27  PwdUtf8[i] = '/'
4280: 3b 0a 20 20 6d 65 6d 63 70 79 28 7a 42 75 66 2c  ;.  memcpy(zBuf,
4290: 20 7a 50 77 64 55 74 66 38 2c 20 6e 50 77 64 2b   zPwdUtf8, nPwd+
42a0: 31 29 3b 0a 20 20 66 6f 73 73 69 6c 5f 66 69 6c  1);.  fossil_fil
42b0: 65 6e 61 6d 65 5f 66 72 65 65 28 7a 50 77 64 55  ename_free(zPwdU
42c0: 74 66 38 29 3b 0a 23 65 6c 73 65 0a 20 20 69 66  tf8);.#else.  if
42d0: 28 20 67 65 74 63 77 64 28 7a 42 75 66 2c 20 6e  ( getcwd(zBuf, n
42e0: 42 75 66 2d 31 29 3d 3d 30 20 29 7b 0a 20 20 20  Buf-1)==0 ){.   
42f0: 20 69 66 28 20 65 72 72 6e 6f 3d 3d 45 52 41 4e   if( errno==ERAN
4300: 47 45 20 29 7b 0a 20 20 20 20 20 20 66 6f 73 73  GE ){.      foss
4310: 69 6c 5f 66 61 74 61 6c 28 22 70 77 64 20 74 6f  il_fatal("pwd to
4320: 6f 20 62 69 67 3a 20 6d 61 78 20 25 64 5c 6e 22  o big: max %d\n"
4330: 2c 20 6e 42 75 66 2d 31 29 3b 0a 20 20 20 20 7d  , nBuf-1);.    }
4340: 65 6c 73 65 7b 0a 20 20 20 20 20 20 66 6f 73 73  else{.      foss
4350: 69 6c 5f 66 61 74 61 6c 28 22 63 61 6e 6e 6f 74  il_fatal("cannot
4360: 20 66 69 6e 64 20 63 75 72 72 65 6e 74 20 77 6f   find current wo
4370: 72 6b 69 6e 67 20 64 69 72 65 63 74 6f 72 79 3b  rking directory;
4380: 20 25 73 22 2c 0a 20 20 20 20 20 20 20 20 20 20   %s",.          
4390: 20 20 20 20 20 20 20 20 20 73 74 72 65 72 72 6f           strerro
43a0: 72 28 65 72 72 6e 6f 29 29 3b 0a 20 20 20 20 7d  r(errno));.    }
43b0: 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f  .  }.#endif.}../
43c0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65  *.** Return true
43d0: 20 69 66 20 7a 50 61 74 68 20 69 73 20 61 6e 20   if zPath is an 
43e0: 61 62 73 6f 6c 75 74 65 20 70 61 74 68 6e 61 6d  absolute pathnam
43f0: 65 2e 20 20 52 65 74 75 72 6e 20 66 61 6c 73 65  e.  Return false
4400: 0a 2a 2a 20 69 66 20 69 74 20 69 73 20 72 65 6c  .** if it is rel
4410: 61 74 69 76 65 2e 0a 2a 2f 0a 69 6e 74 20 66 69  ative..*/.int fi
4420: 6c 65 5f 69 73 5f 61 62 73 6f 6c 75 74 65 5f 70  le_is_absolute_p
4430: 61 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ath(const char *
4440: 7a 50 61 74 68 29 7b 0a 20 20 69 66 28 20 7a 50  zPath){.  if( zP
4450: 61 74 68 5b 30 5d 3d 3d 27 2f 27 0a 23 69 66 20  ath[0]=='/'.#if 
4460: 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a  defined(_WIN32).
4470: 20 20 20 20 20 20 7c 7c 20 7a 50 61 74 68 5b 30        || zPath[0
4480: 5d 3d 3d 27 5c 5c 27 0a 20 20 20 20 20 20 7c 7c  ]=='\\'.      ||
4490: 20 28 73 74 72 6c 65 6e 28 7a 50 61 74 68 29 3e   (strlen(zPath)>
44a0: 33 20 26 26 20 7a 50 61 74 68 5b 31 5d 3d 3d 27  3 && zPath[1]=='
44b0: 3a 27 0a 20 20 20 20 20 20 20 20 20 20 20 26 26  :'.           &&
44c0: 20 28 7a 50 61 74 68 5b 32 5d 3d 3d 27 5c 5c 27   (zPath[2]=='\\'
44d0: 20 7c 7c 20 7a 50 61 74 68 5b 32 5d 3d 3d 27 2f   || zPath[2]=='/
44e0: 27 29 29 0a 23 65 6e 64 69 66 0a 20 20 29 7b 0a  ')).#endif.  ){.
44f0: 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
4500: 7d 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72  }else{.    retur
4510: 6e 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  n 0;.  }.}../*.*
4520: 2a 20 43 6f 6d 70 75 74 65 20 61 20 63 61 6e 6f  * Compute a cano
4530: 6e 69 63 61 6c 20 70 61 74 68 6e 61 6d 65 20 66  nical pathname f
4540: 6f 72 20 61 20 66 69 6c 65 20 6f 72 20 64 69 72  or a file or dir
4550: 65 63 74 6f 72 79 2e 0a 2a 2a 20 4d 61 6b 65 20  ectory..** Make 
4560: 74 68 65 20 6e 61 6d 65 20 61 62 73 6f 6c 75 74  the name absolut
4570: 65 20 69 66 20 69 74 20 69 73 20 72 65 6c 61 74  e if it is relat
4580: 69 76 65 2e 0a 2a 2a 20 52 65 6d 6f 76 65 20 72  ive..** Remove r
4590: 65 64 75 6e 64 61 6e 74 20 2f 20 63 68 61 72 61  edundant / chara
45a0: 63 74 65 72 73 0a 2a 2a 20 52 65 6d 6f 76 65 20  cters.** Remove 
45b0: 61 6c 6c 20 2f 2e 2f 20 70 61 74 68 20 65 6c 65  all /./ path ele
45c0: 6d 65 6e 74 73 2e 0a 2a 2a 20 43 6f 6e 76 65 72  ments..** Conver
45d0: 74 20 2f 41 2f 2e 2e 2f 20 74 6f 20 6a 75 73 74  t /A/../ to just
45e0: 20 2f 0a 2a 2a 20 49 66 20 74 68 65 20 73 6c 61   /.** If the sla
45f0: 73 68 20 70 61 72 61 6d 65 74 65 72 20 69 73 20  sh parameter is 
4600: 6e 6f 6e 2d 7a 65 72 6f 2c 20 74 68 65 20 74 72  non-zero, the tr
4610: 61 69 6c 69 6e 67 20 73 6c 61 73 68 2c 20 69 66  ailing slash, if
4620: 20 61 6e 79 2c 0a 2a 2a 20 69 73 20 72 65 74 61   any,.** is reta
4630: 69 6e 65 64 2e 0a 2a 2f 0a 76 6f 69 64 20 66 69  ined..*/.void fi
4640: 6c 65 5f 63 61 6e 6f 6e 69 63 61 6c 5f 6e 61 6d  le_canonical_nam
4650: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4f  e(const char *zO
4660: 72 69 67 4e 61 6d 65 2c 20 42 6c 6f 62 20 2a 70  rigName, Blob *p
4670: 4f 75 74 2c 20 69 6e 74 20 73 6c 61 73 68 29 7b  Out, int slash){
4680: 0a 20 20 69 66 28 20 66 69 6c 65 5f 69 73 5f 61  .  if( file_is_a
4690: 62 73 6f 6c 75 74 65 5f 70 61 74 68 28 7a 4f 72  bsolute_path(zOr
46a0: 69 67 4e 61 6d 65 29 20 29 7b 0a 23 69 66 20 64  igName) ){.#if d
46b0: 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20  efined(_WIN32). 
46c0: 20 20 20 63 68 61 72 20 2a 7a 4f 75 74 3b 0a 23     char *zOut;.#
46d0: 65 6e 64 69 66 0a 20 20 20 20 62 6c 6f 62 5f 73  endif.    blob_s
46e0: 65 74 28 70 4f 75 74 2c 20 7a 4f 72 69 67 4e 61  et(pOut, zOrigNa
46f0: 6d 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 6d 61  me);.    blob_ma
4700: 74 65 72 69 61 6c 69 7a 65 28 70 4f 75 74 29 3b  terialize(pOut);
4710: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 5f 57 49  .#if defined(_WI
4720: 4e 33 32 29 0a 20 20 20 20 2f 2a 0a 20 20 20 20  N32).    /*.    
4730: 2a 2a 20 4f 6e 20 57 69 6e 64 6f 77 73 2c 20 6e  ** On Windows, n
4740: 6f 72 6d 61 6c 69 7a 65 20 74 68 65 20 64 72 69  ormalize the dri
4750: 76 65 20 6c 65 74 74 65 72 20 74 6f 20 75 70 70  ve letter to upp
4760: 65 72 20 63 61 73 65 2e 0a 20 20 20 20 2a 2f 0a  er case..    */.
4770: 20 20 20 20 7a 4f 75 74 20 3d 20 62 6c 6f 62 5f      zOut = blob_
4780: 73 74 72 28 70 4f 75 74 29 3b 0a 20 20 20 20 69  str(pOut);.    i
4790: 66 28 20 66 6f 73 73 69 6c 5f 69 73 61 6c 70 68  f( fossil_isalph
47a0: 61 28 7a 4f 75 74 5b 30 5d 29 20 26 26 20 7a 4f  a(zOut[0]) && zO
47b0: 75 74 5b 31 5d 3d 3d 27 3a 27 20 29 7b 0a 20 20  ut[1]==':' ){.  
47c0: 20 20 20 20 7a 4f 75 74 5b 30 5d 20 3d 20 66 6f      zOut[0] = fo
47d0: 73 73 69 6c 5f 74 6f 75 70 70 65 72 28 7a 4f 75  ssil_toupper(zOu
47e0: 74 5b 30 5d 29 3b 0a 20 20 20 20 7d 0a 23 65 6e  t[0]);.    }.#en
47f0: 64 69 66 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  dif.  }else{.   
4800: 20 63 68 61 72 20 7a 50 77 64 5b 32 30 30 30 5d   char zPwd[2000]
4810: 3b 0a 20 20 20 20 66 69 6c 65 5f 67 65 74 63 77  ;.    file_getcw
4820: 64 28 7a 50 77 64 2c 20 73 69 7a 65 6f 66 28 7a  d(zPwd, sizeof(z
4830: 50 77 64 29 2d 73 74 72 6c 65 6e 28 7a 4f 72 69  Pwd)-strlen(zOri
4840: 67 4e 61 6d 65 29 29 3b 0a 23 69 66 20 64 65 66  gName));.#if def
4850: 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20 20 20  ined(_WIN32).   
4860: 20 2f 2a 0a 20 20 20 20 2a 2a 20 4f 6e 20 57 69   /*.    ** On Wi
4870: 6e 64 6f 77 73 2c 20 6e 6f 72 6d 61 6c 69 7a 65  ndows, normalize
4880: 20 74 68 65 20 64 72 69 76 65 20 6c 65 74 74 65   the drive lette
4890: 72 20 74 6f 20 75 70 70 65 72 20 63 61 73 65 2e  r to upper case.
48a0: 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69 66 28 20  .    */.    if( 
48b0: 66 6f 73 73 69 6c 5f 69 73 61 6c 70 68 61 28 7a  fossil_isalpha(z
48c0: 50 77 64 5b 30 5d 29 20 26 26 20 7a 50 77 64 5b  Pwd[0]) && zPwd[
48d0: 31 5d 3d 3d 27 3a 27 20 29 7b 0a 20 20 20 20 20  1]==':' ){.     
48e0: 20 7a 50 77 64 5b 30 5d 20 3d 20 66 6f 73 73 69   zPwd[0] = fossi
48f0: 6c 5f 74 6f 75 70 70 65 72 28 7a 50 77 64 5b 30  l_toupper(zPwd[0
4900: 5d 29 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66  ]);.    }.#endif
4910: 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 70  .    blob_zero(p
4920: 4f 75 74 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61  Out);.    blob_a
4930: 70 70 65 6e 64 66 28 70 4f 75 74 2c 20 22 25 2f  ppendf(pOut, "%/
4940: 2f 25 2f 22 2c 20 7a 50 77 64 2c 20 7a 4f 72 69  /%/", zPwd, zOri
4950: 67 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20 62 6c  gName);.  }.  bl
4960: 6f 62 5f 72 65 73 69 7a 65 28 70 4f 75 74 2c 20  ob_resize(pOut, 
4970: 66 69 6c 65 5f 73 69 6d 70 6c 69 66 79 5f 6e 61  file_simplify_na
4980: 6d 65 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 70  me(blob_buffer(p
4990: 4f 75 74 29 2c 0a 20 20 20 20 20 20 20 20 20 20  Out),.          
49a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
49b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 62 6c 6f               blo
49c0: 62 5f 73 69 7a 65 28 70 4f 75 74 29 2c 20 73 6c  b_size(pOut), sl
49d0: 61 73 68 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  ash));.}../*.** 
49e0: 43 4f 4d 4d 41 4e 44 3a 20 20 74 65 73 74 2d 63  COMMAND:  test-c
49f0: 61 6e 6f 6e 69 63 61 6c 2d 6e 61 6d 65 0a 2a 2a  anonical-name.**
4a00: 20 55 73 61 67 65 3a 20 25 66 6f 73 73 69 6c 20   Usage: %fossil 
4a10: 74 65 73 74 2d 63 61 6e 6f 6e 69 63 61 6c 2d 6e  test-canonical-n
4a20: 61 6d 65 20 46 49 4c 45 4e 41 4d 45 2e 2e 2e 0a  ame FILENAME....
4a30: 2a 2a 0a 2a 2a 20 54 65 73 74 20 74 68 65 20 6f  **.** Test the o
4a40: 70 65 72 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  peration of the 
4a50: 63 61 6e 6f 6e 69 63 61 6c 20 6e 61 6d 65 20 67  canonical name g
4a60: 65 6e 65 72 61 74 6f 72 2e 0a 2a 2a 20 41 6c 73  enerator..** Als
4a70: 6f 20 74 65 73 74 20 46 6f 73 73 69 6c 27 73 20  o test Fossil's 
4a80: 61 62 69 6c 69 74 79 20 74 6f 20 6d 65 61 73 75  ability to measu
4a90: 72 65 20 61 74 74 72 69 62 75 74 65 73 20 6f 66  re attributes of
4aa0: 20 61 20 66 69 6c 65 2e 0a 2a 2f 0a 76 6f 69 64   a file..*/.void
4ab0: 20 63 6d 64 5f 74 65 73 74 5f 63 61 6e 6f 6e 69   cmd_test_canoni
4ac0: 63 61 6c 5f 6e 61 6d 65 28 76 6f 69 64 29 7b 0a  cal_name(void){.
4ad0: 20 20 69 6e 74 20 69 3b 0a 20 20 42 6c 6f 62 20    int i;.  Blob 
4ae0: 78 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26  x;.  blob_zero(&
4af0: 78 29 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20 69  x);.  for(i=2; i
4b00: 3c 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20  <g.argc; i++){. 
4b10: 20 20 20 63 68 61 72 20 7a 42 75 66 5b 31 30 30     char zBuf[100
4b20: 5d 3b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61  ];.    const cha
4b30: 72 20 2a 7a 4e 61 6d 65 20 3d 20 67 2e 61 72 67  r *zName = g.arg
4b40: 76 5b 69 5d 3b 0a 20 20 20 20 66 69 6c 65 5f 63  v[i];.    file_c
4b50: 61 6e 6f 6e 69 63 61 6c 5f 6e 61 6d 65 28 7a 4e  anonical_name(zN
4b60: 61 6d 65 2c 20 26 78 2c 20 30 29 3b 0a 20 20 20  ame, &x, 0);.   
4b70: 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 5b   fossil_print("[
4b80: 25 73 5d 20 2d 3e 20 5b 25 73 5d 5c 6e 22 2c 20  %s] -> [%s]\n", 
4b90: 7a 4e 61 6d 65 2c 20 62 6c 6f 62 5f 62 75 66 66  zName, blob_buff
4ba0: 65 72 28 26 78 29 29 3b 0a 20 20 20 20 62 6c 6f  er(&x));.    blo
4bb0: 62 5f 72 65 73 65 74 28 26 78 29 3b 0a 20 20 20  b_reset(&x);.   
4bc0: 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e 74   sqlite3_snprint
4bd0: 66 28 73 69 7a 65 6f 66 28 7a 42 75 66 29 2c 20  f(sizeof(zBuf), 
4be0: 7a 42 75 66 2c 20 22 25 6c 6c 64 22 2c 20 66 69  zBuf, "%lld", fi
4bf0: 6c 65 5f 77 64 5f 73 69 7a 65 28 7a 4e 61 6d 65  le_wd_size(zName
4c00: 29 29 3b 0a 20 20 20 20 66 6f 73 73 69 6c 5f 70  ));.    fossil_p
4c10: 72 69 6e 74 28 22 20 20 66 69 6c 65 5f 73 69 7a  rint("  file_siz
4c20: 65 20 20 20 3d 20 25 73 5c 6e 22 2c 20 7a 42 75  e   = %s\n", zBu
4c30: 66 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  f);.    sqlite3_
4c40: 73 6e 70 72 69 6e 74 66 28 73 69 7a 65 6f 66 28  snprintf(sizeof(
4c50: 7a 42 75 66 29 2c 20 7a 42 75 66 2c 20 22 25 6c  zBuf), zBuf, "%l
4c60: 6c 64 22 2c 20 66 69 6c 65 5f 77 64 5f 6d 74 69  ld", file_wd_mti
4c70: 6d 65 28 7a 4e 61 6d 65 29 29 3b 0a 20 20 20 20  me(zName));.    
4c80: 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 20 20  fossil_print("  
4c90: 66 69 6c 65 5f 6d 74 69 6d 65 20 20 3d 20 25 73  file_mtime  = %s
4ca0: 5c 6e 22 2c 20 7a 42 75 66 29 3b 0a 20 20 20 20  \n", zBuf);.    
4cb0: 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 20 20  fossil_print("  
4cc0: 66 69 6c 65 5f 69 73 66 69 6c 65 20 3d 20 25 64  file_isfile = %d
4cd0: 5c 6e 22 2c 20 66 69 6c 65 5f 77 64 5f 69 73 66  \n", file_wd_isf
4ce0: 69 6c 65 28 7a 4e 61 6d 65 29 29 3b 0a 20 20 20  ile(zName));.   
4cf0: 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 20   fossil_print(" 
4d00: 20 66 69 6c 65 5f 69 73 66 69 6c 65 5f 6f 72 5f   file_isfile_or_
4d10: 6c 69 6e 6b 20 3d 20 25 64 5c 6e 22 2c 66 69 6c  link = %d\n",fil
4d20: 65 5f 77 64 5f 69 73 66 69 6c 65 5f 6f 72 5f 6c  e_wd_isfile_or_l
4d30: 69 6e 6b 28 7a 4e 61 6d 65 29 29 3b 0a 20 20 20  ink(zName));.   
4d40: 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22 20   fossil_print(" 
4d50: 20 66 69 6c 65 5f 69 73 6c 69 6e 6b 20 3d 20 25   file_islink = %
4d60: 64 5c 6e 22 2c 20 66 69 6c 65 5f 77 64 5f 69 73  d\n", file_wd_is
4d70: 6c 69 6e 6b 28 7a 4e 61 6d 65 29 29 3b 0a 20 20  link(zName));.  
4d80: 20 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22    fossil_print("
4d90: 20 20 66 69 6c 65 5f 69 73 65 78 65 20 20 3d 20    file_isexe  = 
4da0: 25 64 5c 6e 22 2c 20 66 69 6c 65 5f 77 64 5f 69  %d\n", file_wd_i
4db0: 73 65 78 65 28 7a 4e 61 6d 65 29 29 3b 0a 20 20  sexe(zName));.  
4dc0: 20 20 66 6f 73 73 69 6c 5f 70 72 69 6e 74 28 22    fossil_print("
4dd0: 20 20 66 69 6c 65 5f 69 73 64 69 72 20 20 3d 20    file_isdir  = 
4de0: 25 64 5c 6e 22 2c 20 66 69 6c 65 5f 77 64 5f 69  %d\n", file_wd_i
4df0: 73 64 69 72 28 7a 4e 61 6d 65 29 29 3b 0a 20 20  sdir(zName));.  
4e00: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  }.}../*.** Retur
4e10: 6e 20 54 52 55 45 20 69 66 20 74 68 65 20 67 69  n TRUE if the gi
4e20: 76 65 6e 20 66 69 6c 65 6e 61 6d 65 20 69 73 20  ven filename is 
4e30: 63 61 6e 6f 6e 69 63 61 6c 2e 0a 2a 2a 0a 2a 2a  canonical..**.**
4e40: 20 43 61 6e 6f 6e 69 63 61 6c 20 6e 61 6d 65 73   Canonical names
4e50: 20 61 72 65 20 66 75 6c 6c 20 70 61 74 68 6e 61   are full pathna
4e60: 6d 65 73 20 75 73 69 6e 67 20 22 2f 22 20 6e 6f  mes using "/" no
4e70: 74 20 22 5c 22 20 61 6e 64 20 77 68 69 63 68 0a  t "\" and which.
4e80: 2a 2a 20 63 6f 6e 74 61 69 6e 20 6e 6f 20 22 2f  ** contain no "/
4e90: 2e 2f 22 20 6f 72 20 22 2f 2e 2e 2f 22 20 74 65  ./" or "/../" te
4ea0: 72 6d 73 2e 0a 2a 2f 0a 69 6e 74 20 66 69 6c 65  rms..*/.int file
4eb0: 5f 69 73 5f 63 61 6e 6f 6e 69 63 61 6c 28 63 6f  _is_canonical(co
4ec0: 6e 73 74 20 63 68 61 72 20 2a 7a 29 7b 0a 20 20  nst char *z){.  
4ed0: 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 7a 5b 30  int i;.  if( z[0
4ee0: 5d 21 3d 27 2f 27 0a 23 69 66 20 64 65 66 69 6e  ]!='/'.#if defin
4ef0: 65 64 28 5f 57 49 4e 33 32 29 0a 20 20 20 20 26  ed(_WIN32).    &
4f00: 26 20 28 7a 5b 30 5d 3d 3d 30 20 7c 7c 20 7a 5b  & (z[0]==0 || z[
4f10: 31 5d 21 3d 27 3a 27 20 7c 7c 20 7a 5b 32 5d 21  1]!=':' || z[2]!
4f20: 3d 27 2f 27 29 0a 23 65 6e 64 69 66 0a 20 20 29  ='/').#endif.  )
4f30: 20 72 65 74 75 72 6e 20 30 3b 0a 0a 20 20 66 6f   return 0;..  fo
4f40: 72 28 69 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b  r(i=0; z[i]; i++
4f50: 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d  ){.    if( z[i]=
4f60: 3d 27 5c 5c 27 20 29 20 72 65 74 75 72 6e 20 30  ='\\' ) return 0
4f70: 3b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d  ;.    if( z[i]==
4f80: 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 69 66 28  '/' ){.      if(
4f90: 20 7a 5b 69 2b 31 5d 3d 3d 27 2e 27 20 29 7b 0a   z[i+1]=='.' ){.
4fa0: 20 20 20 20 20 20 20 20 69 66 28 20 7a 5b 69 2b          if( z[i+
4fb0: 32 5d 3d 3d 27 2f 27 20 7c 7c 20 7a 5b 69 2b 32  2]=='/' || z[i+2
4fc0: 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b  ]==0 ) return 0;
4fd0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 7a 5b 69  .        if( z[i
4fe0: 2b 32 5d 3d 3d 27 2e 27 20 26 26 20 28 7a 5b 69  +2]=='.' && (z[i
4ff0: 2b 33 5d 3d 3d 27 2f 27 20 7c 7c 20 7a 5b 69 2b  +3]=='/' || z[i+
5000: 33 5d 3d 3d 30 29 20 29 20 72 65 74 75 72 6e 20  3]==0) ) return 
5010: 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  0;.      }.    }
5020: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 31 3b  .  }.  return 1;
5030: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
5040: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
5050: 65 20 66 69 72 73 74 20 63 68 61 72 61 63 74 65  e first characte
5060: 72 20 69 6e 20 61 20 70 61 74 68 6e 61 6d 65 20  r in a pathname 
5070: 70 61 73 74 20 74 68 65 0a 2a 2a 20 64 72 69 76  past the.** driv
5080: 65 20 6c 65 74 74 65 72 2e 20 20 54 68 69 73 20  e letter.  This 
5090: 72 6f 75 74 69 6e 65 20 69 73 20 61 20 6e 6f 2d  routine is a no-
50a0: 6f 70 20 6f 6e 20 75 6e 69 78 2e 0a 2a 2f 0a 63  op on unix..*/.c
50b0: 68 61 72 20 2a 66 69 6c 65 5f 77 69 74 68 6f 75  har *file_withou
50c0: 74 5f 64 72 69 76 65 5f 6c 65 74 74 65 72 28 63  t_drive_letter(c
50d0: 68 61 72 20 2a 7a 49 6e 29 7b 0a 23 69 66 64 65  har *zIn){.#ifde
50e0: 66 20 5f 57 49 4e 33 32 0a 20 20 69 66 28 20 66  f _WIN32.  if( f
50f0: 6f 73 73 69 6c 5f 69 73 61 6c 70 68 61 28 7a 49  ossil_isalpha(zI
5100: 6e 5b 30 5d 29 20 26 26 20 7a 49 6e 5b 31 5d 3d  n[0]) && zIn[1]=
5110: 3d 27 3a 27 20 29 20 7a 49 6e 20 2b 3d 20 32 3b  =':' ) zIn += 2;
5120: 0a 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e  .#endif.  return
5130: 20 7a 49 6e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43   zIn;.}../*.** C
5140: 6f 6d 70 75 74 65 20 61 20 70 61 74 68 6e 61 6d  ompute a pathnam
5150: 65 20 66 6f 72 20 61 20 66 69 6c 65 20 6f 72 20  e for a file or 
5160: 64 69 72 65 63 74 6f 72 79 20 74 68 61 74 20 69  directory that i
5170: 73 20 72 65 6c 61 74 69 76 65 0a 2a 2a 20 74 6f  s relative.** to
5180: 20 74 68 65 20 63 75 72 72 65 6e 74 20 64 69 72   the current dir
5190: 65 63 74 6f 72 79 2e 20 20 49 66 20 74 68 65 20  ectory.  If the 
51a0: 73 6c 61 73 68 20 70 61 72 61 6d 65 74 65 72 20  slash parameter 
51b0: 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2c 0a 2a 2a 20  is non-zero,.** 
51c0: 74 68 65 20 74 72 61 69 6c 69 6e 67 20 73 6c 61  the trailing sla
51d0: 73 68 2c 20 69 66 20 61 6e 79 2c 20 69 73 20 72  sh, if any, is r
51e0: 65 74 61 69 6e 65 64 2e 0a 2a 2f 0a 76 6f 69 64  etained..*/.void
51f0: 20 66 69 6c 65 5f 72 65 6c 61 74 69 76 65 5f 6e   file_relative_n
5200: 61 6d 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ame(const char *
5210: 7a 4f 72 69 67 4e 61 6d 65 2c 20 42 6c 6f 62 20  zOrigName, Blob 
5220: 2a 70 4f 75 74 2c 20 69 6e 74 20 73 6c 61 73 68  *pOut, int slash
5230: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 50 61 74 68  ){.  char *zPath
5240: 3b 0a 20 20 62 6c 6f 62 5f 73 65 74 28 70 4f 75  ;.  blob_set(pOu
5250: 74 2c 20 7a 4f 72 69 67 4e 61 6d 65 29 3b 0a 20  t, zOrigName);. 
5260: 20 62 6c 6f 62 5f 72 65 73 69 7a 65 28 70 4f 75   blob_resize(pOu
5270: 74 2c 20 66 69 6c 65 5f 73 69 6d 70 6c 69 66 79  t, file_simplify
5280: 5f 6e 61 6d 65 28 62 6c 6f 62 5f 62 75 66 66 65  _name(blob_buffe
5290: 72 28 70 4f 75 74 29 2c 0a 20 20 20 20 20 20 20  r(pOut),.       
52a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
52b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
52c0: 62 6c 6f 62 5f 73 69 7a 65 28 70 4f 75 74 29 2c  blob_size(pOut),
52d0: 20 73 6c 61 73 68 29 29 3b 0a 20 20 7a 50 61 74   slash));.  zPat
52e0: 68 20 3d 20 66 69 6c 65 5f 77 69 74 68 6f 75 74  h = file_without
52f0: 5f 64 72 69 76 65 5f 6c 65 74 74 65 72 28 62 6c  _drive_letter(bl
5300: 6f 62 5f 62 75 66 66 65 72 28 70 4f 75 74 29 29  ob_buffer(pOut))
5310: 3b 0a 20 20 69 66 28 20 7a 50 61 74 68 5b 30 5d  ;.  if( zPath[0]
5320: 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 69 6e 74  =='/' ){.    int
5330: 20 69 2c 20 6a 3b 0a 20 20 20 20 42 6c 6f 62 20   i, j;.    Blob 
5340: 74 6d 70 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  tmp;.    char *z
5350: 50 77 64 3b 0a 20 20 20 20 63 68 61 72 20 7a 42  Pwd;.    char zB
5360: 75 66 5b 32 30 30 30 5d 3b 0a 20 20 20 20 7a 50  uf[2000];.    zP
5370: 77 64 20 3d 20 7a 42 75 66 3b 0a 20 20 20 20 66  wd = zBuf;.    f
5380: 69 6c 65 5f 67 65 74 63 77 64 28 7a 42 75 66 2c  ile_getcwd(zBuf,
5390: 20 73 69 7a 65 6f 66 28 7a 42 75 66 29 2d 32 30   sizeof(zBuf)-20
53a0: 29 3b 0a 20 20 20 20 7a 50 77 64 20 3d 20 66 69  );.    zPwd = fi
53b0: 6c 65 5f 77 69 74 68 6f 75 74 5f 64 72 69 76 65  le_without_drive
53c0: 5f 6c 65 74 74 65 72 28 7a 42 75 66 29 3b 0a 20  _letter(zBuf);. 
53d0: 20 20 20 69 20 3d 20 31 3b 0a 23 69 66 64 65 66     i = 1;.#ifdef
53e0: 20 5f 57 49 4e 33 32 0a 20 20 20 20 77 68 69 6c   _WIN32.    whil
53f0: 65 28 20 7a 50 61 74 68 5b 69 5d 20 26 26 20 66  e( zPath[i] && f
5400: 6f 73 73 69 6c 5f 74 6f 6c 6f 77 65 72 28 7a 50  ossil_tolower(zP
5410: 77 64 5b 69 5d 29 3d 3d 66 6f 73 73 69 6c 5f 74  wd[i])==fossil_t
5420: 6f 6c 6f 77 65 72 28 7a 50 61 74 68 5b 69 5d 29  olower(zPath[i])
5430: 20 29 20 69 2b 2b 3b 0a 23 65 6c 73 65 0a 20 20   ) i++;.#else.  
5440: 20 20 77 68 69 6c 65 28 20 7a 50 61 74 68 5b 69    while( zPath[i
5450: 5d 20 26 26 20 7a 50 77 64 5b 69 5d 3d 3d 7a 50  ] && zPwd[i]==zP
5460: 61 74 68 5b 69 5d 20 29 20 69 2b 2b 3b 0a 23 65  ath[i] ) i++;.#e
5470: 6e 64 69 66 0a 20 20 20 20 69 66 28 20 7a 50 61  ndif.    if( zPa
5480: 74 68 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20  th[i]==0 ){.    
5490: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 70 4f 75    blob_reset(pOu
54a0: 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 50  t);.      if( zP
54b0: 77 64 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20  wd[i]==0 ){.    
54c0: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28      blob_append(
54d0: 70 4f 75 74 2c 20 22 2e 22 2c 20 31 29 3b 0a 20  pOut, ".", 1);. 
54e0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
54f0: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28      blob_append(
5500: 70 4f 75 74 2c 20 22 2e 2e 22 2c 20 32 29 3b 0a  pOut, "..", 2);.
5510: 20 20 20 20 20 20 20 20 66 6f 72 28 6a 3d 69 2b          for(j=i+
5520: 31 3b 20 7a 50 77 64 5b 6a 5d 3b 20 6a 2b 2b 29  1; zPwd[j]; j++)
5530: 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  {.          if( 
5540: 7a 50 77 64 5b 6a 5d 3d 3d 27 2f 27 20 29 20 7b  zPwd[j]=='/' ) {
5550: 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 6c 6f  .            blo
5560: 62 5f 61 70 70 65 6e 64 28 70 4f 75 74 2c 20 22  b_append(pOut, "
5570: 2f 2e 2e 22 2c 20 33 29 3b 0a 20 20 20 20 20 20  /..", 3);.      
5580: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
5590: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 65        }.      re
55a0: 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20  turn;.    }.    
55b0: 69 66 28 20 7a 50 77 64 5b 69 5d 3d 3d 30 20 26  if( zPwd[i]==0 &
55c0: 26 20 7a 50 61 74 68 5b 69 5d 3d 3d 27 2f 27 20  & zPath[i]=='/' 
55d0: 29 7b 0a 20 20 20 20 20 20 6d 65 6d 63 70 79 28  ){.      memcpy(
55e0: 26 74 6d 70 2c 20 70 4f 75 74 2c 20 73 69 7a 65  &tmp, pOut, size
55f0: 6f 66 28 74 6d 70 29 29 3b 0a 20 20 20 20 20 20  of(tmp));.      
5600: 62 6c 6f 62 5f 73 65 74 28 70 4f 75 74 2c 20 22  blob_set(pOut, "
5610: 2e 2f 22 29 3b 0a 20 20 20 20 20 20 62 6c 6f 62  ./");.      blob
5620: 5f 61 70 70 65 6e 64 28 70 4f 75 74 2c 20 26 7a  _append(pOut, &z
5630: 50 61 74 68 5b 69 2b 31 5d 2c 20 2d 31 29 3b 0a  Path[i+1], -1);.
5640: 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74        blob_reset
5650: 28 26 74 6d 70 29 3b 0a 20 20 20 20 20 20 72 65  (&tmp);.      re
5660: 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20  turn;.    }.    
5670: 77 68 69 6c 65 28 20 7a 50 61 74 68 5b 69 2d 31  while( zPath[i-1
5680: 5d 21 3d 27 2f 27 20 29 7b 20 69 2d 2d 3b 20 7d  ]!='/' ){ i--; }
5690: 0a 20 20 20 20 62 6c 6f 62 5f 73 65 74 28 26 74  .    blob_set(&t
56a0: 6d 70 2c 20 22 2e 2e 2f 22 29 3b 0a 20 20 20 20  mp, "../");.    
56b0: 66 6f 72 28 6a 3d 69 3b 20 7a 50 77 64 5b 6a 5d  for(j=i; zPwd[j]
56c0: 3b 20 6a 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66  ; j++){.      if
56d0: 28 20 7a 50 77 64 5b 6a 5d 3d 3d 27 2f 27 20 29  ( zPwd[j]=='/' )
56e0: 20 7b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f   {.        blob_
56f0: 61 70 70 65 6e 64 28 26 74 6d 70 2c 20 22 2e 2e  append(&tmp, "..
5700: 2f 22 2c 20 33 29 3b 0a 20 20 20 20 20 20 7d 0a  /", 3);.      }.
5710: 20 20 20 20 7d 0a 20 20 20 20 62 6c 6f 62 5f 61      }.    blob_a
5720: 70 70 65 6e 64 28 26 74 6d 70 2c 20 26 7a 50 61  ppend(&tmp, &zPa
5730: 74 68 5b 69 5d 2c 20 2d 31 29 3b 0a 20 20 20 20  th[i], -1);.    
5740: 62 6c 6f 62 5f 72 65 73 65 74 28 70 4f 75 74 29  blob_reset(pOut)
5750: 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 4f 75  ;.    memcpy(pOu
5760: 74 2c 20 26 74 6d 70 2c 20 73 69 7a 65 6f 66 28  t, &tmp, sizeof(
5770: 74 6d 70 29 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  tmp));.  }.}../*
5780: 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 20 74 65  .** COMMAND:  te
5790: 73 74 2d 72 65 6c 61 74 69 76 65 2d 6e 61 6d 65  st-relative-name
57a0: 0a 2a 2a 0a 2a 2a 20 54 65 73 74 20 74 68 65 20  .**.** Test the 
57b0: 6f 70 65 72 61 74 69 6f 6e 20 6f 66 20 74 68 65  operation of the
57c0: 20 72 65 6c 61 74 69 76 65 20 6e 61 6d 65 20 67   relative name g
57d0: 65 6e 65 72 61 74 6f 72 2e 0a 2a 2f 0a 76 6f 69  enerator..*/.voi
57e0: 64 20 63 6d 64 5f 74 65 73 74 5f 72 65 6c 61 74  d cmd_test_relat
57f0: 69 76 65 5f 6e 61 6d 65 28 76 6f 69 64 29 7b 0a  ive_name(void){.
5800: 20 20 69 6e 74 20 69 3b 0a 20 20 42 6c 6f 62 20    int i;.  Blob 
5810: 78 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26  x;.  blob_zero(&
5820: 78 29 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20 69  x);.  for(i=2; i
5830: 3c 67 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20  <g.argc; i++){. 
5840: 20 20 20 66 69 6c 65 5f 72 65 6c 61 74 69 76 65     file_relative
5850: 5f 6e 61 6d 65 28 67 2e 61 72 67 76 5b 69 5d 2c  _name(g.argv[i],
5860: 20 26 78 2c 20 30 29 3b 0a 20 20 20 20 66 6f 73   &x, 0);.    fos
5870: 73 69 6c 5f 70 72 69 6e 74 28 22 25 73 5c 6e 22  sil_print("%s\n"
5880: 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 78  , blob_buffer(&x
5890: 29 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73  ));.    blob_res
58a0: 65 74 28 26 78 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  et(&x);.  }.}../
58b0: 2a 0a 2a 2a 20 43 6f 6d 70 75 74 65 20 61 20 70  *.** Compute a p
58c0: 61 74 68 6e 61 6d 65 20 66 6f 72 20 61 20 66 69  athname for a fi
58d0: 6c 65 20 72 65 6c 61 74 69 76 65 20 74 6f 20 74  le relative to t
58e0: 68 65 20 72 6f 6f 74 20 6f 66 20 74 68 65 20 6c  he root of the l
58f0: 6f 63 61 6c 0a 2a 2a 20 74 72 65 65 2e 20 20 52  ocal.** tree.  R
5900: 65 74 75 72 6e 20 54 52 55 45 20 6f 6e 20 73 75  eturn TRUE on su
5910: 63 63 65 73 73 2e 20 20 4f 6e 20 66 61 69 6c 75  ccess.  On failu
5920: 72 65 2c 20 70 72 69 6e 74 20 61 6e 64 20 65 72  re, print and er
5930: 72 6f 72 0a 2a 2a 20 6d 65 73 73 61 67 65 20 61  ror.** message a
5940: 6e 64 20 71 75 69 74 20 69 66 20 74 68 65 20 65  nd quit if the e
5950: 72 72 46 61 74 61 6c 20 66 6c 61 67 20 69 73 20  rrFatal flag is 
5960: 74 72 75 65 2e 20 20 49 66 20 65 72 72 46 61 74  true.  If errFat
5970: 61 6c 20 69 73 0a 2a 2a 20 66 61 6c 73 65 2c 20  al is.** false, 
5980: 74 68 65 6e 20 73 69 6d 70 6c 79 20 72 65 74 75  then simply retu
5990: 72 6e 20 30 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  rn 0..**.** The 
59a0: 72 6f 6f 74 20 6f 66 20 74 68 65 20 74 72 65 65  root of the tree
59b0: 20 69 73 20 64 65 66 69 6e 65 64 20 62 79 20 74   is defined by t
59c0: 68 65 20 67 2e 7a 4c 6f 63 61 6c 52 6f 6f 74 20  he g.zLocalRoot 
59d0: 76 61 72 69 61 62 6c 65 2e 0a 2a 2f 0a 69 6e 74  variable..*/.int
59e0: 20 66 69 6c 65 5f 74 72 65 65 5f 6e 61 6d 65 28   file_tree_name(
59f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4f 72 69  const char *zOri
5a00: 67 4e 61 6d 65 2c 20 42 6c 6f 62 20 2a 70 4f 75  gName, Blob *pOu
5a10: 74 2c 20 69 6e 74 20 65 72 72 46 61 74 61 6c 29  t, int errFatal)
5a20: 7b 0a 20 20 42 6c 6f 62 20 6c 6f 63 61 6c 52 6f  {.  Blob localRo
5a30: 6f 74 3b 0a 20 20 69 6e 74 20 6e 4c 6f 63 61 6c  ot;.  int nLocal
5a40: 52 6f 6f 74 3b 0a 20 20 63 68 61 72 20 2a 7a 4c  Root;.  char *zL
5a50: 6f 63 61 6c 52 6f 6f 74 3b 0a 20 20 42 6c 6f 62  ocalRoot;.  Blob
5a60: 20 66 75 6c 6c 3b 0a 20 20 69 6e 74 20 6e 46 75   full;.  int nFu
5a70: 6c 6c 3b 0a 20 20 63 68 61 72 20 2a 7a 46 75 6c  ll;.  char *zFul
5a80: 6c 3b 0a 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28  l;..  blob_zero(
5a90: 70 4f 75 74 29 3b 0a 20 20 64 62 5f 6d 75 73 74  pOut);.  db_must
5aa0: 5f 62 65 5f 77 69 74 68 69 6e 5f 74 72 65 65 28  _be_within_tree(
5ab0: 29 3b 0a 20 20 66 69 6c 65 5f 63 61 6e 6f 6e 69  );.  file_canoni
5ac0: 63 61 6c 5f 6e 61 6d 65 28 67 2e 7a 4c 6f 63 61  cal_name(g.zLoca
5ad0: 6c 52 6f 6f 74 2c 20 26 6c 6f 63 61 6c 52 6f 6f  lRoot, &localRoo
5ae0: 74 2c 20 31 29 3b 0a 20 20 6e 4c 6f 63 61 6c 52  t, 1);.  nLocalR
5af0: 6f 6f 74 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28  oot = blob_size(
5b00: 26 6c 6f 63 61 6c 52 6f 6f 74 29 3b 0a 20 20 7a  &localRoot);.  z
5b10: 4c 6f 63 61 6c 52 6f 6f 74 20 3d 20 62 6c 6f 62  LocalRoot = blob
5b20: 5f 62 75 66 66 65 72 28 26 6c 6f 63 61 6c 52 6f  _buffer(&localRo
5b30: 6f 74 29 3b 0a 20 20 61 73 73 65 72 74 28 20 6e  ot);.  assert( n
5b40: 4c 6f 63 61 6c 52 6f 6f 74 3e 30 20 26 26 20 7a  LocalRoot>0 && z
5b50: 4c 6f 63 61 6c 52 6f 6f 74 5b 6e 4c 6f 63 61 6c  LocalRoot[nLocal
5b60: 52 6f 6f 74 2d 31 5d 3d 3d 27 2f 27 20 29 3b 0a  Root-1]=='/' );.
5b70: 20 20 66 69 6c 65 5f 63 61 6e 6f 6e 69 63 61 6c    file_canonical
5b80: 5f 6e 61 6d 65 28 7a 4f 72 69 67 4e 61 6d 65 2c  _name(zOrigName,
5b90: 20 26 66 75 6c 6c 2c 20 30 29 3b 0a 20 20 6e 46   &full, 0);.  nF
5ba0: 75 6c 6c 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28  ull = blob_size(
5bb0: 26 66 75 6c 6c 29 3b 0a 20 20 7a 46 75 6c 6c 20  &full);.  zFull 
5bc0: 3d 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 66  = blob_buffer(&f
5bd0: 75 6c 6c 29 3b 0a 0a 20 20 2f 2a 20 53 70 65 63  ull);..  /* Spec
5be0: 69 61 6c 20 63 61 73 65 2e 20 20 7a 4f 72 69 67  ial case.  zOrig
5bf0: 4e 61 6d 65 20 72 65 66 65 72 73 20 74 6f 20 67  Name refers to g
5c00: 2e 7a 4c 6f 63 61 6c 52 6f 6f 74 20 64 69 72 65  .zLocalRoot dire
5c10: 63 74 6f 72 79 2e 20 2a 2f 0a 20 20 69 66 28 20  ctory. */.  if( 
5c20: 6e 46 75 6c 6c 3d 3d 6e 4c 6f 63 61 6c 52 6f 6f  nFull==nLocalRoo
5c30: 74 2d 31 20 26 26 20 6d 65 6d 63 6d 70 28 7a 4c  t-1 && memcmp(zL
5c40: 6f 63 61 6c 52 6f 6f 74 2c 20 7a 46 75 6c 6c 2c  ocalRoot, zFull,
5c50: 20 6e 46 75 6c 6c 29 3d 3d 30 20 29 7b 0a 20 20   nFull)==0 ){.  
5c60: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 4f    blob_append(pO
5c70: 75 74 2c 20 22 2e 22 2c 20 31 29 3b 0a 20 20 20  ut, ".", 1);.   
5c80: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 6c 6f 63   blob_reset(&loc
5c90: 61 6c 52 6f 6f 74 29 3b 0a 20 20 20 20 62 6c 6f  alRoot);.    blo
5ca0: 62 5f 72 65 73 65 74 28 26 66 75 6c 6c 29 3b 0a  b_reset(&full);.
5cb0: 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20      return 1;.  
5cc0: 7d 0a 0a 20 20 69 66 28 20 6e 46 75 6c 6c 3c 3d  }..  if( nFull<=
5cd0: 6e 4c 6f 63 61 6c 52 6f 6f 74 20 7c 7c 20 6d 65  nLocalRoot || me
5ce0: 6d 63 6d 70 28 7a 4c 6f 63 61 6c 52 6f 6f 74 2c  mcmp(zLocalRoot,
5cf0: 20 7a 46 75 6c 6c 2c 20 6e 4c 6f 63 61 6c 52 6f   zFull, nLocalRo
5d00: 6f 74 29 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f  ot) ){.    blob_
5d10: 72 65 73 65 74 28 26 6c 6f 63 61 6c 52 6f 6f 74  reset(&localRoot
5d20: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  );.    blob_rese
5d30: 74 28 26 66 75 6c 6c 29 3b 0a 20 20 20 20 69 66  t(&full);.    if
5d40: 28 20 65 72 72 46 61 74 61 6c 20 29 7b 0a 20 20  ( errFatal ){.  
5d50: 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c      fossil_fatal
5d60: 28 22 66 69 6c 65 20 6f 75 74 73 69 64 65 20 6f  ("file outside o
5d70: 66 20 63 68 65 63 6b 6f 75 74 20 74 72 65 65 3a  f checkout tree:
5d80: 20 25 73 22 2c 20 7a 4f 72 69 67 4e 61 6d 65 29   %s", zOrigName)
5d90: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 72 65 74 75  ;.    }.    retu
5da0: 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62  rn 0;.  }.  blob
5db0: 5f 61 70 70 65 6e 64 28 70 4f 75 74 2c 20 26 7a  _append(pOut, &z
5dc0: 46 75 6c 6c 5b 6e 4c 6f 63 61 6c 52 6f 6f 74 5d  Full[nLocalRoot]
5dd0: 2c 20 6e 46 75 6c 6c 2d 6e 4c 6f 63 61 6c 52 6f  , nFull-nLocalRo
5de0: 6f 74 29 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 65  ot);.  blob_rese
5df0: 74 28 26 6c 6f 63 61 6c 52 6f 6f 74 29 3b 0a 20  t(&localRoot);. 
5e00: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 66 75 6c   blob_reset(&ful
5e10: 6c 29 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a  l);.  return 1;.
5e20: 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44  }../*.** COMMAND
5e30: 3a 20 20 74 65 73 74 2d 74 72 65 65 2d 6e 61 6d  :  test-tree-nam
5e40: 65 0a 2a 2a 0a 2a 2a 20 54 65 73 74 20 74 68 65  e.**.** Test the
5e50: 20 6f 70 65 72 61 74 69 6f 6e 20 6f 66 20 74 68   operation of th
5e60: 65 20 74 72 65 65 20 6e 61 6d 65 20 67 65 6e 65  e tree name gene
5e70: 72 61 74 6f 72 2e 0a 2a 2f 0a 76 6f 69 64 20 63  rator..*/.void c
5e80: 6d 64 5f 74 65 73 74 5f 74 72 65 65 5f 6e 61 6d  md_test_tree_nam
5e90: 65 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69  e(void){.  int i
5ea0: 3b 0a 20 20 42 6c 6f 62 20 78 3b 0a 20 20 62 6c  ;.  Blob x;.  bl
5eb0: 6f 62 5f 7a 65 72 6f 28 26 78 29 3b 0a 20 20 66  ob_zero(&x);.  f
5ec0: 6f 72 28 69 3d 32 3b 20 69 3c 67 2e 61 72 67 63  or(i=2; i<g.argc
5ed0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  ; i++){.    if( 
5ee0: 66 69 6c 65 5f 74 72 65 65 5f 6e 61 6d 65 28 67  file_tree_name(g
5ef0: 2e 61 72 67 76 5b 69 5d 2c 20 26 78 2c 20 31 29  .argv[i], &x, 1)
5f00: 20 29 7b 0a 20 20 20 20 20 20 66 6f 73 73 69 6c   ){.      fossil
5f10: 5f 70 72 69 6e 74 28 22 25 73 5c 6e 22 2c 20 62  _print("%s\n", b
5f20: 6c 6f 62 5f 62 75 66 66 65 72 28 26 78 29 29 3b  lob_buffer(&x));
5f30: 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 73 65  .      blob_rese
5f40: 74 28 26 78 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  t(&x);.    }.  }
5f50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 73 65 20  .}../*.** Parse 
5f60: 61 20 55 52 49 20 69 6e 74 6f 20 73 63 68 65 6d  a URI into schem
5f70: 65 2c 20 68 6f 73 74 2c 20 70 6f 72 74 2c 20 61  e, host, port, a
5f80: 6e 64 20 70 61 74 68 2e 0a 2a 2f 0a 76 6f 69 64  nd path..*/.void
5f90: 20 66 69 6c 65 5f 70 61 72 73 65 5f 75 72 69 28   file_parse_uri(
5fa0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5fb0: 55 72 69 2c 0a 20 20 42 6c 6f 62 20 2a 70 53 63  Uri,.  Blob *pSc
5fc0: 68 65 6d 65 2c 0a 20 20 42 6c 6f 62 20 2a 70 48  heme,.  Blob *pH
5fd0: 6f 73 74 2c 0a 20 20 69 6e 74 20 2a 70 50 6f 72  ost,.  int *pPor
5fe0: 74 2c 0a 20 20 42 6c 6f 62 20 2a 70 50 61 74 68  t,.  Blob *pPath
5ff0: 0a 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a  .){.  int i, j;.
6000: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 55 72 69  .  for(i=0; zUri
6010: 5b 69 5d 20 26 26 20 7a 55 72 69 5b 69 5d 3e 3d  [i] && zUri[i]>=
6020: 27 61 27 20 26 26 20 7a 55 72 69 5b 69 5d 3c 3d  'a' && zUri[i]<=
6030: 27 7a 27 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69 66  'z'; i++){}.  if
6040: 28 20 7a 55 72 69 5b 69 5d 21 3d 27 3a 27 20 29  ( zUri[i]!=':' )
6050: 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28  {.    blob_zero(
6060: 70 53 63 68 65 6d 65 29 3b 0a 20 20 20 20 62 6c  pScheme);.    bl
6070: 6f 62 5f 7a 65 72 6f 28 70 48 6f 73 74 29 3b 0a  ob_zero(pHost);.
6080: 20 20 20 20 62 6c 6f 62 5f 73 65 74 28 70 50 61      blob_set(pPa
6090: 74 68 2c 20 7a 55 72 69 29 3b 0a 20 20 20 20 72  th, zUri);.    r
60a0: 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 62 6c 6f  eturn;.  }.  blo
60b0: 62 5f 69 6e 69 74 28 70 53 63 68 65 6d 65 2c 20  b_init(pScheme, 
60c0: 7a 55 72 69 2c 20 69 29 3b 0a 20 20 69 2b 2b 3b  zUri, i);.  i++;
60d0: 0a 20 20 69 66 28 20 7a 55 72 69 5b 69 5d 3d 3d  .  if( zUri[i]==
60e0: 27 2f 27 20 26 26 20 7a 55 72 69 5b 69 2b 31 5d  '/' && zUri[i+1]
60f0: 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 69 20 2b  =='/' ){.    i +
6100: 3d 20 32 3b 0a 20 20 20 20 6a 20 3d 20 69 3b 0a  = 2;.    j = i;.
6110: 20 20 20 20 77 68 69 6c 65 28 20 7a 55 72 69 5b      while( zUri[
6120: 69 5d 20 26 26 20 7a 55 72 69 5b 69 5d 21 3d 27  i] && zUri[i]!='
6130: 2f 27 20 26 26 20 7a 55 72 69 5b 69 5d 21 3d 27  /' && zUri[i]!='
6140: 3a 27 20 29 7b 20 69 2b 2b 3b 20 7d 0a 20 20 20  :' ){ i++; }.   
6150: 20 62 6c 6f 62 5f 69 6e 69 74 28 70 48 6f 73 74   blob_init(pHost
6160: 2c 20 26 7a 55 72 69 5b 6a 5d 2c 20 69 2d 6a 29  , &zUri[j], i-j)
6170: 3b 0a 20 20 20 20 69 66 28 20 7a 55 72 69 5b 69  ;.    if( zUri[i
6180: 5d 3d 3d 27 3a 27 20 29 7b 0a 20 20 20 20 20 20  ]==':' ){.      
6190: 69 2b 2b 3b 0a 20 20 20 20 20 20 2a 70 50 6f 72  i++;.      *pPor
61a0: 74 20 3d 20 61 74 6f 69 28 26 7a 55 72 69 5b 69  t = atoi(&zUri[i
61b0: 5d 29 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28  ]);.      while(
61c0: 20 7a 55 72 69 5b 69 5d 20 26 26 20 7a 55 72 69   zUri[i] && zUri
61d0: 5b 69 5d 21 3d 27 2f 27 20 29 7b 20 69 2b 2b 3b  [i]!='/' ){ i++;
61e0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65 6c 73 65   }.    }.  }else
61f0: 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28  {.    blob_zero(
6200: 70 48 6f 73 74 29 3b 0a 20 20 7d 0a 20 20 69 66  pHost);.  }.  if
6210: 28 20 7a 55 72 69 5b 69 5d 3d 3d 27 2f 27 20 29  ( zUri[i]=='/' )
6220: 7b 0a 20 20 20 20 62 6c 6f 62 5f 73 65 74 28 70  {.    blob_set(p
6230: 50 61 74 68 2c 20 26 7a 55 72 69 5b 69 5d 29 3b  Path, &zUri[i]);
6240: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 62 6c  .  }else{.    bl
6250: 6f 62 5f 73 65 74 28 70 50 61 74 68 2c 20 22 2f  ob_set(pPath, "/
6260: 22 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a  ");.  }.}../*.**
6270: 20 43 6f 6e 73 74 72 75 63 74 20 61 20 72 61 6e   Construct a ran
6280: 64 6f 6d 20 74 65 6d 70 6f 72 61 72 79 20 66 69  dom temporary fi
6290: 6c 65 6e 61 6d 65 20 69 6e 74 6f 20 7a 42 75 66  lename into zBuf
62a0: 5b 5d 2e 0a 2a 2f 0a 76 6f 69 64 20 66 69 6c 65  []..*/.void file
62b0: 5f 74 65 6d 70 6e 61 6d 65 28 69 6e 74 20 6e 42  _tempname(int nB
62c0: 75 66 2c 20 63 68 61 72 20 2a 7a 42 75 66 29 7b  uf, char *zBuf){
62d0: 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20  .  static const 
62e0: 63 68 61 72 20 2a 61 7a 44 69 72 73 5b 5d 20 3d  char *azDirs[] =
62f0: 20 7b 0a 23 69 66 20 64 65 66 69 6e 65 64 28 5f   {.#if defined(_
6300: 57 49 4e 33 32 29 0a 20 20 20 20 20 30 2c 20 2f  WIN32).     0, /
6310: 2a 20 47 65 74 54 65 6d 70 50 61 74 68 20 2a 2f  * GetTempPath */
6320: 0a 20 20 20 20 20 30 2c 20 2f 2a 20 54 45 4d 50  .     0, /* TEMP
6330: 20 2a 2f 0a 20 20 20 20 20 30 2c 20 2f 2a 20 54   */.     0, /* T
6340: 4d 50 20 2a 2f 0a 23 65 6c 73 65 0a 20 20 20 20  MP */.#else.    
6350: 20 22 2f 76 61 72 2f 74 6d 70 22 2c 0a 20 20 20   "/var/tmp",.   
6360: 20 20 22 2f 75 73 72 2f 74 6d 70 22 2c 0a 20 20    "/usr/tmp",.  
6370: 20 20 20 22 2f 74 6d 70 22 2c 0a 20 20 20 20 20     "/tmp",.     
6380: 22 2f 74 65 6d 70 22 2c 0a 23 65 6e 64 69 66 0a  "/temp",.#endif.
6390: 20 20 20 20 20 22 2e 22 2c 0a 20 20 7d 3b 0a 20       ".",.  };. 
63a0: 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 75 6e   static const un
63b0: 73 69 67 6e 65 64 20 63 68 61 72 20 7a 43 68 61  signed char zCha
63c0: 72 73 5b 5d 20 3d 0a 20 20 20 20 22 61 62 63 64  rs[] =.    "abcd
63d0: 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74  efghijklmnopqrst
63e0: 75 76 77 78 79 7a 22 0a 20 20 20 20 22 41 42 43  uvwxyz".    "ABC
63f0: 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53  DEFGHIJKLMNOPQRS
6400: 54 55 56 57 58 59 5a 22 0a 20 20 20 20 22 30 31  TUVWXYZ".    "01
6410: 32 33 34 35 36 37 38 39 22 3b 0a 20 20 75 6e 73  23456789";.  uns
6420: 69 67 6e 65 64 20 69 6e 74 20 69 2c 20 6a 3b 0a  igned int i, j;.
6430: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
6440: 69 72 20 3d 20 22 2e 22 3b 0a 20 20 69 6e 74 20  ir = ".";.  int 
6450: 63 6e 74 20 3d 20 30 3b 0a 0a 23 69 66 20 64 65  cnt = 0;..#if de
6460: 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20 20  fined(_WIN32).  
6470: 77 63 68 61 72 5f 74 20 7a 54 6d 70 50 61 74 68  wchar_t zTmpPath
6480: 5b 4d 41 58 5f 50 41 54 48 5d 3b 0a 0a 20 20 69  [MAX_PATH];..  i
6490: 66 28 20 47 65 74 54 65 6d 70 50 61 74 68 57 28  f( GetTempPathW(
64a0: 4d 41 58 5f 50 41 54 48 2c 20 7a 54 6d 70 50 61  MAX_PATH, zTmpPa
64b0: 74 68 29 20 29 7b 0a 20 20 20 20 61 7a 44 69 72  th) ){.    azDir
64c0: 73 5b 30 5d 20 3d 20 66 6f 73 73 69 6c 5f 66 69  s[0] = fossil_fi
64d0: 6c 65 6e 61 6d 65 5f 74 6f 5f 75 74 66 38 28 7a  lename_to_utf8(z
64e0: 54 6d 70 50 61 74 68 29 3b 0a 20 20 7d 0a 0a 20  TmpPath);.  }.. 
64f0: 20 61 7a 44 69 72 73 5b 31 5d 20 3d 20 66 6f 73   azDirs[1] = fos
6500: 73 69 6c 5f 67 65 74 65 6e 76 28 22 54 45 4d 50  sil_getenv("TEMP
6510: 22 29 3b 0a 20 20 61 7a 44 69 72 73 5b 32 5d 20  ");.  azDirs[2] 
6520: 3d 20 66 6f 73 73 69 6c 5f 67 65 74 65 6e 76 28  = fossil_getenv(
6530: 22 54 4d 50 22 29 3b 0a 23 65 6e 64 69 66 0a 0a  "TMP");.#endif..
6540: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69  .  for(i=0; i<si
6550: 7a 65 6f 66 28 61 7a 44 69 72 73 29 2f 73 69 7a  zeof(azDirs)/siz
6560: 65 6f 66 28 61 7a 44 69 72 73 5b 30 5d 29 3b 20  eof(azDirs[0]); 
6570: 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 61 7a  i++){.    if( az
6580: 44 69 72 73 5b 69 5d 3d 3d 30 20 29 20 63 6f 6e  Dirs[i]==0 ) con
6590: 74 69 6e 75 65 3b 0a 20 20 20 20 69 66 28 20 21  tinue;.    if( !
65a0: 66 69 6c 65 5f 69 73 64 69 72 28 61 7a 44 69 72  file_isdir(azDir
65b0: 73 5b 69 5d 29 20 29 20 63 6f 6e 74 69 6e 75 65  s[i]) ) continue
65c0: 3b 0a 20 20 20 20 7a 44 69 72 20 3d 20 61 7a 44  ;.    zDir = azD
65d0: 69 72 73 5b 69 5d 3b 0a 20 20 20 20 62 72 65 61  irs[i];.    brea
65e0: 6b 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 68 65  k;.  }..  /* Che
65f0: 63 6b 20 74 68 61 74 20 74 68 65 20 6f 75 74 70  ck that the outp
6600: 75 74 20 62 75 66 66 65 72 20 69 73 20 6c 61 72  ut buffer is lar
6610: 67 65 20 65 6e 6f 75 67 68 20 66 6f 72 20 74 68  ge enough for th
6620: 65 20 74 65 6d 70 6f 72 61 72 79 20 66 69 6c 65  e temporary file
6630: 0a 20 20 2a 2a 20 6e 61 6d 65 2e 20 49 66 20 69  .  ** name. If i
6640: 74 20 69 73 20 6e 6f 74 2c 20 72 65 74 75 72 6e  t is not, return
6650: 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 2e 0a 20   SQLITE_ERROR.. 
6660: 20 2a 2f 0a 20 20 69 66 28 20 28 73 74 72 6c 65   */.  if( (strle
6670: 6e 28 7a 44 69 72 29 20 2b 20 31 37 29 20 3e 3d  n(zDir) + 17) >=
6680: 20 28 73 69 7a 65 5f 74 29 6e 42 75 66 20 29 7b   (size_t)nBuf ){
6690: 0a 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61  .    fossil_fata
66a0: 6c 28 22 69 6e 73 75 66 66 69 63 69 65 6e 74 20  l("insufficient 
66b0: 73 70 61 63 65 20 66 6f 72 20 74 65 6d 70 6f 72  space for tempor
66c0: 61 72 79 20 66 69 6c 65 6e 61 6d 65 22 29 3b 0a  ary filename");.
66d0: 20 20 7d 0a 0a 20 20 64 6f 7b 0a 20 20 20 20 69    }..  do{.    i
66e0: 66 28 20 63 6e 74 2b 2b 3e 32 30 20 29 20 66 6f  f( cnt++>20 ) fo
66f0: 73 73 69 6c 5f 70 61 6e 69 63 28 22 63 61 6e 6e  ssil_panic("cann
6700: 6f 74 20 67 65 6e 65 72 61 74 65 20 61 20 74 65  ot generate a te
6710: 6d 70 6f 72 61 72 79 20 66 69 6c 65 6e 61 6d 65  mporary filename
6720: 22 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  ");.    sqlite3_
6730: 73 6e 70 72 69 6e 74 66 28 6e 42 75 66 2d 31 37  snprintf(nBuf-17
6740: 2c 20 7a 42 75 66 2c 20 22 25 73 2f 22 2c 20 7a  , zBuf, "%s/", z
6750: 44 69 72 29 3b 0a 20 20 20 20 6a 20 3d 20 28 69  Dir);.    j = (i
6760: 6e 74 29 73 74 72 6c 65 6e 28 7a 42 75 66 29 3b  nt)strlen(zBuf);
6770: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 61 6e  .    sqlite3_ran
6780: 64 6f 6d 6e 65 73 73 28 31 35 2c 20 26 7a 42 75  domness(15, &zBu
6790: 66 5b 6a 5d 29 3b 0a 20 20 20 20 66 6f 72 28 69  f[j]);.    for(i
67a0: 3d 30 3b 20 69 3c 31 35 3b 20 69 2b 2b 2c 20 6a  =0; i<15; i++, j
67b0: 2b 2b 29 7b 0a 20 20 20 20 20 20 7a 42 75 66 5b  ++){.      zBuf[
67c0: 6a 5d 20 3d 20 28 63 68 61 72 29 7a 43 68 61 72  j] = (char)zChar
67d0: 73 5b 20 28 28 75 6e 73 69 67 6e 65 64 20 63 68  s[ ((unsigned ch
67e0: 61 72 29 7a 42 75 66 5b 6a 5d 29 25 28 73 69 7a  ar)zBuf[j])%(siz
67f0: 65 6f 66 28 7a 43 68 61 72 73 29 2d 31 29 20 5d  eof(zChars)-1) ]
6800: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 7a 42 75 66  ;.    }.    zBuf
6810: 5b 6a 5d 20 3d 20 30 3b 0a 20 20 7d 77 68 69 6c  [j] = 0;.  }whil
6820: 65 28 20 66 69 6c 65 5f 73 69 7a 65 28 7a 42 75  e( file_size(zBu
6830: 66 29 3e 3d 30 20 29 3b 0a 0a 23 69 66 20 64 65  f)>=0 );..#if de
6840: 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20 20  fined(_WIN32).  
6850: 66 6f 73 73 69 6c 5f 75 6e 69 63 6f 64 65 5f 66  fossil_unicode_f
6860: 72 65 65 28 28 63 68 61 72 20 2a 29 61 7a 44 69  ree((char *)azDi
6870: 72 73 5b 31 5d 29 3b 0a 20 20 66 6f 73 73 69 6c  rs[1]);.  fossil
6880: 5f 75 6e 69 63 6f 64 65 5f 66 72 65 65 28 28 63  _unicode_free((c
6890: 68 61 72 20 2a 29 61 7a 44 69 72 73 5b 32 5d 29  har *)azDirs[2])
68a0: 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a 0a 2f 2a 0a  ;.#endif.}.../*.
68b0: 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69  ** Return true i
68c0: 66 20 61 20 66 69 6c 65 20 6e 61 6d 65 64 20 7a  f a file named z
68d0: 4e 61 6d 65 20 65 78 69 73 74 73 20 61 6e 64 20  Name exists and 
68e0: 68 61 73 20 69 64 65 6e 74 69 63 61 6c 20 63 6f  has identical co
68f0: 6e 74 65 6e 74 0a 2a 2a 20 74 6f 20 74 68 65 20  ntent.** to the 
6900: 62 6c 6f 62 20 70 43 6f 6e 74 65 6e 74 2e 20 20  blob pContent.  
6910: 49 66 20 7a 4e 61 6d 65 20 64 6f 65 73 20 6e 6f  If zName does no
6920: 74 20 65 78 69 73 74 20 6f 72 20 69 66 20 74 68  t exist or if th
6930: 65 20 63 6f 6e 74 65 6e 74 20 69 73 0a 2a 2a 20  e content is.** 
6940: 64 69 66 66 65 72 65 6e 74 20 69 6e 20 61 6e 79  different in any
6950: 20 77 61 79 2c 20 74 68 65 6e 20 72 65 74 75 72   way, then retur
6960: 6e 20 66 61 6c 73 65 2e 0a 2a 2f 0a 69 6e 74 20  n false..*/.int 
6970: 66 69 6c 65 5f 69 73 5f 74 68 65 5f 73 61 6d 65  file_is_the_same
6980: 28 42 6c 6f 62 20 2a 70 43 6f 6e 74 65 6e 74 2c  (Blob *pContent,
6990: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
69a0: 6d 65 29 7b 0a 20 20 69 36 34 20 69 53 69 7a 65  me){.  i64 iSize
69b0: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 42 6c  ;.  int rc;.  Bl
69c0: 6f 62 20 6f 6e 44 69 73 6b 3b 0a 0a 20 20 69 53  ob onDisk;..  iS
69d0: 69 7a 65 20 3d 20 66 69 6c 65 5f 77 64 5f 73 69  ize = file_wd_si
69e0: 7a 65 28 7a 4e 61 6d 65 29 3b 0a 20 20 69 66 28  ze(zName);.  if(
69f0: 20 69 53 69 7a 65 3c 30 20 29 20 72 65 74 75 72   iSize<0 ) retur
6a00: 6e 20 30 3b 0a 20 20 69 66 28 20 69 53 69 7a 65  n 0;.  if( iSize
6a10: 21 3d 62 6c 6f 62 5f 73 69 7a 65 28 70 43 6f 6e  !=blob_size(pCon
6a20: 74 65 6e 74 29 20 29 20 72 65 74 75 72 6e 20 30  tent) ) return 0
6a30: 3b 0a 20 20 69 66 28 20 66 69 6c 65 5f 77 64 5f  ;.  if( file_wd_
6a40: 69 73 6c 69 6e 6b 28 7a 4e 61 6d 65 29 20 29 7b  islink(zName) ){
6a50: 0a 20 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f 6c  .    blob_read_l
6a60: 69 6e 6b 28 26 6f 6e 44 69 73 6b 2c 20 7a 4e 61  ink(&onDisk, zNa
6a70: 6d 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  me);.  }else{.  
6a80: 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d    blob_read_from
6a90: 5f 66 69 6c 65 28 26 6f 6e 44 69 73 6b 2c 20 7a  _file(&onDisk, z
6aa0: 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20 72 63 20  Name);.  }.  rc 
6ab0: 3d 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65 28 26  = blob_compare(&
6ac0: 6f 6e 44 69 73 6b 2c 20 70 43 6f 6e 74 65 6e 74  onDisk, pContent
6ad0: 29 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28  );.  blob_reset(
6ae0: 26 6f 6e 44 69 73 6b 29 3b 0a 20 20 72 65 74 75  &onDisk);.  retu
6af0: 72 6e 20 72 63 3d 3d 30 3b 0a 7d 0a 0a 2f 2a 0a  rn rc==0;.}../*.
6b00: 2a 2a 20 50 6f 72 74 61 62 6c 65 20 75 6e 69 63  ** Portable unic
6b10: 6f 64 65 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  ode implementati
6b20: 6f 6e 20 6f 66 20 6f 70 65 6e 64 69 72 28 29 0a  on of opendir().
6b30: 2a 2f 0a 23 69 66 20 49 4e 54 45 52 46 41 43 45  */.#if INTERFACE
6b40: 0a 0a 23 69 6e 63 6c 75 64 65 20 3c 64 69 72 65  ..#include <dire
6b50: 6e 74 2e 68 3e 0a 23 69 66 20 64 65 66 69 6e 65  nt.h>.#if define
6b60: 64 28 5f 57 49 4e 33 32 29 0a 23 20 64 65 66 69  d(_WIN32).# defi
6b70: 6e 65 20 44 49 52 20 5f 57 44 49 52 0a 23 20 64  ne DIR _WDIR.# d
6b80: 65 66 69 6e 65 20 64 69 72 65 6e 74 20 5f 77 64  efine dirent _wd
6b90: 69 72 65 6e 74 0a 23 20 64 65 66 69 6e 65 20 6f  irent.# define o
6ba0: 70 65 6e 64 69 72 20 5f 77 6f 70 65 6e 64 69 72  pendir _wopendir
6bb0: 0a 23 20 64 65 66 69 6e 65 20 72 65 61 64 64 69  .# define readdi
6bc0: 72 20 5f 77 72 65 61 64 64 69 72 0a 23 20 64 65  r _wreaddir.# de
6bd0: 66 69 6e 65 20 63 6c 6f 73 65 64 69 72 20 5f 77  fine closedir _w
6be0: 63 6c 6f 73 65 64 69 72 0a 23 65 6e 64 69 66 20  closedir.#endif 
6bf0: 2f 2a 20 5f 57 49 4e 33 32 20 2a 2f 0a 0a 23 65  /* _WIN32 */..#e
6c00: 6e 64 69 66 20 2f 2a 20 49 4e 54 45 52 46 41 43  ndif /* INTERFAC
6c10: 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  E */../*.** Retu
6c20: 72 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20  rn the value of 
6c30: 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76  an environment v
6c40: 61 72 69 61 62 6c 65 20 61 73 20 55 54 46 38 2e  ariable as UTF8.
6c50: 0a 2a 2a 20 55 73 65 20 66 6f 73 73 69 6c 5f 66  .** Use fossil_f
6c60: 69 6c 65 6e 61 6d 65 5f 66 72 65 65 28 29 20 74  ilename_free() t
6c70: 6f 20 72 65 6c 65 61 73 65 20 72 65 73 6f 75 72  o release resour
6c80: 63 65 73 2e 0a 2a 2f 0a 63 68 61 72 20 2a 66 6f  ces..*/.char *fo
6c90: 73 73 69 6c 5f 67 65 74 65 6e 76 28 63 6f 6e 73  ssil_getenv(cons
6ca0: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b 0a  t char *zName){.
6cb0: 23 69 66 64 65 66 20 5f 57 49 4e 33 32 0a 20 20  #ifdef _WIN32.  
6cc0: 77 63 68 61 72 5f 74 20 2a 75 4e 61 6d 65 20 3d  wchar_t *uName =
6cd0: 20 66 6f 73 73 69 6c 5f 75 74 66 38 5f 74 6f 5f   fossil_utf8_to_
6ce0: 75 6e 69 63 6f 64 65 28 7a 4e 61 6d 65 29 3b 0a  unicode(zName);.
6cf0: 20 20 76 6f 69 64 20 2a 7a 56 61 6c 75 65 20 3d    void *zValue =
6d00: 20 5f 77 67 65 74 65 6e 76 28 75 4e 61 6d 65 29   _wgetenv(uName)
6d10: 3b 0a 20 20 66 6f 73 73 69 6c 5f 75 6e 69 63 6f  ;.  fossil_unico
6d20: 64 65 5f 66 72 65 65 28 75 4e 61 6d 65 29 3b 0a  de_free(uName);.
6d30: 23 65 6c 73 65 0a 20 20 63 68 61 72 20 2a 7a 56  #else.  char *zV
6d40: 61 6c 75 65 20 3d 20 67 65 74 65 6e 76 28 7a 4e  alue = getenv(zN
6d50: 61 6d 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20 69  ame);.#endif.  i
6d60: 66 28 20 7a 56 61 6c 75 65 20 29 20 7a 56 61 6c  f( zValue ) zVal
6d70: 75 65 20 3d 20 66 6f 73 73 69 6c 5f 66 69 6c 65  ue = fossil_file
6d80: 6e 61 6d 65 5f 74 6f 5f 75 74 66 38 28 7a 56 61  name_to_utf8(zVa
6d90: 6c 75 65 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a  lue);.  return z
6da0: 56 61 6c 75 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Value;.}../*.** 
6db0: 4c 69 6b 65 20 66 6f 70 65 6e 28 29 20 62 75 74  Like fopen() but
6dc0: 20 61 6c 77 61 79 73 20 74 61 6b 65 73 20 61 20   always takes a 
6dd0: 55 54 46 38 20 61 72 67 75 6d 65 6e 74 2e 0a 2a  UTF8 argument..*
6de0: 2f 0a 46 49 4c 45 20 2a 66 6f 73 73 69 6c 5f 66  /.FILE *fossil_f
6df0: 6f 70 65 6e 28 63 6f 6e 73 74 20 63 68 61 72 20  open(const char 
6e00: 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68  *zName, const ch
6e10: 61 72 20 2a 7a 4d 6f 64 65 29 7b 0a 23 69 66 64  ar *zMode){.#ifd
6e20: 65 66 20 5f 57 49 4e 33 32 0a 20 20 77 63 68 61  ef _WIN32.  wcha
6e30: 72 5f 74 20 2a 75 4d 6f 64 65 20 3d 20 66 6f 73  r_t *uMode = fos
6e40: 73 69 6c 5f 75 74 66 38 5f 74 6f 5f 75 6e 69 63  sil_utf8_to_unic
6e50: 6f 64 65 28 7a 4d 6f 64 65 29 3b 0a 20 20 77 63  ode(zMode);.  wc
6e60: 68 61 72 5f 74 20 2a 75 4e 61 6d 65 20 3d 20 66  har_t *uName = f
6e70: 6f 73 73 69 6c 5f 75 74 66 38 5f 74 6f 5f 66 69  ossil_utf8_to_fi
6e80: 6c 65 6e 61 6d 65 28 7a 4e 61 6d 65 29 3b 0a 20  lename(zName);. 
6e90: 20 46 49 4c 45 20 2a 66 20 3d 20 5f 77 66 6f 70   FILE *f = _wfop
6ea0: 65 6e 28 75 4e 61 6d 65 2c 20 75 4d 6f 64 65 29  en(uName, uMode)
6eb0: 3b 0a 20 20 66 6f 73 73 69 6c 5f 66 69 6c 65 6e  ;.  fossil_filen
6ec0: 61 6d 65 5f 66 72 65 65 28 75 4e 61 6d 65 29 3b  ame_free(uName);
6ed0: 0a 20 20 66 6f 73 73 69 6c 5f 75 6e 69 63 6f 64  .  fossil_unicod
6ee0: 65 5f 66 72 65 65 28 75 4d 6f 64 65 29 3b 0a 23  e_free(uMode);.#
6ef0: 65 6c 73 65 0a 20 20 46 49 4c 45 20 2a 66 20 3d  else.  FILE *f =
6f00: 20 66 6f 70 65 6e 28 7a 4e 61 6d 65 2c 20 7a 4d   fopen(zName, zM
6f10: 6f 64 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20 72  ode);.#endif.  r
6f20: 65 74 75 72 6e 20 66 3b 0a 7d 0a                 eturn f;.}.