Fossil

Check-in [ec56c69f]
Login

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

Overview
Comment:Add the /ext page that will run CGI or deliver static content from a document hierarchy specified by the --extroot command-line option on "fossil server" or the extroot: option in the CGI file.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: ec56c69fe98d26d91a3dac2bb3e6a02a673dd6932a87bd20136a2f7b1beab373
User & Date: drh 2019-07-25 21:11:08
References
2019-08-03
19:49
Fix the repolist function for CGI server invocations, apparently broken by check-in [ec56c69fe98d26d9] check-in: 534b0600 user: drh tags: trunk
2019-07-31
12:21
Fixed fossil_strcmp() usage in cgi_init() when in JSON mode. Through some extremely serendipitous fluke, its broken usage just happened to work until a bit was removed from that function in [ec56c69f] which, purely coincidentally, caused the bug (mine, from 2011!) to start triggering when x-www-form-urlencoded forms were submitted (login/logout). Before that, the buggy block never got a chance to trigger for those forms. check-in: 115a70b2 user: stephan tags: trunk
2019-07-29
14:19
Fix the build for -DFOSSIL_ENABLE_TH1_DOCS. The build was broken by check-in [ed2def5ffb96d74c] and on trunk by [ec56c69fe98d26d9]. check-in: 8abeb627 user: drh tags: trunk
Context
2019-07-25
23:56
Neither Setup nor Admin users get Write-Unversioned permission by default. And only Setup users are able to include Write-Unversioned permission when editing a user. check-in: 9ca4eb2b user: drh tags: trunk
21:11
Add the /ext page that will run CGI or deliver static content from a document hierarchy specified by the --extroot command-line option on "fossil server" or the extroot: option in the CGI file. check-in: ec56c69f user: drh tags: trunk
21:09
Remove an unused variable. Closed-Leaf check-in: c2a98a5d user: drh tags: extension-cgi
2019-07-23
19:17
Make sure an HTTP request always has at least a single "/" in the pathname. check-in: 35d609a0 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/cgi.c.

11
12
13
14
15
16
17
18
19
20
21
22





23
24
25
26
27
28
29
...
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
....
1022
1023
1024
1025
1026
1027
1028


1029
1030




















1031
1032
1033
1034
1035
1036
1037
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains C functions and procedures that provide useful
** services to CGI programs.  There are procedures for parsing and
** dispensing QUERY_STRING parameters and cookies, the "mprintf()"
** formatting function and its cousins, and routines to encode and
** decode strings in HTML or HTTP.





*/
#include "config.h"
#ifdef _WIN32
# if !defined(_WIN32_WINNT)
#  define _WIN32_WINNT 0x0501
# endif
# include <winsock2.h>
................................................................................
    g.zIpAddr = mprintf("%s", z);
  }

  len = atoi(PD("CONTENT_LENGTH", "0"));
  g.zContentType = zType = P("CONTENT_TYPE");
  blob_zero(&g.cgiIn);
  if( len>0 && zType ){
    if( fossil_strcmp(zType,"application/x-www-form-urlencoded")==0
         || strncmp(zType,"multipart/form-data",19)==0 ){
      z = fossil_malloc( len+1 );
      len = fread(z, 1, len, g.httpIn);
      z[len] = 0;
      cgi_trace(z);
      if( zType[0]=='a' ){
        add_param_list(z, '&');
      }else{
        process_multipart_form_data(z, len);
      }
    }else if( fossil_strcmp(zType, "application/x-fossil")==0 ){
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
      blob_uncompress(&g.cgiIn, &g.cgiIn);
    }else if( fossil_strcmp(zType, "application/x-fossil-debug")==0 ){
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
    }else if( fossil_strcmp(zType, "application/x-fossil-uncompressed")==0 ){
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
    }
#ifdef FOSSIL_ENABLE_JSON
    else if( fossil_strcmp(zType, "application/json")
              || fossil_strcmp(zType,"text/plain")/*assume this MIGHT be JSON*/
              || fossil_strcmp(zType,"application/javascript")){
      g.json.isJsonMode = 1;
      cgi_parse_POST_JSON(g.httpIn, (unsigned int)len);
................................................................................
      GET/POST arguments. i prefer for GET entries to take precedence
      over like-named POST entries, but in order for that to happen we
      need to process QUERY_STRING _after_ reading the POST data.
      */
      cgi_set_content_type(json_guess_content_type());
    }
#endif /* FOSSIL_ENABLE_JSON */


  }





















}

/*
** This is the comparison function used to sort the aParamQP[] array of
** query parameters and cookies.
*/
static int qparam_compare(const void *a, const void *b){







|
|
|
|
|
>
>
>
>
>







 







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


<
<
<
<







 







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







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
...
984
985
986
987
988
989
990











991
992
993




994
995
996
997
998
999
1000
....
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains C functions and procedures used by CGI programs
** (Fossil launched as CGI) to interpret CGI environment variables,
** gather the results, and send they reply back to the CGI server.
** This file also contains routines for running a simple web-server
** (the "fossil ui" or "fossil server" command) and launching subprocesses
** to handle each inbound HTTP request using CGI.
**
** This file contains routines used by Fossil when it is acting as a
** CGI client.  For the code used by Fossil when it is acting as a
** CGI server (for the /ext webpage) see the "extcgi.c" source file.
*/
#include "config.h"
#ifdef _WIN32
# if !defined(_WIN32_WINNT)
#  define _WIN32_WINNT 0x0501
# endif
# include <winsock2.h>
................................................................................
    g.zIpAddr = mprintf("%s", z);
  }

  len = atoi(PD("CONTENT_LENGTH", "0"));
  g.zContentType = zType = P("CONTENT_TYPE");
  blob_zero(&g.cgiIn);
  if( len>0 && zType ){











    if( fossil_strcmp(zType, "application/x-fossil")==0 ){
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
      blob_uncompress(&g.cgiIn, &g.cgiIn);




    }
#ifdef FOSSIL_ENABLE_JSON
    else if( fossil_strcmp(zType, "application/json")
              || fossil_strcmp(zType,"text/plain")/*assume this MIGHT be JSON*/
              || fossil_strcmp(zType,"application/javascript")){
      g.json.isJsonMode = 1;
      cgi_parse_POST_JSON(g.httpIn, (unsigned int)len);
................................................................................
      GET/POST arguments. i prefer for GET entries to take precedence
      over like-named POST entries, but in order for that to happen we
      need to process QUERY_STRING _after_ reading the POST data.
      */
      cgi_set_content_type(json_guess_content_type());
    }
#endif /* FOSSIL_ENABLE_JSON */
    else{
      blob_read_from_channel(&g.cgiIn, g.httpIn, len);
    }
  }
}

/*
** Decode POST parameter information in the cgiIn content, if any.
*/
void cgi_decode_post_parameters(void){
  int len = blob_size(&g.cgiIn);
  if( len==0 ) return;
  if( fossil_strcmp(g.zContentType,"application/x-www-form-urlencoded")==0
   || strncmp(g.zContentType,"multipart/form-data",19)==0
  ){
    char *z = blob_str(&g.cgiIn);
    cgi_trace(z);
    if( g.zContentType[0]=='a' ){
      add_param_list(z, '&');
    }else{
      process_multipart_form_data(z, len);
    }
    blob_init(&g.cgiIn, 0, 0);
  }
}

/*
** This is the comparison function used to sort the aParamQP[] array of
** query parameters and cookies.
*/
static int qparam_compare(const void *a, const void *b){

Changes to src/dispatch.c.

45
46
47
48
49
50
51

52
53
54
55
56
57
58
#define CMDFLAG_TEST        0x0004      /* Commands for testing only */
#define CMDFLAG_WEBPAGE     0x0008      /* Web pages */
#define CMDFLAG_COMMAND     0x0010      /* A command */
#define CMDFLAG_SETTING     0x0020      /* A setting */
#define CMDFLAG_VERSIONABLE 0x0040      /* A versionable setting */
#define CMDFLAG_BLOCKTEXT   0x0080      /* Multi-line text setting */
#define CMDFLAG_BOOLEAN     0x0100      /* A boolean setting */

/**************************************************************************/

/* Values for the 2nd parameter to dispatch_name_search() */
#define CMDFLAG_ANY         0x0038      /* Match anything */
#define CMDFLAG_PREFIX      0x0200      /* Prefix match is ok */

#endif /* INTERFACE */







>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#define CMDFLAG_TEST        0x0004      /* Commands for testing only */
#define CMDFLAG_WEBPAGE     0x0008      /* Web pages */
#define CMDFLAG_COMMAND     0x0010      /* A command */
#define CMDFLAG_SETTING     0x0020      /* A setting */
#define CMDFLAG_VERSIONABLE 0x0040      /* A versionable setting */
#define CMDFLAG_BLOCKTEXT   0x0080      /* Multi-line text setting */
#define CMDFLAG_BOOLEAN     0x0100      /* A boolean setting */
#define CMDFLAG_RAWCONTENT  0x0200      /* Do not interpret POST content */
/**************************************************************************/

/* Values for the 2nd parameter to dispatch_name_search() */
#define CMDFLAG_ANY         0x0038      /* Match anything */
#define CMDFLAG_PREFIX      0x0200      /* Prefix match is ok */

#endif /* INTERFACE */

Changes to src/doc.c.

527
528
529
530
531
532
533











































































534
535
536
537
538
539
540
...
616
617
618
619
620
621
622

623
624
625
626
627
628
629
...
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
      blob_append(cgi_output_blob(), &z[base], i-base);
      blob_appendf(cgi_output_blob(), "%R");
      base = i+5;
    }
  }
  blob_append(cgi_output_blob(), &z[base], i-base);
}












































































/*
** WEBPAGE: uv
** WEBPAGE: doc
** URL: /uv/FILE
** URL: /doc/CHECKIN/FILE
**
................................................................................
      zCheckin = mprintf("%.*s", i, zName);
      if( fossil_strcmp(zCheckin,"ckout")==0 && g.localOpen==0 ){
        zCheckin = "tip";
      }
    }
    if( nMiss==count(azSuffix) ){
      zName = "404.md";

    }else if( zName[i]==0 ){
      assert( nMiss>=0 && nMiss<count(azSuffix) );
      zName = azSuffix[nMiss];
    }else if( !isUV ){
      zName += i;
    }
    while( zName[0]=='/' ){ zName++; }
................................................................................
  Th_Store("doc_name", zName);
  if( vid ){
    Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'"
                                       "  FROM blob WHERE rid=%d", vid));
    Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
                                    " WHERE objid=%d AND type='ci'", vid));
  }
  if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
    Blob tail;
    style_adunit_config(ADUNIT_RIGHT_OK);
    if( wiki_find_title(&filebody, &title, &tail) ){
      style_header("%s", blob_str(&title));
      wiki_convert(&tail, 0, WIKI_BUTTONS);
    }else{
      style_header("%s", zDfltTitle);
      wiki_convert(&filebody, 0, WIKI_BUTTONS);
    }
    style_footer();
  }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
    Blob tail = BLOB_INITIALIZER;
    markdown_to_html(&filebody, &title, &tail);
    if( blob_size(&title)>0 ){
      style_header("%s", blob_str(&title));
    }else{
      style_header("%s", nMiss>=count(azSuffix)?
                        "Not Found" : zDfltTitle);
    }
    convert_href_and_output(&tail);
    style_footer();
  }else if( fossil_strcmp(zMime, "text/plain")==0 ){
    style_header("%s", zDfltTitle);
    @ <blockquote><pre>
    @ %h(blob_str(&filebody))
    @ </pre></blockquote>
    style_footer();
  }else if( fossil_strcmp(zMime, "text/html")==0
            && doc_is_embedded_html(&filebody, &title) ){
    if( blob_size(&title)==0 ) blob_append(&title,zName,-1);
    style_header("%s", blob_str(&title));
    convert_href_and_output(&filebody);
    style_footer();
#ifdef FOSSIL_ENABLE_TH1_DOCS
  }else if( Th_AreDocsEnabled() &&
            fossil_strcmp(zMime, "application/x-th1")==0 ){
    int raw = P("raw")!=0;
    if( !raw ){
      Blob tail;
      blob_zero(&tail);
      if( wiki_find_title(&filebody, &title, &tail) ){
        style_header("%s", blob_str(&title));
        Th_Render(blob_str(&tail));
        blob_reset(&tail);
      }else{
        style_header("%h", zName);
        Th_Render(blob_str(&filebody));
      }
    }else{
      Th_Render(blob_str(&filebody));
    }
    if( !raw ){
      style_footer();
    }
#endif
  }else{
    cgi_set_content_type(zMime);
    cgi_set_content(&filebody);
  }
  if( nMiss>=count(azSuffix) ) cgi_set_status(404, "Not Found");
  db_end_transaction(0);
  return;

  /* Jump here when unable to locate the document */
doc_not_found:
  db_end_transaction(0);







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







 







>







 







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







527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
...
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
...
764
765
766
767
768
769
770
771



























































772
773
774
775
776
777
778
      blob_append(cgi_output_blob(), &z[base], i-base);
      blob_appendf(cgi_output_blob(), "%R");
      base = i+5;
    }
  }
  blob_append(cgi_output_blob(), &z[base], i-base);
}

/*
** Render a document as the reply to the HTTP request.  The body
** of the document is contained in pBody.  The body might be binary.
** The mimetype is in zMimetype.
*/
void document_render(
  Blob *pBody,                  /* Document content */
  const char *zMime,            /* MIME-type */
  const char *zDefaultTitle,    /* Default title */
  const char *zFilename         /* Name of the file being rendered */
){
  Blob title;
  blob_init(&title,0,0);
  if( fossil_strcmp(zMime, "text/x-fossil-wiki")==0 ){
    Blob tail;
    style_adunit_config(ADUNIT_RIGHT_OK);
    if( wiki_find_title(pBody, &title, &tail) ){
      style_header("%s", blob_str(&title));
      wiki_convert(&tail, 0, WIKI_BUTTONS);
    }else{
      style_header("%s", zDefaultTitle);
      wiki_convert(pBody, 0, WIKI_BUTTONS);
    }
    style_footer();
  }else if( fossil_strcmp(zMime, "text/x-markdown")==0 ){
    Blob tail = BLOB_INITIALIZER;
    markdown_to_html(pBody, &title, &tail);
    if( blob_size(&title)>0 ){
      style_header("%s", blob_str(&title));
    }else{
      style_header("%s", zDefaultTitle);
    }
    convert_href_and_output(&tail);
    style_footer();
  }else if( fossil_strcmp(zMime, "text/plain")==0 ){
    style_header("%s", zDefaultTitle);
    @ <blockquote><pre>
    @ %h(blob_str(pBody))
    @ </pre></blockquote>
    style_footer();
  }else if( fossil_strcmp(zMime, "text/html")==0
            && doc_is_embedded_html(pBody, &title) ){
    if( blob_size(&title)==0 ) blob_append(&title,zFilename,-1);
    style_header("%s", blob_str(&title));
    convert_href_and_output(pBody);
    style_footer();
#ifdef FOSSIL_ENABLE_TH1_DOCS
  }else if( Th_AreDocsEnabled() &&
            fossil_strcmp(zMime, "application/x-th1")==0 ){
    int raw = P("raw")!=0;
    if( !raw ){
      Blob tail;
      blob_zero(&tail);
      if( wiki_find_title(pBody, &title, &tail) ){
        style_header("%s", blob_str(&title));
        Th_Render(blob_str(&tail));
        blob_reset(&tail);
      }else{
        style_header("%h", zName);
        Th_Render(blob_str(pBody));
      }
    }else{
      Th_Render(blob_str(pBody));
    }
    if( !raw ){
      style_footer();
    }
#endif
  }else{
    cgi_set_content_type(zMime);
    cgi_set_content(pBody);
  }
}


/*
** WEBPAGE: uv
** WEBPAGE: doc
** URL: /uv/FILE
** URL: /doc/CHECKIN/FILE
**
................................................................................
      zCheckin = mprintf("%.*s", i, zName);
      if( fossil_strcmp(zCheckin,"ckout")==0 && g.localOpen==0 ){
        zCheckin = "tip";
      }
    }
    if( nMiss==count(azSuffix) ){
      zName = "404.md";
      zDfltTitle = "Not Found";
    }else if( zName[i]==0 ){
      assert( nMiss>=0 && nMiss<count(azSuffix) );
      zName = azSuffix[nMiss];
    }else if( !isUV ){
      zName += i;
    }
    while( zName[0]=='/' ){ zName++; }
................................................................................
  Th_Store("doc_name", zName);
  if( vid ){
    Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'"
                                       "  FROM blob WHERE rid=%d", vid));
    Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event"
                                    " WHERE objid=%d AND type='ci'", vid));
  }
  document_render(&filebody, zMime, zDfltTitle, zName);



























































  if( nMiss>=count(azSuffix) ) cgi_set_status(404, "Not Found");
  db_end_transaction(0);
  return;

  /* Jump here when unable to locate the document */
doc_not_found:
  db_end_transaction(0);

Added src/extcgi.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/*
** Copyright (c) 2019 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@sqlite.org
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code to invoke CGI-based extensions to the
** Fossil server via the /ext webpage.
**
** The /ext webpage acts like a recursive webserver, relaying the
** HTTP request to some other component - usually another CGI.
**
** Before doing the relay, /ext examines the login cookie to see
** if the HTTP request is coming from a validated user, and if so
** /ext sets some additional environment variables that the extension
** CGI script can use.  In this way, the extension CGI scripts use the
** same login system as the main repository, and appear to be
** an integrated part of the repository.
*/
#include "config.h"
#include "extcgi.h"
#include <assert.h>

#if defined(_WIN32) || defined(WIN32)
# undef popen
# define popen _popen
# undef pclose
# define pclose _pclose
#endif

/*
** These are the environment variables that should be set for CGI
** extension programs:
*/
static const char *azCgiEnv[] = {
   "AUTH_TYPE",
   "AUTH_CONTENT",
   "CONTENT_LENGTH",
   "CONTENT_TYPE",
   "DOCUMENT_ROOT",
   "FOSSIL_CAPABILITIES",
   "FOSSIL_REPOSITORY",
   "FOSSIL_USER",
   "GATEWAY_INTERFACE",
   "HTTP_ACCEPT",
   /* "HTTP_ACCEPT_ENCODING", // omitted from sub-cgi */
   "HTTP_COOKIE",
   "HTTP_HOST",
   "HTTP_IF_MODIFIED_SINCE",
   "HTTP_IF_NONE_MATCH",
   "HTTP_REFERER",
   "HTTP_USER_AGENT",
   "PATH_INFO",
   "QUERY_STRING",
   "REMOTE_ADDR",
   "REMOTE_USER",
   "REQUEST_METHOD",
   "REQUEST_URI",
   "SCRIPT_DIRECTORY",
   "SCRIPT_FILENAME",
   "SCRIPT_NAME",
   "SERVER_NAME",
   "SERVER_PORT",
   "SERVER_PROTOCOL",
};

/*
** WEBPAGE: ext  raw-content
**
** Relay an HTTP request to secondary CGI after first checking the
** login credentials and setting auxiliary environment variables
** so that the secondary CGI can be aware of the credentials and
** capabilities of the Fossil user.
**
** The /ext page is only functional if the "extroot: DIR" setting is
** found in the CGI script that launched Fossil, or if the "--extroot DIR"
** flag is present when Fossil is lauched using the "server", "ui", or
** "http" commands.  DIR must be an absolute pathname (relative to the
** chroot jail) of the root of the file hierarchy that implements the CGI
** functionality.  Executable files are CGI.  Non-executable files are
** static content.
**
** The path after the /ext is the path to the CGI script or static file
** relative to DIR. For security, this path may not contain characters
** other than ASCII letters or digits, ".", "-", "/", and "_".  If the
** "." or "-" characters are present in the path then they may not follow
** a "/".
*/
void ext_page(void){
  const char *zName = P("name");  /* Path information after /ext */
  char *zPath = 0;                /* Complete path from extroot */
  int nRoot;                      /* Number of bytes in the extroot name */
  char *zScript = 0;              /* Name of the CGI script */
  int nScript = 0;                /* Bytes in the CGI script name */
  const char *zFailReason = "???";/* Reason for failure */
  int i;                          /* Loop counter */
  const char *zMime = 0;          /* MIME type of the reply */
  int fdFromChild = -1;           /* File descriptor for reading from child */
  FILE *toChild = 0;              /* FILE for sending to child */
  FILE *fromChild = 0;            /* FILE for reading from child */
  int pidChild = 0;               /* Process id of the child */
  int rc;                         /* Reply code from subroutine call */
  int nContent = -1;              /* Content length */
  Blob reply;                     /* The reply */
  char zLine[1000];               /* One line of the CGI reply */

  login_check_credentials();
  blob_init(&reply, 0, 0);
  if( g.zExtRoot==0 ){
    zFailReason = "extroot is not set";
    goto ext_not_found;
  }
  if( file_is_absolute_path(g.zExtRoot)==0 ){
    zFailReason = "extroot is a relative pathname";
    goto ext_not_found;
  }
  if( zName==0 ){
    zFailReason = "no path beyond /ext";
    goto ext_not_found;
  }
  if( file_isdir(g.zExtRoot,ExtFILE)!=1 ){
    zFailReason = "extroot is not a directory";
    goto ext_not_found;
  }
  zPath = mprintf("%s/%s", g.zExtRoot, zName);
  nRoot = (int)strlen(g.zExtRoot);
  if( file_isfile(zPath, ExtFILE) ){
    nScript = (int)strlen(zPath);
    zScript = zPath;
  }else{
    for(i=nRoot+1; zPath[i]; i++){
      char c = zPath[i];
      if( (c=='.' || c=='-') && zPath[i-1]=='/' ){
        zFailReason = "path element begins with '.' or '-'";
        goto ext_not_found;
      }
      if( !fossil_isalnum(c) && c!='_' && c!='-' && c!='.' && c!='/' ){
        zFailReason = "illegal character in path";
        goto ext_not_found;
      }
      if( c=='/' ){
        int isDir, isFile;
        zPath[i] = 0;
        isDir = file_isdir(zPath, ExtFILE);
        isFile = isDir==2 ? file_isfile(zPath, ExtFILE) : 0;
        zPath[i] = c;
        if( isDir==0 ){
          zFailReason = "path does not match any file or script";
          goto ext_not_found;
        }
        if( isFile!=0 ){
          zScript = mprintf("%.*s", i, zPath);
          nScript = i;
          break;
        }
      }
    }
  }
  if( nScript==0 ){
    zFailReason = "path does not match any file or script";
    goto ext_not_found;
  }
  assert( nScript>=nRoot+1 );
  style_set_current_page("ext/%s", &zScript[nRoot+1]);
  zMime = mimetype_from_name(zScript);
  if( zMime==0 ) zMime = "application/octet-stream";
  if( !file_isexe(zScript, ExtFILE) ){
    /* File is not executable.  Must be a regular file.  In that case,
    ** disallow extra path elements */
    if( zPath[nScript]!=0 ){
      zFailReason = "extra path elements after filename";
      goto ext_not_found;
    }
    blob_read_from_file(&reply, zScript, ExtFILE);
    document_render(&reply, zMime, zName, zName);
    return;
  }

  /* If we reach this point, that means we are dealing with an executable
  ** file name zScript.  Run that file as CGI.
  */
  cgi_replace_parameter("DOCUMENT_ROOT", g.zExtRoot);
  cgi_replace_parameter("SCRIPT_FILENAME", zScript);
  cgi_replace_parameter("SCRIPT_NAME",
        mprintf("%T/ext/%T",g.zTop,zScript+nRoot+1));
  cgi_replace_parameter("SCRIPT_DIRECTORY", file_dirname(zScript));
  cgi_replace_parameter("PATH_INFO", zName + strlen(zScript+nRoot+1));
  if( g.zLogin ){
    cgi_replace_parameter("REMOTE_USER", g.zLogin);
    cgi_set_parameter_nocopy("FOSSIL_USER", g.zLogin, 0);
  }
  cgi_set_parameter_nocopy("FOSSIL_REPOSITORY", g.zRepositoryName, 0);
  cgi_set_parameter_nocopy("FOSSIL_CAPABILITIES",
     db_text("","SELECT fullcap(cap) FROM user WHERE login=%Q",
             g.zLogin ? g.zLogin : "nobody"), 0);
  cgi_replace_parameter("GATEWAY_INTERFACE","CGI/1.0");
  for(i=0; i<sizeof(azCgiEnv)/sizeof(azCgiEnv[0]); i++){
    const char *zVal = P(azCgiEnv[i]);
    if( zVal ) fossil_setenv(azCgiEnv[i], zVal);
  }
  fossil_setenv("HTTP_ACCEPT_ENCODING","");
  rc = popen2(zScript, &fdFromChild, &toChild, &pidChild, 1);
  if( rc ){
    zFailReason = "cannot exec CGI child process";
    goto ext_not_found;
  }
  fromChild = fdopen(fdFromChild, "rb");
  if( fromChild==0 ){
    zFailReason = "cannot open FILE to read from CGI child process";
    goto ext_not_found;
  }
  if( blob_size(&g.cgiIn)>0 ){
    size_t nSent, toSend;
    unsigned char *data = (unsigned char*)blob_buffer(&g.cgiIn);
    toSend = (size_t)blob_size(&g.cgiIn);
    do{
      nSent = fwrite(data, 1, toSend, toChild);
      if( nSent<=0 ){
        zFailReason = "unable to send all content to the CGI child process";
        goto ext_not_found;
      }
      toSend -= nSent;
      data += nSent;
    }while( toSend>0 );
    fflush(toChild);
  }
  if( g.perm.Debug && P("fossil-ext-debug")!=0 ){
    /* For users with Debug privilege, if the "fossil-ext-debug" query
    ** parameter exists, then show raw output from the CGI */
    zMime = "text/plain";
  }else{
    while( fgets(zLine,sizeof(zLine),fromChild) ){
      for(i=0; zLine[i] && zLine[i]!='\r' && zLine[i]!='\n'; i++){}
      zLine[i] = 0;
      if( i==0 ) break;
      if( fossil_strnicmp(zLine,"Location:",9)==0 ){
        fclose(fromChild);
        fclose(toChild);
        cgi_redirect(&zLine[10]); /* no return */
      }else if( fossil_strnicmp(zLine,"Status:",7)==0 ){
        int j;
        for(i=7; fossil_isspace(zLine[i]); i++){}
        for(j=i; fossil_isdigit(zLine[j]); j++){}
        while( fossil_isspace(zLine[j]) ){ j++; }
        cgi_set_status(atoi(&zLine[i]), &zLine[j]);
      }else if( fossil_strnicmp(zLine,"Content-Length:",15)==0 ){
        nContent = atoi(&zLine[15]);
      }else if( fossil_strnicmp(zLine,"Content-Type:",13)==0 ){
        int j;
        for(i=13; fossil_isspace(zLine[i]); i++){}
        for(j=i; zLine[j] && zLine[j]!=';'; j++){}
        zMime = mprintf("%.*s", j-i, &zLine[i]);
      }
    }
  }
  blob_read_from_channel(&reply, fromChild, nContent);
  zFailReason = 0;  /* Indicate success */

ext_not_found:
  fossil_free(zPath);
  if( fromChild ){
    fclose(fromChild);
  }else if( fdFromChild>2 ){
    close(fdFromChild);
  }
  if( toChild ) fclose(toChild);
  if( zFailReason==0 ){
    document_render(&reply, zMime, zName, zName);
  }else{
    cgi_set_status(404, "Not Found");
    @ <h1>Not Found</h1>
    @ <p>Page not found: %h(g.zPath)</p>
    if( g.perm.Debug ){
      @ <p>Reason for failure: %h(zFailReason)</p>
    }
  }
  return;
}

Changes to src/http_transport.c.

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    blob_append_escaped_arg(&zCmd, pUrlData->path);
  }else{
    fossil_panic("ssh:// URI does not specify a path to the repository");
  }
  if( g.fSshTrace ){
    fossil_print("%s\n", blob_str(&zCmd));  /* Show the whole SSH command */
  }
  popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
  if( sshPid==0 ){
    socket_set_errmsg("cannot start ssh tunnel using [%b]", &zCmd);
  }
  blob_reset(&zCmd);
  return sshPid==0;
}








|







138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    blob_append_escaped_arg(&zCmd, pUrlData->path);
  }else{
    fossil_panic("ssh:// URI does not specify a path to the repository");
  }
  if( g.fSshTrace ){
    fossil_print("%s\n", blob_str(&zCmd));  /* Show the whole SSH command */
  }
  popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid, 0);
  if( sshPid==0 ){
    socket_set_errmsg("cannot start ssh tunnel using [%b]", &zCmd);
  }
  blob_reset(&zCmd);
  return sshPid==0;
}

Changes to src/main.c.

171
172
173
174
175
176
177

178
179
180
181
182
183
184
....
1781
1782
1783
1784
1785
1786
1787



1788
1789
1790
1791
1792
1793
1794
....
1939
1940
1941
1942
1943
1944
1945



1946
1947
1948
1949
1950
1951
1952
....
2085
2086
2087
2088
2089
2090
2091









2092
2093
2094
2095
2096
2097
2098
....
2238
2239
2240
2241
2242
2243
2244

2245
2246
2247
2248
2249
2250

2251
2252
2253
2254
2255
2256
2257
....
2295
2296
2297
2298
2299
2300
2301

2302
2303
2304
2305
2306
2307
2308
....
2389
2390
2391
2392
2393
2394
2395

2396
2397
2398
2399
2400
2401
2402
....
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501

2502
2503
2504
2505
2506
2507
2508
....
2535
2536
2537
2538
2539
2540
2541

2542
2543
2544
2545
2546
2547
2548
  int fNoSync;            /* Do not do an autosync ever.  --nosync */
  int fIPv4;              /* Use only IPv4, not IPv6. --ipv4 */
  char *zPath;            /* Name of webpage being served */
  char *zExtra;           /* Extra path information past the webpage name */
  char *zBaseURL;         /* Full text of the URL being served */
  char *zHttpsURL;        /* zBaseURL translated to https: */
  char *zTop;             /* Parent directory of zPath */

  const char *zContentType;  /* The content type of the input HTTP request */
  int iErrPriority;       /* Priority of current error message */
  char *zErrMsg;          /* Text of an error message */
  int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
  Blob cgiIn;             /* Input to an xfer www method */
  int cgiOutput;          /* 0: command-line 1: CGI. 2: after CGI */
  int xferPanic;          /* Write error messages in XFER protocol */
................................................................................
#endif
    {
      @ <h1>Server Configuration Error</h1>
      @ <p>The database schema on the server is out-of-date.  Please ask
      @ the administrator to run <b>fossil rebuild</b>.</p>
    }
  }else{



    if( g.fCgiTrace ){
      fossil_trace("######## Calling %s #########\n", pCmd->zName);
      cgi_print_all(1, 1);
    }
#ifdef FOSSIL_ENABLE_TH1_HOOKS
    {
      /*
................................................................................
**
**    HOME: PATH               Shorthand for "setenv: HOME PATH"
**
**    debug: FILE              Causing debugging information to be written
**                             into FILE.
**
**    errorlog: FILE           Warnings, errors, and panics written to FILE.



**
**    redirect: REPO URL       Extract the "name" query parameter and search
**                             REPO for a check-in or ticket that matches the
**                             value of "name", then redirect to URL.  There
**                             can be multiple "redirect:" lines that are
**                             processed in order.  If the REPO is "*", then
**                             an unconditional redirect to URL is taken.
................................................................................
      **
      ** Causes messages from warnings, errors, and panics to be appended
      ** to FILENAME.
      */
      g.zErrlog = mprintf("%s", blob_str(&value));
      blob_reset(&value);
      continue;









    }
    if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
      /* HOME: VALUE
      **
      ** Set CGI parameter "HOME" to VALUE.  This is legacy.  Use
      ** setenv: instead.
      */
................................................................................
**
** If the --localauth option is given, then automatic login is performed
** for requests coming from localhost, if the "localauth" setting is not
** enabled.
**
** Options:
**   --baseurl URL    base URL (useful with reverse proxies)

**   --files GLOB     comma-separate glob patterns for static file to serve
**   --localauth      enable automatic login for local connections
**   --host NAME      specify hostname of the server
**   --https          signal a request coming in via https
**   --in FILE        Take input from FILE instead of standard input
**   --ipaddr ADDR    Assume the request comes from the given IP address

**   --nocompress     do not compress HTTP replies
**   --nodelay        omit backoffice processing if it would delay process exit
**   --nojail         drop root privilege but do not enter the chroot jail
**   --nossl          signal that no SSL connections are available
**   --notfound URL   use URL as "HTTP 404, object not found" page.
**   --out FILE       write results to FILE instead of to standard output
**   --repolist       If REPOSITORY is directory, URL "/" lists all repos
................................................................................
  skin_override();
  zNotFound = find_option("notfound", 0, 1);
  noJail = find_option("nojail",0,0)!=0;
  allowRepoList = find_option("repolist",0,0)!=0;
  g.useLocalauth = find_option("localauth", 0, 0)!=0;
  g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
  g.fNoHttpCompress = find_option("nocompress",0,0)!=0;

  zInFile = find_option("in",0,1);
  if( zInFile ){
    backoffice_disable();
    g.httpIn = fossil_fopen(zInFile, "rb");
    if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
  }else{
    g.httpIn = stdin;
................................................................................
  const char *zIpAddr;    /* IP address of remote client */

  Th_InitTraceLog();
  login_set_capabilities("sx", 0);
  g.useLocalauth = 1;
  g.httpIn = stdin;
  g.httpOut = stdout;

  find_server_repository(2, 0);
  g.cgiOutput = 1;
  g.fNoHttpCompress = 1;
  g.fullHttpReply = 1;
  zIpAddr = cgi_ssh_remote_addr(0);
  if( zIpAddr && zIpAddr[0] ){
    g.fSshClient |= CGI_SSH_CLIENT;
................................................................................
** --localauth option is present and the "localauth" setting is off and the
** connection is from localhost.  The "ui" command also enables --repolist
** by default.
**
** Options:
**   --baseurl URL       Use URL as the base (useful for reverse proxies)
**   --create            Create a new REPOSITORY if it does not already exist
**   --page PAGE         Start "ui" on PAGE.  ex: --page "timeline?y=ci"
**   --files GLOBLIST    Comma-separated list of glob patterns for static files
**   --localauth         enable automatic login for requests from localhost
**   --localhost         listen on 127.0.0.1 only (always true for "ui")
**   --https             Indicates that the input is coming through a reverse
**                       proxy that has already translated HTTPS into HTTP.
**   --max-latency N     Do not let any single HTTP request run for more than N
**                       seconds (only works on unix)
**   --nocompress        Do not compress HTTP replies
**   --nojail            Drop root privileges but do not enter the chroot jail
**   --nossl             signal that no SSL connections are available (Always
**                       set by default for the "ui" command)
**   --notfound URL      Redirect

**   -P|--port TCPPORT   listen to request on port TCPPORT
**   --th-trace          trace TH1 execution (for debugging purposes)
**   --repolist          If REPOSITORY is dir, URL "/" lists repos.
**   --scgi              Accept SCGI rather than HTTP
**   --skin LABEL        Use override skin LABEL
**   --usepidkey         Use saved encryption key from parent process.  This is
**                       only necessary when using SEE on Windows.
................................................................................
  const char *zStopperFile;    /* Name of file used to terminate server */
  zStopperFile = find_option("stopper", 0, 1);
#endif

  if( g.zErrlog==0 ){
    g.zErrlog = "-";
  }

  zFileGlob = find_option("files-urlenc",0,1);
  if( zFileGlob ){
    char *z = mprintf("%s", zFileGlob);
    dehttpize(z);
    zFileGlob = z;
  }else{
    zFileGlob = find_option("files",0,1);







>







 







>
>
>







 







>
>
>







 







>
>
>
>
>
>
>
>
>







 







>

<




>







 







>







 







>







 







|












>







 







>







171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
....
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
....
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
....
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
....
2254
2255
2256
2257
2258
2259
2260
2261
2262

2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
....
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
....
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
....
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
....
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
  int fNoSync;            /* Do not do an autosync ever.  --nosync */
  int fIPv4;              /* Use only IPv4, not IPv6. --ipv4 */
  char *zPath;            /* Name of webpage being served */
  char *zExtra;           /* Extra path information past the webpage name */
  char *zBaseURL;         /* Full text of the URL being served */
  char *zHttpsURL;        /* zBaseURL translated to https: */
  char *zTop;             /* Parent directory of zPath */
  const char *zExtRoot;   /* Document root for the /ext sub-website */
  const char *zContentType;  /* The content type of the input HTTP request */
  int iErrPriority;       /* Priority of current error message */
  char *zErrMsg;          /* Text of an error message */
  int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
  Blob cgiIn;             /* Input to an xfer www method */
  int cgiOutput;          /* 0: command-line 1: CGI. 2: after CGI */
  int xferPanic;          /* Write error messages in XFER protocol */
................................................................................
#endif
    {
      @ <h1>Server Configuration Error</h1>
      @ <p>The database schema on the server is out-of-date.  Please ask
      @ the administrator to run <b>fossil rebuild</b>.</p>
    }
  }else{
    if( (pCmd->eCmdFlags & CMDFLAG_RAWCONTENT)==0 ){
      cgi_decode_post_parameters();
    }
    if( g.fCgiTrace ){
      fossil_trace("######## Calling %s #########\n", pCmd->zName);
      cgi_print_all(1, 1);
    }
#ifdef FOSSIL_ENABLE_TH1_HOOKS
    {
      /*
................................................................................
**
**    HOME: PATH               Shorthand for "setenv: HOME PATH"
**
**    debug: FILE              Causing debugging information to be written
**                             into FILE.
**
**    errorlog: FILE           Warnings, errors, and panics written to FILE.
**
**    extroot: DIR             Directory that is the root of the sub-CGI tree
**                             on the /ext page.
**
**    redirect: REPO URL       Extract the "name" query parameter and search
**                             REPO for a check-in or ticket that matches the
**                             value of "name", then redirect to URL.  There
**                             can be multiple "redirect:" lines that are
**                             processed in order.  If the REPO is "*", then
**                             an unconditional redirect to URL is taken.
................................................................................
      **
      ** Causes messages from warnings, errors, and panics to be appended
      ** to FILENAME.
      */
      g.zErrlog = mprintf("%s", blob_str(&value));
      blob_reset(&value);
      continue;
    }
    if( blob_eq(&key, "extroot:") && blob_token(&line, &value) ){
      /* extroot: DIRECTORY
      **
      ** Enables the /ext webpage to use sub-cgi rooted at DIRECTORY
      */
      g.zExtRoot = mprintf("%s", blob_str(&value));
      blob_reset(&value);
      continue;
    }
    if( blob_eq(&key, "HOME:") && blob_token(&line, &value) ){
      /* HOME: VALUE
      **
      ** Set CGI parameter "HOME" to VALUE.  This is legacy.  Use
      ** setenv: instead.
      */
................................................................................
**
** If the --localauth option is given, then automatic login is performed
** for requests coming from localhost, if the "localauth" setting is not
** enabled.
**
** Options:
**   --baseurl URL    base URL (useful with reverse proxies)
**   --extroot DIR    document root for the /ext extension mechanism
**   --files GLOB     comma-separate glob patterns for static file to serve

**   --host NAME      specify hostname of the server
**   --https          signal a request coming in via https
**   --in FILE        Take input from FILE instead of standard input
**   --ipaddr ADDR    Assume the request comes from the given IP address
**   --localauth      enable automatic login for local connections
**   --nocompress     do not compress HTTP replies
**   --nodelay        omit backoffice processing if it would delay process exit
**   --nojail         drop root privilege but do not enter the chroot jail
**   --nossl          signal that no SSL connections are available
**   --notfound URL   use URL as "HTTP 404, object not found" page.
**   --out FILE       write results to FILE instead of to standard output
**   --repolist       If REPOSITORY is directory, URL "/" lists all repos
................................................................................
  skin_override();
  zNotFound = find_option("notfound", 0, 1);
  noJail = find_option("nojail",0,0)!=0;
  allowRepoList = find_option("repolist",0,0)!=0;
  g.useLocalauth = find_option("localauth", 0, 0)!=0;
  g.sslNotAvailable = find_option("nossl", 0, 0)!=0;
  g.fNoHttpCompress = find_option("nocompress",0,0)!=0;
  g.zExtRoot = find_option("extroot",0,1);
  zInFile = find_option("in",0,1);
  if( zInFile ){
    backoffice_disable();
    g.httpIn = fossil_fopen(zInFile, "rb");
    if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
  }else{
    g.httpIn = stdin;
................................................................................
  const char *zIpAddr;    /* IP address of remote client */

  Th_InitTraceLog();
  login_set_capabilities("sx", 0);
  g.useLocalauth = 1;
  g.httpIn = stdin;
  g.httpOut = stdout;
  g.zExtRoot = find_option("extroot",0,1);
  find_server_repository(2, 0);
  g.cgiOutput = 1;
  g.fNoHttpCompress = 1;
  g.fullHttpReply = 1;
  zIpAddr = cgi_ssh_remote_addr(0);
  if( zIpAddr && zIpAddr[0] ){
    g.fSshClient |= CGI_SSH_CLIENT;
................................................................................
** --localauth option is present and the "localauth" setting is off and the
** connection is from localhost.  The "ui" command also enables --repolist
** by default.
**
** Options:
**   --baseurl URL       Use URL as the base (useful for reverse proxies)
**   --create            Create a new REPOSITORY if it does not already exist
**   --extroot DIR       Document root for the /ext extension mechanism
**   --files GLOBLIST    Comma-separated list of glob patterns for static files
**   --localauth         enable automatic login for requests from localhost
**   --localhost         listen on 127.0.0.1 only (always true for "ui")
**   --https             Indicates that the input is coming through a reverse
**                       proxy that has already translated HTTPS into HTTP.
**   --max-latency N     Do not let any single HTTP request run for more than N
**                       seconds (only works on unix)
**   --nocompress        Do not compress HTTP replies
**   --nojail            Drop root privileges but do not enter the chroot jail
**   --nossl             signal that no SSL connections are available (Always
**                       set by default for the "ui" command)
**   --notfound URL      Redirect
**   --page PAGE         Start "ui" on PAGE.  ex: --page "timeline?y=ci"
**   -P|--port TCPPORT   listen to request on port TCPPORT
**   --th-trace          trace TH1 execution (for debugging purposes)
**   --repolist          If REPOSITORY is dir, URL "/" lists repos.
**   --scgi              Accept SCGI rather than HTTP
**   --skin LABEL        Use override skin LABEL
**   --usepidkey         Use saved encryption key from parent process.  This is
**                       only necessary when using SEE on Windows.
................................................................................
  const char *zStopperFile;    /* Name of file used to terminate server */
  zStopperFile = find_option("stopper", 0, 1);
#endif

  if( g.zErrlog==0 ){
    g.zErrlog = "-";
  }
  g.zExtRoot = find_option("extroot",0,1);
  zFileGlob = find_option("files-urlenc",0,1);
  if( zFileGlob ){
    char *z = mprintf("%s", zFileGlob);
    dehttpize(z);
    zFileGlob = z;
  }else{
    zFileGlob = find_option("files",0,1);

Changes to src/main.mk.

49
50
51
52
53
54
55

56
57
58
59
60
61
62
...
262
263
264
265
266
267
268

269
270
271
272
273
274
275
...
401
402
403
404
405
406
407

408
409
410
411
412
413
414
...
738
739
740
741
742
743
744

745
746
747
748
749
750
751
....
1140
1141
1142
1143
1144
1145
1146








1147
1148
1149
1150
1151
1152
1153
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/dispatch.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/etag.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \

  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \
  $(SRCDIR)/foci.c \
  $(SRCDIR)/forum.c \
  $(SRCDIR)/fshell.c \
  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
................................................................................
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/dispatch_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/etag_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \

  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \
  $(OBJDIR)/foci_.c \
  $(OBJDIR)/forum_.c \
  $(OBJDIR)/fshell_.c \
  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
................................................................................
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/dispatch.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/etag.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \

 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/foci.o \
 $(OBJDIR)/forum.o \
 $(OBJDIR)/fshell.o \
 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
................................................................................
	$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
	$(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
	$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
	$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
	$(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
	$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
	$(OBJDIR)/export_.c:$(OBJDIR)/export.h \

	$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
	$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
	$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
	$(OBJDIR)/forum_.c:$(OBJDIR)/forum.h \
	$(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \
	$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
	$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
................................................................................
$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/export.c >$@

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers









$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/file.c >$@

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c








>







 







>







 







>







 







>







 







>
>
>
>
>
>
>
>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
...
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
....
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/dispatch.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/etag.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/extcgi.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \
  $(SRCDIR)/foci.c \
  $(SRCDIR)/forum.c \
  $(SRCDIR)/fshell.c \
  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
................................................................................
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/dispatch_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/etag_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/extcgi_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \
  $(OBJDIR)/foci_.c \
  $(OBJDIR)/forum_.c \
  $(OBJDIR)/fshell_.c \
  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
................................................................................
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/dispatch.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/etag.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/extcgi.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/foci.o \
 $(OBJDIR)/forum.o \
 $(OBJDIR)/fshell.o \
 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
................................................................................
	$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
	$(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
	$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
	$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
	$(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
	$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
	$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
	$(OBJDIR)/extcgi_.c:$(OBJDIR)/extcgi.h \
	$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
	$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
	$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
	$(OBJDIR)/forum_.c:$(OBJDIR)/forum.h \
	$(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \
	$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
	$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
................................................................................
$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/export.c >$@

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers

$(OBJDIR)/extcgi_.c:	$(SRCDIR)/extcgi.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/extcgi.c >$@

$(OBJDIR)/extcgi.o:	$(OBJDIR)/extcgi_.c $(OBJDIR)/extcgi.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/extcgi.o -c $(OBJDIR)/extcgi_.c

$(OBJDIR)/extcgi.h:	$(OBJDIR)/headers

$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/file.c >$@

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

Changes to src/makemake.tcl.

59
60
61
62
63
64
65

66
67
68
69
70
71
72
  diff
  diffcmd
  dispatch
  doc
  encode
  etag
  event

  export
  file
  finfo
  foci
  forum
  fshell
  fusefs







>







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  diff
  diffcmd
  dispatch
  doc
  encode
  etag
  event
  extcgi
  export
  file
  finfo
  foci
  forum
  fshell
  fusefs

Changes to src/mkindex.c.

87
88
89
90
91
92
93

94
95
96
97
98
99
100
...
234
235
236
237
238
239
240


241
242
243
244
245
246
247
#define CMDFLAG_TEST        0x0004      /* Commands for testing only */
#define CMDFLAG_WEBPAGE     0x0008      /* Web pages */
#define CMDFLAG_COMMAND     0x0010      /* A command */
#define CMDFLAG_SETTING     0x0020      /* A setting */
#define CMDFLAG_VERSIONABLE 0x0040      /* A versionable setting */
#define CMDFLAG_BLOCKTEXT   0x0080      /* Multi-line text setting */
#define CMDFLAG_BOOLEAN     0x0100      /* A boolean setting */

/**************************************************************************/

/*
** Each entry looks like this:
*/
typedef struct Entry {
  int eType;        /* CMDFLAG_* values */
................................................................................
      aEntry[nUsed].eType |= CMDFLAG_1ST_TIER;
    }else if( j==8 && strncmp(&zLine[i], "2nd-tier", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_TEST);
      aEntry[nUsed].eType |= CMDFLAG_2ND_TIER;
    }else if( j==4 && strncmp(&zLine[i], "test", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_2ND_TIER);
      aEntry[nUsed].eType |= CMDFLAG_TEST;


    }else if( j==7 && strncmp(&zLine[i], "boolean", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_BLOCKTEXT);
      aEntry[nUsed].iWidth = 0;
      aEntry[nUsed].eType |= CMDFLAG_BOOLEAN;
    }else if( j==10 && strncmp(&zLine[i], "block-text", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_BOOLEAN);
      aEntry[nUsed].eType |= CMDFLAG_BLOCKTEXT;







>







 







>
>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
...
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#define CMDFLAG_TEST        0x0004      /* Commands for testing only */
#define CMDFLAG_WEBPAGE     0x0008      /* Web pages */
#define CMDFLAG_COMMAND     0x0010      /* A command */
#define CMDFLAG_SETTING     0x0020      /* A setting */
#define CMDFLAG_VERSIONABLE 0x0040      /* A versionable setting */
#define CMDFLAG_BLOCKTEXT   0x0080      /* Multi-line text setting */
#define CMDFLAG_BOOLEAN     0x0100      /* A boolean setting */
#define CMDFLAG_RAWCONTENT  0x0200      /* Do not interpret webpage content */
/**************************************************************************/

/*
** Each entry looks like this:
*/
typedef struct Entry {
  int eType;        /* CMDFLAG_* values */
................................................................................
      aEntry[nUsed].eType |= CMDFLAG_1ST_TIER;
    }else if( j==8 && strncmp(&zLine[i], "2nd-tier", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_TEST);
      aEntry[nUsed].eType |= CMDFLAG_2ND_TIER;
    }else if( j==4 && strncmp(&zLine[i], "test", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_1ST_TIER|CMDFLAG_2ND_TIER);
      aEntry[nUsed].eType |= CMDFLAG_TEST;
    }else if( j==11 && strncmp(&zLine[i], "raw-content", j)==0 ){
      aEntry[nUsed].eType |= CMDFLAG_RAWCONTENT;
    }else if( j==7 && strncmp(&zLine[i], "boolean", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_BLOCKTEXT);
      aEntry[nUsed].iWidth = 0;
      aEntry[nUsed].eType |= CMDFLAG_BOOLEAN;
    }else if( j==10 && strncmp(&zLine[i], "block-text", j)==0 ){
      aEntry[nUsed].eType &= ~(CMDFLAG_BOOLEAN);
      aEntry[nUsed].eType |= CMDFLAG_BLOCKTEXT;

Changes to src/popen.c.

119
120
121
122
123
124
125
126






127
128
129
130
131
132
133
...
187
188
189
190
191
192
193



194

195
196
197
198
199
200
201
** *ppIn is stdout from the child process.  (The caller
** reads from *ppIn in order to receive input from the child.)
** Note that *ppIn is an unbuffered file descriptor, not a FILE.
** The process ID of the child is written into *pChildPid.
**
** Return the number of errors.
*/
int popen2(const char *zCmd, int *pfdIn, FILE **ppOut, int *pChildPid){






#ifdef _WIN32
  HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr, hStderr;
  SECURITY_ATTRIBUTES saAttr;
  DWORD childPid = 0;
  int fd;

  saAttr.nLength = sizeof(saAttr);
................................................................................
    close(pout[0]);
    close(pout[1]);
    close(1);
    fd = dup(pin[1]);
    if( fd!=1 ) nErr++;
    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]);
    *pfdIn = pin[0];
    close(pout[0]);
    *ppOut = fdopen(pout[1], "w");







|
>
>
>
>
>
>







 







>
>
>
|
>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
** *ppIn is stdout from the child process.  (The caller
** reads from *ppIn in order to receive input from the child.)
** Note that *ppIn is an unbuffered file descriptor, not a FILE.
** The process ID of the child is written into *pChildPid.
**
** Return the number of errors.
*/
int popen2(
  const char *zCmd,      /* Command to run in the child process */
  int *pfdIn,            /* Read from child using this file descriptor */
  FILE **ppOut,          /* Write to child using this file descriptor */
  int *pChildPid,        /* PID of the child process */
  int bDirect            /* 0: run zCmd as a shell cmd.  1: run directly */
){
#ifdef _WIN32
  HANDLE hStdinRd, hStdinWr, hStdoutRd, hStdoutWr, hStderr;
  SECURITY_ATTRIBUTES saAttr;
  DWORD childPid = 0;
  int fd;

  saAttr.nLength = sizeof(saAttr);
................................................................................
    close(pout[0]);
    close(pout[1]);
    close(1);
    fd = dup(pin[1]);
    if( fd!=1 ) nErr++;
    close(pin[0]);
    close(pin[1]);
    if( bDirect ){
      execl(zCmd, zCmd, (char*)0);
    }else{
      execl("/bin/sh", "/bin/sh", "-c", zCmd, (char*)0);
    }
    return 1;
  }else{
    /* This is the parent process */
    close(pin[1]);
    *pfdIn = pin[0];
    close(pout[0]);
    *ppOut = fdopen(pout[1], "w");

Changes to src/xfer.c.

1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
/*
** The CGI/HTTP preprocessor always redirects requests with a content-type
** of application/x-fossil or application/x-fossil-debug to this page,
** regardless of what path was specified in the HTTP header.  This allows
** clone clients to specify a URL that omits default pathnames, such
** as "http://fossil-scm.org/" instead of "http://fossil-scm.org/index.cgi".
**
** WEBPAGE: xfer
**
** This is the transfer handler on the server side.  The transfer
** message has been uncompressed and placed in the g.cgiIn blob.
** Process this message and form an appropriate reply.
*/
void page_xfer(void){
  int isPull = 0;







|







1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
/*
** The CGI/HTTP preprocessor always redirects requests with a content-type
** of application/x-fossil or application/x-fossil-debug to this page,
** regardless of what path was specified in the HTTP header.  This allows
** clone clients to specify a URL that omits default pathnames, such
** as "http://fossil-scm.org/" instead of "http://fossil-scm.org/index.cgi".
**
** WEBPAGE: xfer  raw-content
**
** This is the transfer handler on the server side.  The transfer
** message has been uncompressed and placed in the g.cgiIn blob.
** Process this message and form an appropriate reply.
*/
void page_xfer(void){
  int isPull = 0;

Changes to win/Makefile.dmc.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
348
349
350
351
352
353
354






355
356
357
358
359
360
361
...
950
951
952
953
954
955
956
957
958
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB

SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen

SRC   = add_.c alerts_.c allrepo_.c attach_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c

OBJ   = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O


RC=$(DMDIR)\bin\rcc
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__

APPNAME = $(OBJDIR)\fossil$(E)

................................................................................
	codecheck1$E $(SRC)
	$(DMDIR)\bin\link @link

$(OBJDIR)\fossil.res:	$B\win\fossil.rc
	$(RC) $(RCFLAGS) -o$@ $**

$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
	+echo add alerts allrepo attach backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export file finfo foci forum fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
	+echo fossil >> $@
	+echo fossil >> $@
	+echo $(LIBS) >> $@
	+echo. >> $@
	+echo fossil >> $@

translate$E: $(SRCDIR)\translate.c
................................................................................
	+translate$E $** > $@

$(OBJDIR)\export$O : export_.c export.h
	$(TCC) -o$@ -c export_.c

export_.c : $(SRCDIR)\export.c
	+translate$E $** > $@







$(OBJDIR)\file$O : file_.c file.h
	$(TCC) -o$@ -c file_.c

file_.c : $(SRCDIR)\file.c
	+translate$E $** > $@

................................................................................
$(OBJDIR)\zip$O : zip_.c zip.h
	$(TCC) -o$@ -c zip_.c

zip_.c : $(SRCDIR)\zip.c
	+translate$E $** > $@

headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
	 +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.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 cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
	@copy /Y nul: headers







|

|







 







|







 







>
>
>
>
>
>







 







|

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
...
956
957
958
959
960
961
962
963
964
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32 dnsapi

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB

SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_GET_TABLE -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_USE_ALLOCA -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_INTROSPECTION_PRAGMAS -DSQLITE_ENABLE_DBPAGE_VTAB -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen

SRC   = add_.c alerts_.c allrepo_.c attach_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c glob_.c graph_.c gzip_.c hname_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c piechart_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c webmail_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c

OBJ   = $(OBJDIR)\add$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\webmail$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O


RC=$(DMDIR)\bin\rcc
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__

APPNAME = $(OBJDIR)\fossil$(E)

................................................................................
	codecheck1$E $(SRC)
	$(DMDIR)\bin\link @link

$(OBJDIR)\fossil.res:	$B\win\fossil.rc
	$(RC) $(RCFLAGS) -o$@ $**

$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
	+echo add alerts allrepo attach backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi checkin checkout clearsign clone comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file finfo foci forum fshell fusefs glob graph gzip hname http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path piechart pivot popen pqueue printf publish purge rebuild regexp repolist report rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile webmail wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
	+echo fossil >> $@
	+echo fossil >> $@
	+echo $(LIBS) >> $@
	+echo. >> $@
	+echo fossil >> $@

translate$E: $(SRCDIR)\translate.c
................................................................................
	+translate$E $** > $@

$(OBJDIR)\export$O : export_.c export.h
	$(TCC) -o$@ -c export_.c

export_.c : $(SRCDIR)\export.c
	+translate$E $** > $@

$(OBJDIR)\extcgi$O : extcgi_.c extcgi.h
	$(TCC) -o$@ -c extcgi_.c

extcgi_.c : $(SRCDIR)\extcgi.c
	+translate$E $** > $@

$(OBJDIR)\file$O : file_.c file.h
	$(TCC) -o$@ -c file_.c

file_.c : $(SRCDIR)\file.c
	+translate$E $** > $@

................................................................................
$(OBJDIR)\zip$O : zip_.c zip.h
	$(TCC) -o$@ -c zip_.c

zip_.c : $(SRCDIR)\zip.c
	+translate$E $** > $@

headers: makeheaders$E page_index.h builtin_data.h default_css.h VERSION.h
	 +makeheaders$E add_.c:add.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.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 cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h piechart_.c:piechart.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h webmail_.c:webmail.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
	@copy /Y nul: headers

Changes to win/Makefile.mingw.

471
472
473
474
475
476
477

478
479
480
481
482
483
484
...
684
685
686
687
688
689
690

691
692
693
694
695
696
697
...
823
824
825
826
827
828
829

830
831
832
833
834
835
836
....
1182
1183
1184
1185
1186
1187
1188

1189
1190
1191
1192
1193
1194
1195
....
1586
1587
1588
1589
1590
1591
1592








1593
1594
1595
1596
1597
1598
1599
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/dispatch.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/etag.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \

  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \
  $(SRCDIR)/foci.c \
  $(SRCDIR)/forum.c \
  $(SRCDIR)/fshell.c \
  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
................................................................................
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/dispatch_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/etag_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \

  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \
  $(OBJDIR)/foci_.c \
  $(OBJDIR)/forum_.c \
  $(OBJDIR)/fshell_.c \
  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
................................................................................
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/dispatch.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/etag.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \

 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/foci.o \
 $(OBJDIR)/forum.o \
 $(OBJDIR)/fshell.o \
 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
................................................................................
		$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
		$(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
		$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
		$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
		$(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
		$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
		$(OBJDIR)/export_.c:$(OBJDIR)/export.h \

		$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
		$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
		$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
		$(OBJDIR)/forum_.c:$(OBJDIR)/forum.h \
		$(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \
		$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
		$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
................................................................................
$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/export.c >$@

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers









$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/file.c >$@

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c








>







 







>







 







>







 







>







 







>
>
>
>
>
>
>
>







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
...
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
....
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
....
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/dispatch.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/etag.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/extcgi.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \
  $(SRCDIR)/foci.c \
  $(SRCDIR)/forum.c \
  $(SRCDIR)/fshell.c \
  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
................................................................................
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/dispatch_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/etag_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/extcgi_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \
  $(OBJDIR)/foci_.c \
  $(OBJDIR)/forum_.c \
  $(OBJDIR)/fshell_.c \
  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
................................................................................
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/dispatch.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/etag.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/extcgi.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/foci.o \
 $(OBJDIR)/forum.o \
 $(OBJDIR)/fshell.o \
 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
................................................................................
		$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
		$(OBJDIR)/dispatch_.c:$(OBJDIR)/dispatch.h \
		$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
		$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
		$(OBJDIR)/etag_.c:$(OBJDIR)/etag.h \
		$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
		$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
		$(OBJDIR)/extcgi_.c:$(OBJDIR)/extcgi.h \
		$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
		$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
		$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
		$(OBJDIR)/forum_.c:$(OBJDIR)/forum.h \
		$(OBJDIR)/fshell_.c:$(OBJDIR)/fshell.h \
		$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
		$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
................................................................................
$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/export.c >$@

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

$(OBJDIR)/export.h:	$(OBJDIR)/headers

$(OBJDIR)/extcgi_.c:	$(SRCDIR)/extcgi.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/extcgi.c >$@

$(OBJDIR)/extcgi.o:	$(OBJDIR)/extcgi_.c $(OBJDIR)/extcgi.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/extcgi.o -c $(OBJDIR)/extcgi_.c

$(OBJDIR)/extcgi.h:	$(OBJDIR)/headers

$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/file.c >$@

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

Changes to win/Makefile.msc.

377
378
379
380
381
382
383

384
385
386
387
388
389
390
...
589
590
591
592
593
594
595

596
597
598
599
600
601
602
...
790
791
792
793
794
795
796

797
798
799
800
801
802
803
....
1234
1235
1236
1237
1238
1239
1240






1241
1242
1243
1244
1245
1246
1247
....
1876
1877
1878
1879
1880
1881
1882

1883
1884
1885
1886
1887
1888
1889
        diffcmd_.c \
        dispatch_.c \
        doc_.c \
        encode_.c \
        etag_.c \
        event_.c \
        export_.c \

        file_.c \
        finfo_.c \
        foci_.c \
        forum_.c \
        fshell_.c \
        fusefs_.c \
        glob_.c \
................................................................................
        $(OX)\diffcmd$O \
        $(OX)\dispatch$O \
        $(OX)\doc$O \
        $(OX)\encode$O \
        $(OX)\etag$O \
        $(OX)\event$O \
        $(OX)\export$O \

        $(OX)\file$O \
        $(OX)\finfo$O \
        $(OX)\foci$O \
        $(OX)\forum$O \
        $(OX)\fshell$O \
        $(OX)\fusefs$O \
        $(OX)\glob$O \
................................................................................
	echo $(OX)\diffcmd.obj >> $@
	echo $(OX)\dispatch.obj >> $@
	echo $(OX)\doc.obj >> $@
	echo $(OX)\encode.obj >> $@
	echo $(OX)\etag.obj >> $@
	echo $(OX)\event.obj >> $@
	echo $(OX)\export.obj >> $@

	echo $(OX)\file.obj >> $@
	echo $(OX)\finfo.obj >> $@
	echo $(OX)\foci.obj >> $@
	echo $(OX)\forum.obj >> $@
	echo $(OX)\fshell.obj >> $@
	echo $(OX)\fusefs.obj >> $@
	echo $(OX)\glob.obj >> $@
................................................................................
	translate$E $** > $@

$(OX)\export$O : export_.c export.h
	$(TCC) /Fo$@ -c export_.c

export_.c : $(SRCDIR)\export.c
	translate$E $** > $@







$(OX)\file$O : file_.c file.h
	$(TCC) /Fo$@ -c file_.c

file_.c : $(SRCDIR)\file.c
	translate$E $** > $@

................................................................................
			diffcmd_.c:diffcmd.h \
			dispatch_.c:dispatch.h \
			doc_.c:doc.h \
			encode_.c:encode.h \
			etag_.c:etag.h \
			event_.c:event.h \
			export_.c:export.h \

			file_.c:file.h \
			finfo_.c:finfo.h \
			foci_.c:foci.h \
			forum_.c:forum.h \
			fshell_.c:fshell.h \
			fusefs_.c:fusefs.h \
			glob_.c:glob.h \







>







 







>







 







>







 







>
>
>
>
>
>







 







>







377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
...
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
...
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
....
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
....
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
        diffcmd_.c \
        dispatch_.c \
        doc_.c \
        encode_.c \
        etag_.c \
        event_.c \
        export_.c \
        extcgi_.c \
        file_.c \
        finfo_.c \
        foci_.c \
        forum_.c \
        fshell_.c \
        fusefs_.c \
        glob_.c \
................................................................................
        $(OX)\diffcmd$O \
        $(OX)\dispatch$O \
        $(OX)\doc$O \
        $(OX)\encode$O \
        $(OX)\etag$O \
        $(OX)\event$O \
        $(OX)\export$O \
        $(OX)\extcgi$O \
        $(OX)\file$O \
        $(OX)\finfo$O \
        $(OX)\foci$O \
        $(OX)\forum$O \
        $(OX)\fshell$O \
        $(OX)\fusefs$O \
        $(OX)\glob$O \
................................................................................
	echo $(OX)\diffcmd.obj >> $@
	echo $(OX)\dispatch.obj >> $@
	echo $(OX)\doc.obj >> $@
	echo $(OX)\encode.obj >> $@
	echo $(OX)\etag.obj >> $@
	echo $(OX)\event.obj >> $@
	echo $(OX)\export.obj >> $@
	echo $(OX)\extcgi.obj >> $@
	echo $(OX)\file.obj >> $@
	echo $(OX)\finfo.obj >> $@
	echo $(OX)\foci.obj >> $@
	echo $(OX)\forum.obj >> $@
	echo $(OX)\fshell.obj >> $@
	echo $(OX)\fusefs.obj >> $@
	echo $(OX)\glob.obj >> $@
................................................................................
	translate$E $** > $@

$(OX)\export$O : export_.c export.h
	$(TCC) /Fo$@ -c export_.c

export_.c : $(SRCDIR)\export.c
	translate$E $** > $@

$(OX)\extcgi$O : extcgi_.c extcgi.h
	$(TCC) /Fo$@ -c extcgi_.c

extcgi_.c : $(SRCDIR)\extcgi.c
	translate$E $** > $@

$(OX)\file$O : file_.c file.h
	$(TCC) /Fo$@ -c file_.c

file_.c : $(SRCDIR)\file.c
	translate$E $** > $@

................................................................................
			diffcmd_.c:diffcmd.h \
			dispatch_.c:dispatch.h \
			doc_.c:doc.h \
			encode_.c:encode.h \
			etag_.c:etag.h \
			event_.c:event.h \
			export_.c:export.h \
			extcgi_.c:extcgi.h \
			file_.c:file.h \
			finfo_.c:finfo.h \
			foci_.c:foci.h \
			forum_.c:forum.h \
			fshell_.c:fshell.h \
			fusefs_.c:fusefs.h \
			glob_.c:glob.h \