Fossil

Check-in [958f5966]
Login

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

Overview
Comment:Continuing work on the ssh:// sync protocol.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental
Files: files | file ages | folders
SHA1: 958f59663701959705c820a645e42a12d95cf5f7
User & Date: drh 2010-08-25 16:03:21
Context
2010-08-25
17:00
The ssh:// sync method appears to work now, for linux-to-linux... check-in: 66cdaee6 user: drh tags: experimental
16:03
Continuing work on the ssh:// sync protocol. check-in: 958f5966 user: drh tags: experimental
14:03
Initial code to implement synchronization via ssh. check-in: b19f25fe user: drh tags: experimental
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/cgi.c.

1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
....
1250
1251
1252
1253
1254
1255
1256

1257










1258
1259
1260
1261
1262
1263
1264
      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-security-token:")==0 ){
      if( g.zAccessToken ){
        if( strcmp(zVal,g.zAccessToken)==0 ){
          accessTokenSeen = 1;
        }
      }
    }
#if 0
................................................................................
      /* 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);

    if( select( listener+1, &readfds, 0, 0, &delay) ){










      lenaddr = sizeof(inaddr);
      connection = accept(listener, (struct sockaddr*)&inaddr,
                                    (socklen_t*) &lenaddr);
      if( connection>=0 ){
        child = fork();
        if( child!=0 ){
          if( child>0 ) nchildren++;







|







 







>
|
>
>
>
>
>
>
>
>
>
>







1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
....
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
      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
................................................................................
      /* 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
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
111
112
113
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370

/*
** Global initialization of the transport layer
*/
void transport_global_startup(void){
  if( g.urlIsSsh ){
    char *zCmd;
    int i, j;
    char zReply[200];
    if( g.urlUser && g.urlUser[0] ){
      zCmd = mprintf(
         "ssh -L127.0.0.1:%d:127.0.0.1:%d %s@%s \"fossil sshd -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);
    g.sshIn = popen(zCmd, "r");
    if( g.sshIn==0 ){
      fossil_fatal("cannot start ssh tunnel using [%s]", zCmd);
    }
    free(zCmd);
    zReply[0] = 0;
    fgets(zReply, sizeof(zReply), g.sshIn);
    if( zReply[0]==0 ){
      pclose(g.sshIn);
      fossil_fatal("unable to set up ssh tunnel");
    }
    if( memcmp(zReply, "Access-Token: ", 14)!=0 ){
      pclose(g.sshIn);
      fossil_fatal("ssh tunnel did not send back an access token");


    }
    for(i=14; isspace(zReply[i]); i++);
    for(j=i; isalnum(zReply[j]); j++);
    g.zAccessToken = mprintf("%.*s", j-i, &zReply[i]); 
  }
}

/*
** Open a connection to the server.  The server is defined by the following
** global variables:
**
................................................................................
    i++;
  }
  /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
  return &transport.pBuf[iStart];
}

void transport_global_shutdown(void){
  if( g.urlIsSsh && g.sshIn ){
    pclose(g.sshIn);
    g.sshIn = 0;
  }
  if( g.urlIsHttps ){
    #ifdef FOSSIL_ENABLE_SSL
    ssl_global_shutdown();
    #endif
  }else{
    socket_global_shutdown();
  }
}







|
|


|
>









|
|



|
|
|
|
<
<
|
<
<
>
>

<
<
|







 







|
|
|









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
...
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

/*
** 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:
**
................................................................................
    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

89

90
91
92
93
94
95
96
...
972
973
974
975
976
977
978

979
980
981
982
983
984
985
....
1019
1020
1021
1022
1023
1024
1025





1026
1027
1028
1029
1030
1031
1032
  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 */

  FILE *sshIn;            /* Result of popen("ssh") */


  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 */
................................................................................
  }
  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
................................................................................
  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 ){







>
|
>







 







>







 







>
>
>
>
>







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
...
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
....
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
  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 */
................................................................................
  }
  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
................................................................................
  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
...
121
122
123
124
125
126
127

128
129
130
131
132
133
134
...
193
194
195
196
197
198
199

200
201
202
203
204
205
206
...
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
...
557
558
559
560
561
562
563







564
565
566
567
568
569
570
  $(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 \
................................................................................
  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 \
................................................................................
 $(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 \
................................................................................
#
$(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 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 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
................................................................................
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







>







 







>







 







>







 







|




|







 







>
>
>
>
>
>
>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
...
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
  $(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 \
................................................................................
  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 \
................................................................................
 $(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 \
................................................................................
#
$(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
................................................................................
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
}