Fossil

Check-in [19677d7629]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:When doing an open on a URI, verify that the working directory is not within an existing checkout prior to performing the clone.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 19677d76295ee6c18229dc3be8136fc3932ba25505ceb68e83ed2c7b09a4cc2b
User & Date: drh 2020-08-08 01:55:52.641
Context
2020-08-08
11:29
/wikiedit now marks "deleted" (empty) pages and offers a filter to show/hide them. check-in: 424baf1e10 user: stephan tags: trunk
01:55
When doing an open on a URI, verify that the working directory is not within an existing checkout prior to performing the clone. check-in: 19677d7629 user: drh tags: trunk
01:44
Updates to a slightly newer SQLite in an attempt to avoid a C89 declaration order issue. check-in: 0d813dbf91 user: drh tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/db.c.
3120
3121
3122
3123
3124
3125
3126


3127
3128
3129
3130
3131
3132
3133
3134
3135

3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186

3187
3188

3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202





































3203
3204
3205
3206
3207
3208
3209
  int allowSymlinks;
  int setmtimeFlag;              /* --setmtime.  Set mtimes on files */
  static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
  const char *zWorkDir;          /* --workdir value */
  const char *zRepo = 0;         /* Name of the repository file */
  const char *zRepoDir = 0;      /* --repodir value */
  Blob normalizedRepoName;       /* Normalized repository filename */



  url_proxy_options();
  emptyFlag = find_option("empty",0,0)!=0;
  keepFlag = find_option("keep",0,0)!=0;
  forceMissingFlag = find_option("force-missing",0,0)!=0;
  allowNested = find_option("nested",0,0)!=0;
  setmtimeFlag = find_option("setmtime",0,0)!=0;
  zWorkDir = find_option("workdir",0,1);
  zRepoDir = find_option("repodir",0,1);

  

  /* We should be done with options.. */
  verify_all_options();

  if( g.argc!=3 && g.argc!=4 ){
    usage("REPOSITORY-FILENAME ?VERSION?");
  }
  zRepo = g.argv[2];
  blob_init(&normalizedRepoName, 0, 0);

  /* If REPOSITORY looks like a URI, then try to clone it first */
  if( sqlite3_strglob("http://*", zRepo)==0
   || sqlite3_strglob("https://*", zRepo)==0
   || sqlite3_strglob("ssh:*", zRepo)==0
   || sqlite3_strglob("file:*", zRepo)==0
  ){
    char *zNewBase;   /* Base name of the cloned repository file */
    const char *zUri; /* URI to clone */
    int i;            /* Loop counter */
    int rc;           /* Result code from fossil_system() */
    Blob cmd;         /* Clone command to be run */
    char *zCmd;       /* String version of the clone command */

    zUri = zRepo;
    zNewBase = fossil_strdup(file_tail(zUri));
    for(i=(int)strlen(zNewBase)-1; i>1 && zNewBase[i]!='.'; i--){}
    if( zNewBase[i]=='.' ) zNewBase[i] = 0;
    if( zRepoDir==0 ) zRepoDir = ".";
    zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
    fossil_free(zNewBase);
    blob_init(&cmd, 0, 0);
    blob_append_escaped_arg(&cmd, g.nameOfExe);
    blob_append(&cmd, " clone", -1);
    blob_append_escaped_arg(&cmd, zUri);
    blob_append_escaped_arg(&cmd, zRepo);
    zCmd = blob_str(&cmd);
    fossil_print("%s\n", zCmd);
    rc = fossil_system(zCmd);
    if( rc ){
      fossil_fatal("clone of %s failed", zUri);
    }
    blob_reset(&cmd);
  }else if( zRepoDir ){
    fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
                 "argument is a URI that begins with http:, https:, ssh:, "
                 "or file:");
  }

  /* If --workdir is specified, change to the requested working directory */
  if( zWorkDir ){

    file_canonical_name(zRepo, &normalizedRepoName, 0);
    zRepo = blob_str(&normalizedRepoName);

    if( file_isdir(zWorkDir, ExtFILE)!=1 ){
      file_mkfolder(zWorkDir, ExtFILE, 0, 0);
      if( file_mkdir(zWorkDir, ExtFILE, 0) ){
        fossil_fatal("cannot create directory %s", zWorkDir);
      }
    }
    if( file_chdir(zWorkDir, 0) ){
      fossil_fatal("unable to make %s the working directory", zWorkDir);
    }
  }

  if( !allowNested && db_open_local(0) ){
    fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
  }





































  db_open_repository(zRepo);

  /* Figure out which revision to open. */
  if( !emptyFlag ){
    if( g.argc==4 ){
      g.zOpenRevision = g.argv[3];
    }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){







>
>









>










<
<





<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<


>
|
|
>














>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148


3149
3150
3151
3152
3153







3154
















3155





3156

3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
  int allowSymlinks;
  int setmtimeFlag;              /* --setmtime.  Set mtimes on files */
  static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
  const char *zWorkDir;          /* --workdir value */
  const char *zRepo = 0;         /* Name of the repository file */
  const char *zRepoDir = 0;      /* --repodir value */
  Blob normalizedRepoName;       /* Normalized repository filename */
  char *zPwd;                    /* Initial working directory */
  int isUri = 0;                 /* True if REPOSITORY is a URI */

  url_proxy_options();
  emptyFlag = find_option("empty",0,0)!=0;
  keepFlag = find_option("keep",0,0)!=0;
  forceMissingFlag = find_option("force-missing",0,0)!=0;
  allowNested = find_option("nested",0,0)!=0;
  setmtimeFlag = find_option("setmtime",0,0)!=0;
  zWorkDir = find_option("workdir",0,1);
  zRepoDir = find_option("repodir",0,1);
  zPwd = file_getcwd(0,0);
  

  /* We should be done with options.. */
  verify_all_options();

  if( g.argc!=3 && g.argc!=4 ){
    usage("REPOSITORY-FILENAME ?VERSION?");
  }
  zRepo = g.argv[2];
  blob_init(&normalizedRepoName, 0, 0);


  if( sqlite3_strglob("http://*", zRepo)==0
   || sqlite3_strglob("https://*", zRepo)==0
   || sqlite3_strglob("ssh:*", zRepo)==0
   || sqlite3_strglob("file:*", zRepo)==0
  ){







    isUri = 1;
















  }







  /* If --workdir is specified, change to the requested working directory */
  if( zWorkDir ){
    if( !isUri ){
      file_canonical_name(zRepo, &normalizedRepoName, 0);
      zRepo = blob_str(&normalizedRepoName);
    }
    if( file_isdir(zWorkDir, ExtFILE)!=1 ){
      file_mkfolder(zWorkDir, ExtFILE, 0, 0);
      if( file_mkdir(zWorkDir, ExtFILE, 0) ){
        fossil_fatal("cannot create directory %s", zWorkDir);
      }
    }
    if( file_chdir(zWorkDir, 0) ){
      fossil_fatal("unable to make %s the working directory", zWorkDir);
    }
  }

  if( !allowNested && db_open_local(0) ){
    fossil_fatal("already within an open tree rooted at %s", g.zLocalRoot);
  }

  /* If REPOSITORY looks like a URI, then try to clone it first */
  if( isUri ){
    char *zNewBase;   /* Base name of the cloned repository file */
    const char *zUri; /* URI to clone */
    int i;            /* Loop counter */
    int rc;           /* Result code from fossil_system() */
    Blob cmd;         /* Clone command to be run */
    char *zCmd;       /* String version of the clone command */

    zUri = zRepo;
    zNewBase = fossil_strdup(file_tail(zUri));
    for(i=(int)strlen(zNewBase)-1; i>1 && zNewBase[i]!='.'; i--){}
    if( zNewBase[i]=='.' ) zNewBase[i] = 0;
    if( zRepoDir==0 ) zRepoDir = zPwd;
    zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
    fossil_free(zNewBase);
    blob_init(&cmd, 0, 0);
    blob_append_escaped_arg(&cmd, g.nameOfExe);
    blob_append(&cmd, " clone", -1);
    blob_append_escaped_arg(&cmd, zUri);
    blob_append_escaped_arg(&cmd, zRepo);
    zCmd = blob_str(&cmd);
    fossil_print("%s\n", zCmd);
    if( zWorkDir ) file_chdir(zPwd, 0);
    rc = fossil_system(zCmd);
    if( rc ){
      fossil_fatal("clone of %s failed", zUri);
    }
    blob_reset(&cmd);
    if( zWorkDir ) file_chdir(zWorkDir, 0);
  }else if( zRepoDir ){
    fossil_fatal("the --repodir option only makes sense if the REPOSITORY "
                 "argument is a URI that begins with http:, https:, ssh:, "
                 "or file:");
  }

  db_open_repository(zRepo);

  /* Figure out which revision to open. */
  if( !emptyFlag ){
    if( g.argc==4 ){
      g.zOpenRevision = g.argv[3];
    }else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){