Fossil

Check-in [ab188badcd]
Login

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

Overview
Comment:Merge the latest trunk enhancements into DBP-workflow branch.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | DBP-workflow
Files: files | file ages | folders
SHA1: ab188badcd08b8835c21f2b6d463b068387a4a47
User & Date: drh 2014-12-01 17:26:02.179
Context
2014-12-01
20:26
Store a short description of artifacts in bundles and in purgeitem entries. Use that short description on listings. check-in: 87a04576f2 user: drh tags: DBP-workflow
17:26
Merge the latest trunk enhancements into DBP-workflow branch. check-in: ab188badcd user: drh tags: DBP-workflow
17:22
Add the administrative log capability. check-in: f3455a56ee user: drh tags: trunk
17:17
Change output formatting of describe_artifact_to_stdout() to omit the RID. Make sure the purgeevent and purgeitem tables are not deleted by a rebuild. check-in: 1c7dd7949e user: drh tags: DBP-workflow
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/codecheck1.c.
307
308
309
310
311
312
313

314
315
316
317
318
319
320
** string.
*/
struct {
  const char *zFName;    /* Name of the function */
  int iFmtArg;           /* Index of format argument.  Leftmost is 1. */
  unsigned fmtFlags;     /* Processing flags */
} aFmtFunc[] = {

  { "blob_append_sql",         2, FMT_NO_S },
  { "blob_appendf",            2, 0 },
  { "cgi_panic",               1, 0 },
  { "cgi_redirectf",           1, 0 },
  { "db_blob",                 2, FMT_NO_S },
  { "db_double",               2, FMT_NO_S },
  { "db_err",                  1, 0 },







>







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
** string.
*/
struct {
  const char *zFName;    /* Name of the function */
  int iFmtArg;           /* Index of format argument.  Leftmost is 1. */
  unsigned fmtFlags;     /* Processing flags */
} aFmtFunc[] = {
  { "admin_log",               1, 0 },
  { "blob_append_sql",         2, FMT_NO_S },
  { "blob_appendf",            2, 0 },
  { "cgi_panic",               1, 0 },
  { "cgi_redirectf",           1, 0 },
  { "db_blob",                 2, FMT_NO_S },
  { "db_double",               2, FMT_NO_S },
  { "db_err",                  1, 0 },
Changes to src/db.c.
747
748
749
750
751
752
753





























754
755
756
757
758
759
760
  int rc = mtime_of_manifest_file(sqlite3_value_int(argv[0]),
                                  sqlite3_value_int(argv[1]), &mtime);
  if( rc==0 ){
    sqlite3_result_int64(context, mtime);
  }
}































/*
** Open a database file.  Return a pointer to the new database
** connection.  An error results in process abort.
*/
LOCAL sqlite3 *db_open(const char *zDbName){
  int rc;







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







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
  int rc = mtime_of_manifest_file(sqlite3_value_int(argv[0]),
                                  sqlite3_value_int(argv[1]), &mtime);
  if( rc==0 ){
    sqlite3_result_int64(context, mtime);
  }
}

void db_sym2rid_function(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  char const * arg;
  char const * type;
  if(1 != argc && 2 != argc){
    sqlite3_result_error(context, "Expecting one or two arguments", -1);
    return;
  }
  arg = (const char*)sqlite3_value_text(argv[0]);
  if(!arg){
    sqlite3_result_error(context, "Expecting a STRING argument", -1);
  }else{
    int rid;
    type = (2==argc) ? sqlite3_value_text(argv[1]) : 0;
    if(!type) type = "ci";
    rid = symbolic_name_to_rid( arg, type );
    if(rid<0){
      sqlite3_result_error(context, "Symbolic name is ambiguous.", -1);
    }else if(0==rid){
      sqlite3_result_null(context);
    }else{
      sqlite3_result_int64(context, rid);
    }
  }
}


/*
** Open a database file.  Return a pointer to the new database
** connection.  An error results in process abort.
*/
LOCAL sqlite3 *db_open(const char *zDbName){
  int rc;
779
780
781
782
783
784
785








786
787
788

789
790
791
792
793
794
795
  sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0);
  sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
  sqlite3_create_function(
    db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0
  );
  sqlite3_create_function(
    db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0








  );
  if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0);
  re_add_sql_func(db);

  sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
  return db;
}


/*
** Detaches the zLabel database.







>
>
>
>
>
>
>
>



>







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
  sqlite3_create_function(db, "cgi", 2, SQLITE_UTF8, 0, db_sql_cgi, 0, 0);
  sqlite3_create_function(db, "print", -1, SQLITE_UTF8, 0,db_sql_print,0,0);
  sqlite3_create_function(
    db, "is_selected", 1, SQLITE_UTF8, 0, file_is_selected,0,0
  );
  sqlite3_create_function(
    db, "if_selected", 3, SQLITE_UTF8, 0, file_is_selected,0,0
  );
  sqlite3_create_function(
    db, "symbolic_name_to_rid", 1, SQLITE_UTF8, 0, db_sym2rid_function,
    0, 0
  );
  sqlite3_create_function(
    db, "symbolic_name_to_rid", 2, SQLITE_UTF8, 0, db_sym2rid_function,
    0, 0
  );
  if( g.fSqlTrace ) sqlite3_trace(db, db_sql_trace, 0);
  re_add_sql_func(db);
  foci_register(db);
  sqlite3_exec(db, "PRAGMA foreign_keys=OFF;", 0, 0, 0);
  return db;
}


/*
** Detaches the zLabel database.
2246
2247
2248
2249
2250
2251
2252

2253
2254
2255
2256
2257
2258
2259
  int versionable;      /* Is this setting versionable? */
  int forceTextArea;    /* Force using a text area for display? */
  const char *def;      /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
  { "access-log",       0,              0, 0, 0, "off"                 },

  { "allow-symlinks",   0,              0, 1, 0, "off"                 },
  { "auto-captcha",     "autocaptcha",  0, 0, 0, "on"                  },
  { "auto-hyperlink",   0,              0, 0, 0, "on",                 },
  { "auto-shun",        0,              0, 0, 0, "on"                  },
  { "autosync",         0,              0, 0, 0, "on"                  },
  { "autosync-tries",   0,             16, 0, 0, "1"                   },
  { "binary-glob",      0,             40, 1, 0, ""                    },







>







2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
  int versionable;      /* Is this setting versionable? */
  int forceTextArea;    /* Force using a text area for display? */
  const char *def;      /* Default value */
};
#endif /* INTERFACE */
struct stControlSettings const ctrlSettings[] = {
  { "access-log",       0,              0, 0, 0, "off"                 },
  { "admin-log",        0,              0, 0, 0, "off"                 },
  { "allow-symlinks",   0,              0, 1, 0, "off"                 },
  { "auto-captcha",     "autocaptcha",  0, 0, 0, "on"                  },
  { "auto-hyperlink",   0,              0, 0, 0, "on",                 },
  { "auto-shun",        0,              0, 0, 0, "on"                  },
  { "autosync",         0,              0, 0, 0, "on"                  },
  { "autosync-tries",   0,             16, 0, 0, "1"                   },
  { "binary-glob",      0,             40, 1, 0, ""                    },
2326
2327
2328
2329
2330
2331
2332



2333
2334
2335
2336
2337
2338
2339
** file exists.
**
** The "unset" command clears a property setting.
**
**
**    access-log       If enabled, record successful and failed login attempts
**                     in the "accesslog" table.  Default: off



**
**    allow-symlinks   If enabled, don't follow symlinks, and instead treat
**     (versionable)   them as symlinks on Unix. Has no effect on Windows
**                     (existing links in repository created on Unix become
**                     plain-text files with link destination path inside).
**                     Default: off
**







>
>
>







2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
** file exists.
**
** The "unset" command clears a property setting.
**
**
**    access-log       If enabled, record successful and failed login attempts
**                     in the "accesslog" table.  Default: off
**
**    admin-log        If enabled, record configuration changes in the
**                     "admin_log" table.  Default: off
**
**    allow-symlinks   If enabled, don't follow symlinks, and instead treat
**     (versionable)   them as symlinks on Unix. Has no effect on Windows
**                     (existing links in repository created on Unix become
**                     plain-text files with link destination path inside).
**                     Default: off
**
2702
2703
2704
2705
2706
2707
2708
2709

2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724









































      blob_append_sql(&allSql,
         "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
         "%s WITHOUT ROWID;\n"
         "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
         "DROP TABLE \"x_%w\";\n",
         zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
      );
      fossil_print("Converting table %s of %s to WITHOUT ROWID.\n", zTName, g.argv[i]);

      blob_reset(&newSql);
    }
    blob_append_sql(&allSql, "COMMIT;\n");
    db_finalize(&q);
    if( dryRun ){
      fossil_print("SQL that would have been evaluated:\n");
      fossil_print("-------------------------------------------------------------\n");
      fossil_print("%s", blob_sql_text(&allSql));
    }else{
      db_multi_exec("%s", blob_sql_text(&allSql));
    }
    blob_reset(&allSql);
    db_close(1);
  }
}
















































|
>






|








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
      blob_append_sql(&allSql,
         "ALTER TABLE \"%w\" RENAME TO \"x_%w\";\n"
         "%s WITHOUT ROWID;\n"
         "INSERT INTO \"%w\" SELECT * FROM \"x_%w\";\n"
         "DROP TABLE \"x_%w\";\n",
         zTName, zTName, blob_sql_text(&newSql), zTName, zTName, zTName
      );
      fossil_print("Converting table %s of %s to WITHOUT ROWID.\n",
                    zTName, g.argv[i]);
      blob_reset(&newSql);
    }
    blob_append_sql(&allSql, "COMMIT;\n");
    db_finalize(&q);
    if( dryRun ){
      fossil_print("SQL that would have been evaluated:\n");
      fossil_print("%.78c\n", '-');
      fossil_print("%s", blob_sql_text(&allSql));
    }else{
      db_multi_exec("%s", blob_sql_text(&allSql));
    }
    blob_reset(&allSql);
    db_close(1);
  }
}

/*
** Make sure the adminlog table exists.  Create it if it does not
*/
void create_admin_log_table(void){
  static int once = 0;
  if( once ) return;
  once = 1;
  db_multi_exec(
    "CREATE TABLE IF NOT EXISTS \"%w\".admin_log(\n"
    " id INTEGER PRIMARY KEY,\n"
    " time INTEGER, -- Seconds since 1970\n"
    " page TEXT,    -- path of page\n"
    " who TEXT,     -- User who made the change\n "
    " what TEXT     -- What changed\n"
    ")", db_name("repository")
  );
}

/*
** Write a message into the admin_event table, if admin logging is
** enabled via the admin-log configuration option.
*/
void admin_log(const char *zFormat, ...){
  Blob what = empty_blob;
  va_list ap;
  if( !db_get_boolean("admin-log", 0) ){
      /* Potential leak here (on %z params) but
         the alternative is to let blob_vappendf()
         do it below. */
      return;
  }
  create_admin_log_table();
  va_start(ap,zFormat);
  blob_vappendf( &what, zFormat, ap );
  va_end(ap);
  db_multi_exec("INSERT INTO admin_log(time,page,who,what)"
                " VALUES(now(), %Q, %Q, %B)",
                g.zPath, g.zLogin, &what);
  blob_reset(&what);
}
Added src/foci.c.




























































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*
** Copyright (c) 2014 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)

** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This routine implements an SQLite virtual table that gives all of the
** files associated with a single checkin.
**
** The filename "foci" is short for "Files Of CheckIn".
*/
#include "config.h"
#include "foci.h"
#include <assert.h>

/*
** The schema for the virtual table:
*/
static const char zFociSchema[] = 
@ CREATE TABLE files_of_checkin(
@  checkinID    INTEGER,    -- RID for the checkin manifest
@  filename     TEXT,       -- Name of a file
@  uuid         TEXT,       -- SHA1 hash of the file
@  previousName TEXT,       -- Name of the file in previous checkin
@  prem         TEXT        -- Permissions on the file
@ );
;

#if INTERFACE
/*
** The subclasses of sqlite3_vtab  and sqlite3_vtab_cursor tables
** that implement the files_of_checkin virtual table.
*/
struct FociTable {
  sqlite3_vtab base;        /* Base class - must be first */
};
struct FociCursor {
  sqlite3_vtab_cursor base; /* Base class - must be first */
  Manifest *pMan;           /* Current manifest */
  int iFile;                /* Index of current file */
};
#endif /* INTERFACE */


/*
** Connect to or create a foci virtual table.
*/
static int fociConnect(
  sqlite3 *db,
  void *pAux,
  int argc, const char *const*argv,
  sqlite3_vtab **ppVtab,
  char **pzErr
){
  FociTable *pTab;

  pTab = (FociTable *)sqlite3_malloc(sizeof(FociTable));
  memset(pTab, 0, sizeof(FociTable));
  sqlite3_declare_vtab(db, zFociSchema);
  *ppVtab = &pTab->base;
  return SQLITE_OK;
}

/*
** Disconnect from or destroy a focivfs virtual table.
*/
static int fociDisconnect(sqlite3_vtab *pVtab){
  sqlite3_free(pVtab);
  return SQLITE_OK;
}

/*
** Available scan methods:
**
**   (0)     A full scan.  Visit every manifest in the repo.  (Slow)
**   (1)     checkinID=?.  visit only the single manifest specifed.
*/
static int fociBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
  int i;
  pIdxInfo->estimatedCost = 10000.0;
  for(i=0; i<pIdxInfo->nConstraint; i++){
    if( pIdxInfo->aConstraint[i].iColumn==0
     && pIdxInfo->aConstraint[i].op==SQLITE_INDEX_CONSTRAINT_EQ ){
      pIdxInfo->idxNum = 1;
      pIdxInfo->estimatedCost = 1.0;
      pIdxInfo->aConstraintUsage[i].argvIndex = 1;
      pIdxInfo->aConstraintUsage[i].omit = 1;
      break;
    }
  }
  return SQLITE_OK;
}

/*
** Open a new focivfs cursor.
*/
static int fociOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
  FociTable *pTab = (FociTable *)pVTab;
  FociCursor *pCsr;
  int rc;

  pCsr = (FociCursor *)sqlite3_malloc(sizeof(FociCursor));
  memset(pCsr, 0, sizeof(FociCursor));
  pCsr->base.pVtab = pVTab;
  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
  return SQLITE_OK;
}

/*
** Close a focivfs cursor.
*/
static int fociClose(sqlite3_vtab_cursor *pCursor){
  FociCursor *pCsr = (FociCursor *)pCursor;
  manifest_destroy(pCsr->pMan);
  sqlite3_free(pCsr);
  return SQLITE_OK;
}

/*
** Move a focivfs cursor to the next entry in the file.
*/
static int fociNext(sqlite3_vtab_cursor *pCursor){
  FociCursor *pCsr = (FociCursor *)pCursor;
  pCsr->iFile++;
  return SQLITE_OK;
}

static int fociEof(sqlite3_vtab_cursor *pCursor){
  FociCursor *pCsr = (FociCursor *)pCursor;
  return pCsr->pMan==0 || pCsr->iFile>=pCsr->pMan->nFile;
}

static int fociFilter(
  sqlite3_vtab_cursor *pCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  FociCursor *pCur = (FociCursor *)pCursor;
  manifest_destroy(pCur->pMan);
  if( idxNum ){
    pCur->pMan = manifest_get(sqlite3_value_int(argv[0]), CFTYPE_MANIFEST, 0);
    pCur->iFile = 0;
  }else{
    pCur->pMan = 0;
    pCur->iFile = 0;
  }
  return SQLITE_OK;
}

static int fociColumn(
  sqlite3_vtab_cursor *pCursor, 
  sqlite3_context *ctx, 
  int i
){
  FociCursor *pCsr = (FociCursor *)pCursor;
  switch( i ){
    case 0:            /* checkinID */
      sqlite3_result_int(ctx, pCsr->pMan->rid);
      break;
    case 1:            /* filename */
      sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zName, -1,
                          SQLITE_TRANSIENT);
      break;
    case 2:            /* uuid */
      sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zUuid, -1,
                          SQLITE_TRANSIENT);
      break;
    case 3:            /* previousName */
      sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zPrior, -1,
                          SQLITE_TRANSIENT);
      break;
    case 4:            /* perm */
      sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zPerm, -1,
                          SQLITE_TRANSIENT);
      break;
  }
  return SQLITE_OK;
}

static int fociRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
  FociCursor *pCsr = (FociCursor *)pCursor;
  *pRowid = pCsr->iFile;
  return SQLITE_OK;
}

int foci_register(sqlite3 *db){
  static sqlite3_module foci_module = {
    0,                            /* iVersion */
    fociConnect,                  /* xCreate */
    fociConnect,                  /* xConnect */
    fociBestIndex,                /* xBestIndex */
    fociDisconnect,               /* xDisconnect */
    fociDisconnect,               /* xDestroy */
    fociOpen,                     /* xOpen - open a cursor */
    fociClose,                    /* xClose - close a cursor */
    fociFilter,                   /* xFilter - configure scan constraints */
    fociNext,                     /* xNext - advance a cursor */
    fociEof,                      /* xEof - check for end of scan */
    fociColumn,                   /* xColumn - read data */
    fociRowid,                    /* xRowid - read data */
    0,                            /* xUpdate */
    0,                            /* xBegin */
    0,                            /* xSync */
    0,                            /* xCommit */
    0,                            /* xRollback */
    0,                            /* xFindMethod */
    0,                            /* xRename */
  };
  sqlite3_create_module(db, "files_of_checkin", &foci_module, 0);
  return SQLITE_OK;
}
Changes to src/main.mk.
42
43
44
45
46
47
48

49
50
51
52
53
54
55
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \

  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
  $(SRCDIR)/graph.c \
  $(SRCDIR)/gzip.c \
  $(SRCDIR)/http.c \
  $(SRCDIR)/http_socket.c \
  $(SRCDIR)/http_ssl.c \







>







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \
  $(SRCDIR)/foci.c \
  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
  $(SRCDIR)/graph.c \
  $(SRCDIR)/gzip.c \
  $(SRCDIR)/http.c \
  $(SRCDIR)/http_socket.c \
  $(SRCDIR)/http_ssl.c \
162
163
164
165
166
167
168

169
170
171
172
173
174
175
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \

  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
  $(OBJDIR)/graph_.c \
  $(OBJDIR)/gzip_.c \
  $(OBJDIR)/http_.c \
  $(OBJDIR)/http_socket_.c \
  $(OBJDIR)/http_ssl_.c \







>







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \
  $(OBJDIR)/foci_.c \
  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
  $(OBJDIR)/graph_.c \
  $(OBJDIR)/gzip_.c \
  $(OBJDIR)/http_.c \
  $(OBJDIR)/http_socket_.c \
  $(OBJDIR)/http_ssl_.c \
279
280
281
282
283
284
285

286
287
288
289
290
291
292
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \

 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
 $(OBJDIR)/graph.o \
 $(OBJDIR)/gzip.o \
 $(OBJDIR)/http.o \
 $(OBJDIR)/http_socket.o \
 $(OBJDIR)/http_ssl.o \







>







281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/foci.o \
 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
 $(OBJDIR)/graph.o \
 $(OBJDIR)/gzip.o \
 $(OBJDIR)/http.o \
 $(OBJDIR)/http_socket.o \
 $(OBJDIR)/http_ssl.o \
505
506
507
508
509
510
511

512
513
514
515
516
517
518
	$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
	$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
	$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
	$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
	$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
	$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
	$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \

	$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
	$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
	$(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
	$(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
	$(OBJDIR)/http_.c:$(OBJDIR)/http.h \
	$(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \
	$(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \







>







508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
	$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
	$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
	$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
	$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
	$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
	$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
	$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
	$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
	$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
	$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
	$(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
	$(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
	$(OBJDIR)/http_.c:$(OBJDIR)/http.h \
	$(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \
	$(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \
850
851
852
853
854
855
856








857
858
859
860
861
862
863
$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/finfo.c >$@

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

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









$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c








>
>
>
>
>
>
>
>







854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/finfo.c >$@

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

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

$(OBJDIR)/foci_.c:	$(SRCDIR)/foci.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/foci.c >$@

$(OBJDIR)/foci.o:	$(OBJDIR)/foci_.c $(OBJDIR)/foci.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/foci.o -c $(OBJDIR)/foci_.c

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

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

Changes to src/makemake.tcl.
49
50
51
52
53
54
55

56
57
58
59
60
61
62
  diffcmd
  doc
  encode
  event
  export
  file
  finfo

  fusefs
  glob
  graph
  gzip
  http
  http_socket
  http_transport







>







49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  diffcmd
  doc
  encode
  event
  export
  file
  finfo
  foci
  fusefs
  glob
  graph
  gzip
  http
  http_socket
  http_transport
Changes to src/moderate.c.
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
      fossil_free(zTktid);
    }
    attachRid = db_int(0, "SELECT attachRid FROM modreq WHERE objid=%d", rid);
    if( rid==objid ){
      db_multi_exec("DELETE FROM modreq WHERE objid=%d", rid);
    }
    if( attachRid && object_used(attachRid) ) attachRid = 0;

    rid = attachRid;
  }
  db_end_transaction(0);
}

/*
** Approve an object held for moderation.
*/
void moderation_approve(int rid){
  if( !moderation_pending(rid) ) return;
  db_begin_transaction();
  db_multi_exec(
    "DELETE FROM private WHERE rid=%d;"
    "INSERT OR IGNORE INTO unclustered VALUES(%d);"
    "INSERT OR IGNORE INTO unsent VALUES(%d);",
    rid, rid, rid
  );
  db_multi_exec("DELETE FROM modreq WHERE objid=%d", rid);

  db_end_transaction(0);
}

/*
** WEBPAGE: modreq
**
** Show all pending moderation request







>


















>







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
      fossil_free(zTktid);
    }
    attachRid = db_int(0, "SELECT attachRid FROM modreq WHERE objid=%d", rid);
    if( rid==objid ){
      db_multi_exec("DELETE FROM modreq WHERE objid=%d", rid);
    }
    if( attachRid && object_used(attachRid) ) attachRid = 0;
    admin_log("Disapproved moderation of rid %d.", rid);
    rid = attachRid;
  }
  db_end_transaction(0);
}

/*
** Approve an object held for moderation.
*/
void moderation_approve(int rid){
  if( !moderation_pending(rid) ) return;
  db_begin_transaction();
  db_multi_exec(
    "DELETE FROM private WHERE rid=%d;"
    "INSERT OR IGNORE INTO unclustered VALUES(%d);"
    "INSERT OR IGNORE INTO unsent VALUES(%d);",
    rid, rid, rid
  );
  db_multi_exec("DELETE FROM modreq WHERE objid=%d", rid);
  admin_log("Approved moderation of rid %d.", rid);
  db_end_transaction(0);
}

/*
** WEBPAGE: modreq
**
** Show all pending moderation request
Changes to src/rebuild.c.
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    percent_complete(0);
  }
  rebuild_update_schema();
  for(;;){
    zTable = db_text(0,
       "SELECT name FROM sqlite_master /*scan*/"
       " WHERE type='table'"
       " AND name NOT IN ('blob','delta','rcvfrom','user',"
                         "'config','shun','private','reportfmt',"
                         "'concealed','accesslog','modreq',"
                         "'purgeevent','purgeitem')"
       " AND name NOT GLOB 'sqlite_*'"
       " AND name NOT GLOB 'fx_*'"
    );
    if( zTable==0 ) break;







|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    percent_complete(0);
  }
  rebuild_update_schema();
  for(;;){
    zTable = db_text(0,
       "SELECT name FROM sqlite_master /*scan*/"
       " WHERE type='table'"
       " AND name NOT IN ('admin_log', 'blob','delta','rcvfrom','user',"
                         "'config','shun','private','reportfmt',"
                         "'concealed','accesslog','modreq',"
                         "'purgeevent','purgeitem')"
       " AND name NOT GLOB 'sqlite_*'"
       " AND name NOT GLOB 'fx_*'"
    );
    if( zTable==0 ) break;
Changes to src/setup.c.
107
108
109
110
111
112
113


114
115
116
117
118
119
120
    "Change the logo and background images for the server");
  setup_menu_entry("Shunned", "shun",
    "Show artifacts that are shunned by this repository");
  setup_menu_entry("Log", "rcvfromlist",
    "A record of received artifacts and their sources");
  setup_menu_entry("User-Log", "access_log",
    "A record of login attempts");


  setup_menu_entry("Stats", "stat",
    "Display repository statistics");
  setup_menu_entry("SQL", "admin_sql",
    "Enter raw SQL commands");
  setup_menu_entry("TH1", "admin_th1",
    "Enter raw TH1 commands");
  @ </table>







>
>







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    "Change the logo and background images for the server");
  setup_menu_entry("Shunned", "shun",
    "Show artifacts that are shunned by this repository");
  setup_menu_entry("Log", "rcvfromlist",
    "A record of received artifacts and their sources");
  setup_menu_entry("User-Log", "access_log",
    "A record of login attempts");
  setup_menu_entry("Admin-Log", "admin_log",
    "View the admin_log entries");
  setup_menu_entry("Stats", "stat",
    "Display repository statistics");
  setup_menu_entry("SQL", "admin_sql",
    "Enter raw SQL commands");
  setup_menu_entry("TH1", "admin_th1",
    "Enter raw TH1 commands");
  @ </table>
378
379
380
381
382
383
384
385
386


387
388
389
390
391
392
393
      style_footer();
      return;
    }
    login_verify_csrf_secret();
    db_multi_exec(
       "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
       "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
      uid, P("login"), P("info"), zPw, zCap
    );


    if( atoi(PD("all","0"))>0 ){
      Blob sql;
      char *zErr = 0;
      blob_zero(&sql);
      if( zOldLogin==0 ){
        blob_appendf(&sql,
          "INSERT INTO user(login)"







|

>
>







380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
      style_footer();
      return;
    }
    login_verify_csrf_secret();
    db_multi_exec(
       "REPLACE INTO user(uid,login,info,pw,cap,mtime) "
       "VALUES(nullif(%d,0),%Q,%Q,%Q,%Q,now())",
      uid, zLogin, P("info"), zPw, zCap
    );
    admin_log( "Updated user [%q] with capabilities [%q].",
               zLogin, zCap );
    if( atoi(PD("all","0"))>0 ){
      Blob sql;
      char *zErr = 0;
      blob_zero(&sql);
      if( zOldLogin==0 ){
        blob_appendf(&sql,
          "INSERT INTO user(login)"
405
406
407
408
409
410
411



412
413

414
415
416
417
418
419
420
        "  mtime=now()"
        " WHERE login=%Q;",
        zLogin, P("pw"), zLogin, P("info"), zCap,
        zOldLogin
      );
      login_group_sql(blob_str(&sql), "<li> ", " </li>\n", &zErr);
      blob_reset(&sql);



      if( zErr ){
        style_header("User Change Error");

        @ <span class="loginError">%s(zErr)</span>
        @
        @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p>
        style_footer();
        return;
      }
    }







>
>
>


>







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
        "  mtime=now()"
        " WHERE login=%Q;",
        zLogin, P("pw"), zLogin, P("info"), zCap,
        zOldLogin
      );
      login_group_sql(blob_str(&sql), "<li> ", " </li>\n", &zErr);
      blob_reset(&sql);
      admin_log( "Updated user [%q] in all login groups "
                 "with capabilities [%q].",
                 zLogin, zCap );
      if( zErr ){
        style_header("User Change Error");
        admin_log( "Error updating user '%q': %s'.", zLogin, zErr );
        @ <span class="loginError">%s(zErr)</span>
        @
        @ <p><a href="setup_uedit?id=%d(uid)">[Bummer]</a></p>
        style_footer();
        return;
      }
    }
860
861
862
863
864
865
866


867
868
869
870
871
872
873
    zQ = "off";
  }
  if( zQ ){
    int iQ = fossil_strcmp(zQ,"on")==0 || atoi(zQ);
    if( iQ!=iVal ){
      login_verify_csrf_secret();
      db_set(zVar, iQ ? "1" : "0", 0);


      iVal = iQ;
    }
  }
  @ <input type="checkbox" name="%s(zQParm)"
  if( iVal ){
    @ checked="checked"
  }







>
>







868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
    zQ = "off";
  }
  if( zQ ){
    int iQ = fossil_strcmp(zQ,"on")==0 || atoi(zQ);
    if( iQ!=iVal ){
      login_verify_csrf_secret();
      db_set(zVar, iQ ? "1" : "0", 0);
      admin_log("Set option [%q] to [%q].",
                zVar, iQ ? "on" : "off");
      iVal = iQ;
    }
  }
  @ <input type="checkbox" name="%s(zQParm)"
  if( iVal ){
    @ checked="checked"
  }
887
888
889
890
891
892
893

894
895


896
897
898
899
900
901
902
  const char *zQParm,   /* The query parameter */
  char *zDflt,          /* Default value if VAR table entry does not exist */
  int disabled          /* 1 if disabled */
){
  const char *zVal = db_get(zVar, zDflt);
  const char *zQ = P(zQParm);
  if( zQ && fossil_strcmp(zQ,zVal)!=0 ){

    login_verify_csrf_secret();
    db_set(zVar, zQ, 0);


    zVal = zQ;
  }
  @ <input type="text" id="%s(zQParm)" name="%s(zQParm)" value="%h(zVal)" size="%d(width)"
  if( disabled ){
    @ disabled="disabled"
  }
  @ /> <b>%s(zLabel)</b>







>


>
>







897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
  const char *zQParm,   /* The query parameter */
  char *zDflt,          /* Default value if VAR table entry does not exist */
  int disabled          /* 1 if disabled */
){
  const char *zVal = db_get(zVar, zDflt);
  const char *zQ = P(zQParm);
  if( zQ && fossil_strcmp(zQ,zVal)!=0 ){
    const int nZQ = (int)strlen(zQ);
    login_verify_csrf_secret();
    db_set(zVar, zQ, 0);
    admin_log("Set entry_attribute %Q to: %.*s%s",
              zVar, 20, zQ, (nZQ>20 ? "..." : ""));
    zVal = zQ;
  }
  @ <input type="text" id="%s(zQParm)" name="%s(zQParm)" value="%h(zVal)" size="%d(width)"
  if( disabled ){
    @ disabled="disabled"
  }
  @ /> <b>%s(zLabel)</b>
913
914
915
916
917
918
919

920
921


922
923
924
925
926
927
928
  const char *zQP,      /* The query parameter */
  const char *zDflt,    /* Default value if VAR table entry does not exist */
  int disabled          /* 1 if the textarea should  not be editable */
){
  const char *z = db_get(zVar, (char*)zDflt);
  const char *zQ = P(zQP);
  if( zQ && !disabled && fossil_strcmp(zQ,z)!=0){

    login_verify_csrf_secret();
    db_set(zVar, zQ, 0);


    z = zQ;
  }
  if( rows>0 && cols>0 ){
    @ <textarea id="id%s(zQP)" name="%s(zQP)" rows="%d(rows)"
    if( disabled ){
      @ disabled="disabled"
    }







>


>
>







926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
  const char *zQP,      /* The query parameter */
  const char *zDflt,    /* Default value if VAR table entry does not exist */
  int disabled          /* 1 if the textarea should  not be editable */
){
  const char *z = db_get(zVar, (char*)zDflt);
  const char *zQ = P(zQP);
  if( zQ && !disabled && fossil_strcmp(zQ,z)!=0){
    const int nZQ = (int)strlen(zQ);
    login_verify_csrf_secret();
    db_set(zVar, zQ, 0);
    admin_log("Set textarea_attribute %Q to: %.*s%s",
              zVar, 20, zQ, (nZQ>20 ? "..." : ""));
    z = zQ;
  }
  if( rows>0 && cols>0 ){
    @ <textarea id="id%s(zQP)" name="%s(zQP)" rows="%d(rows)"
    if( disabled ){
      @ disabled="disabled"
    }
944
945
946
947
948
949
950

951
952


953
954
955
956
957
958
959
  int nChoice,          /* Number of choices */
  const char *const *azChoice /* Choices. 2 per choice: (VAR value, Display) */
){
  const char *z = db_get(zVar, (char*)zDflt);
  const char *zQ = P(zQP);
  int i;
  if( zQ && fossil_strcmp(zQ,z)!=0){

    login_verify_csrf_secret();
    db_set(zVar, zQ, 0);


    z = zQ;
  }
  @ <select size="1" name="%s(zQP)" id="id%s(zQP)">
  for(i=0; i<nChoice*2; i+=2){
    const char *zSel = fossil_strcmp(azChoice[i],z)==0 ? " selected" : "";
    @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
  }







>


>
>







960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
  int nChoice,          /* Number of choices */
  const char *const *azChoice /* Choices. 2 per choice: (VAR value, Display) */
){
  const char *z = db_get(zVar, (char*)zDflt);
  const char *zQ = P(zQP);
  int i;
  if( zQ && fossil_strcmp(zQ,z)!=0){
    const int nZQ = (int)strlen(zQ);
    login_verify_csrf_secret();
    db_set(zVar, zQ, 0);
    admin_log("Set multiple_choice_attribute %Q to: %.*s%s",
              zVar, 20, zQ, (nZQ>20 ? "..." : ""));
    z = zQ;
  }
  @ <select size="1" name="%s(zQP)" id="id%s(zQP)">
  for(i=0; i<nChoice*2; i+=2){
    const char *zSel = fossil_strcmp(azChoice[i],z)==0 ? " selected" : "";
    @ <option value="%h(azChoice[i])"%s(zSel)>%h(azChoice[i+1])</option>
  }
2021
2022
2023
2024
2025
2026
2027














































































      @ <pre class="th1result">%h(zR)</pre>
    }else{
      @ <pre class="th1error">%h(zR)</pre>
    }
  }
  style_footer();
}





















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
      @ <pre class="th1result">%h(zR)</pre>
    }else{
      @ <pre class="th1error">%h(zR)</pre>
    }
  }
  style_footer();
}

static void admin_log_render_limits(){
  int const count = db_int(0,"SELECT COUNT(*) FROM admin_log");
  int i;
  int limits[] = {
  10, 20, 50, 100, 250, 500, 0
  };
  for(i = 0; limits[i]; ++i ){
    cgi_printf("%s<a href='?n=%d'>%d</a>",
               i ? " " : "",
               limits[i], limits[i]);
    if(limits[i]>count) break;
  }
}

/*
** WEBPAGE: admin_log
**
** Shows the contents of the admin_log table, which is only created if
** the admin-log setting is enabled. Requires Admin or Setup ('a' or
** 's') permissions.
*/
void page_admin_log(){
  Stmt stLog = empty_Stmt;
  Blob qLog = empty_blob;
  int limit;
  int fLogEnabled;
  int counter = 0;
  login_check_credentials();
  if( !g.perm.Setup && !g.perm.Admin ){
    login_needed();
  }
  style_header("Admin Log");
  create_admin_log_table();
  limit = atoi(PD("n","20"));
  fLogEnabled = db_get_boolean("admin-log", 0);
  @ <div>Admin logging is %s(fLogEnabled?"on":"off").</div>


  @ <div>Limit results to: <span>
  admin_log_render_limits();
  @ </span></div>

  blob_append_sql(&qLog,
               "SELECT datetime(time,'unixepoch'), who, page, what "
               "FROM admin_log "
               "ORDER BY time DESC ");
  if(limit>0){
    @ %d(limit) Most recent entries:
    blob_append_sql(&qLog, "LIMIT %d", limit);
  }
  db_prepare(&stLog, "%s", blob_sql_text(&qLog));
  blob_reset(&qLog);
  @ <table id="adminLogTable" class="adminLogTable" width="100%%">
  @ <thead>
  @ <th>Time</th>
  @ <th>User</th>
  @ <th>Page</th>
  @ <th width="60%%">Message</th>
  @ </thead><tbody>
  while( SQLITE_ROW == db_step(&stLog) ){
    char const * zTime = db_column_text(&stLog, 0);
    char const * zUser = db_column_text(&stLog, 1);
    char const * zPage = db_column_text(&stLog, 2);
    char const * zMessage = db_column_text(&stLog, 3);
    @ <tr class="row%d(counter++%2)">
    @ <td class="adminTime">%s(zTime)</td>
    @ <td>%s(zUser)</td>
    @ <td>%s(zPage)</td>
    @ <td>%h(zMessage)</td>
    @ </tr>
  }
  @ </tbody></table>
  if(limit>0 && counter<limit){
    @ <div>%d(counter) entries shown.</div>
  }
  style_footer();
}
Changes to src/shun.c.
54
55
56
57
58
59
60

61
62
63
64
65
66
67
    login_needed();
  }
  if( P("rebuild") ){
    db_close(1);
    db_open_repository(g.zRepositoryName);
    db_begin_transaction();
    rebuild_db(0, 0, 0);

    db_end_transaction(0);
  }
  if( zUuid ){
    char *p;
    int i = 0;
    int j = 0;
    zCanonical = fossil_malloc(strlen(zUuid)+2);







>







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
    login_needed();
  }
  if( P("rebuild") ){
    db_close(1);
    db_open_repository(g.zRepositoryName);
    db_begin_transaction();
    rebuild_db(0, 0, 0);
    admin_log("Rebuilt database.");
    db_end_transaction(0);
  }
  if( zUuid ){
    char *p;
    int i = 0;
    int j = 0;
    zCanonical = fossil_malloc(strlen(zUuid)+2);
99
100
101
102
103
104
105

106
107
108
109
110
111
112
    int allExist = 1;
    login_verify_csrf_secret();
    while( *p ){
      db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p);
      if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){
        allExist = 0;
      }

      p += UUID_SIZE+1;
    }
    if( allExist ){
      @ <p class="noMoreShun">Artifact(s)<br />
      for( p = zUuid ; *p ; p += UUID_SIZE+1 ){
        @ <a href="%s(g.zTop)/artifact/%s(p)">%s(p)</a><br />
      }







>







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
    int allExist = 1;
    login_verify_csrf_secret();
    while( *p ){
      db_multi_exec("DELETE FROM shun WHERE uuid=%Q", p);
      if( !db_exists("SELECT 1 FROM blob WHERE uuid=%Q", p) ){
        allExist = 0;
      }
      admin_log("Unshunned %Q", p);
      p += UUID_SIZE+1;
    }
    if( allExist ){
      @ <p class="noMoreShun">Artifact(s)<br />
      for( p = zUuid ; *p ; p += UUID_SIZE+1 ){
        @ <a href="%s(g.zTop)/artifact/%s(p)">%s(p)</a><br />
      }
137
138
139
140
141
142
143

144
145
146
147
148
149
150
      }
      tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='tkt-%q'", p);
      if( tagid ){
        db_multi_exec("DELETE FROM ticket WHERE tkt_uuid=%Q", p);
        db_multi_exec("DELETE FROM tag WHERE tagid=%d", tagid);
        db_multi_exec("DELETE FROM tagxref WHERE tagid=%d", tagid);
      }

      p += UUID_SIZE+1;
    }
    @ <p class="shunned">Artifact(s)<br />
    for( p = zUuid ; *p ; p += UUID_SIZE+1 ){
      @ <a href="%s(g.zTop)/artifact/%s(p)">%s(p)</a><br />
    }
    @ have been shunned.  They will no longer be pushed.







>







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
      }
      tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='tkt-%q'", p);
      if( tagid ){
        db_multi_exec("DELETE FROM ticket WHERE tkt_uuid=%Q", p);
        db_multi_exec("DELETE FROM tag WHERE tagid=%d", tagid);
        db_multi_exec("DELETE FROM tagxref WHERE tagid=%d", tagid);
      }
      admin_log("Shunned %Q", p);
      p += UUID_SIZE+1;
    }
    @ <p class="shunned">Artifact(s)<br />
    for( p = zUuid ; *p ; p += UUID_SIZE+1 ){
      @ <a href="%s(g.zTop)/artifact/%s(p)">%s(p)</a><br />
    }
    @ have been shunned.  They will no longer be pushed.
Changes to src/sqlcmd.c.
130
131
132
133
134
135
136


137
138
139
140
141
142
143
static int sqlcmd_autoinit(
  sqlite3 *db,
  const char **pzErrMsg,
  const void *notUsed
){
  add_content_sql_commands(db);
  re_add_sql_func(db);


  g.repositoryOpen = 1;
  g.db = db;
  return SQLITE_OK;
}

/*
** COMMAND: sqlite3







>
>







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
static int sqlcmd_autoinit(
  sqlite3 *db,
  const char **pzErrMsg,
  const void *notUsed
){
  add_content_sql_commands(db);
  re_add_sql_func(db);
  g.zMainDbType = "repository";
  foci_register(db);
  g.repositoryOpen = 1;
  g.db = db;
  return SQLITE_OK;
}

/*
** COMMAND: sqlite3
Changes to src/style.c.
1206
1207
1208
1209
1210
1211
1212










1213
1214
1215
1216
1217
1218
1219
  { "#usetupEditCapability",
    "format for capabilities string, mentioned on the user edit page",
    @ font-weight: bold;
  },
  { "#canvas", "timeline graph node colors",
    @ color: black;
    @ background-color: white;










  },
  { 0,
    0,
    0
  }
};








>
>
>
>
>
>
>
>
>
>







1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
  { "#usetupEditCapability",
    "format for capabilities string, mentioned on the user edit page",
    @ font-weight: bold;
  },
  { "#canvas", "timeline graph node colors",
    @ color: black;
    @ background-color: white;
  },
  { "table.adminLogTable",
    "Class for the /admin_log table",
    @ text-align: left
  },
  { ".adminLogTable .adminTime",
    "Class for the /admin_log table",
    @ text-align: left
    @ vertical-align: top;
    @ white-space: nowrap;
  },
  { 0,
    0,
    0
  }
};

Changes to win/Makefile.dmc.
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
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS

SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen

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

OBJ   = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\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)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$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)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O 


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

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

all: $(APPNAME)

$(APPNAME) : translate$E mkindex$E codecheck1$E headers  $(OBJ) $(OBJDIR)\link
	cd $(OBJDIR)
	codecheck1$E $(SRC)
	$(DMDIR)\bin\link @link

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

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

translate$E: $(SRCDIR)\translate.c







|

|


















|







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
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS

SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen

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

OBJ   = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\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)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$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)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O 


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

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

all: $(APPNAME)

$(APPNAME) : translate$E mkindex$E codecheck1$E headers  $(OBJ) $(OBJDIR)\link
	cd $(OBJDIR)
	codecheck1$E $(SRC)
	$(DMDIR)\bin\link @link

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

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

translate$E: $(SRCDIR)\translate.c
312
313
314
315
316
317
318






319
320
321
322
323
324
325
	+translate$E $** > $@

$(OBJDIR)\finfo$O : finfo_.c finfo.h
	$(TCC) -o$@ -c finfo_.c

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







$(OBJDIR)\fusefs$O : fusefs_.c fusefs.h
	$(TCC) -o$@ -c fusefs_.c

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








>
>
>
>
>
>







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
	+translate$E $** > $@

$(OBJDIR)\finfo$O : finfo_.c finfo.h
	$(TCC) -o$@ -c finfo_.c

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

$(OBJDIR)\foci$O : foci_.c foci.h
	$(TCC) -o$@ -c foci_.c

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

$(OBJDIR)\fusefs$O : fusefs_.c fusefs.h
	$(TCC) -o$@ -c fusefs_.c

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

812
813
814
815
816
817
818
819
820
$(OBJDIR)\zip$O : zip_.c zip.h
	$(TCC) -o$@ -c zip_.c

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

headers: makeheaders$E page_index.h builtin_data.h VERSION.h
	 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h 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 event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h 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 sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
	@copy /Y nul: headers







|

818
819
820
821
822
823
824
825
826
$(OBJDIR)\zip$O : zip_.c zip.h
	$(TCC) -o$@ -c zip_.c

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

headers: makeheaders$E page_index.h builtin_data.h VERSION.h
	 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h 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 event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h 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 sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
	@copy /Y nul: headers
Changes to win/Makefile.mingw.
373
374
375
376
377
378
379

380
381
382
383
384
385
386
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \

  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
  $(SRCDIR)/graph.c \
  $(SRCDIR)/gzip.c \
  $(SRCDIR)/http.c \
  $(SRCDIR)/http_socket.c \
  $(SRCDIR)/http_ssl.c \







>







373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \
  $(SRCDIR)/foci.c \
  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
  $(SRCDIR)/graph.c \
  $(SRCDIR)/gzip.c \
  $(SRCDIR)/http.c \
  $(SRCDIR)/http_socket.c \
  $(SRCDIR)/http_ssl.c \
493
494
495
496
497
498
499

500
501
502
503
504
505
506
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \

  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
  $(OBJDIR)/graph_.c \
  $(OBJDIR)/gzip_.c \
  $(OBJDIR)/http_.c \
  $(OBJDIR)/http_socket_.c \
  $(OBJDIR)/http_ssl_.c \







>







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \
  $(OBJDIR)/foci_.c \
  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
  $(OBJDIR)/graph_.c \
  $(OBJDIR)/gzip_.c \
  $(OBJDIR)/http_.c \
  $(OBJDIR)/http_socket_.c \
  $(OBJDIR)/http_ssl_.c \
610
611
612
613
614
615
616

617
618
619
620
621
622
623
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \

 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
 $(OBJDIR)/graph.o \
 $(OBJDIR)/gzip.o \
 $(OBJDIR)/http.o \
 $(OBJDIR)/http_socket.o \
 $(OBJDIR)/http_ssl.o \







>







612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/foci.o \
 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
 $(OBJDIR)/graph.o \
 $(OBJDIR)/gzip.o \
 $(OBJDIR)/http.o \
 $(OBJDIR)/http_socket.o \
 $(OBJDIR)/http_ssl.o \
920
921
922
923
924
925
926

927
928
929
930
931
932
933
		$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
		$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
		$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
		$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
		$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
		$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
		$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \

		$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
		$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
		$(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
		$(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
		$(OBJDIR)/http_.c:$(OBJDIR)/http.h \
		$(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \
		$(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \







>







923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
		$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
		$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
		$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
		$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
		$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
		$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
		$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
		$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
		$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
		$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
		$(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
		$(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
		$(OBJDIR)/http_.c:$(OBJDIR)/http.h \
		$(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \
		$(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \
1267
1268
1269
1270
1271
1272
1273








1274
1275
1276
1277
1278
1279
1280
$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/finfo.c >$@

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

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









$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c








>
>
>
>
>
>
>
>







1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/finfo.c >$@

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

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

$(OBJDIR)/foci_.c:	$(SRCDIR)/foci.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/foci.c >$@

$(OBJDIR)/foci.o:	$(OBJDIR)/foci_.c $(OBJDIR)/foci.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/foci.o -c $(OBJDIR)/foci_.c

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

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

Changes to win/Makefile.msc.
225
226
227
228
229
230
231

232
233
234
235
236
237
238
        diffcmd_.c \
        doc_.c \
        encode_.c \
        event_.c \
        export_.c \
        file_.c \
        finfo_.c \

        fusefs_.c \
        glob_.c \
        graph_.c \
        gzip_.c \
        http_.c \
        http_socket_.c \
        http_ssl_.c \







>







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
        diffcmd_.c \
        doc_.c \
        encode_.c \
        event_.c \
        export_.c \
        file_.c \
        finfo_.c \
        foci_.c \
        fusefs_.c \
        glob_.c \
        graph_.c \
        gzip_.c \
        http_.c \
        http_socket_.c \
        http_ssl_.c \
344
345
346
347
348
349
350

351
352
353
354
355
356
357
        $(OX)\diffcmd$O \
        $(OX)\doc$O \
        $(OX)\encode$O \
        $(OX)\event$O \
        $(OX)\export$O \
        $(OX)\file$O \
        $(OX)\finfo$O \

        $(OX)\fusefs$O \
        $(OX)\glob$O \
        $(OX)\graph$O \
        $(OX)\gzip$O \
        $(OX)\http$O \
        $(OX)\http_socket$O \
        $(OX)\http_ssl$O \







>







345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
        $(OX)\diffcmd$O \
        $(OX)\doc$O \
        $(OX)\encode$O \
        $(OX)\event$O \
        $(OX)\export$O \
        $(OX)\file$O \
        $(OX)\finfo$O \
        $(OX)\foci$O \
        $(OX)\fusefs$O \
        $(OX)\glob$O \
        $(OX)\graph$O \
        $(OX)\gzip$O \
        $(OX)\http$O \
        $(OX)\http_socket$O \
        $(OX)\http_ssl$O \
516
517
518
519
520
521
522

523
524
525
526
527
528
529
	echo $(OX)\diffcmd.obj >> $@
	echo $(OX)\doc.obj >> $@
	echo $(OX)\encode.obj >> $@
	echo $(OX)\event.obj >> $@
	echo $(OX)\export.obj >> $@
	echo $(OX)\file.obj >> $@
	echo $(OX)\finfo.obj >> $@

	echo $(OX)\fusefs.obj >> $@
	echo $(OX)\glob.obj >> $@
	echo $(OX)\graph.obj >> $@
	echo $(OX)\gzip.obj >> $@
	echo $(OX)\http.obj >> $@
	echo $(OX)\http_socket.obj >> $@
	echo $(OX)\http_ssl.obj >> $@







>







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
	echo $(OX)\diffcmd.obj >> $@
	echo $(OX)\doc.obj >> $@
	echo $(OX)\encode.obj >> $@
	echo $(OX)\event.obj >> $@
	echo $(OX)\export.obj >> $@
	echo $(OX)\file.obj >> $@
	echo $(OX)\finfo.obj >> $@
	echo $(OX)\foci.obj >> $@
	echo $(OX)\fusefs.obj >> $@
	echo $(OX)\glob.obj >> $@
	echo $(OX)\graph.obj >> $@
	echo $(OX)\gzip.obj >> $@
	echo $(OX)\http.obj >> $@
	echo $(OX)\http_socket.obj >> $@
	echo $(OX)\http_ssl.obj >> $@
894
895
896
897
898
899
900






901
902
903
904
905
906
907
	translate$E $** > $@

$(OX)\finfo$O : finfo_.c finfo.h
	$(TCC) /Fo$@ -c finfo_.c

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







$(OX)\fusefs$O : fusefs_.c fusefs.h
	$(TCC) /Fo$@ -c fusefs_.c

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








>
>
>
>
>
>







897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
	translate$E $** > $@

$(OX)\finfo$O : finfo_.c finfo.h
	$(TCC) /Fo$@ -c finfo_.c

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

$(OX)\foci$O : foci_.c foci.h
	$(TCC) /Fo$@ -c foci_.c

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

$(OX)\fusefs$O : fusefs_.c fusefs.h
	$(TCC) /Fo$@ -c fusefs_.c

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

1429
1430
1431
1432
1433
1434
1435

1436
1437
1438
1439
1440
1441
1442
			diffcmd_.c:diffcmd.h \
			doc_.c:doc.h \
			encode_.c:encode.h \
			event_.c:event.h \
			export_.c:export.h \
			file_.c:file.h \
			finfo_.c:finfo.h \

			fusefs_.c:fusefs.h \
			glob_.c:glob.h \
			graph_.c:graph.h \
			gzip_.c:gzip.h \
			http_.c:http.h \
			http_socket_.c:http_socket.h \
			http_ssl_.c:http_ssl.h \







>







1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
			diffcmd_.c:diffcmd.h \
			doc_.c:doc.h \
			encode_.c:encode.h \
			event_.c:event.h \
			export_.c:export.h \
			file_.c:file.h \
			finfo_.c:finfo.h \
			foci_.c:foci.h \
			fusefs_.c:fusefs.h \
			glob_.c:glob.h \
			graph_.c:graph.h \
			gzip_.c:gzip.h \
			http_.c:http.h \
			http_socket_.c:http_socket.h \
			http_ssl_.c:http_ssl.h \