Fossil

Check-in [16e703be]
Login

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

Overview
Comment:Pull over the latest clear-title changes from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | clear-title
Files: files | file ages | folders
SHA1:16e703be111fc2cff7e3af067a3d969578769dc4
User & Date: drh 2010-02-25 14:06:43
Context
2010-03-05
00:10
Pull over from the trunk all recent changes for which we have clear title. check-in: b9d3b428 user: drh tags: clear-title
2010-02-25
14:06
Pull over the latest clear-title changes from trunk. check-in: 16e703be user: drh tags: clear-title
12:58
If a file has been deleted from the filesystem, but not deleted by fossil, then make the "update" command restore that file. Ticket [7c3ca0eae8287] check-in: 63d5a4fe user: drh tags: trunk
2010-02-08
18:16
Merge recent changes into the dual-license branch. check-in: 14c19fbc user: drh tags: clear-title
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.

1
2
3
4
5
6
7





8
9
10
11
12
13
14
..
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#!/usr/bin/make
#
#### The toplevel directory of the source tree.  Fossil can be built
#    in a directory that is separate from the source tree.  Just change
#    the following to point from the build directory to the src/ folder.
#
SRCDIR = ./src






#### C Compiler and options for use in building executables that
#    will run on the platform that is doing the build.  This is used
#    to compile code-generator programs as part of the build process.
#    See TCC below for the C compiler for building the finished binary.
#
BCC = gcc -g -O2
................................................................................
#
LIB = -lz $(LDFLAGS)
# If you're on OpenSolaris:
# LIB += lsocket
# Solaris 10 needs:
# LIB += -lsocket -lnsl
# My assumption is that the Sol10 flags will work for Sol8/9 and possibly 11.


#### Tcl shell for use in running the fossil testsuite.
#
TCLSH = tclsh

#### Include a configuration file that can override any one of these settings.
#
-include config.mak

# You should not need to change anything below this line
###############################################################################
include $(SRCDIR)/main.mk







>
>
>
>
>







 







|





<
<
<
<



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
..
41
42
43
44
45
46
47
48
49
50
51
52
53




54
55
56
#!/usr/bin/make
#
#### The toplevel directory of the source tree.  Fossil can be built
#    in a directory that is separate from the source tree.  Just change
#    the following to point from the build directory to the src/ folder.
#
SRCDIR = ./src

#### The directory into which object code files should be written.
#
#
OBJDIR = ./obj

#### C Compiler and options for use in building executables that
#    will run on the platform that is doing the build.  This is used
#    to compile code-generator programs as part of the build process.
#    See TCC below for the C compiler for building the finished binary.
#
BCC = gcc -g -O2
................................................................................
#
LIB = -lz $(LDFLAGS)
# If you're on OpenSolaris:
# LIB += lsocket
# Solaris 10 needs:
# LIB += -lsocket -lnsl
# My assumption is that the Sol10 flags will work for Sol8/9 and possibly 11.
# 

#### Tcl shell for use in running the fossil testsuite.
#
TCLSH = tclsh





# You should not need to change anything below this line
###############################################################################
include $(SRCDIR)/main.mk

Changes to Makefile.w32.

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
#!/usr/bin/make
#
#### The toplevel directory of the source tree.  Fossil can be built
#    in a directory that is separate from the source tree.  Just change
#    the following to point from the build directory to the src/ folder.
#
SRCDIR = ./src


#### C Compiler and options for use in building executables that
#    will run on the platform that is doing the build.  This is used
#    to compile code-generator programs as part of the build process.
#    See TCC below for the C compiler for building the finished binary.
#
BCC = gcc -g -O2

#### The suffix to add to executable files.  ".exe" for windows.
#    Nothing for unix.
#
E = .exe





#### C Compile and options for use in building executables that 
#    will run on the target platform.  This is usually the same
#    as BCC, unless you are cross-compiling.  This C compiler builds
#    the finished binary for fossil.  The BCC compiler above is used
#    for building intermediate code-generator tools.
#
#TCC = gcc -O6
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = gcc -g -Os -Wall
#TCC = gcc -g -Os -Wall -DFOSSIL_I18N=0 -L/usr/local/lib -I/usr/local/include
TCC = gcc -Os -Wall -DFOSSIL_I18N=0 -L/mingw/lib -I/mingw/include






#### Extra arguments for linking the finished binary.  Fossil needs
#    to link against the Z-Lib compression library.  There are no
#    other dependencies.  We sometimes add the -static option here
#    so that we can build a static executable that will run in a
#    chroot jail.
#
#LIB = -lz
#LIB = -lz -lws2_32
LIB = -lmingwex -lz -lws2_32





#### Tcl shell for use in running the fossil testsuite.
#
TCLSH = tclsh

#### Include a configuration file that can override any one of these settings.
#
-include config.w32

# You should not need to change anything below this line
###############################################################################
include $(SRCDIR)/main.mk







>












>
>
>
>












>
>
>
>
>










>
>
>
>












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
#!/usr/bin/make
#
#### The toplevel directory of the source tree.  Fossil can be built
#    in a directory that is separate from the source tree.  Just change
#    the following to point from the build directory to the src/ folder.
#
SRCDIR = ./src
OBJDIR = ./wobj

#### C Compiler and options for use in building executables that
#    will run on the platform that is doing the build.  This is used
#    to compile code-generator programs as part of the build process.
#    See TCC below for the C compiler for building the finished binary.
#
BCC = gcc -g -O2

#### The suffix to add to executable files.  ".exe" for windows.
#    Nothing for unix.
#
E = .exe

#### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
#
# FOSSIL_ENABLE_SSL=1

#### C Compile and options for use in building executables that 
#    will run on the target platform.  This is usually the same
#    as BCC, unless you are cross-compiling.  This C compiler builds
#    the finished binary for fossil.  The BCC compiler above is used
#    for building intermediate code-generator tools.
#
#TCC = gcc -O6
#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
#TCC = gcc -g -Os -Wall
#TCC = gcc -g -Os -Wall -DFOSSIL_I18N=0 -L/usr/local/lib -I/usr/local/include
TCC = gcc -Os -Wall -DFOSSIL_I18N=0 -L/mingw/lib -I/mingw/include

# With HTTPS support
ifdef FOSSIL_ENABLE_SSL
TCC += -DFOSSIL_ENABLE_SSL=1
endif

#### Extra arguments for linking the finished binary.  Fossil needs
#    to link against the Z-Lib compression library.  There are no
#    other dependencies.  We sometimes add the -static option here
#    so that we can build a static executable that will run in a
#    chroot jail.
#
#LIB = -lz
#LIB = -lz -lws2_32
LIB = -lmingwex -lz -lws2_32
# OpenSSL:
ifdef FOSSIL_ENABLE_SSL
LIB += -lcrypto -lssl
endif

#### Tcl shell for use in running the fossil testsuite.
#
TCLSH = tclsh

#### Include a configuration file that can override any one of these settings.
#
-include config.w32

# You should not need to change anything below this line
###############################################################################
include $(SRCDIR)/main.mk

Changes to src/add.c.

172
173
174
175
176
177
178















































179
180
181
182
183
184
185
...
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
    }else{
      add_one_file(zName, vid, &repo);
    }
    free(zName);
  }
  db_end_transaction(0);
}
















































/*
** COMMAND: rm
** COMMAND: del
**
** Usage: %fossil rm FILE...
**    or: %fossil del FILE...
................................................................................
  vid = db_lget_int("checkout", 0);
  if( vid==0 ){
    fossil_panic("no checkout to remove from");
  }
  db_begin_transaction();
  for(i=2; i<g.argc; i++){
    char *zName;
    char *zPath;
    Blob pathname;

    zName = mprintf("%/", g.argv[i]);
    if( file_isdir(zName) ){


      fossil_fatal("cannot remove directories -"
                   " remove individual files instead");
    }
    file_tree_name(zName, &pathname, 1);
    zPath = blob_str(&pathname);
    if( !db_exists(
             "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){
      fossil_fatal("not in the repository: %s", zName);
    }else{
      db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath);
      printf("DELETED  %s\n", zPath);
    }
    blob_reset(&pathname);

    free(zName);
  }
  db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0");
  db_end_transaction(0);
}

/*







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







 







<
<


|
>
>
|
|
<
|
|
|
|
|
|
|
|
|
|
>







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
...
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
    }else{
      add_one_file(zName, vid, &repo);
    }
    free(zName);
  }
  db_end_transaction(0);
}

/*
** Remove all contents of zDir
*/
void del_directory_content(const char *zDir){
  DIR *d;
  int origSize;
  struct dirent *pEntry;
  Blob path;

  blob_zero(&path);
  blob_append(&path, zDir, -1);
  origSize = blob_size(&path);
  d = opendir(zDir);
  if( d ){
    while( (pEntry=readdir(d))!=0 ){
      char *zPath;
      if( pEntry->d_name[0]=='.'){
        if( !includeDotFiles ) continue;
        if( pEntry->d_name[1]==0 ) continue;
        if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
      }
      blob_appendf(&path, "/%s", pEntry->d_name);
      zPath = blob_str(&path);
      if( file_isdir(zPath)==1 ){
        del_directory_content(zPath);
      }else if( file_isfile(zPath) ){
        char *zFilePath;
        Blob pathname;
        file_tree_name(zPath, &pathname, 1);
        zFilePath = blob_str(&pathname);
        if( !db_exists(
            "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zFilePath)
        ){
          printf("SKIPPED  %s\n", zPath);
        }else{
          db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath);
          printf("DELETED  %s\n", zPath);
        }
        blob_reset(&pathname);
      }
      blob_resize(&path, origSize);
    }
  }
  closedir(d);
  blob_reset(&path);
}

/*
** COMMAND: rm
** COMMAND: del
**
** Usage: %fossil rm FILE...
**    or: %fossil del FILE...
................................................................................
  vid = db_lget_int("checkout", 0);
  if( vid==0 ){
    fossil_panic("no checkout to remove from");
  }
  db_begin_transaction();
  for(i=2; i<g.argc; i++){
    char *zName;



    zName = mprintf("%/", g.argv[i]);
    if( file_isdir(zName) == 1 ){
      del_directory_content(zName);
    } else {
      char *zPath;
      Blob pathname;

      file_tree_name(zName, &pathname, 1);
      zPath = blob_str(&pathname);
      if( !db_exists(
               "SELECT 1 FROM vfile WHERE pathname=%Q AND NOT deleted", zPath) ){
        fossil_fatal("not in the repository: %s", zName);
      }else{
        db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zPath);
        printf("DELETED  %s\n", zPath);
      }
      blob_reset(&pathname);
    }
    free(zName);
  }
  db_multi_exec("DELETE FROM vfile WHERE deleted AND rid=0");
  db_end_transaction(0);
}

/*

Changes to src/checkin.c.

430
431
432
433
434
435
436






















437
438
439
440
441
442
443
...
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
...
655
656
657
658
659
660
661

662
663
664
665
666
667
668
...
688
689
690
691
692
693
694

695
696
697
698
699
700
701
702
703

704
705
706
707
708
709
710
    @                   WHERE tagid=%d AND rid=plink.pid), 'trunk')
    @       =coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.cid), 'trunk')
  ;
  rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
  return rc==0;
}























/*
** COMMAND: ci
** COMMAND: commit
**
** Usage: %fossil commit ?OPTIONS? ?FILE...?
**
................................................................................
    if( zBranch==0 ) zBranch = "private";
    if( zBgColor==0 ) zBgColor = "#fec084";  /* Orange */
  }
  zDateOvrd = find_option("date-override",0,1);
  zUserOvrd = find_option("user-override",0,1);
  db_must_be_within_tree();
  noSign = db_get_boolean("omitsign", 0)|noSign;
  if( db_get_boolean("clearsign", 1)==0 ){ noSign = 1; }
  verify_all_options();

  /* Get the ID of the parent manifest artifact */
  vid = db_lget_int("checkout", 0);
  if( content_is_private(vid) ){
    g.markPrivate = 1;
  }
................................................................................
  if( blob_size(&comment)==0 ){
    blob_append(&comment, "(no comment)", -1);
  }
  blob_appendf(&manifest, "C %F\n", blob_str(&comment));
  zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now");
  zDate[10] = 'T';
  blob_appendf(&manifest, "D %s\n", zDate);

  db_prepare(&q,
    "SELECT pathname, uuid, origname, blob.rid"
    "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
    " WHERE NOT deleted AND vfile.vid=%d"
    " ORDER BY 1", vid);
  blob_zero(&filename);
  blob_appendf(&filename, "%s", g.zLocalRoot);
................................................................................
    }
    if( !g.markPrivate ) content_make_public(frid);
  }
  blob_reset(&filename);
  db_finalize(&q);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
  blob_appendf(&manifest, "P %s", zUuid);


  db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
  db_bind_int(&q2, ":id", 0);
  while( db_step(&q2)==SQLITE_ROW ){
    int mid = db_column_int(&q2, 0);
    if( !g.markPrivate && content_is_private(mid) ) continue;
    zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
    if( zUuid ){
      blob_appendf(&manifest, " %s", zUuid);

      free(zUuid);
    }
  }
  db_reset(&q2);

  blob_appendf(&manifest, "\n");
  blob_appendf(&manifest, "R %b\n", &cksum1);







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







 







|







 







>







 







>









>







430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
...
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
...
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
...
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
    @                   WHERE tagid=%d AND rid=plink.pid), 'trunk')
    @       =coalesce((SELECT value FROM tagxref
    @                   WHERE tagid=%d AND rid=plink.cid), 'trunk')
  ;
  rc = db_int(0, zSql, rid, TAG_BRANCH, TAG_BRANCH);
  return rc==0;
}

/*
** Make sure the current check-in with timestamp zDate is younger than its
** ancestor identified rid and zUuid.  Throw a fatal error if not.
*/
static void checkin_verify_younger(
  int rid,              /* The record ID of the ancestor */
  const char *zUuid,    /* The artifact ID of the ancestor */
  const char *zDate     /* Date & time of the current check-in */
){
  int b;
  b = db_exists(
    "SELECT 1 FROM event"
    " WHERE datetime(mtime)>=%Q"
    "   AND type='ci' AND objid=%d",
    zDate, rid
  );
  if( b ){
    fossil_fatal("ancestor check-in [%.10s] (%s) is younger (clock skew?)",
                 zUuid, zDate);
  }
}

/*
** COMMAND: ci
** COMMAND: commit
**
** Usage: %fossil commit ?OPTIONS? ?FILE...?
**
................................................................................
    if( zBranch==0 ) zBranch = "private";
    if( zBgColor==0 ) zBgColor = "#fec084";  /* Orange */
  }
  zDateOvrd = find_option("date-override",0,1);
  zUserOvrd = find_option("user-override",0,1);
  db_must_be_within_tree();
  noSign = db_get_boolean("omitsign", 0)|noSign;
  if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
  verify_all_options();

  /* Get the ID of the parent manifest artifact */
  vid = db_lget_int("checkout", 0);
  if( content_is_private(vid) ){
    g.markPrivate = 1;
  }
................................................................................
  if( blob_size(&comment)==0 ){
    blob_append(&comment, "(no comment)", -1);
  }
  blob_appendf(&manifest, "C %F\n", blob_str(&comment));
  zDate = db_text(0, "SELECT datetime('%q')", zDateOvrd ? zDateOvrd : "now");
  zDate[10] = 'T';
  blob_appendf(&manifest, "D %s\n", zDate);
  zDate[10] = ' ';
  db_prepare(&q,
    "SELECT pathname, uuid, origname, blob.rid"
    "  FROM vfile JOIN blob ON vfile.mrid=blob.rid"
    " WHERE NOT deleted AND vfile.vid=%d"
    " ORDER BY 1", vid);
  blob_zero(&filename);
  blob_appendf(&filename, "%s", g.zLocalRoot);
................................................................................
    }
    if( !g.markPrivate ) content_make_public(frid);
  }
  blob_reset(&filename);
  db_finalize(&q);
  zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
  blob_appendf(&manifest, "P %s", zUuid);
  checkin_verify_younger(vid, zUuid, zDate);

  db_prepare(&q2, "SELECT merge FROM vmerge WHERE id=:id");
  db_bind_int(&q2, ":id", 0);
  while( db_step(&q2)==SQLITE_ROW ){
    int mid = db_column_int(&q2, 0);
    if( !g.markPrivate && content_is_private(mid) ) continue;
    zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", mid);
    if( zUuid ){
      blob_appendf(&manifest, " %s", zUuid);
      checkin_verify_younger(mid, zUuid, zDate);
      free(zUuid);
    }
  }
  db_reset(&q2);

  blob_appendf(&manifest, "\n");
  blob_appendf(&manifest, "R %b\n", &cksum1);

Changes to src/checkout.c.

178
179
180
181
182
183
184





185
186
187
188
189
190
191
    prior = db_lget_int("checkout",0);
  }
  if( latestFlag ){
    compute_leaves(db_lget_int("checkout",0), 1);
    zVers = db_text(0, "SELECT uuid FROM leaves, event, blob"
                       " WHERE event.objid=leaves.rid AND blob.rid=leaves.rid"
                       " ORDER BY event.mtime DESC");





    if( zVers==0 ){
      fossil_fatal("cannot locate \"latest\" checkout");
    }
  }else{
    zVers = g.argv[2];
  }
  vid = load_vfile(zVers);







>
>
>
>
>







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    prior = db_lget_int("checkout",0);
  }
  if( latestFlag ){
    compute_leaves(db_lget_int("checkout",0), 1);
    zVers = db_text(0, "SELECT uuid FROM leaves, event, blob"
                       " WHERE event.objid=leaves.rid AND blob.rid=leaves.rid"
                       " ORDER BY event.mtime DESC");
    if( zVers==0 ){
      zVers = db_text(0, "SELECT uuid FROM event, blob"
                         " WHERE event.objid=blob.rid AND event.type='ci'"
                         " ORDER BY event.mtime DESC");
    }
    if( zVers==0 ){
      fossil_fatal("cannot locate \"latest\" checkout");
    }
  }else{
    zVers = g.argv[2];
  }
  vid = load_vfile(zVers);

Changes to src/db.c.

1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
**
**
**    autosync         If enabled, automatically pull prior to commit
**                     or update and automatically push after commit or
**                     tag or branch creation.  If the the value is "pullonly"
**                     then only pull operations occur automatically.
**
**    clearsign        When enabled (the default), fossil will attempt to
**                     sign all commits with gpg.  When disabled, commits will
**                     be unsigned.
**
**    diff-command     External command to run when performing a diff.
**                     If undefined, the internal text diff will be used.
**
**    dont-push        Prevent this repository from pushing from client to
**                     server.  Useful when setting up a private branch.







|
|







1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
**
**
**    autosync         If enabled, automatically pull prior to commit
**                     or update and automatically push after commit or
**                     tag or branch creation.  If the the value is "pullonly"
**                     then only pull operations occur automatically.
**
**    clearsign        When enabled, fossil will attempt to sign all commits
**                     with gpg.  When disabled (the default), commits will
**                     be unsigned.
**
**    diff-command     External command to run when performing a diff.
**                     If undefined, the internal text diff will be used.
**
**    dont-push        Prevent this repository from pushing from client to
**                     server.  Useful when setting up a private branch.

Changes to src/encode.c.

233
234
235
236
237
238
239

240
241
242
243
244
245
246
247
*/
char *fossilize(const char *zIn, int nIn){
  int n, i, j, c;
  char *zOut;
  if( nIn<0 ) nIn = strlen(zIn);
  for(i=n=0; i<nIn; i++){
    c = zIn[i];

    if( c==0 || isspace(c) || c=='\\' ) n++;
  }
  n += nIn;
  zOut = malloc( n+1 );
  if( zOut ){
    for(i=j=0; i<nIn; i++){
      int c = zIn[i];
      if( c==0 ){







>
|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
*/
char *fossilize(const char *zIn, int nIn){
  int n, i, j, c;
  char *zOut;
  if( nIn<0 ) nIn = strlen(zIn);
  for(i=n=0; i<nIn; i++){
    c = zIn[i];
    if( c==0 || c==' ' || c=='\n' || c=='\t' || c=='\r' || c=='\f' || c=='\v'
             || c=='\\' ) n++;
  }
  n += nIn;
  zOut = malloc( n+1 );
  if( zOut ){
    for(i=j=0; i<nIn; i++){
      int c = zIn[i];
      if( c==0 ){

Changes to src/file.c.

39
40
41
42
43
44
45

46
47
48
49



50

51

52
53
54
55
56
57
58
59
** Fill in the fileStat variable for the file named zFilename.
** If zFilename==0, then use the previous value of fileStat if
** there is a previous value.
**
** Return the number of errors.  No error messages are generated.
*/
static int getStat(const char *zFilename){

  if( zFilename==0 ){
    if( fileStatValid==0 ) return 1;
  }else{
    if( stat(zFilename, &fileStat)!=0 ) return 1;



    fileStatValid = 1;

  }

  return 0;
}


/*
** Return the size of a file in bytes.  Return -1 if the file does not
** exist.  If zFilename is NULL, return the size of the most recently
** stat-ed file.







>

|

|
>
>
>
|
>
|
>
|







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
** Fill in the fileStat variable for the file named zFilename.
** If zFilename==0, then use the previous value of fileStat if
** there is a previous value.
**
** Return the number of errors.  No error messages are generated.
*/
static int getStat(const char *zFilename){
  int rc = 0;
  if( zFilename==0 ){
    if( fileStatValid==0 ) rc = 1;
  }else{
    if( stat(zFilename, &fileStat)!=0 ){
      fileStatValid = 0;
      rc = 1;
    }else{
      fileStatValid = 1;
      rc = 0;
    }
  }
  return rc;
}


/*
** Return the size of a file in bytes.  Return -1 if the file does not
** exist.  If zFilename is NULL, return the size of the most recently
** stat-ed file.

Changes to src/graph.c.

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
...
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
...
257
258
259
260
261
262
263

264
265






266
267
268
269
270
271
272
  p->pLast = pRow;
}

/*
** Return the index of a rail currently not in use for any row between
** top and bottom, inclusive.  
*/
static int findFreeRail(GraphContext *p, int top, int btm, u32 inUseMask){





  GraphRow *pRow;
  int i;


  for(pRow=p->pFirst; pRow && pRow->idx<top; pRow=pRow->pNext){}
  while( pRow && pRow->idx<=btm ){
    inUseMask |= pRow->railInUse;
    pRow = pRow->pNext;
  }
  for(i=0; i<32; i++){
    if( (inUseMask & (1<<i))==0 ) return i;







  }


  p->nErr++;
  return 0;
}

/*
** Compute the complete graph
*/
void graph_finish(GraphContext *p){
  GraphRow *pRow, *pDesc;
  Bag allRids;
  int i;
  int nRow;
  u32 mask;
  u32 inUse;

................................................................................
  }

  /* Identify rows where the primary parent is off screen.  Assign
  ** each to a rail and draw descenders to the bottom of the screen.
  */
  for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
    if( pRow->nParent==0 || !bag_find(&allRids,pRow->aParent[0]) ){



      pRow->iRail = ++p->mxRail;
      pRow->bDescender = pRow->nParent>0;

      mask = 1<<(pRow->iRail);





      for(pDesc=pRow; pDesc; pDesc=pDesc->pNext){
        pDesc->railInUse |= mask;

      }
    }
  }

  /* Assign rails to all rows that are still unassigned.
  ** The first primary child of a row goes on the same rail as
  ** that row.
  */
  inUse = 0;
  for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
    int parentRid;
    if( pRow->iRail>=0 ) continue;
    assert( pRow->nParent>0 );
    parentRid = pRow->aParent[0];
    assert( bag_find(&allRids, parentRid) );
    for(pDesc=pRow->pNext; pDesc && pDesc->rid!=parentRid; pDesc=pDesc->pNext){}
    assert( pDesc!=0 );





    if( pDesc->aiRaiser[pDesc->iRail]==0 && pDesc->zBranch==pRow->zBranch ){
      pRow->iRail = pDesc->iRail;
    }else{
      pRow->iRail = findFreeRail(p, 0, pDesc->idx, inUse);
    }
    pDesc->aiRaiser[pRow->iRail] = pRow->idx;
    mask = 1<<pRow->iRail;
    if( pRow->isLeaf ){
      inUse &= ~mask;
    }else{
      inUse |= mask;
................................................................................
  for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
    for(i=1; i<pRow->nParent; i++){
      int parentRid = pRow->aParent[i];
      for(pDesc=pRow->pNext; pDesc && pDesc->rid!=parentRid;
          pDesc=pDesc->pNext){}
      if( pDesc==0 ) continue;
      if( pDesc->mergeOut<0 ){

        pDesc->mergeOut = findFreeRail(p, pRow->idx, pDesc->idx, 0);
        pDesc->mergeUpto = pRow->idx;






      }
      pRow->mergeIn |= 1<<pDesc->mergeOut;
    }
  }

  /*
  ** Sort the rail numbers







|
>
>
>
>
>


>
>






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





|







 







>
>
>
|
<
>

>
>
>
>
>
|
|
>








|







|
>
>
>
>
>



|







 







>
|

>
>
>
>
>
>







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
...
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
...
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
  p->pLast = pRow;
}

/*
** Return the index of a rail currently not in use for any row between
** top and bottom, inclusive.  
*/
static int findFreeRail(
  GraphContext *p,         /* The graph context */
  int top, int btm,        /* Span of rows for which the rail is needed */
  u32 inUseMask,           /* Mask or rails already in use */
  int iNearto              /* Find rail nearest to this rail */
){
  GraphRow *pRow;
  int i;
  int iBest = 0;
  int iBestDist = 9999;
  for(pRow=p->pFirst; pRow && pRow->idx<top; pRow=pRow->pNext){}
  while( pRow && pRow->idx<=btm ){
    inUseMask |= pRow->railInUse;
    pRow = pRow->pNext;
  }
  for(i=0; i<32; i++){
    if( (inUseMask & (1<<i))==0 ){
      int dist;
      if( iNearto<=0 ) return i;
      dist = i - iNearto;
      if( dist<0 ) dist = -dist;
      if( dist<iBestDist ){
        iBestDist = dist;
        iBest = i;
      }
    }
  }
  if( iBestDist>1000 ) p->nErr++;
  return iBest;
}

/*
** Compute the complete graph
*/
void graph_finish(GraphContext *p, int omitDescenders){
  GraphRow *pRow, *pDesc;
  Bag allRids;
  int i;
  int nRow;
  u32 mask;
  u32 inUse;

................................................................................
  }

  /* Identify rows where the primary parent is off screen.  Assign
  ** each to a rail and draw descenders to the bottom of the screen.
  */
  for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
    if( pRow->nParent==0 || !bag_find(&allRids,pRow->aParent[0]) ){
      if( omitDescenders ){
        pRow->iRail = findFreeRail(p, pRow->idx, pRow->idx, 0, 0);
      }else{
        pRow->iRail = ++p->mxRail;

      }
      mask = 1<<(pRow->iRail);
      if( omitDescenders ){
        pRow->railInUse |= mask;
        if( pRow->pNext ) pRow->pNext->railInUse |= mask;
      }else{
        pRow->bDescender = pRow->nParent>0;
        for(pDesc=pRow; pDesc; pDesc=pDesc->pNext){
          pDesc->railInUse |= mask;
        }
      }
    }
  }

  /* Assign rails to all rows that are still unassigned.
  ** The first primary child of a row goes on the same rail as
  ** that row.
  */
  inUse = (1<<(p->mxRail+1))-1;
  for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
    int parentRid;
    if( pRow->iRail>=0 ) continue;
    assert( pRow->nParent>0 );
    parentRid = pRow->aParent[0];
    assert( bag_find(&allRids, parentRid) );
    for(pDesc=pRow->pNext; pDesc && pDesc->rid!=parentRid; pDesc=pDesc->pNext){}
    if( pDesc==0 ){
      /* Time skew */
      pRow->iRail = ++p->mxRail;
      pRow->railInUse = 1<<pRow->iRail;
      continue;
    }
    if( pDesc->aiRaiser[pDesc->iRail]==0 && pDesc->zBranch==pRow->zBranch ){
      pRow->iRail = pDesc->iRail;
    }else{
      pRow->iRail = findFreeRail(p, 0, pDesc->idx, inUse, 0);
    }
    pDesc->aiRaiser[pRow->iRail] = pRow->idx;
    mask = 1<<pRow->iRail;
    if( pRow->isLeaf ){
      inUse &= ~mask;
    }else{
      inUse |= mask;
................................................................................
  for(pRow=p->pFirst; pRow; pRow=pRow->pNext){
    for(i=1; i<pRow->nParent; i++){
      int parentRid = pRow->aParent[i];
      for(pDesc=pRow->pNext; pDesc && pDesc->rid!=parentRid;
          pDesc=pDesc->pNext){}
      if( pDesc==0 ) continue;
      if( pDesc->mergeOut<0 ){
        int iTarget = (pRow->iRail + pDesc->iRail)/2;
        pDesc->mergeOut = findFreeRail(p, pRow->idx, pDesc->idx, 0, iTarget);
        pDesc->mergeUpto = pRow->idx;
        mask = 1<<pDesc->mergeOut;
        pDesc->railInUse |= mask;
        for(pDesc=pRow->pNext; pDesc && pDesc->rid!=parentRid;
             pDesc=pDesc->pNext){
          pDesc->railInUse |= mask;
        }
      }
      pRow->mergeIn |= 1<<pDesc->mergeOut;
    }
  }

  /*
  ** Sort the rail numbers

Changes to src/http_transport.c.

47
48
49
50
51
52
53





54
55
56
57
58
59
60
..
77
78
79
80
81
82
83




84
85

86
87
88
89
90
91
92
...
110
111
112
113
114
115
116
117


118
119
120
121
122
123
124
...
135
136
137
138
139
140
141
142








143
144
145
146
147
148
149
...
202
203
204
205
206
207
208
209



210

211
212
213
214
215
216
217
...
291
292
293
294
295
296
297










  0, 0, 0, 0, 0, 0, 0
};

/*
** Return the current transport error message.
*/
const char *transport_errmsg(void){





  return socket_errmsg();
}

/*
** Retrieve send/receive counts from the transport layer.  If "resetFlag"
** is true, then reset the counts.
*/
................................................................................
**
** Return the number of errors.
*/
int transport_open(void){
  int rc = 0;
  if( transport.isOpen==0 ){
    if( g.urlIsHttps ){




      socket_set_errmsg("HTTPS: is not yet implemented");
      rc = 1;

    }else if( g.urlIsFile ){
      sqlite3_uint64 iRandId;
      sqlite3_randomness(sizeof(iRandId), &iRandId);
      transport.zOutFile = mprintf("%s-%llu-out.http", 
                                       g.zRepositoryName, iRandId);
      transport.zInFile = mprintf("%s-%llu-in.http", 
                                       g.zRepositoryName, iRandId);
................................................................................
  if( transport.isOpen ){
    free(transport.pBuf);
    transport.pBuf = 0;
    transport.nAlloc = 0;
    transport.nUsed = 0;
    transport.iCursor = 0;
    if( g.urlIsHttps ){
      /* TBD */


    }else if( g.urlIsFile ){
      if( transport.pFile ){ 
        fclose(transport.pFile);
        transport.pFile = 0;
      }
      unlink(transport.zInFile);
      unlink(transport.zOutFile);
................................................................................
** Send content over the wire.
*/
void transport_send(Blob *toSend){
  char *z = blob_buffer(toSend);
  int n = blob_size(toSend);
  transport.nSent += n;
  if( g.urlIsHttps ){
    /* TBD */








  }else if( g.urlIsFile ){
    fwrite(z, 1, n, transport.pFile);
  }else{
    int sent;
    while( n>0 ){
      sent = socket_send(0, z, n);
      /* printf("Sent %d of %d bytes\n", sent, n); fflush(stdout); */
................................................................................
    N -= toMove;
    zBuf += toMove;
    nByte += toMove;
  }
  if( N>0 ){
    int got;
    if( g.urlIsHttps ){
      /* TBD */



      got = 0;

    }else if( g.urlIsFile ){
      got = fread(zBuf, 1, N, transport.pFile);
    }else{
      got = socket_receive(0, zBuf, N);
      /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
    }
    if( got>0 ){
................................................................................
      break;
    }
    i++;
  }
  /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
  return &transport.pBuf[iStart];
}

















>
>
>
>
>







 







>
>
>
>
|

>







 







|
>
>







 







|
>
>
>
>
>
>
>
>







 







|
>
>
>

>







 







>
>
>
>
>
>
>
>
>
>
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
..
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
...
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
  0, 0, 0, 0, 0, 0, 0
};

/*
** Return the current transport error message.
*/
const char *transport_errmsg(void){
  #ifdef FOSSIL_ENABLE_SSL
  if( g.urlIsHttps ){
    return ssl_errmsg();
  }
  #endif
  return socket_errmsg();
}

/*
** Retrieve send/receive counts from the transport layer.  If "resetFlag"
** is true, then reset the counts.
*/
................................................................................
**
** Return the number of errors.
*/
int transport_open(void){
  int rc = 0;
  if( transport.isOpen==0 ){
    if( g.urlIsHttps ){
      #ifdef FOSSIL_ENABLE_SSL
      rc = ssl_open();
      if( rc==0 ) transport.isOpen = 1;
      #else
      socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
      rc = 1;
      #endif
    }else if( g.urlIsFile ){
      sqlite3_uint64 iRandId;
      sqlite3_randomness(sizeof(iRandId), &iRandId);
      transport.zOutFile = mprintf("%s-%llu-out.http", 
                                       g.zRepositoryName, iRandId);
      transport.zInFile = mprintf("%s-%llu-in.http", 
                                       g.zRepositoryName, iRandId);
................................................................................
  if( transport.isOpen ){
    free(transport.pBuf);
    transport.pBuf = 0;
    transport.nAlloc = 0;
    transport.nUsed = 0;
    transport.iCursor = 0;
    if( g.urlIsHttps ){
      #ifdef FOSSIL_ENABLE_SSL
      ssl_close();
      #endif
    }else if( g.urlIsFile ){
      if( transport.pFile ){ 
        fclose(transport.pFile);
        transport.pFile = 0;
      }
      unlink(transport.zInFile);
      unlink(transport.zOutFile);
................................................................................
** Send content over the wire.
*/
void transport_send(Blob *toSend){
  char *z = blob_buffer(toSend);
  int n = blob_size(toSend);
  transport.nSent += n;
  if( g.urlIsHttps ){
    #ifdef FOSSIL_ENABLE_SSL
    int sent;
    while( n>0 ){
      sent = ssl_send(0, z, n);
      /* printf("Sent %d of %d bytes\n", sent, n); fflush(stdout); */
      if( sent<=0 ) break;
      n -= sent;
    }    
    #endif
  }else if( g.urlIsFile ){
    fwrite(z, 1, n, transport.pFile);
  }else{
    int sent;
    while( n>0 ){
      sent = socket_send(0, z, n);
      /* printf("Sent %d of %d bytes\n", sent, n); fflush(stdout); */
................................................................................
    N -= toMove;
    zBuf += toMove;
    nByte += toMove;
  }
  if( N>0 ){
    int got;
    if( g.urlIsHttps ){
      #ifdef FOSSIL_ENABLE_SSL
      got = ssl_receive(0, zBuf, N);
      /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
      #else
      got = 0;
      #endif
    }else if( g.urlIsFile ){
      got = fread(zBuf, 1, N, transport.pFile);
    }else{
      got = socket_receive(0, zBuf, N);
      /* printf("received %d of %d bytes\n", got, N); fflush(stdout); */
    }
    if( got>0 ){
................................................................................
      break;
    }
    i++;
  }
  /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
  return &transport.pBuf[iStart];
}

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

Changes to src/info.c.

141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
         /* 012345678901234 */
    db_record_repository_filename(0);
    printf("project-name: %s\n", db_get("project-name", "<unnamed>"));
    printf("repository:   %s\n", db_lget("repository", ""));
    printf("local-root:   %s\n", g.zLocalRoot);
#ifdef __MINGW32__
    if( g.zHome ){
      printf("user-home:  : %s\n", g.zHome);
    }
#endif
    printf("project-code: %s\n", db_get("project-code", ""));
    printf("server-code:  %s\n", db_get("server-code", ""));
    vid = db_lget_int("checkout", 0);
    if( vid==0 ){
      printf("checkout:     nil\n");







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
         /* 012345678901234 */
    db_record_repository_filename(0);
    printf("project-name: %s\n", db_get("project-name", "<unnamed>"));
    printf("repository:   %s\n", db_lget("repository", ""));
    printf("local-root:   %s\n", g.zLocalRoot);
#ifdef __MINGW32__
    if( g.zHome ){
      printf("user-home:    %s\n", g.zHome);
    }
#endif
    printf("project-code: %s\n", db_get("project-code", ""));
    printf("server-code:  %s\n", db_get("server-code", ""));
    vid = db_lget_int("checkout", 0);
    if( vid==0 ){
      printf("checkout:     nil\n");

Changes to src/main.c.

704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
  if( g.zExtra ){
    /* CGI parameters get this treatment elsewhere, but places like getfile
    ** will use g.zExtra directly.
    */
    dehttpize(g.zExtra);
    cgi_set_parameter_nocopy("name", g.zExtra);
  }

  /* Prevent robots from indexing this site.
  */
  if( strcmp(g.zPath, "robots.txt")==0 ){
    cgi_set_content_type("text/plain");
    @ User-agent: *
    @ Disallow: /
    cgi_reply();
    exit(0);
  }
  
  /* Locate the method specified by the path and execute the function
  ** that implements that method.
  */
  if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) &&
      name_search("not_found", aWebpage, count(aWebpage), &idx) ){
    cgi_set_status(404,"Not Found");







<
<
<
<
<
<
<
<
<
<







704
705
706
707
708
709
710










711
712
713
714
715
716
717
  if( g.zExtra ){
    /* CGI parameters get this treatment elsewhere, but places like getfile
    ** will use g.zExtra directly.
    */
    dehttpize(g.zExtra);
    cgi_set_parameter_nocopy("name", g.zExtra);
  }










  
  /* Locate the method specified by the path and execute the function
  ** that implements that method.
  */
  if( name_search(g.zPath, aWebpage, count(aWebpage), &idx) &&
      name_search("not_found", aWebpage, count(aWebpage), &idx) ){
    cgi_set_status(404,"Not Found");

Changes to src/main.mk.

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
...
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
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
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
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
  wiki_.c \
  wikiformat_.c \
  winhttp_.c \
  xfer_.c \
  zip_.c

OBJ = \
  add.o \
  allrepo.o \
  bag.o \
  blob.o \
  branch.o \
  browse.o \
  captcha.o \
  cgi.o \
  checkin.o \
  checkout.o \
  clearsign.o \
  clone.o \
  comformat.o \
  configure.o \
  content.o \
  db.o \
  delta.o \
  deltacmd.o \
  descendants.o \
  diff.o \
  diffcmd.o \
  doc.o \
  encode.o \
  file.o \
  finfo.o \
  graph.o \
  http.o \
  http_socket.o \
  http_transport.o \
  info.o \
  login.o \
  main.o \
  manifest.o \
  md5.o \
  merge.o \
  merge3.o \
  name.o \
  pivot.o \
  pqueue.o \
  printf.o \
  rebuild.o \
  report.o \
  rss.o \
  schema.o \
  search.o \
  setup.o \
  sha1.o \
  shun.o \
  skins.o \
  stat.o \
  style.o \
  sync.o \
  tag.o \
  th_main.o \
  timeline.o \
  tkt.o \
  tktsetup.o \
  undo.o \
  update.o \
  url.o \
  user.o \
  verify.o \
  vfile.o \
  wiki.o \
  wikiformat.o \
  winhttp.o \
  xfer.o \
  zip.o

APPNAME = fossil$(E)



all:	$(APPNAME)

install:	$(APPNAME)
	mv $(APPNAME) $(INSTALLDIR)




translate:	$(SRCDIR)/translate.c
	$(BCC) -o translate $(SRCDIR)/translate.c

makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o makeheaders $(SRCDIR)/makeheaders.c

mkindex:	$(SRCDIR)/mkindex.c
................................................................................
	$(TCLSH) test/tester.tcl $(APPNAME)

VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest
	awk '{ printf "#define MANIFEST_UUID \"%s\"\n", $$1}'  $(SRCDIR)/../manifest.uuid >VERSION.h
	awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}'  $(SRCDIR)/../manifest.uuid >>VERSION.h
	awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n", substr($$2,1,10),substr($$2,12)}'  $(SRCDIR)/../manifest >>VERSION.h

$(APPNAME):	headers $(OBJ) sqlite3.o th.o th_lang.o
	$(TCC) -o $(APPNAME) $(OBJ) sqlite3.o th.o th_lang.o $(LIB)

# This rule prevents make from using its default rules to try build
# an executable named "manifest" out of the file named "manifest.c"
#
$(SRCDIR)/../manifest:	
	# noop

clean:	
	rm -f *.o *_.c $(APPNAME) VERSION.h
	rm -f translate makeheaders mkindex page_index.h headers
	rm -f add.h allrepo.h bag.h blob.h branch.h browse.h captcha.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h finfo.h graph.h http.h http_socket.h http_transport.h info.h login.h main.h manifest.h md5.h merge.h merge3.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h schema.h search.h setup.h sha1.h shun.h skins.h stat.h style.h sync.h tag.h th_main.h timeline.h tkt.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h winhttp.h xfer.h zip.h

page_index.h: $(TRANS_SRC) mkindex
	./mkindex $(TRANS_SRC) >$@
headers:	page_index.h makeheaders VERSION.h
	./makeheaders  add_.c:add.h allrepo_.c:allrepo.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h file_.c:file.h finfo_.c:finfo.h graph_.c:graph.h http_.c:http.h http_socket_.c:http_socket.h http_transport_.c:http_transport.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h VERSION.h
	touch headers
headers: Makefile
Makefile:
add_.c:	$(SRCDIR)/add.c translate
	./translate $(SRCDIR)/add.c >add_.c

add.o:	add_.c add.h  $(SRCDIR)/config.h
	$(XTCC) -o add.o -c add_.c

add.h:	headers
allrepo_.c:	$(SRCDIR)/allrepo.c translate
	./translate $(SRCDIR)/allrepo.c >allrepo_.c

allrepo.o:	allrepo_.c allrepo.h  $(SRCDIR)/config.h
	$(XTCC) -o allrepo.o -c allrepo_.c

allrepo.h:	headers
bag_.c:	$(SRCDIR)/bag.c translate
	./translate $(SRCDIR)/bag.c >bag_.c

bag.o:	bag_.c bag.h  $(SRCDIR)/config.h
	$(XTCC) -o bag.o -c bag_.c

bag.h:	headers
blob_.c:	$(SRCDIR)/blob.c translate
	./translate $(SRCDIR)/blob.c >blob_.c

blob.o:	blob_.c blob.h  $(SRCDIR)/config.h
	$(XTCC) -o blob.o -c blob_.c

blob.h:	headers
branch_.c:	$(SRCDIR)/branch.c translate
	./translate $(SRCDIR)/branch.c >branch_.c

branch.o:	branch_.c branch.h  $(SRCDIR)/config.h
	$(XTCC) -o branch.o -c branch_.c

branch.h:	headers
browse_.c:	$(SRCDIR)/browse.c translate
	./translate $(SRCDIR)/browse.c >browse_.c

browse.o:	browse_.c browse.h  $(SRCDIR)/config.h
	$(XTCC) -o browse.o -c browse_.c

browse.h:	headers
captcha_.c:	$(SRCDIR)/captcha.c translate
	./translate $(SRCDIR)/captcha.c >captcha_.c

captcha.o:	captcha_.c captcha.h  $(SRCDIR)/config.h
	$(XTCC) -o captcha.o -c captcha_.c

captcha.h:	headers
cgi_.c:	$(SRCDIR)/cgi.c translate
	./translate $(SRCDIR)/cgi.c >cgi_.c

cgi.o:	cgi_.c cgi.h  $(SRCDIR)/config.h
	$(XTCC) -o cgi.o -c cgi_.c

cgi.h:	headers
checkin_.c:	$(SRCDIR)/checkin.c translate
	./translate $(SRCDIR)/checkin.c >checkin_.c

checkin.o:	checkin_.c checkin.h  $(SRCDIR)/config.h
	$(XTCC) -o checkin.o -c checkin_.c

checkin.h:	headers
checkout_.c:	$(SRCDIR)/checkout.c translate
	./translate $(SRCDIR)/checkout.c >checkout_.c

checkout.o:	checkout_.c checkout.h  $(SRCDIR)/config.h
	$(XTCC) -o checkout.o -c checkout_.c

checkout.h:	headers
clearsign_.c:	$(SRCDIR)/clearsign.c translate
	./translate $(SRCDIR)/clearsign.c >clearsign_.c

clearsign.o:	clearsign_.c clearsign.h  $(SRCDIR)/config.h
	$(XTCC) -o clearsign.o -c clearsign_.c

clearsign.h:	headers
clone_.c:	$(SRCDIR)/clone.c translate
	./translate $(SRCDIR)/clone.c >clone_.c

clone.o:	clone_.c clone.h  $(SRCDIR)/config.h
	$(XTCC) -o clone.o -c clone_.c

clone.h:	headers
comformat_.c:	$(SRCDIR)/comformat.c translate
	./translate $(SRCDIR)/comformat.c >comformat_.c

comformat.o:	comformat_.c comformat.h  $(SRCDIR)/config.h
	$(XTCC) -o comformat.o -c comformat_.c

comformat.h:	headers
configure_.c:	$(SRCDIR)/configure.c translate
	./translate $(SRCDIR)/configure.c >configure_.c

configure.o:	configure_.c configure.h  $(SRCDIR)/config.h
	$(XTCC) -o configure.o -c configure_.c

configure.h:	headers
content_.c:	$(SRCDIR)/content.c translate
	./translate $(SRCDIR)/content.c >content_.c

content.o:	content_.c content.h  $(SRCDIR)/config.h
	$(XTCC) -o content.o -c content_.c

content.h:	headers
db_.c:	$(SRCDIR)/db.c translate
	./translate $(SRCDIR)/db.c >db_.c

db.o:	db_.c db.h  $(SRCDIR)/config.h
	$(XTCC) -o db.o -c db_.c

db.h:	headers
delta_.c:	$(SRCDIR)/delta.c translate
	./translate $(SRCDIR)/delta.c >delta_.c

delta.o:	delta_.c delta.h  $(SRCDIR)/config.h
	$(XTCC) -o delta.o -c delta_.c

delta.h:	headers
deltacmd_.c:	$(SRCDIR)/deltacmd.c translate
	./translate $(SRCDIR)/deltacmd.c >deltacmd_.c

deltacmd.o:	deltacmd_.c deltacmd.h  $(SRCDIR)/config.h
	$(XTCC) -o deltacmd.o -c deltacmd_.c

deltacmd.h:	headers
descendants_.c:	$(SRCDIR)/descendants.c translate
	./translate $(SRCDIR)/descendants.c >descendants_.c

descendants.o:	descendants_.c descendants.h  $(SRCDIR)/config.h
	$(XTCC) -o descendants.o -c descendants_.c

descendants.h:	headers
diff_.c:	$(SRCDIR)/diff.c translate
	./translate $(SRCDIR)/diff.c >diff_.c

diff.o:	diff_.c diff.h  $(SRCDIR)/config.h
	$(XTCC) -o diff.o -c diff_.c

diff.h:	headers
diffcmd_.c:	$(SRCDIR)/diffcmd.c translate
	./translate $(SRCDIR)/diffcmd.c >diffcmd_.c

diffcmd.o:	diffcmd_.c diffcmd.h  $(SRCDIR)/config.h
	$(XTCC) -o diffcmd.o -c diffcmd_.c

diffcmd.h:	headers
doc_.c:	$(SRCDIR)/doc.c translate
	./translate $(SRCDIR)/doc.c >doc_.c

doc.o:	doc_.c doc.h  $(SRCDIR)/config.h
	$(XTCC) -o doc.o -c doc_.c

doc.h:	headers
encode_.c:	$(SRCDIR)/encode.c translate
	./translate $(SRCDIR)/encode.c >encode_.c

encode.o:	encode_.c encode.h  $(SRCDIR)/config.h
	$(XTCC) -o encode.o -c encode_.c

encode.h:	headers
file_.c:	$(SRCDIR)/file.c translate
	./translate $(SRCDIR)/file.c >file_.c

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

file.h:	headers
finfo_.c:	$(SRCDIR)/finfo.c translate
	./translate $(SRCDIR)/finfo.c >finfo_.c

finfo.o:	finfo_.c finfo.h  $(SRCDIR)/config.h
	$(XTCC) -o finfo.o -c finfo_.c

finfo.h:	headers
graph_.c:	$(SRCDIR)/graph.c translate
	./translate $(SRCDIR)/graph.c >graph_.c

graph.o:	graph_.c graph.h  $(SRCDIR)/config.h
	$(XTCC) -o graph.o -c graph_.c

graph.h:	headers
http_.c:	$(SRCDIR)/http.c translate
	./translate $(SRCDIR)/http.c >http_.c

http.o:	http_.c http.h  $(SRCDIR)/config.h
	$(XTCC) -o http.o -c http_.c

http.h:	headers
http_socket_.c:	$(SRCDIR)/http_socket.c translate
	./translate $(SRCDIR)/http_socket.c >http_socket_.c

http_socket.o:	http_socket_.c http_socket.h  $(SRCDIR)/config.h
	$(XTCC) -o http_socket.o -c http_socket_.c

http_socket.h:	headers
http_transport_.c:	$(SRCDIR)/http_transport.c translate
	./translate $(SRCDIR)/http_transport.c >http_transport_.c

http_transport.o:	http_transport_.c http_transport.h  $(SRCDIR)/config.h
	$(XTCC) -o http_transport.o -c http_transport_.c

http_transport.h:	headers
info_.c:	$(SRCDIR)/info.c translate
	./translate $(SRCDIR)/info.c >info_.c

info.o:	info_.c info.h  $(SRCDIR)/config.h
	$(XTCC) -o info.o -c info_.c

info.h:	headers
login_.c:	$(SRCDIR)/login.c translate
	./translate $(SRCDIR)/login.c >login_.c

login.o:	login_.c login.h  $(SRCDIR)/config.h
	$(XTCC) -o login.o -c login_.c

login.h:	headers
main_.c:	$(SRCDIR)/main.c translate
	./translate $(SRCDIR)/main.c >main_.c

main.o:	main_.c main.h page_index.h $(SRCDIR)/config.h
	$(XTCC) -o main.o -c main_.c

main.h:	headers
manifest_.c:	$(SRCDIR)/manifest.c translate
	./translate $(SRCDIR)/manifest.c >manifest_.c

manifest.o:	manifest_.c manifest.h  $(SRCDIR)/config.h
	$(XTCC) -o manifest.o -c manifest_.c

manifest.h:	headers
md5_.c:	$(SRCDIR)/md5.c translate
	./translate $(SRCDIR)/md5.c >md5_.c

md5.o:	md5_.c md5.h  $(SRCDIR)/config.h
	$(XTCC) -o md5.o -c md5_.c

md5.h:	headers
merge_.c:	$(SRCDIR)/merge.c translate
	./translate $(SRCDIR)/merge.c >merge_.c

merge.o:	merge_.c merge.h  $(SRCDIR)/config.h
	$(XTCC) -o merge.o -c merge_.c

merge.h:	headers
merge3_.c:	$(SRCDIR)/merge3.c translate
	./translate $(SRCDIR)/merge3.c >merge3_.c

merge3.o:	merge3_.c merge3.h  $(SRCDIR)/config.h
	$(XTCC) -o merge3.o -c merge3_.c

merge3.h:	headers
name_.c:	$(SRCDIR)/name.c translate
	./translate $(SRCDIR)/name.c >name_.c

name.o:	name_.c name.h  $(SRCDIR)/config.h
	$(XTCC) -o name.o -c name_.c

name.h:	headers
pivot_.c:	$(SRCDIR)/pivot.c translate
	./translate $(SRCDIR)/pivot.c >pivot_.c

pivot.o:	pivot_.c pivot.h  $(SRCDIR)/config.h
	$(XTCC) -o pivot.o -c pivot_.c

pivot.h:	headers
pqueue_.c:	$(SRCDIR)/pqueue.c translate
	./translate $(SRCDIR)/pqueue.c >pqueue_.c

pqueue.o:	pqueue_.c pqueue.h  $(SRCDIR)/config.h
	$(XTCC) -o pqueue.o -c pqueue_.c

pqueue.h:	headers
printf_.c:	$(SRCDIR)/printf.c translate
	./translate $(SRCDIR)/printf.c >printf_.c

printf.o:	printf_.c printf.h  $(SRCDIR)/config.h
	$(XTCC) -o printf.o -c printf_.c

printf.h:	headers
rebuild_.c:	$(SRCDIR)/rebuild.c translate
	./translate $(SRCDIR)/rebuild.c >rebuild_.c

rebuild.o:	rebuild_.c rebuild.h  $(SRCDIR)/config.h
	$(XTCC) -o rebuild.o -c rebuild_.c

rebuild.h:	headers
report_.c:	$(SRCDIR)/report.c translate
	./translate $(SRCDIR)/report.c >report_.c

report.o:	report_.c report.h  $(SRCDIR)/config.h
	$(XTCC) -o report.o -c report_.c

report.h:	headers
rss_.c:	$(SRCDIR)/rss.c translate
	./translate $(SRCDIR)/rss.c >rss_.c

rss.o:	rss_.c rss.h  $(SRCDIR)/config.h
	$(XTCC) -o rss.o -c rss_.c

rss.h:	headers
schema_.c:	$(SRCDIR)/schema.c translate
	./translate $(SRCDIR)/schema.c >schema_.c

schema.o:	schema_.c schema.h  $(SRCDIR)/config.h
	$(XTCC) -o schema.o -c schema_.c

schema.h:	headers
search_.c:	$(SRCDIR)/search.c translate
	./translate $(SRCDIR)/search.c >search_.c

search.o:	search_.c search.h  $(SRCDIR)/config.h
	$(XTCC) -o search.o -c search_.c

search.h:	headers
setup_.c:	$(SRCDIR)/setup.c translate
	./translate $(SRCDIR)/setup.c >setup_.c

setup.o:	setup_.c setup.h  $(SRCDIR)/config.h
	$(XTCC) -o setup.o -c setup_.c

setup.h:	headers
sha1_.c:	$(SRCDIR)/sha1.c translate
	./translate $(SRCDIR)/sha1.c >sha1_.c

sha1.o:	sha1_.c sha1.h  $(SRCDIR)/config.h
	$(XTCC) -o sha1.o -c sha1_.c

sha1.h:	headers
shun_.c:	$(SRCDIR)/shun.c translate
	./translate $(SRCDIR)/shun.c >shun_.c

shun.o:	shun_.c shun.h  $(SRCDIR)/config.h
	$(XTCC) -o shun.o -c shun_.c

shun.h:	headers
skins_.c:	$(SRCDIR)/skins.c translate
	./translate $(SRCDIR)/skins.c >skins_.c

skins.o:	skins_.c skins.h  $(SRCDIR)/config.h
	$(XTCC) -o skins.o -c skins_.c

skins.h:	headers
stat_.c:	$(SRCDIR)/stat.c translate
	./translate $(SRCDIR)/stat.c >stat_.c

stat.o:	stat_.c stat.h  $(SRCDIR)/config.h
	$(XTCC) -o stat.o -c stat_.c

stat.h:	headers
style_.c:	$(SRCDIR)/style.c translate
	./translate $(SRCDIR)/style.c >style_.c

style.o:	style_.c style.h  $(SRCDIR)/config.h
	$(XTCC) -o style.o -c style_.c

style.h:	headers
sync_.c:	$(SRCDIR)/sync.c translate
	./translate $(SRCDIR)/sync.c >sync_.c

sync.o:	sync_.c sync.h  $(SRCDIR)/config.h
	$(XTCC) -o sync.o -c sync_.c

sync.h:	headers
tag_.c:	$(SRCDIR)/tag.c translate
	./translate $(SRCDIR)/tag.c >tag_.c

tag.o:	tag_.c tag.h  $(SRCDIR)/config.h
	$(XTCC) -o tag.o -c tag_.c

tag.h:	headers
th_main_.c:	$(SRCDIR)/th_main.c translate
	./translate $(SRCDIR)/th_main.c >th_main_.c

th_main.o:	th_main_.c th_main.h  $(SRCDIR)/config.h
	$(XTCC) -o th_main.o -c th_main_.c

th_main.h:	headers
timeline_.c:	$(SRCDIR)/timeline.c translate
	./translate $(SRCDIR)/timeline.c >timeline_.c

timeline.o:	timeline_.c timeline.h  $(SRCDIR)/config.h
	$(XTCC) -o timeline.o -c timeline_.c

timeline.h:	headers
tkt_.c:	$(SRCDIR)/tkt.c translate
	./translate $(SRCDIR)/tkt.c >tkt_.c

tkt.o:	tkt_.c tkt.h  $(SRCDIR)/config.h
	$(XTCC) -o tkt.o -c tkt_.c

tkt.h:	headers
tktsetup_.c:	$(SRCDIR)/tktsetup.c translate
	./translate $(SRCDIR)/tktsetup.c >tktsetup_.c

tktsetup.o:	tktsetup_.c tktsetup.h  $(SRCDIR)/config.h
	$(XTCC) -o tktsetup.o -c tktsetup_.c

tktsetup.h:	headers
undo_.c:	$(SRCDIR)/undo.c translate
	./translate $(SRCDIR)/undo.c >undo_.c

undo.o:	undo_.c undo.h  $(SRCDIR)/config.h
	$(XTCC) -o undo.o -c undo_.c

undo.h:	headers
update_.c:	$(SRCDIR)/update.c translate
	./translate $(SRCDIR)/update.c >update_.c

update.o:	update_.c update.h  $(SRCDIR)/config.h
	$(XTCC) -o update.o -c update_.c

update.h:	headers
url_.c:	$(SRCDIR)/url.c translate
	./translate $(SRCDIR)/url.c >url_.c

url.o:	url_.c url.h  $(SRCDIR)/config.h
	$(XTCC) -o url.o -c url_.c

url.h:	headers
user_.c:	$(SRCDIR)/user.c translate
	./translate $(SRCDIR)/user.c >user_.c

user.o:	user_.c user.h  $(SRCDIR)/config.h
	$(XTCC) -o user.o -c user_.c

user.h:	headers
verify_.c:	$(SRCDIR)/verify.c translate
	./translate $(SRCDIR)/verify.c >verify_.c

verify.o:	verify_.c verify.h  $(SRCDIR)/config.h
	$(XTCC) -o verify.o -c verify_.c

verify.h:	headers
vfile_.c:	$(SRCDIR)/vfile.c translate
	./translate $(SRCDIR)/vfile.c >vfile_.c

vfile.o:	vfile_.c vfile.h  $(SRCDIR)/config.h
	$(XTCC) -o vfile.o -c vfile_.c

vfile.h:	headers
wiki_.c:	$(SRCDIR)/wiki.c translate
	./translate $(SRCDIR)/wiki.c >wiki_.c

wiki.o:	wiki_.c wiki.h  $(SRCDIR)/config.h
	$(XTCC) -o wiki.o -c wiki_.c

wiki.h:	headers
wikiformat_.c:	$(SRCDIR)/wikiformat.c translate
	./translate $(SRCDIR)/wikiformat.c >wikiformat_.c

wikiformat.o:	wikiformat_.c wikiformat.h  $(SRCDIR)/config.h
	$(XTCC) -o wikiformat.o -c wikiformat_.c

wikiformat.h:	headers
winhttp_.c:	$(SRCDIR)/winhttp.c translate
	./translate $(SRCDIR)/winhttp.c >winhttp_.c

winhttp.o:	winhttp_.c winhttp.h  $(SRCDIR)/config.h
	$(XTCC) -o winhttp.o -c winhttp_.c

winhttp.h:	headers
xfer_.c:	$(SRCDIR)/xfer.c translate
	./translate $(SRCDIR)/xfer.c >xfer_.c

xfer.o:	xfer_.c xfer.h  $(SRCDIR)/config.h
	$(XTCC) -o xfer.o -c xfer_.c

xfer.h:	headers
zip_.c:	$(SRCDIR)/zip.c translate
	./translate $(SRCDIR)/zip.c >zip_.c

zip.o:	zip_.c zip.h  $(SRCDIR)/config.h
	$(XTCC) -o zip.o -c zip_.c

zip.h:	headers
sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -Dlocaltime=fossil_localtime -c $(SRCDIR)/sqlite3.c -o sqlite3.o

th.o:	$(SRCDIR)/th.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o th.o

th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o th_lang.o








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|





|




>
>
>







 







|
|








|













|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|





|
|


|
|

|
|

|
|

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
...
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
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
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
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
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
762
  wiki_.c \
  wikiformat_.c \
  winhttp_.c \
  xfer_.c \
  zip_.c

OBJ = \
 $(OBJDIR)/add.o \
 $(OBJDIR)/allrepo.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.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)/db.o \
 $(OBJDIR)/delta.o \
 $(OBJDIR)/deltacmd.o \
 $(OBJDIR)/descendants.o \
 $(OBJDIR)/diff.o \
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/graph.o \
 $(OBJDIR)/http.o \
 $(OBJDIR)/http_socket.o \
 $(OBJDIR)/http_transport.o \
 $(OBJDIR)/info.o \
 $(OBJDIR)/login.o \
 $(OBJDIR)/main.o \
 $(OBJDIR)/manifest.o \
 $(OBJDIR)/md5.o \
 $(OBJDIR)/merge.o \
 $(OBJDIR)/merge3.o \
 $(OBJDIR)/name.o \
 $(OBJDIR)/pivot.o \
 $(OBJDIR)/pqueue.o \
 $(OBJDIR)/printf.o \
 $(OBJDIR)/rebuild.o \
 $(OBJDIR)/report.o \
 $(OBJDIR)/rss.o \
 $(OBJDIR)/schema.o \
 $(OBJDIR)/search.o \
 $(OBJDIR)/setup.o \
 $(OBJDIR)/sha1.o \
 $(OBJDIR)/shun.o \
 $(OBJDIR)/skins.o \
 $(OBJDIR)/stat.o \
 $(OBJDIR)/style.o \
 $(OBJDIR)/sync.o \
 $(OBJDIR)/tag.o \
 $(OBJDIR)/th_main.o \
 $(OBJDIR)/timeline.o \
 $(OBJDIR)/tkt.o \
 $(OBJDIR)/tktsetup.o \
 $(OBJDIR)/undo.o \
 $(OBJDIR)/update.o \
 $(OBJDIR)/url.o \
 $(OBJDIR)/user.o \
 $(OBJDIR)/verify.o \
 $(OBJDIR)/vfile.o \
 $(OBJDIR)/wiki.o \
 $(OBJDIR)/wikiformat.o \
 $(OBJDIR)/winhttp.o \
 $(OBJDIR)/xfer.o \
 $(OBJDIR)/zip.o

APPNAME = fossil$(E)



all:	$(OBJDIR) $(APPNAME)

install:	$(APPNAME)
	mv $(APPNAME) $(INSTALLDIR)

$(OBJDIR):
	-mkdir $(OBJDIR)

translate:	$(SRCDIR)/translate.c
	$(BCC) -o translate $(SRCDIR)/translate.c

makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o makeheaders $(SRCDIR)/makeheaders.c

mkindex:	$(SRCDIR)/mkindex.c
................................................................................
	$(TCLSH) test/tester.tcl $(APPNAME)

VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest
	awk '{ printf "#define MANIFEST_UUID \"%s\"\n", $$1}'  $(SRCDIR)/../manifest.uuid >VERSION.h
	awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}'  $(SRCDIR)/../manifest.uuid >>VERSION.h
	awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n", substr($$2,1,10),substr($$2,12)}'  $(SRCDIR)/../manifest >>VERSION.h

$(APPNAME):	headers $(OBJ) $(OBJDIR)/sqlite3.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o
	$(TCC) -o $(APPNAME) $(OBJ) $(OBJDIR)/sqlite3.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(LIB)

# This rule prevents make from using its default rules to try build
# an executable named "manifest" out of the file named "manifest.c"
#
$(SRCDIR)/../manifest:	
	# noop

clean:	
	rm -f $(OBJDIR)/*.o *_.c $(APPNAME) VERSION.h
	rm -f translate makeheaders mkindex page_index.h headers
	rm -f add.h allrepo.h bag.h blob.h branch.h browse.h captcha.h cgi.h checkin.h checkout.h clearsign.h clone.h comformat.h configure.h content.h db.h delta.h deltacmd.h descendants.h diff.h diffcmd.h doc.h encode.h file.h finfo.h graph.h http.h http_socket.h http_transport.h info.h login.h main.h manifest.h md5.h merge.h merge3.h name.h pivot.h pqueue.h printf.h rebuild.h report.h rss.h schema.h search.h setup.h sha1.h shun.h skins.h stat.h style.h sync.h tag.h th_main.h timeline.h tkt.h tktsetup.h undo.h update.h url.h user.h verify.h vfile.h wiki.h wikiformat.h winhttp.h xfer.h zip.h

page_index.h: $(TRANS_SRC) mkindex
	./mkindex $(TRANS_SRC) >$@
headers:	page_index.h makeheaders VERSION.h
	./makeheaders  add_.c:add.h allrepo_.c:allrepo.h bag_.c:bag.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h file_.c:file.h finfo_.c:finfo.h graph_.c:graph.h http_.c:http.h http_socket_.c:http_socket.h http_transport_.c:http_transport.h info_.c:info.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h name_.c:name.h pivot_.c:pivot.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h update_.c:update.h url_.c:url.h user_.c:user.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h xfer_.c:xfer.h zip_.c:zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h VERSION.h
	touch headers
headers: Makefile
Makefile:
add_.c:	$(SRCDIR)/add.c translate
	./translate $(SRCDIR)/add.c >add_.c

$(OBJDIR)/add.o:	add_.c add.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/add.o -c add_.c

add.h:	headers
allrepo_.c:	$(SRCDIR)/allrepo.c translate
	./translate $(SRCDIR)/allrepo.c >allrepo_.c

$(OBJDIR)/allrepo.o:	allrepo_.c allrepo.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/allrepo.o -c allrepo_.c

allrepo.h:	headers
bag_.c:	$(SRCDIR)/bag.c translate
	./translate $(SRCDIR)/bag.c >bag_.c

$(OBJDIR)/bag.o:	bag_.c bag.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bag.o -c bag_.c

bag.h:	headers
blob_.c:	$(SRCDIR)/blob.c translate
	./translate $(SRCDIR)/blob.c >blob_.c

$(OBJDIR)/blob.o:	blob_.c blob.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/blob.o -c blob_.c

blob.h:	headers
branch_.c:	$(SRCDIR)/branch.c translate
	./translate $(SRCDIR)/branch.c >branch_.c

$(OBJDIR)/branch.o:	branch_.c branch.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/branch.o -c branch_.c

branch.h:	headers
browse_.c:	$(SRCDIR)/browse.c translate
	./translate $(SRCDIR)/browse.c >browse_.c

$(OBJDIR)/browse.o:	browse_.c browse.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/browse.o -c browse_.c

browse.h:	headers
captcha_.c:	$(SRCDIR)/captcha.c translate
	./translate $(SRCDIR)/captcha.c >captcha_.c

$(OBJDIR)/captcha.o:	captcha_.c captcha.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/captcha.o -c captcha_.c

captcha.h:	headers
cgi_.c:	$(SRCDIR)/cgi.c translate
	./translate $(SRCDIR)/cgi.c >cgi_.c

$(OBJDIR)/cgi.o:	cgi_.c cgi.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cgi.o -c cgi_.c

cgi.h:	headers
checkin_.c:	$(SRCDIR)/checkin.c translate
	./translate $(SRCDIR)/checkin.c >checkin_.c

$(OBJDIR)/checkin.o:	checkin_.c checkin.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkin.o -c checkin_.c

checkin.h:	headers
checkout_.c:	$(SRCDIR)/checkout.c translate
	./translate $(SRCDIR)/checkout.c >checkout_.c

$(OBJDIR)/checkout.o:	checkout_.c checkout.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkout.o -c checkout_.c

checkout.h:	headers
clearsign_.c:	$(SRCDIR)/clearsign.c translate
	./translate $(SRCDIR)/clearsign.c >clearsign_.c

$(OBJDIR)/clearsign.o:	clearsign_.c clearsign.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clearsign.o -c clearsign_.c

clearsign.h:	headers
clone_.c:	$(SRCDIR)/clone.c translate
	./translate $(SRCDIR)/clone.c >clone_.c

$(OBJDIR)/clone.o:	clone_.c clone.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clone.o -c clone_.c

clone.h:	headers
comformat_.c:	$(SRCDIR)/comformat.c translate
	./translate $(SRCDIR)/comformat.c >comformat_.c

$(OBJDIR)/comformat.o:	comformat_.c comformat.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/comformat.o -c comformat_.c

comformat.h:	headers
configure_.c:	$(SRCDIR)/configure.c translate
	./translate $(SRCDIR)/configure.c >configure_.c

$(OBJDIR)/configure.o:	configure_.c configure.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/configure.o -c configure_.c

configure.h:	headers
content_.c:	$(SRCDIR)/content.c translate
	./translate $(SRCDIR)/content.c >content_.c

$(OBJDIR)/content.o:	content_.c content.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/content.o -c content_.c

content.h:	headers
db_.c:	$(SRCDIR)/db.c translate
	./translate $(SRCDIR)/db.c >db_.c

$(OBJDIR)/db.o:	db_.c db.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/db.o -c db_.c

db.h:	headers
delta_.c:	$(SRCDIR)/delta.c translate
	./translate $(SRCDIR)/delta.c >delta_.c

$(OBJDIR)/delta.o:	delta_.c delta.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/delta.o -c delta_.c

delta.h:	headers
deltacmd_.c:	$(SRCDIR)/deltacmd.c translate
	./translate $(SRCDIR)/deltacmd.c >deltacmd_.c

$(OBJDIR)/deltacmd.o:	deltacmd_.c deltacmd.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/deltacmd.o -c deltacmd_.c

deltacmd.h:	headers
descendants_.c:	$(SRCDIR)/descendants.c translate
	./translate $(SRCDIR)/descendants.c >descendants_.c

$(OBJDIR)/descendants.o:	descendants_.c descendants.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/descendants.o -c descendants_.c

descendants.h:	headers
diff_.c:	$(SRCDIR)/diff.c translate
	./translate $(SRCDIR)/diff.c >diff_.c

$(OBJDIR)/diff.o:	diff_.c diff.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diff.o -c diff_.c

diff.h:	headers
diffcmd_.c:	$(SRCDIR)/diffcmd.c translate
	./translate $(SRCDIR)/diffcmd.c >diffcmd_.c

$(OBJDIR)/diffcmd.o:	diffcmd_.c diffcmd.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diffcmd.o -c diffcmd_.c

diffcmd.h:	headers
doc_.c:	$(SRCDIR)/doc.c translate
	./translate $(SRCDIR)/doc.c >doc_.c

$(OBJDIR)/doc.o:	doc_.c doc.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/doc.o -c doc_.c

doc.h:	headers
encode_.c:	$(SRCDIR)/encode.c translate
	./translate $(SRCDIR)/encode.c >encode_.c

$(OBJDIR)/encode.o:	encode_.c encode.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/encode.o -c encode_.c

encode.h:	headers
file_.c:	$(SRCDIR)/file.c translate
	./translate $(SRCDIR)/file.c >file_.c

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

file.h:	headers
finfo_.c:	$(SRCDIR)/finfo.c translate
	./translate $(SRCDIR)/finfo.c >finfo_.c

$(OBJDIR)/finfo.o:	finfo_.c finfo.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c finfo_.c

finfo.h:	headers
graph_.c:	$(SRCDIR)/graph.c translate
	./translate $(SRCDIR)/graph.c >graph_.c

$(OBJDIR)/graph.o:	graph_.c graph.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/graph.o -c graph_.c

graph.h:	headers
http_.c:	$(SRCDIR)/http.c translate
	./translate $(SRCDIR)/http.c >http_.c

$(OBJDIR)/http.o:	http_.c http.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http.o -c http_.c

http.h:	headers
http_socket_.c:	$(SRCDIR)/http_socket.c translate
	./translate $(SRCDIR)/http_socket.c >http_socket_.c

$(OBJDIR)/http_socket.o:	http_socket_.c http_socket.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_socket.o -c http_socket_.c

http_socket.h:	headers
http_transport_.c:	$(SRCDIR)/http_transport.c translate
	./translate $(SRCDIR)/http_transport.c >http_transport_.c

$(OBJDIR)/http_transport.o:	http_transport_.c http_transport.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_transport.o -c http_transport_.c

http_transport.h:	headers
info_.c:	$(SRCDIR)/info.c translate
	./translate $(SRCDIR)/info.c >info_.c

$(OBJDIR)/info.o:	info_.c info.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/info.o -c info_.c

info.h:	headers
login_.c:	$(SRCDIR)/login.c translate
	./translate $(SRCDIR)/login.c >login_.c

$(OBJDIR)/login.o:	login_.c login.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/login.o -c login_.c

login.h:	headers
main_.c:	$(SRCDIR)/main.c translate
	./translate $(SRCDIR)/main.c >main_.c

$(OBJDIR)/main.o:	main_.c main.h page_index.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/main.o -c main_.c

main.h:	headers
manifest_.c:	$(SRCDIR)/manifest.c translate
	./translate $(SRCDIR)/manifest.c >manifest_.c

$(OBJDIR)/manifest.o:	manifest_.c manifest.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/manifest.o -c manifest_.c

manifest.h:	headers
md5_.c:	$(SRCDIR)/md5.c translate
	./translate $(SRCDIR)/md5.c >md5_.c

$(OBJDIR)/md5.o:	md5_.c md5.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/md5.o -c md5_.c

md5.h:	headers
merge_.c:	$(SRCDIR)/merge.c translate
	./translate $(SRCDIR)/merge.c >merge_.c

$(OBJDIR)/merge.o:	merge_.c merge.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge.o -c merge_.c

merge.h:	headers
merge3_.c:	$(SRCDIR)/merge3.c translate
	./translate $(SRCDIR)/merge3.c >merge3_.c

$(OBJDIR)/merge3.o:	merge3_.c merge3.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge3.o -c merge3_.c

merge3.h:	headers
name_.c:	$(SRCDIR)/name.c translate
	./translate $(SRCDIR)/name.c >name_.c

$(OBJDIR)/name.o:	name_.c name.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/name.o -c name_.c

name.h:	headers
pivot_.c:	$(SRCDIR)/pivot.c translate
	./translate $(SRCDIR)/pivot.c >pivot_.c

$(OBJDIR)/pivot.o:	pivot_.c pivot.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pivot.o -c pivot_.c

pivot.h:	headers
pqueue_.c:	$(SRCDIR)/pqueue.c translate
	./translate $(SRCDIR)/pqueue.c >pqueue_.c

$(OBJDIR)/pqueue.o:	pqueue_.c pqueue.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pqueue.o -c pqueue_.c

pqueue.h:	headers
printf_.c:	$(SRCDIR)/printf.c translate
	./translate $(SRCDIR)/printf.c >printf_.c

$(OBJDIR)/printf.o:	printf_.c printf.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c printf_.c

printf.h:	headers
rebuild_.c:	$(SRCDIR)/rebuild.c translate
	./translate $(SRCDIR)/rebuild.c >rebuild_.c

$(OBJDIR)/rebuild.o:	rebuild_.c rebuild.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c rebuild_.c

rebuild.h:	headers
report_.c:	$(SRCDIR)/report.c translate
	./translate $(SRCDIR)/report.c >report_.c

$(OBJDIR)/report.o:	report_.c report.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/report.o -c report_.c

report.h:	headers
rss_.c:	$(SRCDIR)/rss.c translate
	./translate $(SRCDIR)/rss.c >rss_.c

$(OBJDIR)/rss.o:	rss_.c rss.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rss.o -c rss_.c

rss.h:	headers
schema_.c:	$(SRCDIR)/schema.c translate
	./translate $(SRCDIR)/schema.c >schema_.c

$(OBJDIR)/schema.o:	schema_.c schema.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/schema.o -c schema_.c

schema.h:	headers
search_.c:	$(SRCDIR)/search.c translate
	./translate $(SRCDIR)/search.c >search_.c

$(OBJDIR)/search.o:	search_.c search.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/search.o -c search_.c

search.h:	headers
setup_.c:	$(SRCDIR)/setup.c translate
	./translate $(SRCDIR)/setup.c >setup_.c

$(OBJDIR)/setup.o:	setup_.c setup.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/setup.o -c setup_.c

setup.h:	headers
sha1_.c:	$(SRCDIR)/sha1.c translate
	./translate $(SRCDIR)/sha1.c >sha1_.c

$(OBJDIR)/sha1.o:	sha1_.c sha1.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sha1.o -c sha1_.c

sha1.h:	headers
shun_.c:	$(SRCDIR)/shun.c translate
	./translate $(SRCDIR)/shun.c >shun_.c

$(OBJDIR)/shun.o:	shun_.c shun.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c shun_.c

shun.h:	headers
skins_.c:	$(SRCDIR)/skins.c translate
	./translate $(SRCDIR)/skins.c >skins_.c

$(OBJDIR)/skins.o:	skins_.c skins.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c skins_.c

skins.h:	headers
stat_.c:	$(SRCDIR)/stat.c translate
	./translate $(SRCDIR)/stat.c >stat_.c

$(OBJDIR)/stat.o:	stat_.c stat.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stat.o -c stat_.c

stat.h:	headers
style_.c:	$(SRCDIR)/style.c translate
	./translate $(SRCDIR)/style.c >style_.c

$(OBJDIR)/style.o:	style_.c style.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/style.o -c style_.c

style.h:	headers
sync_.c:	$(SRCDIR)/sync.c translate
	./translate $(SRCDIR)/sync.c >sync_.c

$(OBJDIR)/sync.o:	sync_.c sync.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sync.o -c sync_.c

sync.h:	headers
tag_.c:	$(SRCDIR)/tag.c translate
	./translate $(SRCDIR)/tag.c >tag_.c

$(OBJDIR)/tag.o:	tag_.c tag.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tag.o -c tag_.c

tag.h:	headers
th_main_.c:	$(SRCDIR)/th_main.c translate
	./translate $(SRCDIR)/th_main.c >th_main_.c

$(OBJDIR)/th_main.o:	th_main_.c th_main.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/th_main.o -c th_main_.c

th_main.h:	headers
timeline_.c:	$(SRCDIR)/timeline.c translate
	./translate $(SRCDIR)/timeline.c >timeline_.c

$(OBJDIR)/timeline.o:	timeline_.c timeline.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/timeline.o -c timeline_.c

timeline.h:	headers
tkt_.c:	$(SRCDIR)/tkt.c translate
	./translate $(SRCDIR)/tkt.c >tkt_.c

$(OBJDIR)/tkt.o:	tkt_.c tkt.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tkt.o -c tkt_.c

tkt.h:	headers
tktsetup_.c:	$(SRCDIR)/tktsetup.c translate
	./translate $(SRCDIR)/tktsetup.c >tktsetup_.c

$(OBJDIR)/tktsetup.o:	tktsetup_.c tktsetup.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tktsetup.o -c tktsetup_.c

tktsetup.h:	headers
undo_.c:	$(SRCDIR)/undo.c translate
	./translate $(SRCDIR)/undo.c >undo_.c

$(OBJDIR)/undo.o:	undo_.c undo.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/undo.o -c undo_.c

undo.h:	headers
update_.c:	$(SRCDIR)/update.c translate
	./translate $(SRCDIR)/update.c >update_.c

$(OBJDIR)/update.o:	update_.c update.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/update.o -c update_.c

update.h:	headers
url_.c:	$(SRCDIR)/url.c translate
	./translate $(SRCDIR)/url.c >url_.c

$(OBJDIR)/url.o:	url_.c url.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/url.o -c url_.c

url.h:	headers
user_.c:	$(SRCDIR)/user.c translate
	./translate $(SRCDIR)/user.c >user_.c

$(OBJDIR)/user.o:	user_.c user.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/user.o -c user_.c

user.h:	headers
verify_.c:	$(SRCDIR)/verify.c translate
	./translate $(SRCDIR)/verify.c >verify_.c

$(OBJDIR)/verify.o:	verify_.c verify.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/verify.o -c verify_.c

verify.h:	headers
vfile_.c:	$(SRCDIR)/vfile.c translate
	./translate $(SRCDIR)/vfile.c >vfile_.c

$(OBJDIR)/vfile.o:	vfile_.c vfile.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/vfile.o -c vfile_.c

vfile.h:	headers
wiki_.c:	$(SRCDIR)/wiki.c translate
	./translate $(SRCDIR)/wiki.c >wiki_.c

$(OBJDIR)/wiki.o:	wiki_.c wiki.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wiki.o -c wiki_.c

wiki.h:	headers
wikiformat_.c:	$(SRCDIR)/wikiformat.c translate
	./translate $(SRCDIR)/wikiformat.c >wikiformat_.c

$(OBJDIR)/wikiformat.o:	wikiformat_.c wikiformat.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wikiformat.o -c wikiformat_.c

wikiformat.h:	headers
winhttp_.c:	$(SRCDIR)/winhttp.c translate
	./translate $(SRCDIR)/winhttp.c >winhttp_.c

$(OBJDIR)/winhttp.o:	winhttp_.c winhttp.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winhttp.o -c winhttp_.c

winhttp.h:	headers
xfer_.c:	$(SRCDIR)/xfer.c translate
	./translate $(SRCDIR)/xfer.c >xfer_.c

$(OBJDIR)/xfer.o:	xfer_.c xfer.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfer.o -c xfer_.c

xfer.h:	headers
zip_.c:	$(SRCDIR)/zip.c translate
	./translate $(SRCDIR)/zip.c >zip_.c

$(OBJDIR)/zip.o:	zip_.c zip.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/zip.o -c zip_.c

zip.h:	headers
$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -Dlocaltime=fossil_localtime -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o

Changes to src/makemake.tcl.

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
...
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
...
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
puts -nonewline "TRANS_SRC ="
foreach s [lsort $src] {
  puts -nonewline " \\\n  ${s}_.c"
}
puts "\n"
puts -nonewline "OBJ ="
foreach s [lsort $src] {
  puts -nonewline " \\\n  $s.o"
}
puts "\n"
puts "APPNAME = $name\$(E)"
puts "\n"

puts {
all:	$(APPNAME)

install:	$(APPNAME)
	mv $(APPNAME) $(INSTALLDIR)




translate:	$(SRCDIR)/translate.c
	$(BCC) -o translate $(SRCDIR)/translate.c

makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o makeheaders $(SRCDIR)/makeheaders.c

mkindex:	$(SRCDIR)/mkindex.c
................................................................................
		$(SRCDIR)/../manifest.uuid >VERSION.h
	awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}' \
		$(SRCDIR)/../manifest.uuid >>VERSION.h
	awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n",\
		substr($$2,1,10),substr($$2,12)}' \
		$(SRCDIR)/../manifest >>VERSION.h

$(APPNAME):	headers $(OBJ) sqlite3.o th.o th_lang.o
	$(TCC) -o $(APPNAME) $(OBJ) sqlite3.o th.o th_lang.o $(LIB)

# This rule prevents make from using its default rules to try build
# an executable named "manifest" out of the file named "manifest.c"
#
$(SRCDIR)/../manifest:	
	# noop

clean:	
	rm -f *.o *_.c $(APPNAME) VERSION.h
	rm -f translate makeheaders mkindex page_index.h headers}

set hfiles {}
foreach s [lsort $src] {lappend hfiles $s.h}
puts "\trm -f $hfiles\n"

set mhargs {}
................................................................................
puts "headers: Makefile"
puts "Makefile:"
set extra_h(main) page_index.h

foreach s [lsort $src] {
  puts "${s}_.c:\t\$(SRCDIR)/$s.c translate"
  puts "\t./translate \$(SRCDIR)/$s.c >${s}_.c\n"
  puts "$s.o:\t${s}_.c $s.h $extra_h($s) \$(SRCDIR)/config.h"
  puts "\t\$(XTCC) -o $s.o -c ${s}_.c\n"
  puts "$s.h:\theaders"
#  puts "\t./makeheaders $mhargs\n\ttouch headers\n"
#  puts "\t./makeheaders ${s}_.c:${s}.h\n"
}


puts "sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
set opt {-DSQLITE_OMIT_LOAD_EXTENSION=1}
append opt " -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4"
#append opt " -DSQLITE_ENABLE_FTS3=1"
append opt " -Dlocaltime=fossil_localtime"
puts "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o sqlite3.o\n"

puts "th.o:\t\$(SRCDIR)/th.c"
puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th.c -o th.o\n"

puts "th_lang.o:\t\$(SRCDIR)/th_lang.c"
puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o th_lang.o\n"







|






|




>
>
>







 







|
|








|







 







|
|






|




|

|
|

|
|
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
...
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
...
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
puts -nonewline "TRANS_SRC ="
foreach s [lsort $src] {
  puts -nonewline " \\\n  ${s}_.c"
}
puts "\n"
puts -nonewline "OBJ ="
foreach s [lsort $src] {
  puts -nonewline " \\\n \$(OBJDIR)/$s.o"
}
puts "\n"
puts "APPNAME = $name\$(E)"
puts "\n"

puts {
all:	$(OBJDIR) $(APPNAME)

install:	$(APPNAME)
	mv $(APPNAME) $(INSTALLDIR)

$(OBJDIR):
	-mkdir $(OBJDIR)

translate:	$(SRCDIR)/translate.c
	$(BCC) -o translate $(SRCDIR)/translate.c

makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o makeheaders $(SRCDIR)/makeheaders.c

mkindex:	$(SRCDIR)/mkindex.c
................................................................................
		$(SRCDIR)/../manifest.uuid >VERSION.h
	awk '{ printf "#define MANIFEST_VERSION \"[%.10s]\"\n", $$1}' \
		$(SRCDIR)/../manifest.uuid >>VERSION.h
	awk '$$1=="D"{printf "#define MANIFEST_DATE \"%s %s\"\n",\
		substr($$2,1,10),substr($$2,12)}' \
		$(SRCDIR)/../manifest >>VERSION.h

$(APPNAME):	headers $(OBJ) $(OBJDIR)/sqlite3.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o
	$(TCC) -o $(APPNAME) $(OBJ) $(OBJDIR)/sqlite3.o $(OBJDIR)/th.o $(OBJDIR)/th_lang.o $(LIB)

# This rule prevents make from using its default rules to try build
# an executable named "manifest" out of the file named "manifest.c"
#
$(SRCDIR)/../manifest:	
	# noop

clean:	
	rm -f $(OBJDIR)/*.o *_.c $(APPNAME) VERSION.h
	rm -f translate makeheaders mkindex page_index.h headers}

set hfiles {}
foreach s [lsort $src] {lappend hfiles $s.h}
puts "\trm -f $hfiles\n"

set mhargs {}
................................................................................
puts "headers: Makefile"
puts "Makefile:"
set extra_h(main) page_index.h

foreach s [lsort $src] {
  puts "${s}_.c:\t\$(SRCDIR)/$s.c translate"
  puts "\t./translate \$(SRCDIR)/$s.c >${s}_.c\n"
  puts "\$(OBJDIR)/$s.o:\t${s}_.c $s.h $extra_h($s) \$(SRCDIR)/config.h"
  puts "\t\$(XTCC) -o \$(OBJDIR)/$s.o -c ${s}_.c\n"
  puts "$s.h:\theaders"
#  puts "\t./makeheaders $mhargs\n\ttouch headers\n"
#  puts "\t./makeheaders ${s}_.c:${s}.h\n"
}


puts "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
set opt {-DSQLITE_OMIT_LOAD_EXTENSION=1}
append opt " -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4"
#append opt " -DSQLITE_ENABLE_FTS3=1"
append opt " -Dlocaltime=fossil_localtime"
puts "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"

puts "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"

puts "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
puts "\t\$(XTCC) -I\$(SRCDIR) -c \$(SRCDIR)/th_lang.c -o \$(OBJDIR)/th_lang.o\n"

Changes to src/rss.c.

33
34
35
36
37
38
39

40
41
42
43
44
45
46
..
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
...
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
*/
void page_timeline_rss(void){
  Stmt q;
  int nLine=0;
  char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
  Blob bSQL;
  const char *zType = PD("y","all"); /* Type of events.  All if NULL */

  const char zSQL1[] =
    @ SELECT
    @   blob.rid,
    @   uuid,
    @   event.mtime,
    @   coalesce(ecomment,comment),
    @   coalesce(euser,user),
................................................................................
  login_check_credentials();
  if( !g.okRead && !g.okRdTkt && !g.okRdWiki ){ 
    return;
  }

  blob_zero(&bSQL);
  blob_append( &bSQL, zSQL1, -1 );
  
  if( zType[0]!='a' ){
    if( zType[0]=='c' && !g.okRead ) zType = "x";
    if( zType[0]=='w' && !g.okRdWiki ) zType = "x";
    if( zType[0]=='t' && !g.okRdTkt ) zType = "x";
    blob_appendf(&bSQL, " AND event.type=%Q", zType);
  }else{
    if( !g.okRead ){
................................................................................
  @     <title>%h(zProjectName)</title>
  @     <link>%s(g.zBaseURL)</link>
  @     <description>%h(zProjectDescr)</description>
  @     <pubDate>%s(zPubDate)</pubDate>
  @     <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
  db_prepare(&q, blob_str(&bSQL));
  blob_reset( &bSQL );
  while( db_step(&q)==SQLITE_ROW && nLine<=20 ){
    const char *zId = db_column_text(&q, 1);
    const char *zCom = db_column_text(&q, 3);
    const char *zAuthor = db_column_text(&q, 4);
    char *zPrefix = "";
    char *zDate;
    int nChild = db_column_int(&q, 5);
    int nParent = db_column_int(&q, 6);







>







 







|







 







|







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
..
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
*/
void page_timeline_rss(void){
  Stmt q;
  int nLine=0;
  char *zPubDate, *zProjectName, *zProjectDescr, *zFreeProjectName=0;
  Blob bSQL;
  const char *zType = PD("y","all"); /* Type of events.  All if NULL */
  int nLimit = atoi(PD("n","20"));
  const char zSQL1[] =
    @ SELECT
    @   blob.rid,
    @   uuid,
    @   event.mtime,
    @   coalesce(ecomment,comment),
    @   coalesce(euser,user),
................................................................................
  login_check_credentials();
  if( !g.okRead && !g.okRdTkt && !g.okRdWiki ){ 
    return;
  }

  blob_zero(&bSQL);
  blob_append( &bSQL, zSQL1, -1 );

  if( zType[0]!='a' ){
    if( zType[0]=='c' && !g.okRead ) zType = "x";
    if( zType[0]=='w' && !g.okRdWiki ) zType = "x";
    if( zType[0]=='t' && !g.okRdTkt ) zType = "x";
    blob_appendf(&bSQL, " AND event.type=%Q", zType);
  }else{
    if( !g.okRead ){
................................................................................
  @     <title>%h(zProjectName)</title>
  @     <link>%s(g.zBaseURL)</link>
  @     <description>%h(zProjectDescr)</description>
  @     <pubDate>%s(zPubDate)</pubDate>
  @     <generator>Fossil version %s(MANIFEST_VERSION) %s(MANIFEST_DATE)</generator>
  db_prepare(&q, blob_str(&bSQL));
  blob_reset( &bSQL );
  while( db_step(&q)==SQLITE_ROW && nLine<=nLimit ){
    const char *zId = db_column_text(&q, 1);
    const char *zCom = db_column_text(&q, 3);
    const char *zAuthor = db_column_text(&q, 4);
    char *zPrefix = "";
    char *zDate;
    int nChild = db_column_int(&q, 5);
    int nParent = db_column_int(&q, 6);

Changes to src/style.c.

86
87
88
89
90
91
92



93
94
95
96
97
98
99
  login_check_credentials();

  va_start(ap, zTitleFormat);
  zTitle = vmprintf(zTitleFormat, ap);
  va_end(ap);
  
  cgi_destination(CGI_HEADER);



  
  if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);

  /* Generate the header up through the main menu */
  Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
  Th_Store("title", zTitle);
  Th_Store("baseurl", g.zBaseURL);







>
>
>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
  login_check_credentials();

  va_start(ap, zTitleFormat);
  zTitle = vmprintf(zTitleFormat, ap);
  va_end(ap);
  
  cgi_destination(CGI_HEADER);
  cgi_printf("%s",
     "<!DOCTYPE html PUBLIC \"-//W3C/DTD XHTML 1.0 Strict//EN\""
     " \"http://www.x3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
  
  if( g.thTrace ) Th_Trace("BEGIN_HEADER<br />\n", -1);

  /* Generate the header up through the main menu */
  Th_Store("project_name", db_get("project-name","Unnamed Fossil Project"));
  Th_Store("title", zTitle);
  Th_Store("baseurl", g.zBaseURL);

Changes to src/timeline.c.

152
153
154
155
156
157
158

159
160
161
162
163
164
165
...
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
...
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
...
494
495
496
497
498
499
500
501
502
503
504
505
506

507
508
509
510
511



















512
513
514
515
516
517
518
...
634
635
636
637
638
639
640

641
642
643
644
645
646
647
...
675
676
677
678
679
680
681



682
683
684
685
686
687
688
...
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
** Allowed flags for the tmFlags argument to www_print_timeline
*/
#if INTERFACE
#define TIMELINE_ARTID    0x0001  /* Show artifact IDs on non-check-in lines */
#define TIMELINE_LEAFONLY 0x0002  /* Show "Leaf", but not "Merge", "Fork" etc */
#define TIMELINE_BRIEF    0x0004  /* Combine adjacent elements of same object */
#define TIMELINE_GRAPH    0x0008  /* Compute a graph */

#endif

/*
** Output a timeline in the web format given a query.  The query
** should return these columns:
**
**    0.  rid
................................................................................
      @   <div class="divider"><nobr>%s(zPrevDate)</nobr></div>
      @ </td></tr>
    }
    memcpy(zTime, &zDate[11], 5);
    zTime[5] = 0;
    @ <tr>
    @ <td valign="top" align="right">%s(zTime)</td>
    @ <td width="20" align="center" valign="top">
    @ <div id="m%d(rid)"></div>
    if( zBgClr && zBgClr[0] ){
      @ <td valign="top" align="left" bgcolor="%h(zBgClr)">
    }else{
      @ <td valign="top" align="left">
    }
    if( zType[0]=='c' ){
................................................................................
  if( suppressCnt ){
    @ <tr><td><td><td>
    @ <small><i>... %d(suppressCnt) similar
    @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr>
    suppressCnt = 0;
  }
  if( pGraph ){
    graph_finish(pGraph);
    if( pGraph->nErr ){
      graph_free(pGraph);
      pGraph = 0;
    }else{
      @ <tr><td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
    }
  }
................................................................................
      }
      if( cSep=='[' ) cgi_printf("[");
      cgi_printf("]}%s", pRow->pNext ? ",\n" : "];\n");
    }
    cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
    graph_free(pGraph);
    @ var canvasDiv = document.getElementById("canvas");

    @ function drawBox(color,x0,y0,x1,y1){
    @   var n = document.createElement("div");
    @   if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
    @   if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
    @   var w = x1-x0+1;
    @   var h = y1-y0+1;
    @   n.setAttribute("style",
    @     "position:absolute;"+
    @     "left:"+x0+"px;"+
    @     "top:"+y0+"px;"+
    @     "width:"+w+"px;"+
    @     "height:"+h+"px;"+
    @     "background-color:"+color+";"
    @   );
    @   canvasDiv.appendChild(n);
    @ }
    @ function absoluteY(id){
    @   var obj = document.getElementById(id);
    @   if( !obj ) return;
    @   var top = 0;
    @   if( obj.offsetParent ){
    @     do{
................................................................................
    @     }else{
    @       drawThinArrow(y0,mx,p.x-5);
    @     }
    @   }
    @ }
    @ function renderGraph(){
    @   var canvasDiv = document.getElementById("canvas");
    @   for(var i=canvasDiv.childNodes.length-1; i>=0; i--){
    @     var c = canvasDiv.childNodes[i];
    @     delete canvasDiv.removeChild(c);
    @   }
    @   var canvasY = absoluteY("canvas");
    @   var left = absoluteX(rowinfo[0].id) - absoluteX("canvas") + 15;

    @   for(var i in rowinfo){
    @     rowinfo[i].y = absoluteY(rowinfo[i].id) + 10 - canvasY;
    @     rowinfo[i].x = left + rowinfo[i].r*20;
    @   }
    @   var btm = rowinfo[rowinfo.length-1].y + 20;



















    @   for(var i in rowinfo){
    @     drawNode(rowinfo[i], left, btm);
    @   }
    @ }
    @ var lastId = rowinfo[rowinfo.length-1].id;
    @ var lastY = 0;
    @ function checkHeight(){
................................................................................
**    n=COUNT        number of events in output
**    p=RID          artifact RID and up to COUNT parents and ancestors
**    d=RID          artifact RID and up to COUNT descendants
**    t=TAGID        show only check-ins with the given tagid
**    u=USER         only if belonging to this user
**    y=TYPE         'ci', 'w', 't'
**    s=TEXT         string search (comment and brief)

**
** p= and d= can appear individually or together.  If either p= or d=
** appear, then u=, y=, a=, and b= are ignored.
**
** If a= and b= appear, only a= is used.  If neither appear, the most
** recent events are choosen.
**
................................................................................
    tagid = 0;
  }
  if( zType[0]=='a' ){
    tmFlags = TIMELINE_BRIEF | TIMELINE_GRAPH;
  }else{
    tmFlags = TIMELINE_GRAPH;
  }




  style_header("Timeline");
  login_anonymous_available();
  timeline_temp_table();
  blob_zero(&sql);
  blob_zero(&desc);
  blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1);
................................................................................
      blob_appendf(&desc, "%d %ss", n, zEType);
    }
    if( zUser ){
      blob_appendf(&desc, " by user %h", zUser);
    }
    if( tagid>0 ){
      blob_appendf(&desc, " tagged with \"%h\"", zTagName);
      tmFlags &= ~TIMELINE_GRAPH;
    }
    if( zAfter ){
      blob_appendf(&desc, " occurring on or after %h.<br>", zAfter);
    }else if( zBefore ){
      blob_appendf(&desc, " occurring on or before %h.<br>", zBefore);
    }else if( zCirca ){
      blob_appendf(&desc, " occurring around %h.<br>", zCirca);







>







 







|







 







|







 







>






|
|
|
|
|
|
|
|
<







 







|
<
|



>





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







 







>







 







>
>
>







 







|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415

416
417
418
419
420
421
422
...
495
496
497
498
499
500
501
502

503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
...
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
...
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
** Allowed flags for the tmFlags argument to www_print_timeline
*/
#if INTERFACE
#define TIMELINE_ARTID    0x0001  /* Show artifact IDs on non-check-in lines */
#define TIMELINE_LEAFONLY 0x0002  /* Show "Leaf", but not "Merge", "Fork" etc */
#define TIMELINE_BRIEF    0x0004  /* Combine adjacent elements of same object */
#define TIMELINE_GRAPH    0x0008  /* Compute a graph */
#define TIMELINE_DISJOINT 0x0010  /* Elements are not contiguous */
#endif

/*
** Output a timeline in the web format given a query.  The query
** should return these columns:
**
**    0.  rid
................................................................................
      @   <div class="divider"><nobr>%s(zPrevDate)</nobr></div>
      @ </td></tr>
    }
    memcpy(zTime, &zDate[11], 5);
    zTime[5] = 0;
    @ <tr>
    @ <td valign="top" align="right">%s(zTime)</td>
    @ <td width="20" align="left" valign="top">
    @ <div id="m%d(rid)"></div>
    if( zBgClr && zBgClr[0] ){
      @ <td valign="top" align="left" bgcolor="%h(zBgClr)">
    }else{
      @ <td valign="top" align="left">
    }
    if( zType[0]=='c' ){
................................................................................
  if( suppressCnt ){
    @ <tr><td><td><td>
    @ <small><i>... %d(suppressCnt) similar
    @ event%s(suppressCnt>1?"s":"") omitted.</i></small></tr>
    suppressCnt = 0;
  }
  if( pGraph ){
    graph_finish(pGraph, (tmFlags & TIMELINE_DISJOINT)!=0);
    if( pGraph->nErr ){
      graph_free(pGraph);
      pGraph = 0;
    }else{
      @ <tr><td><td><div style="width:%d(pGraph->mxRail*20+30)px;"></div>
    }
  }
................................................................................
      }
      if( cSep=='[' ) cgi_printf("[");
      cgi_printf("]}%s", pRow->pNext ? ",\n" : "];\n");
    }
    cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
    graph_free(pGraph);
    @ var canvasDiv = document.getElementById("canvas");
    @ var realCanvas = null;
    @ function drawBox(color,x0,y0,x1,y1){
    @   var n = document.createElement("div");
    @   if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
    @   if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
    @   var w = x1-x0+1;
    @   var h = y1-y0+1;
    @   canvasDiv.appendChild(n);
    @   n.style.position = "absolute";
    @   n.style.overflow = "hidden";
    @   n.style.left = x0+"px";
    @   n.style.top = y0+"px";
    @   n.style.width = w+"px";
    @   n.style.height = h+"px";
    @   n.style.backgroundColor = color;

    @ }
    @ function absoluteY(id){
    @   var obj = document.getElementById(id);
    @   if( !obj ) return;
    @   var top = 0;
    @   if( obj.offsetParent ){
    @     do{
................................................................................
    @     }else{
    @       drawThinArrow(y0,mx,p.x-5);
    @     }
    @   }
    @ }
    @ function renderGraph(){
    @   var canvasDiv = document.getElementById("canvas");
    @   while( canvasDiv.hasChildNodes() ){

    @     canvasDiv.removeChild(canvasDiv.firstChild);
    @   }
    @   var canvasY = absoluteY("canvas");
    @   var left = absoluteX(rowinfo[0].id) - absoluteX("canvas") + 15;
    @   var width = nrail*20;
    @   for(var i in rowinfo){
    @     rowinfo[i].y = absoluteY(rowinfo[i].id) + 10 - canvasY;
    @     rowinfo[i].x = left + rowinfo[i].r*20;
    @   }
    @   var btm = rowinfo[rowinfo.length-1].y + 20;
    @   canvasDiv.innerHTML = '<canvas id="timeline-canvas" '+
    @      'style="position:absolute;left:'+(left-5)+'px;"' +
    @      ' width="'+width+'" height="'+btm+'"></canvas>';
    @   realCanvas = document.getElementById('timeline-canvas');
    @   var context;
    @   if( realCanvas && realCanvas.getContext
    @        && (context = realCanvas.getContext('2d'))) {
    @     drawBox = function(color,x0,y0,x1,y1) {
    @       var colors = {
    @          'white':'rgba(255,255,255,1)',
    @          'black':'rgba(0,0,0,1)'
    @       };
    @       if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
    @       if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
    @       if(isNaN(x0) || isNaN(y0) || isNaN(x1) || isNaN(y1)) return;
    @       context.fillStyle = colors[color];
    @       context.fillRect(x0-left+5,y0,x1-x0+1,y1-y0+1);
    @     };
    @   }
    @   for(var i in rowinfo){
    @     drawNode(rowinfo[i], left, btm);
    @   }
    @ }
    @ var lastId = rowinfo[rowinfo.length-1].id;
    @ var lastY = 0;
    @ function checkHeight(){
................................................................................
**    n=COUNT        number of events in output
**    p=RID          artifact RID and up to COUNT parents and ancestors
**    d=RID          artifact RID and up to COUNT descendants
**    t=TAGID        show only check-ins with the given tagid
**    u=USER         only if belonging to this user
**    y=TYPE         'ci', 'w', 't'
**    s=TEXT         string search (comment and brief)
**    ng             Suppress the graph if present
**
** p= and d= can appear individually or together.  If either p= or d=
** appear, then u=, y=, a=, and b= are ignored.
**
** If a= and b= appear, only a= is used.  If neither appear, the most
** recent events are choosen.
**
................................................................................
    tagid = 0;
  }
  if( zType[0]=='a' ){
    tmFlags = TIMELINE_BRIEF | TIMELINE_GRAPH;
  }else{
    tmFlags = TIMELINE_GRAPH;
  }
  if( P("ng")!=0 ){
    tmFlags &= ~TIMELINE_GRAPH;
  }

  style_header("Timeline");
  login_anonymous_available();
  timeline_temp_table();
  blob_zero(&sql);
  blob_zero(&desc);
  blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1);
................................................................................
      blob_appendf(&desc, "%d %ss", n, zEType);
    }
    if( zUser ){
      blob_appendf(&desc, " by user %h", zUser);
    }
    if( tagid>0 ){
      blob_appendf(&desc, " tagged with \"%h\"", zTagName);
      tmFlags |= TIMELINE_DISJOINT;
    }
    if( zAfter ){
      blob_appendf(&desc, " occurring on or after %h.<br>", zAfter);
    }else if( zBefore ){
      blob_appendf(&desc, " occurring on or before %h.<br>", zBefore);
    }else if( zCirca ){
      blob_appendf(&desc, " occurring around %h.<br>", zCirca);

Changes to src/tktsetup.c.

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
@      submit_ticket
@   }
@ </th1>
@ <h1 align="center">Enter A New Ticket</h1>
@ <table cellpadding="5">
@ <tr>
@ <td colspan="2">
@ Enter a one-line summary of the problem:<br>
@ <input type="text" name="title" size="60" value="$<title>">
@ </td>
@ </tr>
@ 
@ <tr>
@ <td align="right">Type:
@ <th1>combobox type $type_choices 1</th1>







|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
@      submit_ticket
@   }
@ </th1>
@ <h1 align="center">Enter A New Ticket</h1>
@ <table cellpadding="5">
@ <tr>
@ <td colspan="2">
@ Enter a one-line summary of the ticket:<br>
@ <input type="text" name="title" size="60" value="$<title>">
@ </td>
@ </tr>
@ 
@ <tr>
@ <td align="right">Type:
@ <th1>combobox type $type_choices 1</th1>

Changes to src/vfile.c.

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
    }else if( oldChnged>=2 ){
      chnged = oldChnged;
    }else if( rid==0 ){
      chnged = 1;
    }
    if( chnged!=1 ){
      currentMtime = file_mtime(0);
      assert( currentMtime>0 );
    }
    if( chnged!=1 && (checkMtime==0 || currentMtime!=oldMtime) ){
      db_ephemeral_blob(&q, 5, &origCksum);
      if( sha1sum_file(zName, &fileCksum) ){
        blob_zero(&fileCksum);
      }
      if( blob_compare(&fileCksum, &origCksum) ){







<







180
181
182
183
184
185
186

187
188
189
190
191
192
193
    }else if( oldChnged>=2 ){
      chnged = oldChnged;
    }else if( rid==0 ){
      chnged = 1;
    }
    if( chnged!=1 ){
      currentMtime = file_mtime(0);

    }
    if( chnged!=1 && (checkMtime==0 || currentMtime!=oldMtime) ){
      db_ephemeral_blob(&q, 5, &origCksum);
      if( sha1sum_file(zName, &fileCksum) ){
        blob_zero(&fileCksum);
      }
      if( blob_compare(&fileCksum, &origCksum) ){

Changes to src/xfer.c.

1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
    /* If this is a clone, the go at least two rounds */
    if( cloneFlag && nCycle==1 ) go = 1;
  };
  transport_stats(&nSent, &nRcvd, 1);
  printf("Total network traffic: %d bytes sent, %d bytes received\n",
         nSent, nRcvd);
  transport_close();
  socket_global_shutdown();
  db_multi_exec("DROP TABLE onremote");
  manifest_crosslink_end();
  db_end_transaction(0);
}







|




1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
    /* If this is a clone, the go at least two rounds */
    if( cloneFlag && nCycle==1 ) go = 1;
  };
  transport_stats(&nSent, &nRcvd, 1);
  printf("Total network traffic: %d bytes sent, %d bytes received\n",
         nSent, nRcvd);
  transport_close();
  transport_global_shutdown();
  db_multi_exec("DROP TABLE onremote");
  manifest_crosslink_end();
  db_end_transaction(0);
}

Added www/custom_ticket.wiki.



































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<nowiki>
<h1 align="center">Customizing The Ticket System</h1>
<p>
This guide will explain how to add the "assigned_to" and "submitted_by" fields
to the ticket system in Fossil, as well as making the system more useful.  You
must have "admin" access to the repository to implement these instructions.
</p>

<h2>First modify the TICKET table</h2><blockquote>
<p>
Click on the "Admin" menu, then "Tickets", then "Table".  After the other fields
and before the final ")", insert:
<pre>
  ,
  assigned_to TEXT,
  opened_by TEXT
</pre>
And "Apply Changes".  You have just added two more fields to the ticket
database!  NOTE: I won't tell you to "Apply Changes" after each step from here
on out.  Now, how do you use these fields?
</p>
</blockquote>

<h2>Next add assignees</h2><blockquote>
<p>
Back to the "Tickets" admin page, and click "Common".  Add something like this:
<pre>
set assigned_choices {
  tom
  dick
  harriet
}
</pre>
Obviously, choose names corresponding to the logins on your system.
</p>
</blockquote>

<h2>Now modify the 'new ticket' page</h2><blockquote>
<p>
Back to the "Tickets" admin page, and click "New Ticket Page".  This is a little
more tricky.  Edit the top part:
<pre>
  if {[info exists submit]} {
     set status Open
     set opened_by $login
     submit_ticket
  }
</pre>
Note the "set opened_by" bit -- that will automatically set the "opened_by"
field to the login name of the bug reporter.  Now, skip to the part with "EMail"
and modify it like so:
<pre>
&lt;th1>enable_output [expr { "$login" eq "anonymous"}]&lt;/th1>
&lt;tr>
&lt;td align="right">EMail:
&lt;input type="text" name="private_contact" value="$&lt;private_contact>" size="30">
&lt;/td>
&lt;td>&lt;u>Not publicly visible&lt;/u>. Used by developers to contact you with
questions.&lt;/td>
&lt;/tr>
&lt;th1>enable_output 1&lt;/th1>
</pre>
This bit of code will get rid of the "email" field entry for logged-in users.
Since we know the user's information, we don't have to ask for it. NOTE: it
might be good to automatically scoop up the user's email and put it here. 
</p>
</blockquote>

<h2>Modify the 'view ticket' page</h2><blockquote>
<p>
Look for the text "Contact:" (about halfway through).  Then insert these lines
after the closing tr tag and before the "enable_output" line:
<pre>
<tr>
  &lt;td align="right">Assigned to:&lt;/td>&lt;td bgcolor="#d0d0d0">
  $&lt;assigned_to>
  &lt;/td>
  &lt;td align="right">Opened by:&lt;/td>&lt;td bgcolor="#d0d0d0">
  $&lt;opened_by>
  &lt;/td>
</pre>
This will add a row which displays these two fields, in the event the user has
"edit" capability.  
</p>
</blockquote>

<h2>Modify the 'edit ticket' page</h2><blockquote>
<p>
Before the "Severity:" line, add this:
<pre>
&lt;tr>&lt;td align="right">Assigned to:&lt;/td>&lt;td>
&lt;th1>combobox assigned_to $assigned_choices 1&lt;/th1>
&lt;/td>&lt;/tr>
</pre>
That will give you a drop-down list of assignees.  Now, similar to the previous
section, look for "Contact:" and add this:
<pre>
  &lt;tr>&lt;td align="right">Reported by:&lt;/td>&lt;td>
  &lt;input type="text" name="opened_by" size="40"
   value="$&lt;opened_by>">
  &lt;/td>&lt;/tr>
</pre>
</p>
</blockquote>

<h2>What next?</h2><blockquote>
<p>
Now you can add custom reports which select based on the person to whom the
ticket is assigned.  For example, an "Assigned to me" report could be:
<pre>
SELECT
  CASE WHEN status IN ('Open','Verified') THEN '#f2dcdc'
       WHEN status='Review' THEN '#e8e8e8'
       WHEN status='Fixed' THEN '#cfe8bd'
       WHEN status='Tested' THEN '#bde5d6'
       WHEN status='Deferred' THEN '#cacae5'
       ELSE '#c8c8c8' END AS 'bgcolor',
  substr(tkt_uuid,1,10) AS '#',
  datetime(tkt_mtime) AS 'mtime',
  type,
  status,
  subsystem,
  title
FROM ticket
WHERE assigned_to=user()
</pre>
</p>
</blockquote>
</nowiki>

Changes to www/fileformat.wiki.


1
2
3
4
5
6
7
...
214
215
216
217
218
219
220



221
222
223
224
225
226
227
...
259
260
261
262
263
264
265



266
267
268
269
270
271
272

<h1 align="center">
Fossil File Formats
</h1>

<p>The global state of a fossil repository is kept simple so that it can
endure in useful form for decades or centuries. 
A fossil repository is intended to be readable,
................................................................................
to the Z-card is a 32-character lowercase hexadecimal MD5 hash
of all prior lines of the manifest up to and including the newline 
character that immediately precedes the "Z".  The Z-card is just
a sanity check to prove that the manifest is well-formed and
consistent.
</p>




<h2>2.0 Clusters</h2>

<p>
A cluster is a artifact that declares the existence of other artifacts.
Clusters are used during repository synchronization to help 
reduce network traffic.  As such, clusters are an optimization and
may be removed from a repository without loss or damage to the
................................................................................
line.  Each M card has a single argument which is the artifact ID of 
another artifact in the repository.  The Z card work exactly like
the Z card of a manifest.  The argument to the Z card is the
lower-case hexadecimal representation of the MD5 checksum of all
prior cards in the cluster.  Note that the Z card is required
on a cluster.
</p>





<h2>3.0 Control Artifacts</h2>

<p>
Control artifacts are used to assign properties to other artifacts
within the repository.  The basic format of a control artifact is
>







 







>
>
>







 







>
>
>







1
2
3
4
5
6
7
8
...
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
...
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
<title>Fossil File Formats</title>
<h1 align="center">
Fossil File Formats
</h1>

<p>The global state of a fossil repository is kept simple so that it can
endure in useful form for decades or centuries. 
A fossil repository is intended to be readable,
................................................................................
to the Z-card is a 32-character lowercase hexadecimal MD5 hash
of all prior lines of the manifest up to and including the newline 
character that immediately precedes the "Z".  The Z-card is just
a sanity check to prove that the manifest is well-formed and
consistent.
</p>

<p>A sample manifest from Fossil itself can be seen
[/artifact/28987096ac | here].

<h2>2.0 Clusters</h2>

<p>
A cluster is a artifact that declares the existence of other artifacts.
Clusters are used during repository synchronization to help 
reduce network traffic.  As such, clusters are an optimization and
may be removed from a repository without loss or damage to the
................................................................................
line.  Each M card has a single argument which is the artifact ID of 
another artifact in the repository.  The Z card work exactly like
the Z card of a manifest.  The argument to the Z card is the
lower-case hexadecimal representation of the MD5 checksum of all
prior cards in the cluster.  Note that the Z card is required
on a cluster.
</p>

<p>An example cluster from Fossil can be seen
[/artifact/d03dbdd73a2a8 | here].</p>


<h2>3.0 Control Artifacts</h2>

<p>
Control artifacts are used to assign properties to other artifacts
within the repository.  The basic format of a control artifact is

Changes to www/index.wiki.

121
122
123
124
125
126
127


128
129
130
131
132
133
134
135
136
137
138
139
  *  How to [./shunning.wiki | delete content] from a fossil repository.
  *  How Fossil does [./password.wiki | password management].
  *  Some (unfinished but expanding) extended
      [./reference.wiki | reference documentation] for the fossil command line.
  *  Documentation on the
     [http://www.sqliteconcepts.org/THManual.pdf | TH1 Script Language] used
     to configure the ticketing subsystem.



<h3>Links For Fossil Developer:</h3>

  *  [./theory1.wiki | Thoughts On The Design Of Fossil].
  *  [./pop.wiki | Principles Of Operation]
  *  The [./fileformat.wiki | file format] used by every content
     file stored in the repository.
  *  The [./delta_format.wiki | format of deltas] used to
     efficiently store changes between file revisions.
  *  The [./delta_encoder_algorithm.wiki | encoder algorithm] used to
     efficiently generate deltas.
  *  The [./sync.wiki | synchronization protocol].







>
>












121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  *  How to [./shunning.wiki | delete content] from a fossil repository.
  *  How Fossil does [./password.wiki | password management].
  *  Some (unfinished but expanding) extended
      [./reference.wiki | reference documentation] for the fossil command line.
  *  Documentation on the
     [http://www.sqliteconcepts.org/THManual.pdf | TH1 Script Language] used
     to configure the ticketing subsystem.
  *  How to [./server.wiki | set up a server] for your repository.
  *  Customizing the [./custom_ticket.wiki | ticket system].

<h3>Links For Fossil Developer:</h3>

  *  [./theory1.wiki | Thoughts On The Design Of Fossil].
  *  [./pop.wiki | Principles Of Operation]
  *  The [./fileformat.wiki | file format] used by every content
     file stored in the repository.
  *  The [./delta_format.wiki | format of deltas] used to
     efficiently store changes between file revisions.
  *  The [./delta_encoder_algorithm.wiki | encoder algorithm] used to
     efficiently generate deltas.
  *  The [./sync.wiki | synchronization protocol].

Added www/server.wiki.







































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
<nowiki>
<h1 align="center">Server Setup Guide</h1>
<p>This guide is intended to help guide you in setting up a Fossil server.</p>

<h2>Standalone server</h2><blockquote>
The easiest way to set up a Fossil server is to use the <tt>server</tt> or
<tt>ui</tt> command.  Assuming the repository you are interested in serving is
in the file "<tt>repo.fossil</tt>", you can use either of these commands to
start Fossil as a server:
<ul>
<li><tt>fossil server repo.fossil</tt>
<li><tt>fossil ui repo.fossil</tt>
</ul>

<p>
Both of these commands start a Fossil server on port 8080 on the local machine,
which can be accessed with the URL: <tt>http://localhost:8080/</tt> using any
handy web browser.  The difference between the two commands is that "ui", in
addition to starting the Fossil server, also starts a web browser and points it
to the URL mentioned above.
</p>
<p>
NOTES:
<ol>
<li>The option "--port NNN" will start the server on port "NNN" instead of 8080.  
<li>If port 8080 is already being used (perhaps by another Fossil server), then
Fossil will use the next available port number.
<li>Starting either command from within an "open" Fossil checkout will start a
server using the repository corresponding to the checkout.
<li>This is an excellent option for quickly sharing with coworkers on a small network.
<li>A huge advantage to this deployment scenario is that no special "root" or "administrator" access is required in order to share the repository.
</ol>
</p>
</blockquote>

<h2>Fossil as an ''inetd'' service</h2><blockquote>
<p>
Modify your <tt>/etc/inetd.conf</tt> (on Linux, modify as appropriate for your platform) so it contains a line like this:
<blockquote>
<tt>
12345 stream tcp nowait.1000 root /path-to/fossil /path-to/fossil http /other-path-to/repository
</tt>
</blockquote>
In this example, you are telling "inetd" that when an incoming connection on port "12345" happens, it should launch the binary "/path-to/fossil".  Obviously you will need to modify the "path-to" parts as appropriate for your particular setup.
</p>
<p>
This is a more complex setup than the "standalone" server, but it has the advantage of only using system resources when an actual connection is attempted.  If no-one ever connects to that port, a Fossil server will not (automatically) run.  It has the disadvantage of requiring "root" access and therefore may not normally be available to lower-priced "shared" servers on the internet.
</p>
</blockquote>

<h2>Fossil as a ''CGI script''</h2><blockquote>
<p>
This is the most flexible and most likely to be widely usable of these deployment scenarios.  In order for it to work, you must have the ability to install "CGI scripts" on the server you are interested in using. 
</p>
</blockquote>

<h3>One script per repository</h3><blockquote>
<p>
Create a script (let's call it 'repo') in your CGI directory which has content like this:
<blockquote><tt>
#!/path-to/fossil
repository: /path-to-repo/repository
</tt></blockquote>
</p>
<p>
It may be necessary to set permissions properly, or to modify an ".htaccess" file or other server-specific things like that.  Consult with your server provider if you need that sort of assistance.
</p>
<p>
Once the script is set up correctly, and assuming your server is also set correctly, you should be able to access your repository with a URL like: <tt>http://mydomain.org/cgi-bin/repo</tt> (assuming the "repo" script is accessible under "cgi-bin", which would be a typical deployment on Apache for instance).
</p>
</blockquote>

<h3>Serving multiple repositories with one script</h3><blockquote>
<p>
This scenario is almost identical to the previous one.  However, here we will assume you have multiple repositories, in one directory (call it 'fossils').  So as before, create a script (again, 'repo'):
<blockquote><tt>
#!/path-to/fossil
directory: /path-to-repo/fossils
notfound: http://url-to-go-to-if-repo-not-found/
</tt></blockquote>
</p>
<p>
Once deployed, a URL like: <tt>http://mydomain.org/cgi-bin/repo/XYZ</tt> will serve up the repository "fossils/XYX" (if it exists).  This makes serving multiple projects on one server pretty painless.
</p>
</blockquote>

<h2>Securing a repository with SSL</h2><blockquote>
<p>
Using either of the CGI script approaches, it is trivial to use SSL to secure the server.  Simply set up the Fossil CGI scripts etc. as above, but modify the Apache (or IIS, etc.) server to require SSL (that is, a URL with "https://") in order to access the CGI script directory.  This may also be accomplished (on Apache, at least) using appropriate ".htaccess" rules.
</p>
<p>
If you are using "inetd" to serve your repository, then you simply need to add "/usr/bin/stunnel" (perhaps on a different path, depending on your setup) before the command line to launch Fossil.
</p>
<p>
At this stage, the standalone server (e.g. "fossil server") does not support SSL.
</p>
</blockquote>

<h2>Various security concerns with hosted repositories</h2><blockquote>
<p>
There are two main concerns relating to usage of Fossil for sharing sensitive information (source or any other data):
<ul>
<li>Interception of the Fossil synchronization stream, thereby capturing data, and
</ul>Direct access to the Fossil repository on the server
</p>
<p>
Regarding the first, it is adequate to secure the server using SSL, and disallowing any non-SSL access.  The data stream will be encrypted by the HTTPS protocol, rendering the data reasonably secure.  The truly paranoid may wish to deploy <i>ssh</i> encrypted tunnels, but that is quite a bit more difficult and cumbersome to set up (particularly for a larger number of users).
</p>
<p>
As far as direct access to the repository, the same steps must be taken as for any other internet-facing data-store.  Access passwords to any disk-accessing accounts should be strong (and preferably changed from time to time).  However, the data in the repository itself are <i>not</i> encrypted (unless you save encrypted data yourself), and so the system administrators of your server will be able to access your data (as with any hosting service setup).  The only workaround in this case is to host the server yourself, in which case you will need to allocate resources to deal with administration issues.
</p>

</blockquote>

</nowiki>

Changes to www/theory1.wiki.

109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
just a programming language.

For certain types of problems, SQL has a huge advantage over other
programming languages because it is so high level and because it allows
programmers to focus more on the <i>what</i> and less of the <i>how</i>
of a computation.  In other words,
programmers tend to think about problems at a much higher level when
using SQL, can this can result in better applications.
SQL is also very dense.
In practice, this often means that a few
lines of SQL can often replace hundreds or thousands of lines of
procedural code, with a corresponding decrease in programming effort
and opportunities to introduce bugs.
Fossil happens to be one of those problems for which SQL is well suited.








|







109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
just a programming language.

For certain types of problems, SQL has a huge advantage over other
programming languages because it is so high level and because it allows
programmers to focus more on the <i>what</i> and less of the <i>how</i>
of a computation.  In other words,
programmers tend to think about problems at a much higher level when
using SQL; this can result in better applications.
SQL is also very dense.
In practice, this often means that a few
lines of SQL can often replace hundreds or thousands of lines of
procedural code, with a corresponding decrease in programming effort
and opportunities to introduce bugs.
Fossil happens to be one of those problems for which SQL is well suited.