Fossil SCM

Refactor the HTTP client logic to make it much easier to add support for "file:" and "https:" URLs on push, pull, sync, and clone.

drh 2009-03-30 00:31 trunk
Commit 737e76a69fbc2e8327195198d14a9287d6863880
+153 -333
--- src/http.c
+++ src/http.c
@@ -23,291 +23,39 @@
2323
**
2424
** This file contains code that implements the client-side HTTP protocol
2525
*/
2626
#include "config.h"
2727
#include "http.h"
28
-#ifdef __MINGW32__
29
-# include <windows.h>
30
-# include <winsock2.h>
31
-#else
32
-# include <arpa/inet.h>
33
-# include <sys/socket.h>
34
-# include <netdb.h>
35
-# include <netinet/in.h>
36
-#endif
37
-#include <assert.h>
38
-#include <sys/types.h>
39
-#include <signal.h>
40
-
41
-/*
42
-** Persistent information about the HTTP connection.
43
-*/
44
-
45
-#ifdef __MINGW32__
46
-static WSADATA ws_info;
47
-static int pSocket = 0; /* The socket on which we talk to the server on */
48
-#else
49
-static FILE *pSocket = 0; /* The socket filehandle on which we talk to the server */
50
-#endif
51
-
52
-/*
53
-** Winsock must be initialize before use. This helper method allows us to
54
-** always call ws_init in our code regardless of platform but only actually
55
-** initialize winsock on the windows platform.
56
-*/
57
-static void ws_init(){
58
-#ifdef __MINGW32__
59
- if (WSAStartup(MAKEWORD(2,0), &ws_info) != 0){
60
- fossil_panic("can't initialize winsock");
61
- }
62
-#endif
63
-}
64
-
65
-/*
66
-** Like ws_init, winsock must also be cleaned up after.
67
-*/
68
-static void ws_cleanup(){
69
-#ifdef __MINGW32__
70
- WSACleanup();
71
-#endif
72
-}
73
-
74
-/*
75
-** Open a socket connection to the server. Return 0 on success and
76
-** non-zero if an error occurs.
77
-*/
78
-static int http_open_socket(void){
79
- static struct sockaddr_in addr; /* The server address */
80
- static int addrIsInit = 0; /* True once addr is initialized */
81
- int s;
82
-
83
- if( g.urlIsHttps ){
84
- fossil_fatal("SSL/TLS is not yet implemented.");
85
- }
86
- ws_init();
87
- if( !addrIsInit ){
88
- addr.sin_family = AF_INET;
89
- addr.sin_port = htons(g.urlPort);
90
- *(int*)&addr.sin_addr = inet_addr(g.urlName);
91
- if( -1 == *(int*)&addr.sin_addr ){
92
-#ifndef FOSSIL_STATIC_LINK
93
- struct hostent *pHost;
94
- pHost = gethostbyname(g.urlName);
95
- if( pHost!=0 ){
96
- memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length);
97
- }else
98
-#endif
99
- {
100
- fossil_panic("can't resolve host name: %s\n", g.urlName);
101
- }
102
- }
103
- addrIsInit = 1;
104
-
105
- /* Set the Global.zIpAddr variable to the server we are talking to.
106
- ** This is used to populate the ipaddr column of the rcvfrom table,
107
- ** if any files are received from the server.
108
- */
109
- g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr));
110
- }
111
- s = socket(AF_INET,SOCK_STREAM,0);
112
- if( s<0 ){
113
- fossil_panic("cannot create a socket");
114
- }
115
- if( connect(s,(struct sockaddr*)&addr,sizeof(addr))<0 ){
116
- fossil_panic("cannot connect to host %s:%d", g.urlName, g.urlPort);
117
- }
118
-#ifdef __MINGW32__
119
- pSocket = s;
120
-#else
121
- pSocket = fdopen(s,"r+");
122
- signal(SIGPIPE, SIG_IGN);
123
-#endif
124
- return 0;
125
-}
126
-
127
-#ifdef __MINGW32__
128
-/*
129
-** Read the socket until a newline '\n' is found. Return the number
130
-** of characters read. pSockId contains the socket handel. pOut
131
-** contains a pointer to the buffer to write to. pOutSize contains
132
-** the maximum size of the line that pOut can handle.
133
-*/
134
-static int socket_recv_line(int pSockId, char* pOut, int pOutSize){
135
- int received=0;
136
- char letter;
137
- memset(pOut,0,pOutSize);
138
- for(; received<pOutSize-1;received++){
139
- if( recv(pSockId,(char*)&letter,1,0)>0 ){
140
- pOut[received]=letter;
141
- if( letter=='\n' ){
142
- break;
143
- }
144
- }else{
145
- break;
146
- }
147
- }
148
- return received;
149
-}
150
-
151
-/*
152
-** Initialize a blob to the data on an input socket. return
153
-** the number of bytes read into the blob. Any prior content
154
-** of the blob is discarded, not freed.
155
-**
156
-** The function was placed here in http.c due to it's socket
157
-** nature and we did not want to introduce socket headers into
158
-** the socket neutral blob.c file.
159
-*/
160
-int socket_read_blob(Blob *pBlob, int pSockId, int nToRead){
161
- int i=0,read=0;
162
- char rbuf[50];
163
- blob_zero(pBlob);
164
- while ( i<nToRead ){
165
- read = recv(pSockId, rbuf, 50, 0);
166
- i += read;
167
- if( read<=0 ){
168
- return 0;
169
- }
170
- blob_append(pBlob, rbuf, read);
171
- }
172
- return blob_size(pBlob);
173
-}
174
-#endif
175
-
176
-/*
177
-** Make a single attempt to talk to the server. Return TRUE on success
178
-** and FALSE on a failure.
179
-**
180
-** pHeader contains the HTTP header. pPayload contains the content.
181
-** The content of the reply is written into pReply. pReply is assumed
182
-** to be uninitialized prior to this call.
183
-**
184
-** If an error occurs, this routine return false, resets pReply and
185
-** closes the persistent connection, if any.
186
-*/
187
-static int http_send_recv(Blob *pHeader, Blob *pPayload, Blob *pReply){
188
- int closeConnection=1; /* default to closing the connection */
189
- int rc;
190
- int iLength;
191
- int iHttpVersion;
192
- int i;
193
- int nRead;
194
- char zLine[2000];
195
-
196
- if( pSocket==0 && http_open_socket() ){
197
- return 0;
198
- }
199
- iLength = -1;
200
-#ifdef __MINGW32__
201
- /*
202
- ** Use recv/send on the windows platform as winsock does not allow
203
- ** sockets to be used as FILE handles, thus fdopen, fwrite, fgets
204
- ** does not function on windows for sockets.
205
- */
206
- rc = send(pSocket, blob_buffer(pHeader), blob_size(pHeader), 0);
207
- if( rc!=blob_size(pHeader) ) goto write_err;
208
- rc = send(pSocket, blob_buffer(pPayload), blob_size(pPayload), 0);
209
- if( rc!=blob_size(pPayload) ) goto write_err;
210
-
211
- /* Read the response */
212
- while( socket_recv_line(pSocket, zLine, 2000) ){
213
- for( i=0; zLine[i] && zLine[i]!='\n' && zLine[i]!='\r'; i++ ){}
214
- if( i==0 ) break;
215
- zLine[i] = 0;
216
- if( strncasecmp(zLine, "http/1.", 7)==0 ){
217
- if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
218
- if( rc!=200 ) goto write_err;
219
- if( iHttpVersion==0 ){
220
- closeConnection = 1;
221
- }else{
222
- closeConnection = 0;
223
- }
224
- } else if( strncasecmp(zLine, "content-length:", 15)==0 ){
225
- iLength = atoi(&zLine[16]);
226
- }else if( strncasecmp(zLine, "connection:", 11)==0 ){
227
- for(i=12; isspace(zLine[i]); i++){}
228
- if( zLine[i]=='c' || zLine[i]=='C' ){
229
- closeConnection = 1;
230
- }else if( zLine[i]=='k' || zLine[i]=='K' ){
231
- closeConnection = 0;
232
- }
233
- }
234
- }
235
- if( iLength<0 ) goto write_err;
236
- nRead = socket_read_blob(pReply, pSocket, iLength);
237
-#else
238
- rc = fwrite(blob_buffer(pHeader), 1, blob_size(pHeader), pSocket);
239
- if( rc!=blob_size(pHeader) ) goto write_err;
240
- rc = fwrite(blob_buffer(pPayload), 1, blob_size(pPayload), pSocket);
241
- if( rc!=blob_size(pPayload) ) goto write_err;
242
- if( fflush(pSocket) ) goto write_err;
243
- if( fgets(zLine, sizeof(zLine), pSocket)==0 ) goto write_err;
244
- if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
245
- if( rc!=200 ) goto write_err;
246
- if( iHttpVersion==0 ){
247
- closeConnection = 1; /* Connection: close */
248
- }else{
249
- closeConnection = 0; /* Connection: keep-alive */
250
- }
251
- while( fgets(zLine, sizeof(zLine), pSocket) ){
252
- for(i=0; zLine[i] && zLine[i]!='\n' && zLine[i]!='\r'; i++){}
253
- if( i==0 ) break;
254
- zLine[i] = 0;
255
- if( strncasecmp(zLine,"content-length:",15)==0 ){
256
- iLength = atoi(&zLine[16]);
257
- }else if( strncasecmp(zLine, "connection:", 11)==0 ){
258
- for(i=12; isspace(zLine[i]); i++){}
259
- if( zLine[i]=='c' || zLine[i]=='C' ){
260
- closeConnection = 1; /* Connection: close */
261
- }else if( zLine[i]=='k' || zLine[i]=='K' ){
262
- closeConnection = 0; /* Connection: keep-alive */
263
- }
264
- }
265
- }
266
- if( iLength<0 ) goto write_err;
267
- nRead = blob_read_from_channel(pReply, pSocket, iLength);
268
-#endif
269
- if( nRead!=iLength ){
270
- blob_reset(pReply);
271
- goto write_err;
272
- }
273
- if( closeConnection ){
274
- http_close();
275
- }
276
- return 1;
277
-
278
-write_err:
279
- http_close();
280
- return 0;
281
-}
282
-
283
-/*
284
-** Sign the content in pSend, compress it, and send it to the server
285
-** via HTTP. Get a reply, uncompress the reply, and store the reply
286
-** in pRecv. pRecv is assumed to be uninitialized when
287
-** this routine is called - this routine will initialize it.
288
-**
289
-** The server address is contain in the "g" global structure. The
290
-** url_parse() routine should have been called prior to this routine
291
-** in order to fill this structure appropriately.
292
-*/
293
-void http_exchange(Blob *pSend, Blob *pRecv){
294
- Blob login, nonce, sig, pw, payload, hdr;
295
- const char *zSep;
296
- int i;
297
- int cnt = 0;
28
+#include <assert.h>
29
+
30
+/*
31
+** Construct the "login" card with the client credentials.
32
+**
33
+** login LOGIN NONCE SIGNATURE
34
+**
35
+** The LOGIN is the user id of the client. NONCE is the sha1 checksum
36
+** of all payload that follows the login card. SIGNATURE is the sha1
37
+** checksum of the nonce followed by the user password.
38
+**
39
+** Write the constructed login card into pLogin. pLogin is initialized
40
+** by this routine.
41
+*/
42
+static void http_build_login_card(Blob *pPayload, Blob *pLogin){
43
+ Blob nonce; /* The nonce */
44
+ Blob pw; /* The user password */
45
+ Blob sig; /* The signature field */
29846
29947
blob_zero(&nonce);
30048
blob_zero(&pw);
301
- sha1sum_blob(pSend, &nonce);
49
+ sha1sum_blob(pPayload, &nonce);
30250
blob_copy(&pw, &nonce);
303
- blob_zero(&login);
51
+ blob_zero(pLogin);
30452
if( g.urlUser==0 ){
30553
user_select();
30654
db_blob(&pw, "SELECT pw FROM user WHERE uid=%d", g.userUid);
30755
sha1sum_blob(&pw, &sig);
308
- blob_appendf(&login, "login %s %b %b\n", g.zLogin, &nonce, &sig);
56
+ blob_appendf(pLogin, "login %s %b %b\n", g.zLogin, &nonce, &sig);
30957
}else{
31058
if( g.urlPasswd==0 ){
31159
if( strcmp(g.urlUser,"anonymous")!=0 ){
31260
char *zPrompt = mprintf("password for %s: ", g.urlUser);
31361
Blob x;
@@ -317,48 +65,90 @@
31765
}else{
31866
g.urlPasswd = "";
31967
}
32068
}
32169
blob_append(&pw, g.urlPasswd, -1);
322
- /* printf("presig=[%s]\n", blob_str(&pw)); */
32370
sha1sum_blob(&pw, &sig);
324
- blob_appendf(&login, "login %s %b %b\n", g.urlUser, &nonce, &sig);
71
+ blob_appendf(pLogin, "login %s %b %b\n", g.urlUser, &nonce, &sig);
32572
}
32673
blob_reset(&nonce);
32774
blob_reset(&pw);
32875
blob_reset(&sig);
76
+}
77
+
78
+/*
79
+** Construct an appropriate HTTP request header. Write the header
80
+** into pHdr. This routine initializes the pHdr blob. pPayload is
81
+** the complete payload (including the login card) already compressed.
82
+*/
83
+static void http_build_header(Blob *pPayload, Blob *pHdr){
84
+ int i;
85
+ const char *zSep;
86
+
87
+ blob_zero(pHdr);
88
+ i = strlen(g.urlPath);
89
+ if( i>0 && g.urlPath[i-1]=='/' ){
90
+ zSep = "";
91
+ }else{
92
+ zSep = "/";
93
+ }
94
+ blob_appendf(pHdr, "POST %s%sxfer HTTP/1.1\r\n", g.urlPath, zSep);
95
+ blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
96
+ blob_appendf(pHdr, "User-Agent: Fossil/" MANIFEST_VERSION "\r\n");
97
+ if( g.fHttpTrace ){
98
+ blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
99
+ }else{
100
+ blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
101
+ }
102
+ blob_appendf(pHdr, "Content-Length: %d\r\n\r\n", blob_size(pPayload));
103
+}
104
+
105
+/*
106
+** Sign the content in pSend, compress it, and send it to the server
107
+** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply
108
+** in pRecv. pRecv is assumed to be uninitialized when
109
+** this routine is called - this routine will initialize it.
110
+**
111
+** The server address is contain in the "g" global structure. The
112
+** url_parse() routine should have been called prior to this routine
113
+** in order to fill this structure appropriately.
114
+*/
115
+void http_exchange(Blob *pSend, Blob *pReply){
116
+ Blob login; /* The login card */
117
+ Blob payload; /* The complete payload including login card */
118
+ Blob hdr; /* The HTTP request header */
119
+ int closeConnection; /* True to close the connection when done */
120
+ int iLength; /* Length of the reply payload */
121
+ int rc; /* Result code */
122
+ int iHttpVersion; /* Which version of HTTP protocol server uses */
123
+ char *zLine; /* A single line of the reply header */
124
+ int i; /* Loop counter */
125
+
126
+ if( transport_open() ){
127
+ fossil_fatal(transport_errmsg());
128
+ }
129
+
130
+ /* Construct the login card and prepare the complete payload */
131
+ http_build_login_card(pSend, &login);
329132
if( g.fHttpTrace ){
330133
payload = login;
331134
blob_append(&payload, blob_buffer(pSend), blob_size(pSend));
332135
}else{
333136
blob_compress2(&login, pSend, &payload);
334137
blob_reset(&login);
335138
}
336
- blob_zero(&hdr);
337
- i = strlen(g.urlPath);
338
- if( i>0 && g.urlPath[i-1]=='/' ){
339
- zSep = "";
340
- }else{
341
- zSep = "/";
342
- }
343
- blob_appendf(&hdr, "POST %s%sxfer HTTP/1.1\r\n", g.urlPath, zSep);
344
- blob_appendf(&hdr, "Host: %s\r\n", g.urlHostname);
345
- blob_appendf(&hdr, "User-Agent: Fossil/" MANIFEST_VERSION "\r\n");
346
- if( g.fHttpTrace ){
347
- blob_appendf(&hdr, "Content-Type: application/x-fossil-debug\r\n");
348
- }else{
349
- blob_appendf(&hdr, "Content-Type: application/x-fossil\r\n");
350
- }
351
- blob_appendf(&hdr, "Content-Length: %d\r\n\r\n", blob_size(&payload));
352
-
353
- if( g.fHttpTrace ){
354
- /* When tracing, write the transmitted HTTP message both to standard
355
- ** output and into a file. The file can then be used to drive the
356
- ** server-side like this:
357
- **
358
- ** ./fossil http <http-trace-1.txt
359
- */
139
+
140
+ /* Construct the HTTP request header */
141
+ http_build_header(&payload, &hdr);
142
+
143
+ /* When tracing, write the transmitted HTTP message both to standard
144
+ ** output and into a file. The file can then be used to drive the
145
+ ** server-side like this:
146
+ **
147
+ ** ./fossil http <http-trace-1.txt
148
+ */
149
+ if( g.fHttpTrace ){
360150
static int traceCnt = 0;
361151
char *zOutFile;
362152
FILE *out;
363153
traceCnt++;
364154
zOutFile = mprintf("http-trace-%d.txt", traceCnt);
@@ -369,42 +159,72 @@
369159
fwrite(blob_buffer(&hdr), 1, blob_size(&hdr), out);
370160
fwrite(blob_buffer(&payload), 1, blob_size(&payload), out);
371161
fclose(out);
372162
}
373163
}
374
- for(cnt=0; cnt<2; cnt++){
375
- if( http_send_recv(&hdr, &payload, pRecv) ) break;
376
- }
377
- if( cnt>=2 ){
378
- fossil_fatal("connection to server failed");
379
- }
164
+
165
+ /*
166
+ ** Send the request to the server.
167
+ */
168
+ transport_send(&hdr);
169
+ transport_send(&payload);
380170
blob_reset(&hdr);
381171
blob_reset(&payload);
382
- if( g.fHttpTrace ){
383
- printf("HTTP RECEIVE:\n%s\n=======================\n", blob_str(pRecv));
384
- }else{
385
- blob_uncompress(pRecv, pRecv);
386
- }
387
-}
388
-
389
-
390
-/*
391
-** Make sure the socket to the HTTP server is closed
392
-*/
393
-void http_close(void){
394
- if( pSocket ){
395
-#ifdef __MINGW32__
396
- closesocket(pSocket);
397
-#else
398
- fclose(pSocket);
399
-#endif
400
- pSocket = 0;
401
- }
402
- /*
403
- ** This is counter productive. Each time we open a connection we initialize
404
- ** winsock and then when closing we cleanup. It would be better to
405
- ** initialize winsock once at application start when we know we are going to
406
- ** use the socket interface and then cleanup once at application exit when
407
- ** we are all done with all socket operations.
408
- */
409
- ws_cleanup();
172
+
173
+ /*
174
+ ** Read and interpret the server reply
175
+ */
176
+ closeConnection = 1;
177
+ iLength = -1;
178
+ while( (zLine = transport_receive_line())!=0 && zLine[0]!=0 ){
179
+ if( strncasecmp(zLine, "http/1.", 7)==0 ){
180
+ if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
181
+ if( rc!=200 ) goto write_err;
182
+ if( iHttpVersion==0 ){
183
+ closeConnection = 1;
184
+ }else{
185
+ closeConnection = 0;
186
+ }
187
+ } else if( strncasecmp(zLine, "content-length:", 15)==0 ){
188
+ for(i=15; isspace(zLine[i]); i++){}
189
+ iLength = atoi(&zLine[i]);
190
+ }else if( strncasecmp(zLine, "connection:", 11)==0 ){
191
+ char c;
192
+ for(i=11; isspace(zLine[i]); i++){}
193
+ c = zLine[i];
194
+ if( c=='c' || c=='C' ){
195
+ closeConnection = 1;
196
+ }else if( c=='k' || c=='K' ){
197
+ closeConnection = 0;
198
+ }
199
+ }
200
+ }
201
+
202
+ /*
203
+ ** Extract the reply payload that follows the header
204
+ */
205
+ if( iLength<0 ) goto write_err;
206
+ blob_zero(pReply);
207
+ blob_resize(pReply, iLength);
208
+ iLength = transport_receive(blob_buffer(pReply), iLength);
209
+ blob_resize(pReply, iLength);
210
+ if( g.fHttpTrace ){
211
+ printf("HTTP RECEIVE:\n%s\n=======================\n", blob_str(pReply));
212
+ }else{
213
+ blob_uncompress(pReply, pReply);
214
+ }
215
+
216
+ /*
217
+ ** Close the connection to the server if appropriate.
218
+ */
219
+ if( closeConnection ){
220
+ transport_close();
221
+ }
222
+ return;
223
+
224
+ /*
225
+ ** Jump to here if an error is seen.
226
+ */
227
+write_err:
228
+ transport_close();
229
+ return;
410230
}
411231
412232
ADDED src/http_socket.c
413233
ADDED src/http_transport.c
--- src/http.c
+++ src/http.c
@@ -23,291 +23,39 @@
23 **
24 ** This file contains code that implements the client-side HTTP protocol
25 */
26 #include "config.h"
27 #include "http.h"
28 #ifdef __MINGW32__
29 # include <windows.h>
30 # include <winsock2.h>
31 #else
32 # include <arpa/inet.h>
33 # include <sys/socket.h>
34 # include <netdb.h>
35 # include <netinet/in.h>
36 #endif
37 #include <assert.h>
38 #include <sys/types.h>
39 #include <signal.h>
40
41 /*
42 ** Persistent information about the HTTP connection.
43 */
44
45 #ifdef __MINGW32__
46 static WSADATA ws_info;
47 static int pSocket = 0; /* The socket on which we talk to the server on */
48 #else
49 static FILE *pSocket = 0; /* The socket filehandle on which we talk to the server */
50 #endif
51
52 /*
53 ** Winsock must be initialize before use. This helper method allows us to
54 ** always call ws_init in our code regardless of platform but only actually
55 ** initialize winsock on the windows platform.
56 */
57 static void ws_init(){
58 #ifdef __MINGW32__
59 if (WSAStartup(MAKEWORD(2,0), &ws_info) != 0){
60 fossil_panic("can't initialize winsock");
61 }
62 #endif
63 }
64
65 /*
66 ** Like ws_init, winsock must also be cleaned up after.
67 */
68 static void ws_cleanup(){
69 #ifdef __MINGW32__
70 WSACleanup();
71 #endif
72 }
73
74 /*
75 ** Open a socket connection to the server. Return 0 on success and
76 ** non-zero if an error occurs.
77 */
78 static int http_open_socket(void){
79 static struct sockaddr_in addr; /* The server address */
80 static int addrIsInit = 0; /* True once addr is initialized */
81 int s;
82
83 if( g.urlIsHttps ){
84 fossil_fatal("SSL/TLS is not yet implemented.");
85 }
86 ws_init();
87 if( !addrIsInit ){
88 addr.sin_family = AF_INET;
89 addr.sin_port = htons(g.urlPort);
90 *(int*)&addr.sin_addr = inet_addr(g.urlName);
91 if( -1 == *(int*)&addr.sin_addr ){
92 #ifndef FOSSIL_STATIC_LINK
93 struct hostent *pHost;
94 pHost = gethostbyname(g.urlName);
95 if( pHost!=0 ){
96 memcpy(&addr.sin_addr,pHost->h_addr_list[0],pHost->h_length);
97 }else
98 #endif
99 {
100 fossil_panic("can't resolve host name: %s\n", g.urlName);
101 }
102 }
103 addrIsInit = 1;
104
105 /* Set the Global.zIpAddr variable to the server we are talking to.
106 ** This is used to populate the ipaddr column of the rcvfrom table,
107 ** if any files are received from the server.
108 */
109 g.zIpAddr = mprintf("%s", inet_ntoa(addr.sin_addr));
110 }
111 s = socket(AF_INET,SOCK_STREAM,0);
112 if( s<0 ){
113 fossil_panic("cannot create a socket");
114 }
115 if( connect(s,(struct sockaddr*)&addr,sizeof(addr))<0 ){
116 fossil_panic("cannot connect to host %s:%d", g.urlName, g.urlPort);
117 }
118 #ifdef __MINGW32__
119 pSocket = s;
120 #else
121 pSocket = fdopen(s,"r+");
122 signal(SIGPIPE, SIG_IGN);
123 #endif
124 return 0;
125 }
126
127 #ifdef __MINGW32__
128 /*
129 ** Read the socket until a newline '\n' is found. Return the number
130 ** of characters read. pSockId contains the socket handel. pOut
131 ** contains a pointer to the buffer to write to. pOutSize contains
132 ** the maximum size of the line that pOut can handle.
133 */
134 static int socket_recv_line(int pSockId, char* pOut, int pOutSize){
135 int received=0;
136 char letter;
137 memset(pOut,0,pOutSize);
138 for(; received<pOutSize-1;received++){
139 if( recv(pSockId,(char*)&letter,1,0)>0 ){
140 pOut[received]=letter;
141 if( letter=='\n' ){
142 break;
143 }
144 }else{
145 break;
146 }
147 }
148 return received;
149 }
150
151 /*
152 ** Initialize a blob to the data on an input socket. return
153 ** the number of bytes read into the blob. Any prior content
154 ** of the blob is discarded, not freed.
155 **
156 ** The function was placed here in http.c due to it's socket
157 ** nature and we did not want to introduce socket headers into
158 ** the socket neutral blob.c file.
159 */
160 int socket_read_blob(Blob *pBlob, int pSockId, int nToRead){
161 int i=0,read=0;
162 char rbuf[50];
163 blob_zero(pBlob);
164 while ( i<nToRead ){
165 read = recv(pSockId, rbuf, 50, 0);
166 i += read;
167 if( read<=0 ){
168 return 0;
169 }
170 blob_append(pBlob, rbuf, read);
171 }
172 return blob_size(pBlob);
173 }
174 #endif
175
176 /*
177 ** Make a single attempt to talk to the server. Return TRUE on success
178 ** and FALSE on a failure.
179 **
180 ** pHeader contains the HTTP header. pPayload contains the content.
181 ** The content of the reply is written into pReply. pReply is assumed
182 ** to be uninitialized prior to this call.
183 **
184 ** If an error occurs, this routine return false, resets pReply and
185 ** closes the persistent connection, if any.
186 */
187 static int http_send_recv(Blob *pHeader, Blob *pPayload, Blob *pReply){
188 int closeConnection=1; /* default to closing the connection */
189 int rc;
190 int iLength;
191 int iHttpVersion;
192 int i;
193 int nRead;
194 char zLine[2000];
195
196 if( pSocket==0 && http_open_socket() ){
197 return 0;
198 }
199 iLength = -1;
200 #ifdef __MINGW32__
201 /*
202 ** Use recv/send on the windows platform as winsock does not allow
203 ** sockets to be used as FILE handles, thus fdopen, fwrite, fgets
204 ** does not function on windows for sockets.
205 */
206 rc = send(pSocket, blob_buffer(pHeader), blob_size(pHeader), 0);
207 if( rc!=blob_size(pHeader) ) goto write_err;
208 rc = send(pSocket, blob_buffer(pPayload), blob_size(pPayload), 0);
209 if( rc!=blob_size(pPayload) ) goto write_err;
210
211 /* Read the response */
212 while( socket_recv_line(pSocket, zLine, 2000) ){
213 for( i=0; zLine[i] && zLine[i]!='\n' && zLine[i]!='\r'; i++ ){}
214 if( i==0 ) break;
215 zLine[i] = 0;
216 if( strncasecmp(zLine, "http/1.", 7)==0 ){
217 if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
218 if( rc!=200 ) goto write_err;
219 if( iHttpVersion==0 ){
220 closeConnection = 1;
221 }else{
222 closeConnection = 0;
223 }
224 } else if( strncasecmp(zLine, "content-length:", 15)==0 ){
225 iLength = atoi(&zLine[16]);
226 }else if( strncasecmp(zLine, "connection:", 11)==0 ){
227 for(i=12; isspace(zLine[i]); i++){}
228 if( zLine[i]=='c' || zLine[i]=='C' ){
229 closeConnection = 1;
230 }else if( zLine[i]=='k' || zLine[i]=='K' ){
231 closeConnection = 0;
232 }
233 }
234 }
235 if( iLength<0 ) goto write_err;
236 nRead = socket_read_blob(pReply, pSocket, iLength);
237 #else
238 rc = fwrite(blob_buffer(pHeader), 1, blob_size(pHeader), pSocket);
239 if( rc!=blob_size(pHeader) ) goto write_err;
240 rc = fwrite(blob_buffer(pPayload), 1, blob_size(pPayload), pSocket);
241 if( rc!=blob_size(pPayload) ) goto write_err;
242 if( fflush(pSocket) ) goto write_err;
243 if( fgets(zLine, sizeof(zLine), pSocket)==0 ) goto write_err;
244 if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
245 if( rc!=200 ) goto write_err;
246 if( iHttpVersion==0 ){
247 closeConnection = 1; /* Connection: close */
248 }else{
249 closeConnection = 0; /* Connection: keep-alive */
250 }
251 while( fgets(zLine, sizeof(zLine), pSocket) ){
252 for(i=0; zLine[i] && zLine[i]!='\n' && zLine[i]!='\r'; i++){}
253 if( i==0 ) break;
254 zLine[i] = 0;
255 if( strncasecmp(zLine,"content-length:",15)==0 ){
256 iLength = atoi(&zLine[16]);
257 }else if( strncasecmp(zLine, "connection:", 11)==0 ){
258 for(i=12; isspace(zLine[i]); i++){}
259 if( zLine[i]=='c' || zLine[i]=='C' ){
260 closeConnection = 1; /* Connection: close */
261 }else if( zLine[i]=='k' || zLine[i]=='K' ){
262 closeConnection = 0; /* Connection: keep-alive */
263 }
264 }
265 }
266 if( iLength<0 ) goto write_err;
267 nRead = blob_read_from_channel(pReply, pSocket, iLength);
268 #endif
269 if( nRead!=iLength ){
270 blob_reset(pReply);
271 goto write_err;
272 }
273 if( closeConnection ){
274 http_close();
275 }
276 return 1;
277
278 write_err:
279 http_close();
280 return 0;
281 }
282
283 /*
284 ** Sign the content in pSend, compress it, and send it to the server
285 ** via HTTP. Get a reply, uncompress the reply, and store the reply
286 ** in pRecv. pRecv is assumed to be uninitialized when
287 ** this routine is called - this routine will initialize it.
288 **
289 ** The server address is contain in the "g" global structure. The
290 ** url_parse() routine should have been called prior to this routine
291 ** in order to fill this structure appropriately.
292 */
293 void http_exchange(Blob *pSend, Blob *pRecv){
294 Blob login, nonce, sig, pw, payload, hdr;
295 const char *zSep;
296 int i;
297 int cnt = 0;
298
299 blob_zero(&nonce);
300 blob_zero(&pw);
301 sha1sum_blob(pSend, &nonce);
302 blob_copy(&pw, &nonce);
303 blob_zero(&login);
304 if( g.urlUser==0 ){
305 user_select();
306 db_blob(&pw, "SELECT pw FROM user WHERE uid=%d", g.userUid);
307 sha1sum_blob(&pw, &sig);
308 blob_appendf(&login, "login %s %b %b\n", g.zLogin, &nonce, &sig);
309 }else{
310 if( g.urlPasswd==0 ){
311 if( strcmp(g.urlUser,"anonymous")!=0 ){
312 char *zPrompt = mprintf("password for %s: ", g.urlUser);
313 Blob x;
@@ -317,48 +65,90 @@
317 }else{
318 g.urlPasswd = "";
319 }
320 }
321 blob_append(&pw, g.urlPasswd, -1);
322 /* printf("presig=[%s]\n", blob_str(&pw)); */
323 sha1sum_blob(&pw, &sig);
324 blob_appendf(&login, "login %s %b %b\n", g.urlUser, &nonce, &sig);
325 }
326 blob_reset(&nonce);
327 blob_reset(&pw);
328 blob_reset(&sig);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
329 if( g.fHttpTrace ){
330 payload = login;
331 blob_append(&payload, blob_buffer(pSend), blob_size(pSend));
332 }else{
333 blob_compress2(&login, pSend, &payload);
334 blob_reset(&login);
335 }
336 blob_zero(&hdr);
337 i = strlen(g.urlPath);
338 if( i>0 && g.urlPath[i-1]=='/' ){
339 zSep = "";
340 }else{
341 zSep = "/";
342 }
343 blob_appendf(&hdr, "POST %s%sxfer HTTP/1.1\r\n", g.urlPath, zSep);
344 blob_appendf(&hdr, "Host: %s\r\n", g.urlHostname);
345 blob_appendf(&hdr, "User-Agent: Fossil/" MANIFEST_VERSION "\r\n");
346 if( g.fHttpTrace ){
347 blob_appendf(&hdr, "Content-Type: application/x-fossil-debug\r\n");
348 }else{
349 blob_appendf(&hdr, "Content-Type: application/x-fossil\r\n");
350 }
351 blob_appendf(&hdr, "Content-Length: %d\r\n\r\n", blob_size(&payload));
352
353 if( g.fHttpTrace ){
354 /* When tracing, write the transmitted HTTP message both to standard
355 ** output and into a file. The file can then be used to drive the
356 ** server-side like this:
357 **
358 ** ./fossil http <http-trace-1.txt
359 */
360 static int traceCnt = 0;
361 char *zOutFile;
362 FILE *out;
363 traceCnt++;
364 zOutFile = mprintf("http-trace-%d.txt", traceCnt);
@@ -369,42 +159,72 @@
369 fwrite(blob_buffer(&hdr), 1, blob_size(&hdr), out);
370 fwrite(blob_buffer(&payload), 1, blob_size(&payload), out);
371 fclose(out);
372 }
373 }
374 for(cnt=0; cnt<2; cnt++){
375 if( http_send_recv(&hdr, &payload, pRecv) ) break;
376 }
377 if( cnt>=2 ){
378 fossil_fatal("connection to server failed");
379 }
380 blob_reset(&hdr);
381 blob_reset(&payload);
382 if( g.fHttpTrace ){
383 printf("HTTP RECEIVE:\n%s\n=======================\n", blob_str(pRecv));
384 }else{
385 blob_uncompress(pRecv, pRecv);
386 }
387 }
388
389
390 /*
391 ** Make sure the socket to the HTTP server is closed
392 */
393 void http_close(void){
394 if( pSocket ){
395 #ifdef __MINGW32__
396 closesocket(pSocket);
397 #else
398 fclose(pSocket);
399 #endif
400 pSocket = 0;
401 }
402 /*
403 ** This is counter productive. Each time we open a connection we initialize
404 ** winsock and then when closing we cleanup. It would be better to
405 ** initialize winsock once at application start when we know we are going to
406 ** use the socket interface and then cleanup once at application exit when
407 ** we are all done with all socket operations.
408 */
409 ws_cleanup();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410 }
411
412 DDED src/http_socket.c
413 DDED src/http_transport.c
--- src/http.c
+++ src/http.c
@@ -23,291 +23,39 @@
23 **
24 ** This file contains code that implements the client-side HTTP protocol
25 */
26 #include "config.h"
27 #include "http.h"
28 #include <assert.h>
29
30 /*
31 ** Construct the "login" card with the client credentials.
32 **
33 ** login LOGIN NONCE SIGNATURE
34 **
35 ** The LOGIN is the user id of the client. NONCE is the sha1 checksum
36 ** of all payload that follows the login card. SIGNATURE is the sha1
37 ** checksum of the nonce followed by the user password.
38 **
39 ** Write the constructed login card into pLogin. pLogin is initialized
40 ** by this routine.
41 */
42 static void http_build_login_card(Blob *pPayload, Blob *pLogin){
43 Blob nonce; /* The nonce */
44 Blob pw; /* The user password */
45 Blob sig; /* The signature field */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
47 blob_zero(&nonce);
48 blob_zero(&pw);
49 sha1sum_blob(pPayload, &nonce);
50 blob_copy(&pw, &nonce);
51 blob_zero(pLogin);
52 if( g.urlUser==0 ){
53 user_select();
54 db_blob(&pw, "SELECT pw FROM user WHERE uid=%d", g.userUid);
55 sha1sum_blob(&pw, &sig);
56 blob_appendf(pLogin, "login %s %b %b\n", g.zLogin, &nonce, &sig);
57 }else{
58 if( g.urlPasswd==0 ){
59 if( strcmp(g.urlUser,"anonymous")!=0 ){
60 char *zPrompt = mprintf("password for %s: ", g.urlUser);
61 Blob x;
@@ -317,48 +65,90 @@
65 }else{
66 g.urlPasswd = "";
67 }
68 }
69 blob_append(&pw, g.urlPasswd, -1);
 
70 sha1sum_blob(&pw, &sig);
71 blob_appendf(pLogin, "login %s %b %b\n", g.urlUser, &nonce, &sig);
72 }
73 blob_reset(&nonce);
74 blob_reset(&pw);
75 blob_reset(&sig);
76 }
77
78 /*
79 ** Construct an appropriate HTTP request header. Write the header
80 ** into pHdr. This routine initializes the pHdr blob. pPayload is
81 ** the complete payload (including the login card) already compressed.
82 */
83 static void http_build_header(Blob *pPayload, Blob *pHdr){
84 int i;
85 const char *zSep;
86
87 blob_zero(pHdr);
88 i = strlen(g.urlPath);
89 if( i>0 && g.urlPath[i-1]=='/' ){
90 zSep = "";
91 }else{
92 zSep = "/";
93 }
94 blob_appendf(pHdr, "POST %s%sxfer HTTP/1.1\r\n", g.urlPath, zSep);
95 blob_appendf(pHdr, "Host: %s\r\n", g.urlHostname);
96 blob_appendf(pHdr, "User-Agent: Fossil/" MANIFEST_VERSION "\r\n");
97 if( g.fHttpTrace ){
98 blob_appendf(pHdr, "Content-Type: application/x-fossil-debug\r\n");
99 }else{
100 blob_appendf(pHdr, "Content-Type: application/x-fossil\r\n");
101 }
102 blob_appendf(pHdr, "Content-Length: %d\r\n\r\n", blob_size(pPayload));
103 }
104
105 /*
106 ** Sign the content in pSend, compress it, and send it to the server
107 ** via HTTP or HTTPS. Get a reply, uncompress the reply, and store the reply
108 ** in pRecv. pRecv is assumed to be uninitialized when
109 ** this routine is called - this routine will initialize it.
110 **
111 ** The server address is contain in the "g" global structure. The
112 ** url_parse() routine should have been called prior to this routine
113 ** in order to fill this structure appropriately.
114 */
115 void http_exchange(Blob *pSend, Blob *pReply){
116 Blob login; /* The login card */
117 Blob payload; /* The complete payload including login card */
118 Blob hdr; /* The HTTP request header */
119 int closeConnection; /* True to close the connection when done */
120 int iLength; /* Length of the reply payload */
121 int rc; /* Result code */
122 int iHttpVersion; /* Which version of HTTP protocol server uses */
123 char *zLine; /* A single line of the reply header */
124 int i; /* Loop counter */
125
126 if( transport_open() ){
127 fossil_fatal(transport_errmsg());
128 }
129
130 /* Construct the login card and prepare the complete payload */
131 http_build_login_card(pSend, &login);
132 if( g.fHttpTrace ){
133 payload = login;
134 blob_append(&payload, blob_buffer(pSend), blob_size(pSend));
135 }else{
136 blob_compress2(&login, pSend, &payload);
137 blob_reset(&login);
138 }
139
140 /* Construct the HTTP request header */
141 http_build_header(&payload, &hdr);
142
143 /* When tracing, write the transmitted HTTP message both to standard
144 ** output and into a file. The file can then be used to drive the
145 ** server-side like this:
146 **
147 ** ./fossil http <http-trace-1.txt
148 */
149 if( g.fHttpTrace ){
 
 
 
 
 
 
 
 
 
 
 
 
 
150 static int traceCnt = 0;
151 char *zOutFile;
152 FILE *out;
153 traceCnt++;
154 zOutFile = mprintf("http-trace-%d.txt", traceCnt);
@@ -369,42 +159,72 @@
159 fwrite(blob_buffer(&hdr), 1, blob_size(&hdr), out);
160 fwrite(blob_buffer(&payload), 1, blob_size(&payload), out);
161 fclose(out);
162 }
163 }
164
165 /*
166 ** Send the request to the server.
167 */
168 transport_send(&hdr);
169 transport_send(&payload);
170 blob_reset(&hdr);
171 blob_reset(&payload);
172
173 /*
174 ** Read and interpret the server reply
175 */
176 closeConnection = 1;
177 iLength = -1;
178 while( (zLine = transport_receive_line())!=0 && zLine[0]!=0 ){
179 if( strncasecmp(zLine, "http/1.", 7)==0 ){
180 if( sscanf(zLine, "HTTP/1.%d %d", &iHttpVersion, &rc)!=2 ) goto write_err;
181 if( rc!=200 ) goto write_err;
182 if( iHttpVersion==0 ){
183 closeConnection = 1;
184 }else{
185 closeConnection = 0;
186 }
187 } else if( strncasecmp(zLine, "content-length:", 15)==0 ){
188 for(i=15; isspace(zLine[i]); i++){}
189 iLength = atoi(&zLine[i]);
190 }else if( strncasecmp(zLine, "connection:", 11)==0 ){
191 char c;
192 for(i=11; isspace(zLine[i]); i++){}
193 c = zLine[i];
194 if( c=='c' || c=='C' ){
195 closeConnection = 1;
196 }else if( c=='k' || c=='K' ){
197 closeConnection = 0;
198 }
199 }
200 }
201
202 /*
203 ** Extract the reply payload that follows the header
204 */
205 if( iLength<0 ) goto write_err;
206 blob_zero(pReply);
207 blob_resize(pReply, iLength);
208 iLength = transport_receive(blob_buffer(pReply), iLength);
209 blob_resize(pReply, iLength);
210 if( g.fHttpTrace ){
211 printf("HTTP RECEIVE:\n%s\n=======================\n", blob_str(pReply));
212 }else{
213 blob_uncompress(pReply, pReply);
214 }
215
216 /*
217 ** Close the connection to the server if appropriate.
218 */
219 if( closeConnection ){
220 transport_close();
221 }
222 return;
223
224 /*
225 ** Jump to here if an error is seen.
226 */
227 write_err:
228 transport_close();
229 return;
230 }
231
232 DDED src/http_socket.c
233 DDED src/http_transport.c
--- a/src/http_socket.c
+++ b/src/http_socket.c
@@ -0,0 +1,37 @@
1
+** known as the "2-Clause License" or "FreeBSD License".)
2
+
3
+** This program is distributed in the hope tributed in the hope onst is distributed iGNU General Public
4
+** License version 2 as published by the Free Software Foundation.
5
+**ty; witho/*
6
+** Copyright (c) 2009 D. righi->ai_family == AF_INET) {
7
+ (WITHOUT ANY WARRANTYai_family == AFMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8
+** General Public License for more details.
9
+**
10
+** You should have received a copy of the GNU General Public
11
+** License along with this library; if not, write to the
12
+** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
13
+** Boston, MA 02111-1307, USAwn as the "2-Clause License" or "FreeBSD License".)
14
+
15
+** This program is distributed in the hope tributed in the hope onst is distributed in the hope that it will be useful,
16
+** but without any warranty; witho/*
17
+** Copyright (c) 2009 D. righi->ai_family == AF_INET) {
18
+ ((struct sockaddr_in*)i->ai_addr)->} else if(i->ai_family == AF_INET6) {
19
+ ((struct sockaddr_in6*)i->ai_addr)->sin6 ibute it and/or
20
+** modify it un/*
21
+** Copyrighreturn 1;
22
+ }
23
+#if !0got;
24
+ N -= \ndef __MINGW32__
25
+# include <windowsdef __MINGW32__def __MINGW32__def __MINGW32__def __MINGW32__ndef __MINGW32__** known as the "2-Clause License" or "FreeBSD License".)
26
+
27
+** This program is distributed in the hope tributed in the hope onst is distributed in the hope that it will be useful,
28
+** but without any warranty; witho/*
29
+** Copyright (c) 2009 D. righi->ai_family == AF_INET) {
30
+ ((struct sockaddr_in*)i->ai_addr)->} else if(i->ai_family == AF_INET6) {
31
+ ((struct sockaddr_in6*)i->ai_addr)->sin6 ibute it and/or
32
+** modify it un/*
33
+** Copyrighreturn 1;
34
+ }
35
+#if !0got;
36
+ N -= \ndef __MINGW32__
37
+# include <windowsdef __MINGW32__def __MINGW32__def __MINGW32__def __MINGW32__ndef __MINGW32__
--- a/src/http_socket.c
+++ b/src/http_socket.c
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/http_socket.c
+++ b/src/http_socket.c
@@ -0,0 +1,37 @@
1 ** known as the "2-Clause License" or "FreeBSD License".)
2
3 ** This program is distributed in the hope tributed in the hope onst is distributed iGNU General Public
4 ** License version 2 as published by the Free Software Foundation.
5 **ty; witho/*
6 ** Copyright (c) 2009 D. righi->ai_family == AF_INET) {
7 (WITHOUT ANY WARRANTYai_family == AFMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8 ** General Public License for more details.
9 **
10 ** You should have received a copy of the GNU General Public
11 ** License along with this library; if not, write to the
12 ** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
13 ** Boston, MA 02111-1307, USAwn as the "2-Clause License" or "FreeBSD License".)
14
15 ** This program is distributed in the hope tributed in the hope onst is distributed in the hope that it will be useful,
16 ** but without any warranty; witho/*
17 ** Copyright (c) 2009 D. righi->ai_family == AF_INET) {
18 ((struct sockaddr_in*)i->ai_addr)->} else if(i->ai_family == AF_INET6) {
19 ((struct sockaddr_in6*)i->ai_addr)->sin6 ibute it and/or
20 ** modify it un/*
21 ** Copyrighreturn 1;
22 }
23 #if !0got;
24 N -= \ndef __MINGW32__
25 # include <windowsdef __MINGW32__def __MINGW32__def __MINGW32__def __MINGW32__ndef __MINGW32__** known as the "2-Clause License" or "FreeBSD License".)
26
27 ** This program is distributed in the hope tributed in the hope onst is distributed in the hope that it will be useful,
28 ** but without any warranty; witho/*
29 ** Copyright (c) 2009 D. righi->ai_family == AF_INET) {
30 ((struct sockaddr_in*)i->ai_addr)->} else if(i->ai_family == AF_INET6) {
31 ((struct sockaddr_in6*)i->ai_addr)->sin6 ibute it and/or
32 ** modify it un/*
33 ** Copyrighreturn 1;
34 }
35 #if !0got;
36 N -= \ndef __MINGW32__
37 # include <windowsdef __MINGW32__def __MINGW32__def __MINGW32__def __MINGW32__ndef __MINGW32__
--- a/src/http_transport.c
+++ b/src/http_transport.c
@@ -0,0 +1,119 @@
1
+
2
+ }
3
+ += written;
4
+ return ( != written)zIn[200];ree(zHost)%s\n", blob_str(&zCmd)); */sshin_read(zIn, sizeof(zIn)fprintf(stdoram is free software; you can redistribute it andmodify it under the terms of the Simplified BSD Licensonto the wire does
5
+** not equal the size of the blob being sennt{
6
+ written char *zCmd;
7
+ char zIn[20];at", ie44_randomness fossil_fatal(" is currently only nodelay*
8
+** Copyright (c) 2009 D. Richard Hipp
9
+**
10
+** This program is free software; you can redistribute it and/or
11
+** modify it under the terms of the Simplified BSD License (al\"%s\" \n16160"test", ie44_randomness(0, fossil_nameofexe()33_randomness(* Returns whether sending was errant, i.e.,
12
+** the count of bytes written onto the wire does
13
+** not equal the size of the blob being sent.
14
+*/
15
+intsize_t written = 0;){
16
+ written = /* printf("s(unsigned long) written, ns free software; you can redistribute it and/or
17
+** modify it under the te/*
18
+** Copyright (c) 2009 D --nodelay*
19
+** Copyright (c) 2009 D. Richard Hipp
20
+**
21
+** This program is free software; you can redistribute itfossil_fatal(" is currently only
22
+ popen2(zCmd, &g.sshIn, '%s'\"",
23
+ g.urlPort, g.urlPort, g/_nameofexe()/*
24
+** Copyr*
25
+** Copyright (c) 2009 D --nodel
26
+** Copy return ( != written)zIn[200];ree(
27
+ }
28
+ += written;
29
+ returnsi", ie44_randomness fossil_fatal(" is currentlY it under the tMER/* TBD */
30
+
31
+ }
32
+ += written;
33
+ return ( !
34
+ return ( != writte/* run "fossil http" to procprintf("s(unsigned lTLS}else{
35
+ rc = socket_open();
36
+
37
+ }
38
+ += written;
39
+ return ( != written)zIn[200];ree(zHost)%s\n", blob_str(&zCmd)); */written;
40
+ return ( was errant, i.e.,
41
+** the count of bytes written onto the wire does
42
+** not equal the size of the blo*
43
+** Copyright (c) 2009 D. Richard Hipp
44
+**
45
+** This program is free software; yopen2(zCmd, &g.sshIn, '%s'\"",
46
+ g/_nameofexe()/*
47
+** Copyr*
48
+**int sent;
49
+ while( n>0 ){
50
+ Copy retn ( != written)zIn[200];rn -= sent;en;
51
+ returnsi", ie44_randomness fossil_fatal(" is currentlY it under the tMER/* TBD */
52
+
53
+ }
54
+ += written;
55
+ return ( !
56
+ return ( != writte/* run "fossil http" to procritten)zIn[200];ree(zHost)%s\n", blob_str(&zCmd)); */sshin_read(zIn, sizeof(zIn)fprintf(stdoram is free software; you can redistribute it andmodify it under the terms of the Simplified BSD Licensonto the wire does
57
+** not equal the size of the blob being sennt{
58
+ written char *zCmd;
59
+ char zIn[20];at", ie44_randomness fossil_fatal(" is currently only nodelay*
60
+** Copyright (c) 2009 D. Richard Hipp
61
+**
62
+** This program is free software; you can redistribute it and/or
63
+** modify it under the terms of the Simplified BSD License (al\"%s\" \n16160"test", ie44_randomness(0, fossil_nameofexe()33_randomness(* Returns whether sending was errant, i.e.,
64
+** the count of bytes written onto the wire does
65
+** not equal the size of the blob being sent.
66
+*/
67
+intsize_t written = 0;){
68
+ written = /* printf("s(unsigned long) written, ns free software; you can redistribute it and/or
69
+** modify it under the te/*
70
+** Copyright (c) 2009 D --nodelay*
71
+** Copyright (c) 2009 D. Richard Hipp
72
+**
73
+** This program is free software; you can redistribute itfossil_fatal(" is currently only
74
+ popen2(zCmd, &g.sshIn, '%s'\"",
75
+ g.urlPort, g.urlPort, g/_nameofexe()/*
76
+** Copyr*
77
+** Copyright (c) 2009 D --nodel
78
+** Copy return ( != written)zIn[200];ree(
79
+ }
80
+ += written;
81
+ returnsi", ie44_randomness fossil_fatal(" is currentlY it under the tMER/* TBD */
82
+
83
+ }
84
+ += written;
85
+ return ( !
86
+ return ( != writte/* run "fossil http" to proc
87
+ }
88
+ += written;
89
+ return ( != written)zIn[200];ree(zHost)%s\n", blob_str(&zCmd)); */sshin_read(zIn, sizeof(zIn)fprintf(stdoram is free software; you can redistribute it andmodify it under the terms of the Simplified BSD Licensonto the wire does
90
+** not equal the size of the blob being sennt{
91
+ written char *zCmd;
92
+ char zIn[20];at", ie44_randomness fossil_fatal(" is currently only nodelay*
93
+** Copyright (c) 2009 D. Richard Hipp
94
+**
95
+** This program is free software; you can redistribute it and/or
96
+** modify it under the terms of the Simplified BSD License (al\"%s\" \n16160"test", ie44_randomness(0, fossil_nameofexe()33_randomness(* Returns whether sending was errant, i.e.,
97
+** the count of bytes written onto the wire does
98
+** not equal the size of the blob being sent.
99
+*/
100
+intsize_t written = 0;){
101
+ written = /* printf("s(unsigned long) written, ns free software; you can redistribute it and/or
102
+** modify it under the te/*
103
+** Copyright (c) 2009 D --nodelay*
104
+** Copyright (c) 2009 D. Richard Hipp
105
+**
106
+** This program is free software; you can redistribute itfossil_fatal(" is currently only
107
+ popen2(zCmd, &g.sshIn, '%s'\"",
108
+ g.urlPort, g.urlPort, g/_nameofexe()/*
109
+** Copyr*
110
+** Copyright (c) 2009 D --nodel
111
+** Copy return ( != written)zIn[200];ree(
112
+ }
113
+ += written;
114
+ returnsi", ie44_randomness fossil_fatal(" is currentlY it under the tMER/* TBD */
115
+
116
+ }
117
+ += written;
118
+ return ( !
119
+ return ( != writte/* run "fossil http" to proc
--- a/src/http_transport.c
+++ b/src/http_transport.c
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/http_transport.c
+++ b/src/http_transport.c
@@ -0,0 +1,119 @@
1
2 }
3 += written;
4 return ( != written)zIn[200];ree(zHost)%s\n", blob_str(&zCmd)); */sshin_read(zIn, sizeof(zIn)fprintf(stdoram is free software; you can redistribute it andmodify it under the terms of the Simplified BSD Licensonto the wire does
5 ** not equal the size of the blob being sennt{
6 written char *zCmd;
7 char zIn[20];at", ie44_randomness fossil_fatal(" is currently only nodelay*
8 ** Copyright (c) 2009 D. Richard Hipp
9 **
10 ** This program is free software; you can redistribute it and/or
11 ** modify it under the terms of the Simplified BSD License (al\"%s\" \n16160"test", ie44_randomness(0, fossil_nameofexe()33_randomness(* Returns whether sending was errant, i.e.,
12 ** the count of bytes written onto the wire does
13 ** not equal the size of the blob being sent.
14 */
15 intsize_t written = 0;){
16 written = /* printf("s(unsigned long) written, ns free software; you can redistribute it and/or
17 ** modify it under the te/*
18 ** Copyright (c) 2009 D --nodelay*
19 ** Copyright (c) 2009 D. Richard Hipp
20 **
21 ** This program is free software; you can redistribute itfossil_fatal(" is currently only
22 popen2(zCmd, &g.sshIn, '%s'\"",
23 g.urlPort, g.urlPort, g/_nameofexe()/*
24 ** Copyr*
25 ** Copyright (c) 2009 D --nodel
26 ** Copy return ( != written)zIn[200];ree(
27 }
28 += written;
29 returnsi", ie44_randomness fossil_fatal(" is currentlY it under the tMER/* TBD */
30
31 }
32 += written;
33 return ( !
34 return ( != writte/* run "fossil http" to procprintf("s(unsigned lTLS}else{
35 rc = socket_open();
36
37 }
38 += written;
39 return ( != written)zIn[200];ree(zHost)%s\n", blob_str(&zCmd)); */written;
40 return ( was errant, i.e.,
41 ** the count of bytes written onto the wire does
42 ** not equal the size of the blo*
43 ** Copyright (c) 2009 D. Richard Hipp
44 **
45 ** This program is free software; yopen2(zCmd, &g.sshIn, '%s'\"",
46 g/_nameofexe()/*
47 ** Copyr*
48 **int sent;
49 while( n>0 ){
50 Copy retn ( != written)zIn[200];rn -= sent;en;
51 returnsi", ie44_randomness fossil_fatal(" is currentlY it under the tMER/* TBD */
52
53 }
54 += written;
55 return ( !
56 return ( != writte/* run "fossil http" to procritten)zIn[200];ree(zHost)%s\n", blob_str(&zCmd)); */sshin_read(zIn, sizeof(zIn)fprintf(stdoram is free software; you can redistribute it andmodify it under the terms of the Simplified BSD Licensonto the wire does
57 ** not equal the size of the blob being sennt{
58 written char *zCmd;
59 char zIn[20];at", ie44_randomness fossil_fatal(" is currently only nodelay*
60 ** Copyright (c) 2009 D. Richard Hipp
61 **
62 ** This program is free software; you can redistribute it and/or
63 ** modify it under the terms of the Simplified BSD License (al\"%s\" \n16160"test", ie44_randomness(0, fossil_nameofexe()33_randomness(* Returns whether sending was errant, i.e.,
64 ** the count of bytes written onto the wire does
65 ** not equal the size of the blob being sent.
66 */
67 intsize_t written = 0;){
68 written = /* printf("s(unsigned long) written, ns free software; you can redistribute it and/or
69 ** modify it under the te/*
70 ** Copyright (c) 2009 D --nodelay*
71 ** Copyright (c) 2009 D. Richard Hipp
72 **
73 ** This program is free software; you can redistribute itfossil_fatal(" is currently only
74 popen2(zCmd, &g.sshIn, '%s'\"",
75 g.urlPort, g.urlPort, g/_nameofexe()/*
76 ** Copyr*
77 ** Copyright (c) 2009 D --nodel
78 ** Copy return ( != written)zIn[200];ree(
79 }
80 += written;
81 returnsi", ie44_randomness fossil_fatal(" is currentlY it under the tMER/* TBD */
82
83 }
84 += written;
85 return ( !
86 return ( != writte/* run "fossil http" to proc
87 }
88 += written;
89 return ( != written)zIn[200];ree(zHost)%s\n", blob_str(&zCmd)); */sshin_read(zIn, sizeof(zIn)fprintf(stdoram is free software; you can redistribute it andmodify it under the terms of the Simplified BSD Licensonto the wire does
90 ** not equal the size of the blob being sennt{
91 written char *zCmd;
92 char zIn[20];at", ie44_randomness fossil_fatal(" is currently only nodelay*
93 ** Copyright (c) 2009 D. Richard Hipp
94 **
95 ** This program is free software; you can redistribute it and/or
96 ** modify it under the terms of the Simplified BSD License (al\"%s\" \n16160"test", ie44_randomness(0, fossil_nameofexe()33_randomness(* Returns whether sending was errant, i.e.,
97 ** the count of bytes written onto the wire does
98 ** not equal the size of the blob being sent.
99 */
100 intsize_t written = 0;){
101 written = /* printf("s(unsigned long) written, ns free software; you can redistribute it and/or
102 ** modify it under the te/*
103 ** Copyright (c) 2009 D --nodelay*
104 ** Copyright (c) 2009 D. Richard Hipp
105 **
106 ** This program is free software; you can redistribute itfossil_fatal(" is currently only
107 popen2(zCmd, &g.sshIn, '%s'\"",
108 g.urlPort, g.urlPort, g/_nameofexe()/*
109 ** Copyr*
110 ** Copyright (c) 2009 D --nodel
111 ** Copy return ( != written)zIn[200];ree(
112 }
113 += written;
114 returnsi", ie44_randomness fossil_fatal(" is currentlY it under the tMER/* TBD */
115
116 }
117 += written;
118 return ( !
119 return ( != writte/* run "fossil http" to proc
+22 -2
--- src/main.mk
+++ src/main.mk
@@ -37,10 +37,12 @@
3737
$(SRCDIR)/diffcmd.c \
3838
$(SRCDIR)/doc.c \
3939
$(SRCDIR)/encode.c \
4040
$(SRCDIR)/file.c \
4141
$(SRCDIR)/http.c \
42
+ $(SRCDIR)/http_socket.c \
43
+ $(SRCDIR)/http_transport.c \
4244
$(SRCDIR)/info.c \
4345
$(SRCDIR)/login.c \
4446
$(SRCDIR)/main.c \
4547
$(SRCDIR)/manifest.c \
4648
$(SRCDIR)/md5.c \
@@ -105,10 +107,12 @@
105107
diffcmd_.c \
106108
doc_.c \
107109
encode_.c \
108110
file_.c \
109111
http_.c \
112
+ http_socket_.c \
113
+ http_transport_.c \
110114
info_.c \
111115
login_.c \
112116
main_.c \
113117
manifest_.c \
114118
md5_.c \
@@ -173,10 +177,12 @@
173177
diffcmd.o \
174178
doc.o \
175179
encode.o \
176180
file.o \
177181
http.o \
182
+ http_socket.o \
183
+ http_transport.o \
178184
info.o \
179185
login.o \
180186
main.o \
181187
manifest.o \
182188
md5.o \
@@ -255,16 +261,16 @@
255261
# noop
256262
257263
clean:
258264
rm -f *.o *_.c $(APPNAME) VERSION.h
259265
rm -f translate makeheaders mkindex page_index.h headers
260
- rm -f add.h admin.h allrepo.h bag.h blob.h branch.h browse.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h construct.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h http.h info.h login.h main.h manifest.h md5.h merge.h merge3.h my_page.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h rstats.h schema.h setup.h sha1.h shun.h stat.h style.h sync.h tag.h tagview.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
266
+ rm -f add.h admin.h allrepo.h bag.h blob.h branch.h browse.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h construct.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h http.h http_socket.h http_transport.h info.h login.h main.h manifest.h md5.h merge.h merge3.h my_page.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h rstats.h schema.h setup.h sha1.h shun.h stat.h style.h sync.h tag.h tagview.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
261267
262268
page_index.h: $(TRANS_SRC) mkindex
263269
./mkindex $(TRANS_SRC) >$@
264270
headers: page_index.h makeheaders VERSION.h
265
- ./makeheaders add_.c:add.h admin_.c:admin.h allrepo_.c:allrepo.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.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 construct_.c:construct.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 http_.c:http.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 my_page_.c:my_page.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 rstats_.c:rstats.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.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
271
+ ./makeheaders add_.c:add.h admin_.c:admin.h allrepo_.c:allrepo.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.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 construct_.c:construct.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 http_.c:http.h http_socket_.c:http_socket.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 my_page_.c:my_page.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 rstats_.c:rstats.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.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
266272
touch headers
267273
headers: Makefile
268274
Makefile:
269275
add_.c: $(SRCDIR)/add.c $(SRCDIR)/VERSION translate
270276
./translate $(SRCDIR)/add.c | sed -f $(SRCDIR)/VERSION >add_.c
@@ -446,10 +452,24 @@
446452
447453
http.o: http_.c http.h $(SRCDIR)/config.h
448454
$(XTCC) -o http.o -c http_.c
449455
450456
http.h: headers
457
+http_socket_.c: $(SRCDIR)/http_socket.c $(SRCDIR)/VERSION translate
458
+ ./translate $(SRCDIR)/http_socket.c | sed -f $(SRCDIR)/VERSION >http_socket_.c
459
+
460
+http_socket.o: http_socket_.c http_socket.h $(SRCDIR)/config.h
461
+ $(XTCC) -o http_socket.o -c http_socket_.c
462
+
463
+http_socket.h: headers
464
+http_transport_.c: $(SRCDIR)/http_transport.c $(SRCDIR)/VERSION translate
465
+ ./translate $(SRCDIR)/http_transport.c | sed -f $(SRCDIR)/VERSION >http_transport_.c
466
+
467
+http_transport.o: http_transport_.c http_transport.h $(SRCDIR)/config.h
468
+ $(XTCC) -o http_transport.o -c http_transport_.c
469
+
470
+http_transport.h: headers
451471
info_.c: $(SRCDIR)/info.c $(SRCDIR)/VERSION translate
452472
./translate $(SRCDIR)/info.c | sed -f $(SRCDIR)/VERSION >info_.c
453473
454474
info.o: info_.c info.h $(SRCDIR)/config.h
455475
$(XTCC) -o info.o -c info_.c
456476
--- src/main.mk
+++ src/main.mk
@@ -37,10 +37,12 @@
37 $(SRCDIR)/diffcmd.c \
38 $(SRCDIR)/doc.c \
39 $(SRCDIR)/encode.c \
40 $(SRCDIR)/file.c \
41 $(SRCDIR)/http.c \
 
 
42 $(SRCDIR)/info.c \
43 $(SRCDIR)/login.c \
44 $(SRCDIR)/main.c \
45 $(SRCDIR)/manifest.c \
46 $(SRCDIR)/md5.c \
@@ -105,10 +107,12 @@
105 diffcmd_.c \
106 doc_.c \
107 encode_.c \
108 file_.c \
109 http_.c \
 
 
110 info_.c \
111 login_.c \
112 main_.c \
113 manifest_.c \
114 md5_.c \
@@ -173,10 +177,12 @@
173 diffcmd.o \
174 doc.o \
175 encode.o \
176 file.o \
177 http.o \
 
 
178 info.o \
179 login.o \
180 main.o \
181 manifest.o \
182 md5.o \
@@ -255,16 +261,16 @@
255 # noop
256
257 clean:
258 rm -f *.o *_.c $(APPNAME) VERSION.h
259 rm -f translate makeheaders mkindex page_index.h headers
260 rm -f add.h admin.h allrepo.h bag.h blob.h branch.h browse.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h construct.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h http.h info.h login.h main.h manifest.h md5.h merge.h merge3.h my_page.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h rstats.h schema.h setup.h sha1.h shun.h stat.h style.h sync.h tag.h tagview.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
261
262 page_index.h: $(TRANS_SRC) mkindex
263 ./mkindex $(TRANS_SRC) >$@
264 headers: page_index.h makeheaders VERSION.h
265 ./makeheaders add_.c:add.h admin_.c:admin.h allrepo_.c:allrepo.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.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 construct_.c:construct.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 http_.c:http.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 my_page_.c:my_page.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 rstats_.c:rstats.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.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
266 touch headers
267 headers: Makefile
268 Makefile:
269 add_.c: $(SRCDIR)/add.c $(SRCDIR)/VERSION translate
270 ./translate $(SRCDIR)/add.c | sed -f $(SRCDIR)/VERSION >add_.c
@@ -446,10 +452,24 @@
446
447 http.o: http_.c http.h $(SRCDIR)/config.h
448 $(XTCC) -o http.o -c http_.c
449
450 http.h: headers
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451 info_.c: $(SRCDIR)/info.c $(SRCDIR)/VERSION translate
452 ./translate $(SRCDIR)/info.c | sed -f $(SRCDIR)/VERSION >info_.c
453
454 info.o: info_.c info.h $(SRCDIR)/config.h
455 $(XTCC) -o info.o -c info_.c
456
--- src/main.mk
+++ src/main.mk
@@ -37,10 +37,12 @@
37 $(SRCDIR)/diffcmd.c \
38 $(SRCDIR)/doc.c \
39 $(SRCDIR)/encode.c \
40 $(SRCDIR)/file.c \
41 $(SRCDIR)/http.c \
42 $(SRCDIR)/http_socket.c \
43 $(SRCDIR)/http_transport.c \
44 $(SRCDIR)/info.c \
45 $(SRCDIR)/login.c \
46 $(SRCDIR)/main.c \
47 $(SRCDIR)/manifest.c \
48 $(SRCDIR)/md5.c \
@@ -105,10 +107,12 @@
107 diffcmd_.c \
108 doc_.c \
109 encode_.c \
110 file_.c \
111 http_.c \
112 http_socket_.c \
113 http_transport_.c \
114 info_.c \
115 login_.c \
116 main_.c \
117 manifest_.c \
118 md5_.c \
@@ -173,10 +177,12 @@
177 diffcmd.o \
178 doc.o \
179 encode.o \
180 file.o \
181 http.o \
182 http_socket.o \
183 http_transport.o \
184 info.o \
185 login.o \
186 main.o \
187 manifest.o \
188 md5.o \
@@ -255,16 +261,16 @@
261 # noop
262
263 clean:
264 rm -f *.o *_.c $(APPNAME) VERSION.h
265 rm -f translate makeheaders mkindex page_index.h headers
266 rm -f add.h admin.h allrepo.h bag.h blob.h branch.h browse.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h construct.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h http.h http_socket.h http_transport.h info.h login.h main.h manifest.h md5.h merge.h merge3.h my_page.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h rstats.h schema.h setup.h sha1.h shun.h stat.h style.h sync.h tag.h tagview.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
267
268 page_index.h: $(TRANS_SRC) mkindex
269 ./mkindex $(TRANS_SRC) >$@
270 headers: page_index.h makeheaders VERSION.h
271 ./makeheaders add_.c:add.h admin_.c:admin.h allrepo_.c:allrepo.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.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 construct_.c:construct.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 http_.c:http.h http_socket_.c:http_socket.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 my_page_.c:my_page.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 rstats_.c:rstats.h schema_.c:schema.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tagview_.c:tagview.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
272 touch headers
273 headers: Makefile
274 Makefile:
275 add_.c: $(SRCDIR)/add.c $(SRCDIR)/VERSION translate
276 ./translate $(SRCDIR)/add.c | sed -f $(SRCDIR)/VERSION >add_.c
@@ -446,10 +452,24 @@
452
453 http.o: http_.c http.h $(SRCDIR)/config.h
454 $(XTCC) -o http.o -c http_.c
455
456 http.h: headers
457 http_socket_.c: $(SRCDIR)/http_socket.c $(SRCDIR)/VERSION translate
458 ./translate $(SRCDIR)/http_socket.c | sed -f $(SRCDIR)/VERSION >http_socket_.c
459
460 http_socket.o: http_socket_.c http_socket.h $(SRCDIR)/config.h
461 $(XTCC) -o http_socket.o -c http_socket_.c
462
463 http_socket.h: headers
464 http_transport_.c: $(SRCDIR)/http_transport.c $(SRCDIR)/VERSION translate
465 ./translate $(SRCDIR)/http_transport.c | sed -f $(SRCDIR)/VERSION >http_transport_.c
466
467 http_transport.o: http_transport_.c http_transport.h $(SRCDIR)/config.h
468 $(XTCC) -o http_transport.o -c http_transport_.c
469
470 http_transport.h: headers
471 info_.c: $(SRCDIR)/info.c $(SRCDIR)/VERSION translate
472 ./translate $(SRCDIR)/info.c | sed -f $(SRCDIR)/VERSION >info_.c
473
474 info.o: info_.c info.h $(SRCDIR)/config.h
475 $(XTCC) -o info.o -c info_.c
476
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -31,10 +31,12 @@
3131
diffcmd
3232
doc
3333
encode
3434
file
3535
http
36
+ http_socket
37
+ http_transport
3638
info
3739
login
3840
main
3941
manifest
4042
md5
@@ -195,6 +197,5 @@
195197
puts "th.o:\t\$(SRCDIR)/th.c"
196198
puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th.c -o th.o\n"
197199
198200
puts "th_lang.o:\t\$(SRCDIR)/th_lang.c"
199201
puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o th_lang.o\n"
200
-
201202
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -31,10 +31,12 @@
31 diffcmd
32 doc
33 encode
34 file
35 http
 
 
36 info
37 login
38 main
39 manifest
40 md5
@@ -195,6 +197,5 @@
195 puts "th.o:\t\$(SRCDIR)/th.c"
196 puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th.c -o th.o\n"
197
198 puts "th_lang.o:\t\$(SRCDIR)/th_lang.c"
199 puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o th_lang.o\n"
200
201
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -31,10 +31,12 @@
31 diffcmd
32 doc
33 encode
34 file
35 http
36 http_socket
37 http_transport
38 info
39 login
40 main
41 manifest
42 md5
@@ -195,6 +197,5 @@
197 puts "th.o:\t\$(SRCDIR)/th.c"
198 puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th.c -o th.o\n"
199
200 puts "th_lang.o:\t\$(SRCDIR)/th_lang.c"
201 puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o th_lang.o\n"
 
202
+16 -14
--- src/xfer.c
+++ src/xfer.c
@@ -848,31 +848,32 @@
848848
** Records are pushed to the server if pushFlag is true. Records
849849
** are pulled if pullFlag is true. A full sync occurs if both are
850850
** true.
851851
*/
852852
void client_sync(
853
- int pushFlag, /* True to do a push (or a sync) */
854
- int pullFlag, /* True to do a pull (or a sync) */
855
- int cloneFlag, /* True if this is a clone */
856
- int configRcvMask, /* Receive these configuration items */
857
- int configSendMask /* Send these configuration items */
853
+ int pushFlag, /* True to do a push (or a sync) */
854
+ int pullFlag, /* True to do a pull (or a sync) */
855
+ int cloneFlag, /* True if this is a clone */
856
+ int configRcvMask, /* Receive these configuration items */
857
+ int configSendMask /* Send these configuration items */
858858
){
859
- int go = 1; /* Loop until zero */
860
- const char *zSCode = db_get("server-code", "x");
861
- const char *zPCode = db_get("project-code", 0);
862
- int nCard = 0; /* Number of cards sent or received */
863
- int nCycle = 0; /* Number of round trips to the server */
859
+ int go = 1; /* Loop until zero */
860
+ int nCard = 0; /* Number of cards sent or received */
861
+ int nCycle = 0; /* Number of round trips to the server */
864862
int size; /* Size of a config value */
865863
int nFileSend = 0;
866864
int origConfigRcvMask; /* Original value of configRcvMask */
867865
int nFileRecv; /* Number of files received */
868866
int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
869867
const char *zCookie; /* Server cookie */
870
- Blob send; /* Text we are sending to the server */
871
- Blob recv; /* Reply we got back from the server */
872
- Xfer xfer; /* Transfer data */
868
+ Blob send; /* Text we are sending to the server */
869
+ Blob recv; /* Reply we got back from the server */
870
+ Xfer xfer; /* Transfer data */
871
+ const char *zSCode = db_get("server-code", "x");
872
+ const char *zPCode = db_get("project-code", 0);
873873
874
+ socket_global_init();
874875
memset(&xfer, 0, sizeof(xfer));
875876
xfer.pIn = &recv;
876877
xfer.pOut = &send;
877878
xfer.mxSend = db_get_int("max-upload", 250000);
878879
@@ -1176,9 +1177,10 @@
11761177
*/
11771178
if( xfer.nFileSent+xfer.nDeltaSent>0 ){
11781179
go = 1;
11791180
}
11801181
};
1181
- http_close();
1182
+ transport_close();
1183
+ socket_global_shutdown();
11821184
db_multi_exec("DROP TABLE onremote");
11831185
db_end_transaction(0);
11841186
}
11851187
--- src/xfer.c
+++ src/xfer.c
@@ -848,31 +848,32 @@
848 ** Records are pushed to the server if pushFlag is true. Records
849 ** are pulled if pullFlag is true. A full sync occurs if both are
850 ** true.
851 */
852 void client_sync(
853 int pushFlag, /* True to do a push (or a sync) */
854 int pullFlag, /* True to do a pull (or a sync) */
855 int cloneFlag, /* True if this is a clone */
856 int configRcvMask, /* Receive these configuration items */
857 int configSendMask /* Send these configuration items */
858 ){
859 int go = 1; /* Loop until zero */
860 const char *zSCode = db_get("server-code", "x");
861 const char *zPCode = db_get("project-code", 0);
862 int nCard = 0; /* Number of cards sent or received */
863 int nCycle = 0; /* Number of round trips to the server */
864 int size; /* Size of a config value */
865 int nFileSend = 0;
866 int origConfigRcvMask; /* Original value of configRcvMask */
867 int nFileRecv; /* Number of files received */
868 int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
869 const char *zCookie; /* Server cookie */
870 Blob send; /* Text we are sending to the server */
871 Blob recv; /* Reply we got back from the server */
872 Xfer xfer; /* Transfer data */
 
 
873
 
874 memset(&xfer, 0, sizeof(xfer));
875 xfer.pIn = &recv;
876 xfer.pOut = &send;
877 xfer.mxSend = db_get_int("max-upload", 250000);
878
@@ -1176,9 +1177,10 @@
1176 */
1177 if( xfer.nFileSent+xfer.nDeltaSent>0 ){
1178 go = 1;
1179 }
1180 };
1181 http_close();
 
1182 db_multi_exec("DROP TABLE onremote");
1183 db_end_transaction(0);
1184 }
1185
--- src/xfer.c
+++ src/xfer.c
@@ -848,31 +848,32 @@
848 ** Records are pushed to the server if pushFlag is true. Records
849 ** are pulled if pullFlag is true. A full sync occurs if both are
850 ** true.
851 */
852 void client_sync(
853 int pushFlag, /* True to do a push (or a sync) */
854 int pullFlag, /* True to do a pull (or a sync) */
855 int cloneFlag, /* True if this is a clone */
856 int configRcvMask, /* Receive these configuration items */
857 int configSendMask /* Send these configuration items */
858 ){
859 int go = 1; /* Loop until zero */
860 int nCard = 0; /* Number of cards sent or received */
861 int nCycle = 0; /* Number of round trips to the server */
 
 
862 int size; /* Size of a config value */
863 int nFileSend = 0;
864 int origConfigRcvMask; /* Original value of configRcvMask */
865 int nFileRecv; /* Number of files received */
866 int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
867 const char *zCookie; /* Server cookie */
868 Blob send; /* Text we are sending to the server */
869 Blob recv; /* Reply we got back from the server */
870 Xfer xfer; /* Transfer data */
871 const char *zSCode = db_get("server-code", "x");
872 const char *zPCode = db_get("project-code", 0);
873
874 socket_global_init();
875 memset(&xfer, 0, sizeof(xfer));
876 xfer.pIn = &recv;
877 xfer.pOut = &send;
878 xfer.mxSend = db_get_int("max-upload", 250000);
879
@@ -1176,9 +1177,10 @@
1177 */
1178 if( xfer.nFileSent+xfer.nDeltaSent>0 ){
1179 go = 1;
1180 }
1181 };
1182 transport_close();
1183 socket_global_shutdown();
1184 db_multi_exec("DROP TABLE onremote");
1185 db_end_transaction(0);
1186 }
1187

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button