Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Continuing work on the ssh:// sync protocol. |
|---|---|
| Timelines: | family | ancestors | descendants | both | experimental |
| Files: | files | file ages | folders |
| SHA1: |
958f59663701959705c820a645e42a12 |
| User & Date: | drh 2010-08-25 16:03:21.000 |
Context
|
2010-08-25
| ||
| 17:00 | The ssh:// sync method appears to work now, for linux-to-linux... check-in: 66cdaee68e user: drh tags: experimental | |
| 16:03 | Continuing work on the ssh:// sync protocol. check-in: 958f596637 user: drh tags: experimental | |
| 14:03 | Initial code to implement synchronization via ssh. check-in: b19f25fe87 user: drh tags: experimental | |
Changes
Changes to src/cgi.c.
| ︙ | ︙ | |||
1147 1148 1149 1150 1151 1152 1153 |
cgi_setenv("HTTPS", zVal);
}else if( strcmp(zFieldName,"host:")==0 ){
cgi_setenv("HTTP_HOST", zVal);
}else if( strcmp(zFieldName,"if-none-match:")==0 ){
cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
}else if( strcmp(zFieldName,"if-modified-since:")==0 ){
cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
| | | 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 |
cgi_setenv("HTTPS", zVal);
}else if( strcmp(zFieldName,"host:")==0 ){
cgi_setenv("HTTP_HOST", zVal);
}else if( strcmp(zFieldName,"if-none-match:")==0 ){
cgi_setenv("HTTP_IF_NONE_MATCH", zVal);
}else if( strcmp(zFieldName,"if-modified-since:")==0 ){
cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal);
}else if( strcmp(zFieldName,"x-fossil-access-token:")==0 ){
if( g.zAccessToken ){
if( strcmp(zVal,g.zAccessToken)==0 ){
accessTokenSeen = 1;
}
}
}
#if 0
|
| ︙ | ︙ | |||
1250 1251 1252 1253 1254 1255 1256 |
/* Slow down if connections are arriving too fast */
sleep( nchildren-MAX_PARALLEL );
}
delay.tv_sec = 60;
delay.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET( listener, &readfds);
| > | > > > > > > > > > > | 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 |
/* Slow down if connections are arriving too fast */
sleep( nchildren-MAX_PARALLEL );
}
delay.tv_sec = 60;
delay.tv_usec = 0;
FD_ZERO(&readfds);
FD_SET( listener, &readfds);
FD_SET( 0, &readfds);
select( listener+1, &readfds, 0, 0, &delay);
if( FD_ISSET(0, &readfds) ){
int i;
char zIn[200];
zIn[0] = 0;
fgets(zIn, sizeof(zIn), stdin);
for(i=0; zIn[i] && zIn[i]!='\n'; i++){}
zIn[i] = 0;
if( strcmp(zIn, "quit")==0 ) fossil_exit(0);
}
if( FD_ISSET(listener, &readfds) ){
lenaddr = sizeof(inaddr);
connection = accept(listener, (struct sockaddr*)&inaddr,
(socklen_t*) &lenaddr);
if( connection>=0 ){
child = fork();
if( child!=0 ){
if( child>0 ) nchildren++;
|
| ︙ | ︙ |
Changes to src/config.h.
| ︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #include <ctype.h> #include <string.h> #include <stdarg.h> #include <assert.h> #ifdef __MINGW32__ # include <windows.h> #else # include <pwd.h> #endif #include "sqlite3.h" /* ** Typedef for a 64-bit integer | > > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #include <ctype.h> #include <string.h> #include <stdarg.h> #include <assert.h> #ifdef __MINGW32__ # include <windows.h> #else # include <sys/types.h> # include <signal.h> # include <pwd.h> #endif #include "sqlite3.h" /* ** Typedef for a 64-bit integer |
| ︙ | ︙ |
Changes to src/http_transport.c.
| ︙ | ︙ | |||
68 69 70 71 72 73 74 |
/*
** Global initialization of the transport layer
*/
void transport_global_startup(void){
if( g.urlIsSsh ){
char *zCmd;
| | | | > | | | | | | < < | | | < < | | 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
/*
** Global initialization of the transport layer
*/
void transport_global_startup(void){
if( g.urlIsSsh ){
char *zCmd;
int i;
char zIn[200];
if( g.urlUser && g.urlUser[0] ){
zCmd = mprintf(
"ssh -L127.0.0.1:%d:127.0.0.1:%d %s@%s "
"\"fossil server -P %d '%s'\"",
g.urlPort, g.urlPort, g.urlUser, g.urlSshHost, g.urlPort, g.urlPath
);
}else{
zCmd = mprintf(
"ssh -L127.0.0.1:%d:127.0.0.1:%d %s \"fossil sshd -P %d '%s'\"",
g.urlPort, g.urlPort, g.urlSshHost, g.urlPort, g.urlPath
);
}
printf("%s\n", zCmd);
popen2(zCmd, &g.sshIn, &g.sshOut, &g.sshPid);
if( g.sshPid==0 ){
fossil_fatal("cannot start ssh tunnel using [%s]", zCmd);
}
free(zCmd);
zIn[0] = 0;
fgets(zIn, sizeof(zIn), g.sshIn);
for(i=0; zIn[i] && zIn[i]!='\n'; i++){}
zIn[i] = 0;
if( memcmp(zIn, "Access-Token: ", 14)!=0 ){
pclose2(g.sshIn, g.sshOut, g.sshPid);
fossil_fatal("failed to start ssh tunnel");
}
g.zAccessToken = mprintf("%s", &zIn[14]);
}
}
/*
** Open a connection to the server. The server is defined by the following
** global variables:
**
|
| ︙ | ︙ | |||
352 353 354 355 356 357 358 |
i++;
}
/* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
return &transport.pBuf[iStart];
}
void transport_global_shutdown(void){
| | | | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 |
i++;
}
/* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
return &transport.pBuf[iStart];
}
void transport_global_shutdown(void){
if( g.urlIsSsh && g.sshPid ){
pclose2(g.sshIn, g.sshOut, g.sshPid);
g.sshPid = 0;
}
if( g.urlIsHttps ){
#ifdef FOSSIL_ENABLE_SSL
ssl_global_shutdown();
#endif
}else{
socket_global_shutdown();
}
}
|
Changes to src/main.c.
| ︙ | ︙ | |||
82 83 84 85 86 87 88 | FILE *httpIn; /* Accept HTTP input from here */ FILE *httpOut; /* Send HTTP output here */ int xlinkClusterOnly; /* Set when cloning. Only process clusters */ int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ char *zAccessToken; /* X-Fossil-Access-Token HTTP header field */ | > | > | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | FILE *httpIn; /* Accept HTTP input from here */ FILE *httpOut; /* Send HTTP output here */ int xlinkClusterOnly; /* Set when cloning. Only process clusters */ int fTimeFormat; /* 1 for UTC. 2 for localtime. 0 not yet selected */ int *aCommitFile; /* Array of files to be committed */ int markPrivate; /* All new artifacts are private if true */ char *zAccessToken; /* X-Fossil-Access-Token HTTP header field */ int sshPid; /* Process id of ssh subprocess */ FILE *sshIn; /* From ssh subprocess to this */ FILE *sshOut; /* From this to ssh subprocess */ int urlIsFile; /* True if a "file:" url */ int urlIsHttps; /* True if a "https:" url */ int urlIsSsh; /* True if an "ssh:" url */ char *urlName; /* Hostname for http: or filename for file: */ char *urlSshHost; /* Hostname for ssh: tunnels */ char *urlHostname; /* The HOST: parameter on http headers */ |
| ︙ | ︙ | |||
972 973 974 975 976 977 978 979 980 981 982 983 984 985 | } return 0; } #endif #endif /* ** COMMAND: server ** COMMAND: ui ** ** Usage: %fossil server ?-P|--port TCPPORT? ?REPOSITORY? ** Or: %fossil ui ?-P|--port TCPPORT? ?REPOSITORY? ** ** Open a socket and begin listening and responding to HTTP requests on | > | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 | } return 0; } #endif #endif /* ** COMMAND: sshd ** COMMAND: server ** COMMAND: ui ** ** Usage: %fossil server ?-P|--port TCPPORT? ?REPOSITORY? ** Or: %fossil ui ?-P|--port TCPPORT? ?REPOSITORY? ** ** Open a socket and begin listening and responding to HTTP requests on |
| ︙ | ︙ | |||
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 |
isUiCmd = g.argv[1][0]=='u';
find_server_repository(isUiCmd);
if( zPort ){
iPort = mxPort = atoi(zPort);
}else{
iPort = db_get_int("http-port", 8080);
mxPort = iPort+100;
}
#ifndef __MINGW32__
/* Unix implementation */
if( isUiCmd ){
#if !defined(__DARWIN__) && !defined(__APPLE__)
zBrowser = db_get("web-browser", 0);
if( zBrowser==0 ){
| > > > > > | 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 |
isUiCmd = g.argv[1][0]=='u';
find_server_repository(isUiCmd);
if( zPort ){
iPort = mxPort = atoi(zPort);
}else{
iPort = db_get_int("http-port", 8080);
mxPort = iPort+100;
}
if( g.argv[1][0]=='s' && g.argv[1][1]=='s' ){
g.zAccessToken = db_text(0, "SELECT lower(hex(randomblob(20)))");
printf("Access-Token: %s\n", g.zAccessToken);
fflush(stdout);
}
#ifndef __MINGW32__
/* Unix implementation */
if( isUiCmd ){
#if !defined(__DARWIN__) && !defined(__APPLE__)
zBrowser = db_get("web-browser", 0);
if( zBrowser==0 ){
|
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
49 50 51 52 53 54 55 56 57 58 59 60 61 62 | $(SRCDIR)/main.c \ $(SRCDIR)/manifest.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/name.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/rebuild.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ | > | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | $(SRCDIR)/main.c \ $(SRCDIR)/manifest.c \ $(SRCDIR)/md5.c \ $(SRCDIR)/merge.c \ $(SRCDIR)/merge3.c \ $(SRCDIR)/name.c \ $(SRCDIR)/pivot.c \ $(SRCDIR)/popen.c \ $(SRCDIR)/pqueue.c \ $(SRCDIR)/printf.c \ $(SRCDIR)/rebuild.c \ $(SRCDIR)/report.c \ $(SRCDIR)/rss.c \ $(SRCDIR)/schema.c \ $(SRCDIR)/search.c \ |
| ︙ | ︙ | |||
121 122 123 124 125 126 127 128 129 130 131 132 133 134 | main_.c \ manifest_.c \ md5_.c \ merge_.c \ merge3_.c \ name_.c \ pivot_.c \ pqueue_.c \ printf_.c \ rebuild_.c \ report_.c \ rss_.c \ schema_.c \ search_.c \ | > | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | main_.c \ manifest_.c \ md5_.c \ merge_.c \ merge3_.c \ name_.c \ pivot_.c \ popen_.c \ pqueue_.c \ printf_.c \ rebuild_.c \ report_.c \ rss_.c \ schema_.c \ search_.c \ |
| ︙ | ︙ | |||
193 194 195 196 197 198 199 200 201 202 203 204 205 206 | $(OBJDIR)/main.o \ $(OBJDIR)/manifest.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/name.o \ $(OBJDIR)/pivot.o \ $(OBJDIR)/pqueue.o \ $(OBJDIR)/printf.o \ $(OBJDIR)/rebuild.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ | > | 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | $(OBJDIR)/main.o \ $(OBJDIR)/manifest.o \ $(OBJDIR)/md5.o \ $(OBJDIR)/merge.o \ $(OBJDIR)/merge3.o \ $(OBJDIR)/name.o \ $(OBJDIR)/pivot.o \ $(OBJDIR)/popen.o \ $(OBJDIR)/pqueue.o \ $(OBJDIR)/printf.o \ $(OBJDIR)/rebuild.o \ $(OBJDIR)/report.o \ $(OBJDIR)/rss.o \ $(OBJDIR)/schema.o \ $(OBJDIR)/search.o \ |
| ︙ | ︙ | |||
268 269 270 271 272 273 274 | # $(SRCDIR)/../manifest: # noop clean: rm -f $(OBJDIR)/*.o *_.c $(APPNAME) VERSION.h rm -f translate makeheaders mkindex page_index.h headers | | | | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | # $(SRCDIR)/../manifest: # noop clean: rm -f $(OBJDIR)/*.o *_.c $(APPNAME) VERSION.h rm -f translate makeheaders mkindex page_index.h headers rm -f add.h allrepo.h attach.h bag.h blob.h branch.h browse.h captcha.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h finfo.h graph.h http.h http_socket.h http_ssl.h http_transport.h info.h login.h main.h manifest.h md5.h merge.h merge3.h name.h pivot.h popen.h pqueue.h printf.h rebuild.h report.h rss.h schema.h search.h setup.h sha1.h shun.h skins.h stat.h style.h sync.h tag.h th_main.h timeline.h tkt.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h winhttp.h xfer.h zip.h page_index.h: $(TRANS_SRC) mkindex ./mkindex $(TRANS_SRC) >$@ headers: page_index.h makeheaders VERSION.h ./makeheaders add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h file_.c:file.h finfo_.c:finfo.h graph_.c:graph.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h VERSION.h touch headers headers: Makefile Makefile: add_.c: $(SRCDIR)/add.c translate ./translate $(SRCDIR)/add.c >add_.c $(OBJDIR)/add.o: add_.c add.h $(SRCDIR)/config.h |
| ︙ | ︙ | |||
557 558 559 560 561 562 563 564 565 566 567 568 569 570 | pivot_.c: $(SRCDIR)/pivot.c translate ./translate $(SRCDIR)/pivot.c >pivot_.c $(OBJDIR)/pivot.o: pivot_.c pivot.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pivot.o -c pivot_.c pivot.h: headers pqueue_.c: $(SRCDIR)/pqueue.c translate ./translate $(SRCDIR)/pqueue.c >pqueue_.c $(OBJDIR)/pqueue.o: pqueue_.c pqueue.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pqueue.o -c pqueue_.c pqueue.h: headers | > > > > > > > | 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 | pivot_.c: $(SRCDIR)/pivot.c translate ./translate $(SRCDIR)/pivot.c >pivot_.c $(OBJDIR)/pivot.o: pivot_.c pivot.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pivot.o -c pivot_.c pivot.h: headers popen_.c: $(SRCDIR)/popen.c translate ./translate $(SRCDIR)/popen.c >popen_.c $(OBJDIR)/popen.o: popen_.c popen.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/popen.o -c popen_.c popen.h: headers pqueue_.c: $(SRCDIR)/pqueue.c translate ./translate $(SRCDIR)/pqueue.c >pqueue_.c $(OBJDIR)/pqueue.o: pqueue_.c pqueue.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/pqueue.o -c pqueue_.c pqueue.h: headers |
| ︙ | ︙ |
Changes to src/makemake.tcl.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 49 50 51 52 53 54 55 | main manifest md5 merge merge3 name pivot pqueue printf rebuild report rss schema search | > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | main manifest md5 merge merge3 name pivot popen pqueue printf rebuild report rss schema search |
| ︙ | ︙ |
Added src/popen.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
/*
** Copyright (c) 2010 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains an implementation of a bi-directional popen().
*/
#include "config.h"
#include "popen.h"
/*
** Create a child process running shell command "zCmd". *ppOut is
** a FILE that becomes the standard input of the child process.
** (The caller writes to *ppOut in order to send text to the child.)
** *ppIn is stdout from the child process. (The caller
** reads from *ppIn in order to receive input from the child.)
** The process ID of the child is written into *pChildPid.
**
** Return the number of errors.
*/
int popen2(const char *zCmd, FILE **ppIn, FILE **ppOut, int *pChildPid){
#ifdef __MINGW32__
return 1; /* Not implemented on windows, yet */
#else
int pin[2], pout[2];
*ppIn = 0;
*ppOut = 0;
*pChildPid = 0;
if( pipe(pin)<0 ){
return 1;
}
if( pipe(pout)<0 ){
close(pin[0]);
close(pin[1]);
return 1;
}
*pChildPid = fork();
if( *pChildPid<0 ){
close(pin[0]);
close(pin[1]);
close(pout[0]);
close(pout[1]);
*pChildPid = 0;
return 1;
}
if( *pChildPid==0 ){
/* This is the child process */
close(0);
dup(pout[0]);
close(pout[0]);
close(pout[1]);
close(1);
dup(pin[1]);
close(pin[0]);
close(pin[1]);
execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
return 1;
}else{
/* This is the parent process */
close(pin[1]);
*ppIn = fdopen(pin[0], "r");
close(pout[0]);
*ppOut = fdopen(pout[1], "w");
return 0;
}
#endif
}
/*
** Close the connection to a child process previously created using
** popen2(). Kill off the child process, then close the pipes.
*/
void pclose2(FILE *pIn, FILE *pOut, int childPid){
#ifdef __MINGW32__
/* Not implemented, yet */
#else
kill(childPid, SIGINT);
fclose(pIn);
fclose(pOut);
#endif
}
|