Fossil

Check-in [979a75de]
Login

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

Overview
Comment:save first version of patch for ssh from Andy Bradford (from list)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | andy_bradford_ssh_imporvement_patch_1
Files: files | file ages | folders
SHA1:979a75de0633768c375c2549d0381b54b8e9441e
User & Date: mgagnon 2013-07-10 21:31:06
Context
2013-07-10
21:31
save first version of patch for ssh from Andy Bradford (from list) Leaf check-in: 979a75de user: mgagnon tags: andy_bradford_ssh_imporvement_patch_1
2013-06-18
21:09
Version 1.26 check-in: c9cb6e72 user: drh tags: trunk, release, version-1.26
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/clone.c.

101
102
103
104
105
106
107

108
109
110
111
112
113
114
...
172
173
174
175
176
177
178









void clone_cmd(void){
  char *zPassword;
  const char *zDefaultUser;   /* Optional name of the default user */
  int nErr = 0;
  int bPrivate = 0;           /* Also clone private branches */

  if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;

  url_proxy_options();
  if( g.argc < 4 ){
    usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
  }
  db_open_config(0);
  if( file_size(g.argv[3])>0 ){
    fossil_panic("file already exists: %s", g.argv[3]);
................................................................................
  fossil_print("Rebuilding repository meta-data...\n");
  rebuild_db(0, 1, 0);
  fossil_print("project-id: %s\n", db_get("project-code", 0));
  zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
  fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
  db_end_transaction(0);
}
















>







 







>
>
>
>
>
>
>
>
>
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
...
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
void clone_cmd(void){
  char *zPassword;
  const char *zDefaultUser;   /* Optional name of the default user */
  int nErr = 0;
  int bPrivate = 0;           /* Also clone private branches */

  if( find_option("private",0,0)!=0 ) bPrivate = SYNC_PRIVATE;
  clone_ssh_options();
  url_proxy_options();
  if( g.argc < 4 ){
    usage("?OPTIONS? FILE-OR-URL NEW-REPOSITORY");
  }
  db_open_config(0);
  if( file_size(g.argv[3])>0 ){
    fossil_panic("file already exists: %s", g.argv[3]);
................................................................................
  fossil_print("Rebuilding repository meta-data...\n");
  rebuild_db(0, 1, 0);
  fossil_print("project-id: %s\n", db_get("project-code", 0));
  zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
  fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
  db_end_transaction(0);
}

void clone_ssh_options(void){
  const char *zSshRemoteCmd;  /* Path to remote fossil command for SSH */

  zSshRemoteCmd = find_option("sshremotecmd","s",1);
  if( zSshRemoteCmd && zSshRemoteCmd[0] ){
    g.fSshRemoteCmd = mprintf("%s", zSshRemoteCmd);
  }
}

Changes to src/http_transport.c.

181
182
183
184
185
186
187


188
189
190









191
192
193
194
195
196
197
...
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
...
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600









  if( g.urlIsSsh ){
    /* Only SSH requires a global initialization.  For SSH we need to create
    ** and run an SSH command to talk to the remote machine.
    */
    const char *zSsh;  /* The base SSH command */
    Blob zCmd;         /* The SSH command */
    char *zHost;       /* The host name to contact */


    int n;             /* Size of prefix string */

    zSsh = db_get("ssh-command", zDefaultSshCmd);









    blob_init(&zCmd, zSsh, -1);
    if( g.urlPort!=g.urlDfltPort ){
#ifdef __MINGW32__
      blob_appendf(&zCmd, " -P %d", g.urlPort);
#else
      blob_appendf(&zCmd, " -p %d", g.urlPort);
#endif
................................................................................
#endif
    }else{
      zHost = mprintf("%s", g.urlName);
    }
    n = blob_size(&zCmd);
    blob_append(&zCmd, " ", 1);
    shell_escape(&zCmd, zHost);
    if( g.urlShell ){
      blob_appendf(&zCmd, " %s", g.urlShell);
    }else{
#if defined(FOSSIL_ENABLE_SSH_FAR_SIDE)
      /* The following works.  But only if the fossil on the remote side
      ** is recent enough to support the test-ssh-far-side command.  That
      ** command was added on 2013-02-06.  We will leave this turned off
      ** until most fossil servers have upgraded to that version or a later
      ** version.  The sync will still work as long as the shell on the far
      ** side is bash and not tcsh.  And if the default far side shell is
      ** tcsh, then the shell=/bin/bash query parameter can be used as a
      ** work-around.  Enable this code after about a year...
      */
      blob_appendf(&zCmd, " exec %s test-ssh-far-side", g.urlFossil);
#endif
    }
    fossil_print("%s\n", blob_str(&zCmd)+n);  /* Show tail of SSH command */
    free(zHost);
    popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
    if( sshPid==0 ){
      fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
    }
    blob_reset(&zCmd);
    transport_ssh_startup();
  }
}

/*
** COMMAND: test-ssh-far-side
**
** Read lines of input text, one by one, and evaluate each line using
................................................................................
**
** Return the number of errors.
*/
int transport_open(void){
  int rc = 0;
  if( transport.isOpen==0 ){
    if( g.urlIsSsh ){
      Blob cmd;
      blob_zero(&cmd);
      shell_escape(&cmd, g.urlFossil);
      blob_append(&cmd, " test-http ", -1);
      shell_escape(&cmd, g.urlPath);
      fprintf(sshOut, "%s || true\n", blob_str(&cmd));
      fflush(sshOut);
      if( g.fSshTrace ) printf("Sent: [%s]\n", blob_str(&cmd));
      blob_reset(&cmd);
    }else if( g.urlIsHttps ){
      #ifdef FOSSIL_ENABLE_SSL
      rc = ssl_open();
      if( rc==0 ) transport.isOpen = 1;
      #else
      socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
      rc = 1;
................................................................................
    i++;
  }
  if( g.fSshTrace ) printf("Got line: [%s]\n", &transport.pBuf[iStart]);
  return &transport.pBuf[iStart];
}

void transport_global_shutdown(void){
  if( g.urlIsSsh && sshPid ){
    /*printf("Closing SSH tunnel: ");*/
    fflush(stdout);
    pclose2(sshIn, sshOut, sshPid);
    sshPid = 0;
  }
  if( g.urlIsHttps ){
    #ifdef FOSSIL_ENABLE_SSL
    ssl_global_shutdown();
    #endif
  }else{
    socket_global_shutdown();
  }
}
















>
>



>
>
>
>
>
>
>
>
>







 







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








<







 







|
<
<
<
<
<
<
<
<







 







|
<
<
<
<
<








>
>
>
>
>
>
>
>
>
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
...
232
233
234
235
236
237
238
239
240
241
242
243
244









245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
...
287
288
289
290
291
292
293
294








295
296
297
298
299
300
301
...
573
574
575
576
577
578
579
580





581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  if( g.urlIsSsh ){
    /* Only SSH requires a global initialization.  For SSH we need to create
    ** and run an SSH command to talk to the remote machine.
    */
    const char *zSsh;  /* The base SSH command */
    Blob zCmd;         /* The SSH command */
    char *zHost;       /* The host name to contact */
    char *zPath;       /* The path to the remote file for SSH */
    char *zfCmd;       /* The path to remote fossil for SSH */
    int n;             /* Size of prefix string */

    zSsh = db_get("ssh-command", zDefaultSshCmd);
    if( g.fSshRemoteCmd && g.fSshRemoteCmd[0] ){
      zfCmd = g.fSshRemoteCmd;
      db_set("last-ssh-remote-cmd", zfCmd, 0);
    }else{
      zfCmd = db_get("last-ssh-remote-cmd", 0);
      if( zfCmd==0 ){
	zfCmd = "fossil";
      }
    }
    blob_init(&zCmd, zSsh, -1);
    if( g.urlPort!=g.urlDfltPort ){
#ifdef __MINGW32__
      blob_appendf(&zCmd, " -P %d", g.urlPort);
#else
      blob_appendf(&zCmd, " -p %d", g.urlPort);
#endif
................................................................................
#endif
    }else{
      zHost = mprintf("%s", g.urlName);
    }
    n = blob_size(&zCmd);
    blob_append(&zCmd, " ", 1);
    shell_escape(&zCmd, zHost);
    blob_append(&zCmd, " ", 1);
    shell_escape(&zCmd, zfCmd);
    blob_append(&zCmd, " http ", 6);
    if( g.urlPath && g.urlPath[0] ){
      zPath = mprintf("%s", g.urlPath);
      shell_escape(&zCmd, zPath);









    }
    fossil_print("%s\n", blob_str(&zCmd)+n);  /* Show tail of SSH command */
    free(zHost);
    popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
    if( sshPid==0 ){
      fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
    }
    blob_reset(&zCmd);

  }
}

/*
** COMMAND: test-ssh-far-side
**
** Read lines of input text, one by one, and evaluate each line using
................................................................................
**
** Return the number of errors.
*/
int transport_open(void){
  int rc = 0;
  if( transport.isOpen==0 ){
    if( g.urlIsSsh ){
      /* no-op now */








    }else if( g.urlIsHttps ){
      #ifdef FOSSIL_ENABLE_SSL
      rc = ssl_open();
      if( rc==0 ) transport.isOpen = 1;
      #else
      socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
      rc = 1;
................................................................................
    i++;
  }
  if( g.fSshTrace ) printf("Got line: [%s]\n", &transport.pBuf[iStart]);
  return &transport.pBuf[iStart];
}

void transport_global_shutdown(void){
  transport_global_ssh_shutdown();





  if( g.urlIsHttps ){
    #ifdef FOSSIL_ENABLE_SSL
    ssl_global_shutdown();
    #endif
  }else{
    socket_global_shutdown();
  }
}

void transport_global_ssh_shutdown(void){
  if( g.urlIsSsh && sshPid ){
    /*printf("Closing SSH tunnel: ");*/
    fflush(stdout);
    pclose2(sshIn, sshOut, sshPid);
    sshPid = 0;
  }
}

Changes to src/main.c.

132
133
134
135
136
137
138

139
140
141
142
143
144
145
...
576
577
578
579
580
581
582

583
584
585
586
587
588
589
  int fSqlTrace;          /* True if --sqltrace flag is present */
  int fSqlStats;          /* True if --sqltrace or --sqlstats are present */
  int fSqlPrint;          /* True if -sqlprint flag is present */
  int fQuiet;             /* True if -quiet flag is present */
  int fHttpTrace;         /* Trace outbound HTTP requests */
  int fSystemTrace;       /* Trace calls to fossil_system(), --systemtrace */
  int fSshTrace;          /* Trace the SSH setup traffic */

  int fNoSync;            /* Do not do an autosync ever.  --nosync */
  char *zPath;            /* Name of webpage being served */
  char *zExtra;           /* Extra path information past the webpage name */
  char *zBaseURL;         /* Full text of the URL being served */
  char *zTop;             /* Parent directory of zPath */
  const char *zContentType;  /* The content type of the input HTTP request */
  int iErrPriority;       /* Priority of current error message */
................................................................................
    const char *zChdir = find_option("chdir",0,1);
    g.isHTTP = 0;
    g.fQuiet = find_option("quiet", 0, 0)!=0;
    g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
    g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
    g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
    g.fSshTrace = find_option("sshtrace", 0, 0)!=0;

    if( g.fSqlTrace ) g.fSqlStats = 1;
    g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
    g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
    g.zLogin = find_option("user", "U", 1);
    g.zSSLIdentity = find_option("ssl-identity", 0, 1);
    if( find_option("utc",0,0) ) g.fTimeFormat = 1;
    if( find_option("localtime",0,0) ) g.fTimeFormat = 2;







>







 







>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
...
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
  int fSqlTrace;          /* True if --sqltrace flag is present */
  int fSqlStats;          /* True if --sqltrace or --sqlstats are present */
  int fSqlPrint;          /* True if -sqlprint flag is present */
  int fQuiet;             /* True if -quiet flag is present */
  int fHttpTrace;         /* Trace outbound HTTP requests */
  int fSystemTrace;       /* Trace calls to fossil_system(), --systemtrace */
  int fSshTrace;          /* Trace the SSH setup traffic */
  char *fSshRemoteCmd;    /* Path to remoe fossil command for SSH */
  int fNoSync;            /* Do not do an autosync ever.  --nosync */
  char *zPath;            /* Name of webpage being served */
  char *zExtra;           /* Extra path information past the webpage name */
  char *zBaseURL;         /* Full text of the URL being served */
  char *zTop;             /* Parent directory of zPath */
  const char *zContentType;  /* The content type of the input HTTP request */
  int iErrPriority;       /* Priority of current error message */
................................................................................
    const char *zChdir = find_option("chdir",0,1);
    g.isHTTP = 0;
    g.fQuiet = find_option("quiet", 0, 0)!=0;
    g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
    g.fSqlStats = find_option("sqlstats", 0, 0)!=0;
    g.fSystemTrace = find_option("systemtrace", 0, 0)!=0;
    g.fSshTrace = find_option("sshtrace", 0, 0)!=0;
    g.fSshRemoteCmd = 0;
    if( g.fSqlTrace ) g.fSqlStats = 1;
    g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
    g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
    g.zLogin = find_option("user", "U", 1);
    g.zSSLIdentity = find_option("ssl-identity", 0, 1);
    if( find_option("utc",0,0) ) g.fTimeFormat = 1;
    if( find_option("localtime",0,0) ) g.fTimeFormat = 2;

Changes to src/sync.c.

92
93
94
95
96
97
98

99
100
101
102
103
104
105
  if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
  if( find_option("private",0,0)!=0 ){
    *pSyncFlags |= SYNC_PRIVATE;
  }
  if( find_option("verbose","v",0)!=0 ){
    *pSyncFlags |= SYNC_VERBOSE;
  }

  url_proxy_options();
  db_find_and_open_repository(0, 0);
  db_open_config(0);
  if( g.argc==2 ){
    if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN;
  }else if( g.argc==3 ){
    zUrl = g.argv[2];







>







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
  if( find_option("once",0,0)!=0 ) urlFlags &= ~URL_REMEMBER;
  if( find_option("private",0,0)!=0 ){
    *pSyncFlags |= SYNC_PRIVATE;
  }
  if( find_option("verbose","v",0)!=0 ){
    *pSyncFlags |= SYNC_VERBOSE;
  }
  clone_ssh_options();
  url_proxy_options();
  db_find_and_open_repository(0, 0);
  db_open_config(0);
  if( g.argc==2 ){
    if( db_get_boolean("auto-shun",1) ) configSync = CONFIGSET_SHUN;
  }else if( g.argc==3 ){
    zUrl = g.argv[2];

Changes to src/xfer.c.

1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404
....
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
....
1822
1823
1824
1825
1826
1827
1828

1829
1830
1831
1832
1833
1834
1835
  }
  if( syncFlags & SYNC_PUSH ){
    blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
    nCardSent++;
    if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
  }
  manifest_crosslink_begin();
  transport_global_startup();
  if( syncFlags & SYNC_VERBOSE ){
    fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
  }

  while( go ){

    int newPhantom = 0;
    char *zRandomness;

    /* Send make the most recently received cookie.  Let the server
    ** figure out if this is a cookie that it cares about.
    */
    zCookie = db_get("cookie", 0);
................................................................................
    nCardSent = 0;
    nCardRcvd = 0;
    xfer.nFileSent = 0;
    xfer.nDeltaSent = 0;
    xfer.nGimmeSent = 0;
    xfer.nIGotSent = 0;
    if( syncFlags & SYNC_VERBOSE ){
      fossil_print("waiting for server...");
    }
    fflush(stdout);
    if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0,
        MAX_REDIRECTS) ){
      nErr++;
      break;
    }
................................................................................

    /* Stop the cycle if the server sends a "clone_seqno 0" card and
    ** we have gone at least two rounds.  Always go at least two rounds
    ** on a clone in order to be sure to retrieve the configuration
    ** information which is only sent on the second round.
    */
    if( cloneSeqno<=0 && nCycle>1 ) go = 0;   

  };
  transport_stats(&nSent, &nRcvd, 1);
  fossil_force_newline();
  fossil_print(
     "%s finished with %lld bytes sent, %lld bytes received\n",
     zOpType, nSent, nRcvd);
  transport_close();







<





>







 







|







 







>







1385
1386
1387
1388
1389
1390
1391

1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
....
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
....
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
  }
  if( syncFlags & SYNC_PUSH ){
    blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
    nCardSent++;
    if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
  }
  manifest_crosslink_begin();

  if( syncFlags & SYNC_VERBOSE ){
    fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
  }

  while( go ){
    transport_global_startup();
    int newPhantom = 0;
    char *zRandomness;

    /* Send make the most recently received cookie.  Let the server
    ** figure out if this is a cookie that it cares about.
    */
    zCookie = db_get("cookie", 0);
................................................................................
    nCardSent = 0;
    nCardRcvd = 0;
    xfer.nFileSent = 0;
    xfer.nDeltaSent = 0;
    xfer.nGimmeSent = 0;
    xfer.nIGotSent = 0;
    if( syncFlags & SYNC_VERBOSE ){
      fossil_print("waiting for server...\n");
    }
    fflush(stdout);
    if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0,
        MAX_REDIRECTS) ){
      nErr++;
      break;
    }
................................................................................

    /* Stop the cycle if the server sends a "clone_seqno 0" card and
    ** we have gone at least two rounds.  Always go at least two rounds
    ** on a clone in order to be sure to retrieve the configuration
    ** information which is only sent on the second round.
    */
    if( cloneSeqno<=0 && nCycle>1 ) go = 0;   
    transport_global_ssh_shutdown();
  };
  transport_stats(&nSent, &nRcvd, 1);
  fossil_force_newline();
  fossil_print(
     "%s finished with %lld bytes sent, %lld bytes received\n",
     zOpType, nSent, nRcvd);
  transport_close();