Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | "char const" -> "const char" and various other coding style improvements. No functional change. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
4e18dba698479a222076a070d6f443ed |
| User & Date: | jan.nijtmans 2014-08-07 10:02:43.184 |
Context
|
2014-08-07
| ||
| 10:12 | Update referenced OpenSSL version. ... (check-in: 3a93461738 user: jan.nijtmans tags: trunk) | |
| 10:02 | "char const" -> "const char" and various other coding style improvements. No functional change. ... (check-in: 4e18dba698 user: jan.nijtmans tags: trunk) | |
| 07:13 | Follow-up to [3ba28b23a4d7626691b56debae4add06cd24d4ca|3ba28b23a4]: Eliminate unnecessary calls to sqlite3_win32_is_nt(), but now for MSC and PellesC as well. ... (check-in: ffa67c1b9b user: jan.nijtmans tags: trunk) | |
Changes
Changes to src/add.c.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 |
"_FOSSIL_-wal",
"_FOSSIL_-shm",
".fslckout",
".fslckout-journal",
".fslckout-wal",
".fslckout-shm",
| | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
"_FOSSIL_-wal",
"_FOSSIL_-shm",
".fslckout",
".fslckout-journal",
".fslckout-wal",
".fslckout-shm",
/* The use of ".fos" as the name of the checkout database is
** deprecated. Use ".fslckout" instead. At some point, the following
** entries should be removed. 2012-02-04 */
".fos",
".fos-journal",
".fos-wal",
".fos-shm",
};
|
| ︙ | ︙ | |||
121 122 123 124 125 126 127 |
**
** Show all reserved filenames for the current check-out.
*/
void test_reserved_names(void){
int i;
const char *z;
int omitRepo = find_option("omitrepo",0,0)!=0;
| | | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
**
** Show all reserved filenames for the current check-out.
*/
void test_reserved_names(void){
int i;
const char *z;
int omitRepo = find_option("omitrepo",0,0)!=0;
/* We should be done with options.. */
verify_all_options();
db_must_be_within_tree();
for(i=0; (z = fossil_reserved_name(i, omitRepo))!=0; i++){
fossil_print("%3d: %s\n", i, z);
}
|
| ︙ | ︙ | |||
179 180 181 182 183 184 185 | const char *zRepo; /* Name of the repository database file */ int nAdd = 0; /* Number of files added */ int i; /* Loop counter */ const char *zReserved; /* Name of a reserved file */ Blob repoName; /* Treename of the repository */ Stmt loop; /* SQL to loop over all files to add */ int (*xCmp)(const char*,const char*); | | | 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
const char *zRepo; /* Name of the repository database file */
int nAdd = 0; /* Number of files added */
int i; /* Loop counter */
const char *zReserved; /* Name of a reserved file */
Blob repoName; /* Treename of the repository */
Stmt loop; /* SQL to loop over all files to add */
int (*xCmp)(const char*,const char*);
if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){
blob_zero(&repoName);
zRepo = "";
}else{
zRepo = blob_str(&repoName);
}
if( filenames_are_case_sensitive() ){
|
| ︙ | ︙ | |||
235 236 237 238 239 240 241 | ** The --case-sensitive option determines whether or not filenames should ** be treated case sensitive or not. If the option is not given, the default ** depends on the global setting, or the operating system default, if not set. ** ** Options: ** ** --case-sensitive <BOOL> override case-sensitive setting | | | | | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 |
** The --case-sensitive option determines whether or not filenames should
** be treated case sensitive or not. If the option is not given, the default
** depends on the global setting, or the operating system default, if not set.
**
** Options:
**
** --case-sensitive <BOOL> override case-sensitive setting
** --dotfiles include files beginning with a dot (".")
** -f|--force Add files without prompting
** --ignore <CSG> ignore files matching patterns from the
** comma separated list of glob patterns.
** --clean <CSG> also ignore files matching patterns from
** the comma separated list of glob patterns.
**
** See also: addremove, rm
*/
void add_cmd(void){
int i; /* Loop counter */
int vid; /* Currently checked out version */
int nRoot; /* Full path characters in g.zLocalRoot */
const char *zCleanFlag; /* The --clean option or clean-glob setting */
|
| ︙ | ︙ | |||
277 278 279 280 281 282 283 |
vid = db_lget_int("checkout",0);
db_begin_transaction();
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
filename_collation());
pClean = glob_create(zCleanFlag);
pIgnore = glob_create(zIgnoreFlag);
nRoot = strlen(g.zLocalRoot);
| | | 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
vid = db_lget_int("checkout",0);
db_begin_transaction();
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
filename_collation());
pClean = glob_create(zCleanFlag);
pIgnore = glob_create(zIgnoreFlag);
nRoot = strlen(g.zLocalRoot);
/* Load the names of all files that are to be added into sfile temp table */
for(i=2; i<g.argc; i++){
char *zName;
int isDir;
Blob fullName;
/* file_tree_name() throws a fatal error if g.argv[i] is outside of the
|
| ︙ | ︙ | |||
352 353 354 355 356 357 358 |
** See also: addremove, add
*/
void delete_cmd(void){
int i;
Stmt loop;
capture_case_sensitive_option();
| | | 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 |
** See also: addremove, add
*/
void delete_cmd(void){
int i;
Stmt loop;
capture_case_sensitive_option();
/* We should be done with options.. */
verify_all_options();
db_must_be_within_tree();
db_begin_transaction();
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
filename_collation());
|
| ︙ | ︙ | |||
377 378 379 380 381 382 383 |
" OR (pathname>'%q/' %s AND pathname<'%q0' %s))"
" AND NOT deleted",
zTreeName, filename_collation(), zTreeName,
filename_collation(), zTreeName, filename_collation()
);
blob_reset(&treeName);
}
| | | 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 |
" OR (pathname>'%q/' %s AND pathname<'%q0' %s))"
" AND NOT deleted",
zTreeName, filename_collation(), zTreeName,
filename_collation(), zTreeName, filename_collation()
);
blob_reset(&treeName);
}
db_prepare(&loop, "SELECT x FROM sfile");
while( db_step(&loop)==SQLITE_ROW ){
fossil_print("DELETED %s\n", db_column_text(&loop, 0));
}
db_finalize(&loop);
db_multi_exec(
"UPDATE vfile SET deleted=1 WHERE pathname IN sfile;"
|
| ︙ | ︙ | |||
492 493 494 495 496 497 498 | ** --case-sensitive option with the "case-sensitive" setting and the ** --clean option with the "clean-glob" setting. See the documentation ** on the "settings" command for further information. ** ** The -n|--dry-run option shows what would happen without actually doing anything. ** ** This command can be used to track third party software. | | | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 |
** --case-sensitive option with the "case-sensitive" setting and the
** --clean option with the "clean-glob" setting. See the documentation
** on the "settings" command for further information.
**
** The -n|--dry-run option shows what would happen without actually doing anything.
**
** This command can be used to track third party software.
**
** Options:
** --case-sensitive <BOOL> override case-sensitive setting
** --dotfiles include files beginning with a dot (".")
** --ignore <CSG> ignore files matching patterns from the
** comma separated list of glob patterns.
** --clean <CSG> also ignore files matching patterns from
** the comma separated list of glob patterns.
** -n|--dry-run If given, display instead of run actions
|
| ︙ | ︙ | |||
521 522 523 524 525 526 527 |
int nDelete = 0;
Glob *pIgnore, *pClean;
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
}
capture_case_sensitive_option();
| | | | 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 |
int nDelete = 0;
Glob *pIgnore, *pClean;
if( !dryRunFlag ){
dryRunFlag = find_option("test",0,0)!=0; /* deprecated */
}
capture_case_sensitive_option();
/* We should be done with options.. */
verify_all_options();
db_must_be_within_tree();
if( zCleanFlag==0 ){
zCleanFlag = db_get("clean-glob", 0);
}
if( zIgnoreFlag==0 ){
zIgnoreFlag = db_get("ignore-glob", 0);
}
vid = db_lget_int("checkout",0);
db_begin_transaction();
/* step 1:
** Populate the temp table "sfile" with the names of all unmanaged
** files currently in the check-out, except for files that match the
** --ignore or ignore-glob patterns and dot-files. Then add all of
** the files in the sfile temp table to the set of managed files.
*/
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY %s)",
filename_collation());
|
| ︙ | ︙ | |||
561 562 563 564 565 566 567 |
db_prepare(&q,
"SELECT pathname, %Q || pathname, deleted FROM vfile"
" WHERE NOT deleted"
" ORDER BY 1",
g.zLocalRoot
);
while( db_step(&q)==SQLITE_ROW ){
| | | | 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 |
db_prepare(&q,
"SELECT pathname, %Q || pathname, deleted FROM vfile"
" WHERE NOT deleted"
" ORDER BY 1",
g.zLocalRoot
);
while( db_step(&q)==SQLITE_ROW ){
const char *zFile;
const char *zPath;
zFile = db_column_text(&q, 0);
zPath = db_column_text(&q, 1);
if( !file_wd_isfile_or_link(zPath) ){
if( !dryRunFlag ){
db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile);
}
|
| ︙ | ︙ | |||
593 594 595 596 597 598 599 |
*/
static void mv_one_file(int vid, const char *zOrig, const char *zNew){
int x = db_int(-1, "SELECT deleted FROM vfile WHERE pathname=%Q %s",
zNew, filename_collation());
if( x>=0 ){
if( x==0 ){
fossil_fatal("cannot rename '%s' to '%s' since another file named '%s'"
| | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 |
*/
static void mv_one_file(int vid, const char *zOrig, const char *zNew){
int x = db_int(-1, "SELECT deleted FROM vfile WHERE pathname=%Q %s",
zNew, filename_collation());
if( x>=0 ){
if( x==0 ){
fossil_fatal("cannot rename '%s' to '%s' since another file named '%s'"
" is currently under management", zOrig, zNew, zNew);
}else{
fossil_fatal("cannot rename '%s' to '%s' since the delete of '%s' has "
"not yet been committed", zOrig, zNew, zNew);
}
}
fossil_print("RENAME %s %s\n", zOrig, zNew);
db_multi_exec(
|
| ︙ | ︙ | |||
634 635 636 637 638 639 640 | int vid; char *zDest; Blob dest; Stmt q; capture_case_sensitive_option(); db_must_be_within_tree(); | | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 |
int vid;
char *zDest;
Blob dest;
Stmt q;
capture_case_sensitive_option();
db_must_be_within_tree();
/* We should be done with options.. */
verify_all_options();
vid = db_lget_int("checkout", 0);
if( vid==0 ){
fossil_fatal("no checkout rename files in");
}
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
294 295 296 297 298 299 300 |
** --force|-f necessary to close a check out with uncommitted changes
**
** See also: open
*/
void close_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
db_must_be_within_tree();
| | | | 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 |
** --force|-f necessary to close a check out with uncommitted changes
**
** See also: open
*/
void close_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
db_must_be_within_tree();
/* We should be done with options.. */
verify_all_options();
if( !forceFlag && unsaved_changes(0) ){
fossil_fatal("there are unsaved changes in the current checkout");
}
if( !forceFlag
&& db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='stash'",
db_name("localdb"))
&& db_exists("SELECT 1 FROM %s.stash", db_name("localdb"))
){
fossil_fatal("closing the checkout will delete your stash");
}
if( db_is_writeable("repository") ){
char *zUnset = mprintf("ckout:%q", g.zLocalRoot);
db_unset(zUnset, 1);
fossil_free(zUnset);
}
unlink_local_database(1);
db_close(1);
unlink_local_database(0);
}
|
Changes to src/db.c.
| ︙ | ︙ | |||
626 627 628 629 630 631 632 | /* ** Execute a query. Return the first column of the first row ** of the result set as a string. Space to hold the string is ** obtained from malloc(). If the result set is empty, return ** zDefault instead. */ | | | 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 |
/*
** Execute a query. Return the first column of the first row
** of the result set as a string. Space to hold the string is
** obtained from malloc(). If the result set is empty, return
** zDefault instead.
*/
char *db_text(const char *zDefault, const char *zSql, ...){
va_list ap;
Stmt s;
char *z;
va_start(ap, zSql);
db_vprepare(&s, 0, zSql, ap);
va_end(ap);
if( db_step(&s)==SQLITE_ROW ){
|
| ︙ | ︙ | |||
1480 1481 1482 1483 1484 1485 1486 |
const char *zDate; /* Date of the initial check-in */
const char *zDefaultUser; /* Optional name of the default user */
zTemplate = find_option("template",0,1);
zDate = find_option("date-override",0,1);
zDefaultUser = find_option("admin-user","A",1);
find_option("empty", 0, 0); /* deprecated */
| | | 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 |
const char *zDate; /* Date of the initial check-in */
const char *zDefaultUser; /* Optional name of the default user */
zTemplate = find_option("template",0,1);
zDate = find_option("date-override",0,1);
zDefaultUser = find_option("admin-user","A",1);
find_option("empty", 0, 0); /* deprecated */
/* We should be done with options.. */
verify_all_options();
if( g.argc!=3 ){
usage("REPOSITORY-NAME");
}
db_create_repository(g.argv[2]);
|
| ︙ | ︙ | |||
1937 1938 1939 1940 1941 1942 1943 | } /* ** Returns non-0 if the database (which must be open) table identified ** by zTableName has a column named zColName (case-sensitive), else ** returns 0. */ | | | | 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 |
}
/*
** Returns non-0 if the database (which must be open) table identified
** by zTableName has a column named zColName (case-sensitive), else
** returns 0.
*/
int db_table_has_column(const char *zTableName, const char *zColName){
Stmt q = empty_Stmt;
int rc = 0;
db_prepare( &q, "PRAGMA table_info(%Q)", zTableName );
while(SQLITE_ROW == db_step(&q)){
/* Columns: (cid, name, type, notnull, dflt_value, pk) */
const char *zCol = db_column_text(&q, 1);
if( 0==fossil_strcmp(zColName, zCol) ){
rc = 1;
break;
}
}
db_finalize(&q);
return rc;
|
| ︙ | ︙ | |||
2038 2039 2040 2041 2042 2043 2044 |
static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
url_proxy_options();
emptyFlag = find_option("empty",0,0)!=0;
keepFlag = find_option("keep",0,0)!=0;
forceMissingFlag = find_option("force-missing",0,0)!=0;
allowNested = find_option("nested",0,0)!=0;
| | | 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 |
static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
url_proxy_options();
emptyFlag = find_option("empty",0,0)!=0;
keepFlag = find_option("keep",0,0)!=0;
forceMissingFlag = find_option("force-missing",0,0)!=0;
allowNested = find_option("nested",0,0)!=0;
/* We should be done with options.. */
verify_all_options();
if( g.argc!=3 && g.argc!=4 ){
usage("REPOSITORY-FILENAME ?VERSION?");
}
if( !allowNested && db_open_local(0) ){
|
| ︙ | ︙ | |||
2142 2143 2144 2145 2146 2147 2148 |
** width is the length for the edit field on the behavior page, 0
** is used for on/off checkboxes.
** The behaviour page doesn't use a special layout. It lists all
** set-commands and displays the 'set'-help as info.
*/
#if INTERFACE
struct stControlSettings {
| | | | | 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 |
** width is the length for the edit field on the behavior page, 0
** is used for on/off checkboxes.
** The behaviour page doesn't use a special layout. It lists all
** set-commands and displays the 'set'-help as info.
*/
#if INTERFACE
struct stControlSettings {
const char *name; /* Name of the setting */
const char *var; /* Internal variable name used by db_set() */
int width; /* Width of display. 0 for boolean values. */
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", },
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
206 207 208 209 210 211 212 | ** Searches for the user ID matching the given name and password. ** On success it returns a positive value. On error it returns 0. ** On serious (DB-level) error it will probably exit. ** ** zPassword may be either the plain-text form or the encrypted ** form of the user's password. */ | | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
** Searches for the user ID matching the given name and password.
** On success it returns a positive value. On error it returns 0.
** On serious (DB-level) error it will probably exit.
**
** zPassword may be either the plain-text form or the encrypted
** form of the user's password.
*/
int login_search_uid(const char *zUsername, const char *zPasswd){
char *zSha1Pw = sha1_shared_secret(zPasswd, zUsername, 0);
int const uid =
db_int(0,
"SELECT uid FROM user"
" WHERE login=%Q"
" AND length(cap)>0 AND length(pw)>0"
" AND login NOT IN ('anonymous','nobody','developer','reader')"
" AND (pw=%Q OR (length(pw)<>40 AND pw=%Q))",
|
| ︙ | ︙ | |||
229 230 231 232 233 234 235 | ** Generates a login cookie value for a non-anonymous user. ** ** The zHash parameter must be a random value which must be ** subsequently stored in user.cookie for later validation. ** ** The returned memory should be free()d after use. */ | | | | | | | 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 |
** Generates a login cookie value for a non-anonymous user.
**
** The zHash parameter must be a random value which must be
** subsequently stored in user.cookie for later validation.
**
** The returned memory should be free()d after use.
*/
char *login_gen_user_cookie_value(const char *zUsername, const char *zHash){
char *zProjCode = db_get("project-code",NULL);
char *zCode = abbreviated_project_code(zProjCode);
free(zProjCode);
assert((zUsername && *zUsername) && "Invalid user data.");
return mprintf("%s/%z/%s", zHash, zCode, zUsername);
}
/*
** Generates a login cookie for NON-ANONYMOUS users. Note that this
** function "could" figure out the uid by itself but it currently
** doesn't because the code which calls this already has the uid.
**
** This function also updates the user.cookie, user.ipaddr,
** and user.cexpire fields for the given user.
**
** If zDest is not NULL then the generated cookie is copied to
** *zDdest and ownership is transfered to the caller (who should
** eventually pass it to free()).
*/
void login_set_user_cookie(
const char *zUsername, /* User's name */
int uid, /* User's ID */
char **zDest /* Optional: store generated cookie value. */
){
const char *zCookieName = login_cookie_name();
const char *zExpire = db_get("cookie-expire","8766");
int expires = atoi(zExpire)*3600;
char *zHash;
char *zCookie;
const char *zIpAddr = PD("REMOTE_ADDR","nil"); /* IP address of user */
char *zRemoteAddr = ipPrefix(zIpAddr); /* Abbreviated IP address */
assert((zUsername && *zUsername) && (uid > 0) && "Invalid user data.");
zHash = db_text(0,
"SELECT cookie FROM user"
" WHERE uid=%d"
" AND ipaddr=%Q"
|
| ︙ | ︙ | |||
301 302 303 304 305 306 307 | ** ** If either zIpAddr or zRemoteAddr are NULL then REMOTE_ADDR ** is used. ** ** If zCookieDest is not NULL then the generated cookie is assigned to ** *zCookieDest and the caller must eventually free() it. */ | | | | | | 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 |
**
** If either zIpAddr or zRemoteAddr are NULL then REMOTE_ADDR
** is used.
**
** If zCookieDest is not NULL then the generated cookie is assigned to
** *zCookieDest and the caller must eventually free() it.
*/
void login_set_anon_cookie(const char *zIpAddr, char **zCookieDest ){
const char *zNow; /* Current time (julian day number) */
char *zCookie; /* The login cookie */
const char *zCookieName; /* Name of the login cookie */
Blob b; /* Blob used during cookie construction */
char *zRemoteAddr; /* Abbreviated IP address */
if(!zIpAddr){
zIpAddr = PD("REMOTE_ADDR","nil");
}
zRemoteAddr = ipPrefix(zIpAddr);
zCookieName = login_cookie_name();
zNow = db_text("0", "SELECT julianday('now')");
assert( zCookieName && zRemoteAddr && zIpAddr && zNow );
|
| ︙ | ︙ | |||
342 343 344 345 346 347 348 |
**
** This is a no-op if g.userUid is 0.
*/
void login_clear_login_data(){
if(!g.userUid){
return;
}else{
| | | 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 |
**
** This is a no-op if g.userUid is 0.
*/
void login_clear_login_data(){
if(!g.userUid){
return;
}else{
const char *cookie = login_cookie_name();
/* To logout, change the cookie value to an empty string */
cgi_set_cookie(cookie, "",
login_cookie_path(), -86400);
db_multi_exec("UPDATE user SET cookie=NULL, ipaddr=NULL, "
" cexpire=0 WHERE uid=%d"
" AND login NOT IN ('anonymous','nobody',"
" 'developer','reader')", g.userUid);
|
| ︙ | ︙ | |||
627 628 629 630 631 632 633 |
@ the login to take.</p>
if( db_get_boolean("self-register", 0) ){
@ <p>If you do not have an account, you can
@ <a href="%s(g.zTop)/register?g=%T(P("G"))">create one</a>.
}
if( zAnonPw ){
unsigned int uSeed = captcha_seed();
| | | 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 |
@ the login to take.</p>
if( db_get_boolean("self-register", 0) ){
@ <p>If you do not have an account, you can
@ <a href="%s(g.zTop)/register?g=%T(P("G"))">create one</a>.
}
if( zAnonPw ){
unsigned int uSeed = captcha_seed();
const char *zDecoded = captcha_decode(uSeed);
int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
char *zCaptcha = captcha_render(zDecoded);
@ <p><input type="hidden" name="cs" value="%u(uSeed)" />
@ Visitors may enter <b>anonymous</b> as the user-ID with
@ the 8-character hexadecimal password shown below:</p>
@ <div class="captcha"><table class="captcha"><tr><td><pre>
|
| ︙ | ︙ | |||
1234 1235 1236 1237 1238 1239 1240 |
**
** Generate the register page.
**
*/
void register_page(void){
const char *zUsername, *zPasswd, *zConfirm, *zContact, *zCS, *zPw, *zCap;
unsigned int uSeed;
| | | 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 |
**
** Generate the register page.
**
*/
void register_page(void){
const char *zUsername, *zPasswd, *zConfirm, *zContact, *zCS, *zPw, *zCap;
unsigned int uSeed;
const char *zDecoded;
char *zCaptcha;
if( !db_get_boolean("self-register", 0) ){
style_header("Registration not possible");
@ <p>This project does not allow user self-registration. Please contact the
@ project administrator to obtain an account.</p>
style_footer();
return;
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
227 228 229 230 231 232 233 |
responses and always exit() with
code 0 to avoid an HTTP 500 error.
*/
int resultCode; /* used for passing back specific codes
** from /json callbacks. */
int errorDetailParanoia; /* 0=full error codes, 1=%10, 2=%100, 3=%1000 */
cson_output_opt outOpt; /* formatting options for JSON mode. */
| | | | | | | | | | | | | | | | 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 |
responses and always exit() with
code 0 to avoid an HTTP 500 error.
*/
int resultCode; /* used for passing back specific codes
** from /json callbacks. */
int errorDetailParanoia; /* 0=full error codes, 1=%10, 2=%100, 3=%1000 */
cson_output_opt outOpt; /* formatting options for JSON mode. */
cson_value *authToken; /* authentication token */
const char *jsonp; /* Name of JSONP function wrapper. */
unsigned char dispatchDepth /* Tells JSON command dispatching
which argument we are currently
working on. For this purpose, arg#0
is the "json" path/CLI arg.
*/;
struct { /* "garbage collector" */
cson_value *v;
cson_array *a;
} gc;
struct { /* JSON POST data. */
cson_value *v;
cson_array *a;
int offset; /* Tells us which PATH_INFO/CLI args
part holds the "json" command, so
that we can account for sub-repos
and path prefixes. This is handled
differently for CLI and CGI modes.
*/
const char *commandStr /*"command" request param.*/;
} cmd;
struct { /* JSON POST data. */
cson_value *v;
cson_object *o;
} post;
struct { /* GET/COOKIE params in JSON mode. */
cson_value *v;
cson_object *o;
} param;
struct {
cson_value *v;
cson_object *o;
} reqPayload; /* request payload object (if any) */
cson_array *warnings; /* response warnings */
int timerId; /* fetched from fossil_timer_start() */
} json;
#endif /* FOSSIL_ENABLE_JSON */
};
/*
** Macro for debugging:
|
| ︙ | ︙ | |||
389 390 391 392 393 394 395 | Blob file = empty_blob; /* Content of the file */ Blob line = empty_blob; /* One line of the file */ unsigned int nLine; /* Number of lines in the file*/ unsigned int i, j, k; /* Loop counters */ int n; /* Number of bytes in one line */ char *z; /* General use string pointer */ char **newArgv; /* New expanded g.argv under construction */ | | | 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | Blob file = empty_blob; /* Content of the file */ Blob line = empty_blob; /* One line of the file */ unsigned int nLine; /* Number of lines in the file*/ unsigned int i, j, k; /* Loop counters */ int n; /* Number of bytes in one line */ char *z; /* General use string pointer */ char **newArgv; /* New expanded g.argv under construction */ const char *zFileName; /* input file name */ FILE *inFile; /* input FILE */ #if defined(_WIN32) wchar_t buf[MAX_PATH]; #endif g.argc = argc; g.argv = argv; |
| ︙ | ︙ | |||
1002 1003 1004 1005 1006 1007 1008 |
** %fossil help --t|-test Show test commands only
** %fossil help --x|-aux Show auxiliary commands only
** %fossil help --w|-www Show list of WWW pages
*/
void help_cmd(void){
int rc, idx, isPage = 0;
const char *z;
| | | | 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 |
** %fossil help --t|-test Show test commands only
** %fossil help --x|-aux Show auxiliary commands only
** %fossil help --w|-www Show list of WWW pages
*/
void help_cmd(void){
int rc, idx, isPage = 0;
const char *z;
const char *zCmdOrPage;
const char *zCmdOrPagePlural;
if( g.argc<3 ){
z = g.argv[0];
fossil_print(
"Usage: %s help COMMAND\n"
"Common COMMANDs: (use \"%s help -a|--all\" for a complete list)\n",
z, z);
command_list(0, CMDFLAG_1ST_TIER);
|
| ︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 |
}
/*
** WEBPAGE: help
** URL: /help/CMD
*/
void help_page(void){
| | | | 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 |
}
/*
** WEBPAGE: help
** URL: /help/CMD
*/
void help_page(void){
const char *zCmd = P("cmd");
if( zCmd==0 ) zCmd = P("name");
style_header("Command-line Help");
if( zCmd ){
int rc, idx;
char *z, *s, *d;
const char *zCmdOrPage = ('/'==*zCmd) ? "page" : "command";
style_submenu_element("Command-List", "Command-List", "%s/help", g.zTop);
@ <h1>The "%s(zCmd)" %s(zCmdOrPage):</h1>
rc = name_search(zCmd, aCommand, count(aCommand), 0, &idx);
if( rc==1 ){
@ unknown command: %s(zCmd)
}else if( rc==2 ){
@ ambiguous command prefix: %s(zCmd)
|
| ︙ | ︙ | |||
2120 2121 2122 2123 2124 2125 2126 |
zPort = find_option("port", "P", 1);
zNotFound = find_option("notfound", 0, 1);
zAltBase = find_option("baseurl", 0, 1);
if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI;
if( zAltBase ){
set_base_url(zAltBase);
}
| | | 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 |
zPort = find_option("port", "P", 1);
zNotFound = find_option("notfound", 0, 1);
zAltBase = find_option("baseurl", 0, 1);
if( find_option("scgi", 0, 0)!=0 ) flags |= HTTP_SERVER_SCGI;
if( zAltBase ){
set_base_url(zAltBase);
}
if( find_option("localhost", 0, 0)!=0 ){
flags |= HTTP_SERVER_LOCALHOST;
}
/* We should be done with options.. */
verify_all_options();
if( g.argc!=2 && g.argc!=3 ) usage("?REPOSITORY?");
|
| ︙ | ︙ |
Changes to src/merge3.c.
| ︙ | ︙ | |||
134 135 136 137 138 139 140 | } return i; } /* ** Text of boundary markers for merge conflicts. */ | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
}
return i;
}
/*
** Text of boundary markers for merge conflicts.
*/
static const char *const mergeMarker[] = {
/*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
"<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<\n",
"======= COMMON ANCESTOR content follows ============================\n",
"======= MERGED IN content follows ==================================\n",
">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n"
};
|
| ︙ | ︙ | |||
366 367 368 369 370 371 372 |
** cp Xup.c Xbase.c
** # Verify that everything still works
** fossil commit
**
*/
void delta_3waymerge_cmd(void){
Blob pivot, v1, v2, merged;
| | | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 |
** cp Xup.c Xbase.c
** # Verify that everything still works
** fossil commit
**
*/
void delta_3waymerge_cmd(void){
Blob pivot, v1, v2, merged;
/* We should be done with options.. */
verify_all_options();
if( g.argc!=6 ){
usage("PIVOT V1 V2 MERGED");
}
if( blob_read_from_file(&pivot, g.argv[2])<0 ){
|
| ︙ | ︙ |
Changes to src/report.c.
| ︙ | ︙ | |||
1110 1111 1112 1113 1114 1115 1116 |
/*
** show all reports, which can be used for ticket show.
** Output is written to stdout as tab delimited table
*/
void rpt_list_reports(void){
Stmt q;
| | | 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 |
/*
** show all reports, which can be used for ticket show.
** Output is written to stdout as tab delimited table
*/
void rpt_list_reports(void){
Stmt q;
const char aRptOutFrmt[] = "%s\t%s\n";
fossil_print("Available reports:\n");
fossil_print(aRptOutFrmt,"report number","report title");
fossil_print(aRptOutFrmt,zFullTicketRptRn,zFullTicketRptTitle);
db_prepare(&q,"SELECT rn,title FROM reportfmt ORDER BY rn");
while( db_step(&q)==SQLITE_ROW ){
const char *zRn = db_column_text(&q, 0);
|
| ︙ | ︙ | |||
1215 1216 1217 1218 1219 1220 1221 | Stmt q; char *zSql; char *zErr1 = 0; char *zErr2 = 0; int count = 0; int rn; | | | 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 |
Stmt q;
char *zSql;
char *zErr1 = 0;
char *zErr2 = 0;
int count = 0;
int rn;
if( !zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){
zSql = "SELECT * FROM ticket";
}else{
rn = atoi(zRep);
if( rn ){
db_prepare(&q,
"SELECT sqlcode FROM reportfmt WHERE rn=%d", rn);
}else{
|
| ︙ | ︙ |
Changes to src/tag.c.
| ︙ | ︙ | |||
48 49 50 51 52 53 54 | pqueuex_init(&queue); pqueuex_insert(&queue, pid, 0.0, 0); /* Query for children of :pid to which to propagate the tag. ** Three returns: (1) rid of the child. (2) timestamp of child. ** (3) True to propagate or false to block. */ | | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
pqueuex_init(&queue);
pqueuex_insert(&queue, pid, 0.0, 0);
/* Query for children of :pid to which to propagate the tag.
** Three returns: (1) rid of the child. (2) timestamp of child.
** (3) True to propagate or false to block.
*/
db_prepare(&s,
"SELECT cid, plink.mtime,"
" coalesce(srcid=0 AND tagxref.mtime<:mtime, %d) AS doit"
" FROM plink LEFT JOIN tagxref ON cid=rid AND tagid=%d"
" WHERE pid=:pid AND isprim",
tagType==2, tagid
);
db_bind_double(&s, ":mtime", mtime);
|
| ︙ | ︙ | |||
177 178 179 180 181 182 183 |
db_bind_double(&s, ":mtime", mtime);
rc = db_step(&s);
db_finalize(&s);
if( rc==SQLITE_ROW ){
/* Another entry that is more recent already exists. Do nothing */
return tagid;
}
| | | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
db_bind_double(&s, ":mtime", mtime);
rc = db_step(&s);
db_finalize(&s);
if( rc==SQLITE_ROW ){
/* Another entry that is more recent already exists. Do nothing */
return tagid;
}
db_prepare(&s,
"REPLACE INTO tagxref(tagid,tagtype,srcId,origid,value,mtime,rid)"
" VALUES(%d,%d,%d,%d,%Q,:mtime,%d)",
tagid, tagtype, srcId, rid, zValue, rid
);
db_bind_double(&s, ":mtime", mtime);
db_step(&s);
db_finalize(&s);
|
| ︙ | ︙ | |||
254 255 256 257 258 259 260 |
usage("TAGNAME ARTIFACT-ID ?VALUE?");
}
zTag = g.argv[2];
switch( zTag[0] ){
case '+': tagtype = 1; break;
case '*': tagtype = 2; break;
case '-': tagtype = 0; break;
| | | 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 |
usage("TAGNAME ARTIFACT-ID ?VALUE?");
}
zTag = g.argv[2];
switch( zTag[0] ){
case '+': tagtype = 1; break;
case '*': tagtype = 2; break;
case '-': tagtype = 0; break;
default:
fossil_fatal("tag should begin with '+', '*', or '-'");
return;
}
rid = name_to_rid(g.argv[3]);
if( rid==0 ){
fossil_fatal("no such object: %s", g.argv[3]);
}
|
| ︙ | ︙ | |||
376 377 378 379 380 381 382 | ** will be taken as an artifact or baseline ID and fossil will ** probably complain that no such revision was found. However ** ** fossil update tag:decaf ** ** will assume that "decaf" is a tag/branch name. ** | | | | | | 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 |
** will be taken as an artifact or baseline ID and fossil will
** probably complain that no such revision was found. However
**
** fossil update tag:decaf
**
** will assume that "decaf" is a tag/branch name.
**
** only allow --date-override and --user-override in
** %fossil tag add --date-override 'YYYY-MMM-DD HH:MM:SS' \\
** --user-override user
** in order to import history from other scm systems
*/
void tag_cmd(void){
int n;
int fRaw = find_option("raw","",0)!=0;
int fPropagate = find_option("propagate","",0)!=0;
const char *zPrefix = fRaw ? "" : "sym-";
const char *zFindLimit = find_option("limit","n",1);
const int nFindLimit = zFindLimit ? atoi(zFindLimit) : -2000;
db_find_and_open_repository(0, 0);
if( g.argc<3 ){
goto tag_cmd_usage;
}
n = strlen(g.argv[2]);
if( n==0 ){
|
| ︙ | ︙ | |||
476 477 478 479 480 481 482 |
}
}
}else
if( strncmp(g.argv[2],"list",n)==0 ){
Stmt q;
if( g.argc==3 ){
| | | 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 |
}
}
}else
if( strncmp(g.argv[2],"list",n)==0 ){
Stmt q;
if( g.argc==3 ){
db_prepare(&q,
"SELECT tagname FROM tag"
" WHERE EXISTS(SELECT 1 FROM tagxref"
" WHERE tagid=tag.tagid"
" AND tagtype>0)"
" ORDER BY tagname"
);
while( db_step(&q)==SQLITE_ROW ){
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
1967 1968 1969 1970 1971 1972 1973 | */ static int statsReportType = 0; /* ** Set by stats_report_init_view() to one of the y=XXXX values ** accepted by /timeline?y=XXXX. */ | | | | | 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 |
*/
static int statsReportType = 0;
/*
** Set by stats_report_init_view() to one of the y=XXXX values
** accepted by /timeline?y=XXXX.
*/
static const char *statsReportTimelineYFlag = NULL;
/*
** Creates a TEMP VIEW named v_reports which is a wrapper around the
** EVENT table filtered on event.type. It looks for the request
** parameter 'type' (reminder: we "should" use 'y' for consistency
** with /timeline, but /reports uses 'y' for the year) and expects it
** to contain one of the conventional values from event.type or the
** value "all", which is treated as equivalent to "*". By default (if
** no 'y' is specified), "*" is assumed (that is also the default for
** invalid/unknown filter values). That 'y' filter is the one used for
** the event list. Note that a filter of "*" or "all" is equivalent to
** querying against the full event table. The view, however, adds an
** abstraction level to simplify the implementation code for the
** various /reports pages.
**
** Returns one of: 'c', 'w', 'g', 't', 'e', representing the type of
** filter it applies, or '*' if no filter is applied (i.e. if "all" is
** used).
*/
static int stats_report_init_view(){
const char *zType = PD("type","*"); /* analog to /timeline?y=... */
const char *zRealType = NULL; /* normalized form of zType */
int rc = 0; /* result code */
assert( !statsReportType && "Must not be called more than once." );
switch( (zType && *zType) ? *zType : 0 ){
case 'c':
case 'C':
zRealType = "ci";
rc = *zRealType;
|
| ︙ | ︙ | |||
2042 2043 2044 2045 2046 2047 2048 | /* ** Returns a string suitable (for a given value of suitable) for ** use in a label with the header of the /reports pages, dependent ** on the 'type' flag. See stats_report_init_view(). ** The returned bytes are static. */ | | | 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 |
/*
** Returns a string suitable (for a given value of suitable) for
** use in a label with the header of the /reports pages, dependent
** on the 'type' flag. See stats_report_init_view().
** The returned bytes are static.
*/
static const char *stats_report_label_for_type(){
assert( statsReportType && "Must call stats_report_init_view() first." );
switch( statsReportType ){
case 'c':
return "checkins";
case 'e':
return "events";
case 'w':
|
| ︙ | ︙ | |||
2069 2070 2071 2072 2073 2074 2075 | ** of links for the various type=XXX flags. zCurrentViewName must be ** the name/value of the 'view' parameter which is in effect at the ** time this is called. e.g. if called from the 'byuser' view then ** zCurrentViewName must be "byuser". Any URL parameters which need to ** be added to the generated URLs should be passed in zParam. The ** caller is expected to have already encoded any zParam in the %T or ** %t encoding. */ | | | | | 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 |
** of links for the various type=XXX flags. zCurrentViewName must be
** the name/value of the 'view' parameter which is in effect at the
** time this is called. e.g. if called from the 'byuser' view then
** zCurrentViewName must be "byuser". Any URL parameters which need to
** be added to the generated URLs should be passed in zParam. The
** caller is expected to have already encoded any zParam in the %T or
** %t encoding. */
static void stats_report_event_types_menu(const char *zCurrentViewName,
const char *zParam){
char *zTop;
if(zParam && !*zParam){
zParam = NULL;
}
zTop = mprintf("%s/reports?view=%s%s%s", g.zTop, zCurrentViewName,
zParam ? "&" : "", zParam);
cgi_printf("<div>");
cgi_printf("<span>Types:</span> ");
|
| ︙ | ︙ | |||
2119 2120 2121 2122 2123 2124 2125 | /* ** Helper for stats_report_by_month_year(), which generates a list of ** week numbers. zTimeframe should be either a timeframe in the form YYYY ** or YYYY-MM. */ | | | | | | 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 |
/*
** Helper for stats_report_by_month_year(), which generates a list of
** week numbers. zTimeframe should be either a timeframe in the form YYYY
** or YYYY-MM.
*/
static void stats_report_output_week_links(const char *zTimeframe){
Stmt stWeek = empty_Stmt;
char yearPart[5] = {0,0,0,0,0};
memcpy(yearPart, zTimeframe, 4);
db_prepare(&stWeek,
"SELECT DISTINCT strftime('%%W',mtime) AS wk, "
"count(*) AS n, "
"substr(date(mtime),1,%d) AS ym "
"FROM v_reports "
"WHERE ym=%Q AND mtime < current_timestamp "
"GROUP BY wk ORDER BY wk",
strlen(zTimeframe),
zTimeframe);
while( SQLITE_ROW == db_step(&stWeek) ){
const char *zWeek = db_column_text(&stWeek,0);
const int nCount = db_column_int(&stWeek,1);
cgi_printf("<a href='%s/timeline?"
"yw=%t-%t&n=%d&y=%s'>%s</a>",
g.zTop, yearPart, zWeek,
nCount, statsReportTimelineYFlag, zWeek);
}
db_finalize(&stWeek);
}
/*
** Implements the "byyear" and "bymonth" reports for /reports.
** If includeMonth is true then it generates the "bymonth" report,
** else the "byyear" report. If zUserName is not NULL and not empty
** then the report is restricted to events created by the named user
** account.
*/
static void stats_report_by_month_year(char includeMonth,
char includeWeeks,
const char *zUserName){
Stmt query = empty_Stmt;
int nRowNumber = 0; /* current TR number */
int nEventTotal = 0; /* Total event count */
int rowClass = 0; /* counter for alternating
row colors */
Blob sql = empty_blob; /* SQL */
const char *zTimeLabel = includeMonth ? "Year/Month" : "Year";
char zPrevYear[5] = {0}; /* For keeping track of when
we change years while looping */
int nEventsPerYear = 0; /* Total event count for the
current year */
char showYearTotal = 0; /* Flag telling us when to show
the per-year event totals */
Blob header = empty_blob; /* Page header text */
|
| ︙ | ︙ | |||
2214 2215 2216 2217 2218 2219 2220 |
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
++iterations;
}
db_reset(&query);
while( SQLITE_ROW == db_step(&query) ){
| | | 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 |
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
++iterations;
}
db_reset(&query);
while( SQLITE_ROW == db_step(&query) ){
const char *zTimeframe = db_column_text(&query, 0);
const int nCount = db_column_int(&query, 1);
int nSize = nCount
? (int)(100 * nCount / nMaxEvents)
: 1;
showYearTotal = 0;
if(!nSize) nSize = 1;
if(includeMonth){
|
| ︙ | ︙ | |||
2299 2300 2301 2302 2303 2304 2305 |
@ <tr class='row%d(rowClass)'>
@ <td></td>
@ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td>
@</tr>
}
@ </tbody></table>
if(nEventTotal){
| | | 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 |
@ <tr class='row%d(rowClass)'>
@ <td></td>
@ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td>
@</tr>
}
@ </tbody></table>
if(nEventTotal){
const char *zAvgLabel = includeMonth ? "month" : "year";
int nAvg = iterations ? (nEventTotal/iterations) : 0;
@ <br><div>Total events: %d(nEventTotal)
@ <br>Average per active %s(zAvgLabel): %d(nAvg)
@ </div>
}
if( !includeMonth ){
output_table_sorting_javascript("statsTable","tnx");
|
| ︙ | ︙ | |||
2349 2350 2351 2352 2353 2354 2355 |
const int nCount = db_column_int(&query, 1);
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
}
db_reset(&query);
while( SQLITE_ROW == db_step(&query) ){
| | | 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 |
const int nCount = db_column_int(&query, 1);
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
}
db_reset(&query);
while( SQLITE_ROW == db_step(&query) ){
const char *zUser = db_column_text(&query, 0);
const int nCount = db_column_int(&query, 1);
int nSize = nCount
? (int)(100 * nCount / nMaxEvents)
: 0;
if(!nCount) continue /* arguable! Possible? */;
else if(!nSize) nSize = 1;
rowClass = ++nRowNumber % 2;
|
| ︙ | ︙ | |||
2389 2390 2391 2392 2393 2394 2395 |
int nRowNumber = 0; /* current TR number */
int nEventTotal = 0; /* Total event count */
int rowClass = 0; /* counter for alternating
row colors */
Blob sql = empty_blob; /* SQL */
int nMaxEvents = 1; /* max number of events for
all rows. */
| | | 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 |
int nRowNumber = 0; /* current TR number */
int nEventTotal = 0; /* Total event count */
int rowClass = 0; /* counter for alternating
row colors */
Blob sql = empty_blob; /* SQL */
int nMaxEvents = 1; /* max number of events for
all rows. */
static const char *const daysOfWeek[] = {
"Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday"
};
stats_report_init_view();
stats_report_event_types_menu("byweekday", NULL);
blob_append(&sql,
|
| ︙ | ︙ | |||
2422 2423 2424 2425 2426 2427 2428 |
const int nCount = db_column_int(&query, 1);
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
}
db_reset(&query);
while( SQLITE_ROW == db_step(&query) ){
| | | 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 |
const int nCount = db_column_int(&query, 1);
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
}
db_reset(&query);
while( SQLITE_ROW == db_step(&query) ){
const int dayNum =db_column_int(&query, 0);
const int nCount = db_column_int(&query, 1);
int nSize = nCount
? (int)(100 * nCount / nMaxEvents)
: 0;
if(!nCount) continue /* arguable! Possible? */;
else if(!nSize) nSize = 1;
rowClass = ++nRowNumber % 2;
|
| ︙ | ︙ | |||
2452 2453 2454 2455 2456 2457 2458 | /* ** Helper for stats_report_by_month_year(), which generates a list of ** week numbers. zTimeframe should be either a timeframe in the form YYYY ** or YYYY-MM. */ | | | | | 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 |
/*
** Helper for stats_report_by_month_year(), which generates a list of
** week numbers. zTimeframe should be either a timeframe in the form YYYY
** or YYYY-MM.
*/
static void stats_report_year_weeks(const char *zUserName){
const char *zYear = P("y");
int nYear = zYear ? strlen(zYear) : 0;
int i = 0;
Stmt qYears = empty_Stmt;
char *zDefaultYear = NULL;
Blob sql = empty_blob;
int nMaxEvents = 1; /* max number of events for
all rows. */
int iterations = 0; /* # of active time periods. */
stats_report_init_view();
if(4==nYear){
Blob urlParams = empty_blob;
|
| ︙ | ︙ | |||
2482 2483 2484 2485 2486 2487 2488 |
blob_appendf(&sql,"AND user=%Q ", zUserName);
}
blob_append(&sql,"GROUP BY y ORDER BY y", -1);
db_prepare(&qYears, blob_str(&sql));
blob_reset(&sql);
cgi_printf("Select year: ");
while( SQLITE_ROW == db_step(&qYears) ){
| | | 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 |
blob_appendf(&sql,"AND user=%Q ", zUserName);
}
blob_append(&sql,"GROUP BY y ORDER BY y", -1);
db_prepare(&qYears, blob_str(&sql));
blob_reset(&sql);
cgi_printf("Select year: ");
while( SQLITE_ROW == db_step(&qYears) ){
const char *zT = db_column_text(&qYears, 0);
if( i++ ){
cgi_printf(" ");
}
cgi_printf("<a href='?view=byweek&y=%s&type=%c", zT,
(char)statsReportType);
if(zUserName && *zUserName){
cgi_printf("&user=%t",zUserName);
|
| ︙ | ︙ | |||
2542 2543 2544 2545 2546 2547 2548 |
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
++iterations;
}
db_reset(&stWeek);
while( SQLITE_ROW == db_step(&stWeek) ){
| | | 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 |
if(nCount>nMaxEvents){
nMaxEvents = nCount;
}
++iterations;
}
db_reset(&stWeek);
while( SQLITE_ROW == db_step(&stWeek) ){
const char *zWeek = db_column_text(&stWeek,0);
const int nCount = db_column_int(&stWeek,1);
int nSize = nCount
? (int)(100 * nCount / nMaxEvents)
: 0;
if(!nSize) nSize = 1;
total += nCount;
cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
|
| ︙ | ︙ | |||
2602 2603 2604 2605 2606 2607 2608 |
** view=byweek:
**
** y=YYYY The year to report (default is the server's
** current year).
*/
void stats_report_page(){
HQuery url; /* URL for various branch links */
| | | 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 |
** view=byweek:
**
** y=YYYY The year to report (default is the server's
** current year).
*/
void stats_report_page(){
HQuery url; /* URL for various branch links */
const char *zView = P("view"); /* Which view/report to show. */
const char *zUserName = P("user");
login_check_credentials();
if( !g.perm.Read ){ login_needed(); return; }
if(!zUserName) zUserName = P("u");
url_initialize(&url, "reports");
if(zUserName && *zUserName){
|
| ︙ | ︙ |
Changes to src/unicode.c.
| ︙ | ︙ | |||
206 207 208 209 210 211 212 |
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( key>=aDia[iRes] );
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
| < > | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( key>=aDia[iRes] );
return ((c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : (int)aChar[iRes]);
}
/*
** Return true if the argument interpreted as a unicode codepoint
** is a diacritical modifier character.
*/
int unicode_is_diacritic(int c){
|
| ︙ | ︙ |
Changes to src/util.c.
| ︙ | ︙ | |||
293 294 295 296 297 298 299 |
** Returns true (non-0) if the given timer ID (as returned from
** fossil_timer_start() is currently active.
*/
int fossil_timer_is_active( int timerId ){
if(timerId<1 || timerId>FOSSIL_TIMER_COUNT){
return 0;
}else{
| | | 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
** Returns true (non-0) if the given timer ID (as returned from
** fossil_timer_start() is currently active.
*/
int fossil_timer_is_active( int timerId ){
if(timerId<1 || timerId>FOSSIL_TIMER_COUNT){
return 0;
}else{
const int rc = fossilTimerList[timerId-1].id;
assert(!rc || (rc == timerId));
return fossilTimerList[timerId-1].id;
}
}
/*
** Return TRUE if fd is a valid open file descriptor. This only
|
| ︙ | ︙ | |||
315 316 317 318 319 320 321 | #endif } /* ** Returns TRUE if zSym is exactly UUID_SIZE bytes long and contains ** only lower-case ASCII hexadecimal values. */ | | | 315 316 317 318 319 320 321 322 323 324 325 326 |
#endif
}
/*
** Returns TRUE if zSym is exactly UUID_SIZE bytes long and contains
** only lower-case ASCII hexadecimal values.
*/
int fossil_is_uuid(const char *zSym){
return zSym
&& (UUID_SIZE==strlen(zSym))
&& validate16(zSym, UUID_SIZE);
}
|
Changes to src/wiki.c.
| ︙ | ︙ | |||
858 859 860 861 862 863 864 |
** WEBPAGE: wfind
**
** URL: /wfind?title=TITLE
** List all wiki pages whose titles contain the search text
*/
void wfind_page(void){
Stmt q;
| | | 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 |
** WEBPAGE: wfind
**
** URL: /wfind?title=TITLE
** List all wiki pages whose titles contain the search text
*/
void wfind_page(void){
Stmt q;
const char *zTitle;
login_check_credentials();
if( !g.perm.RdWiki ){ login_needed(); return; }
zTitle = PD("title","*");
style_header("Wiki Pages Found");
@ <ul>
db_prepare(&q,
"SELECT substr(tagname, 6, 1000) FROM tag WHERE tagname like 'wiki-%%%q%%'"
|
| ︙ | ︙ | |||
958 959 960 961 962 963 964 | ** ** The content of the new page is given by the blob pContent. ** ** zMimeType specifies the N-card for the wiki page. If it is 0, ** empty, or "text/x-fossil-wiki" (the default format) then it is ** ignored. */ | | | | | 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 |
**
** The content of the new page is given by the blob pContent.
**
** zMimeType specifies the N-card for the wiki page. If it is 0,
** empty, or "text/x-fossil-wiki" (the default format) then it is
** ignored.
*/
int wiki_cmd_commit(const char *zPageName, int isNew, Blob *pContent,
const char *zMimeType){
Blob wiki; /* Wiki page content */
Blob cksum; /* wiki checksum */
int rid; /* artifact ID of parent page */
char *zDate; /* timestamp */
char *zUuid; /* uuid for rid */
rid = db_int(0,
"SELECT x.rid FROM tag t, tagxref x"
" WHERE x.tagid=t.tagid AND t.tagname='wiki-%q'"
" ORDER BY x.mtime DESC LIMIT 1",
zPageName
);
if( rid==0 && !isNew ){
|
| ︙ | ︙ | |||
1056 1057 1058 1059 1060 1061 1062 |
}
n = strlen(g.argv[2]);
if( n==0 ){
goto wiki_cmd_usage;
}
if( strncmp(g.argv[2],"export",n)==0 ){
| | | | 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 |
}
n = strlen(g.argv[2]);
if( n==0 ){
goto wiki_cmd_usage;
}
if( strncmp(g.argv[2],"export",n)==0 ){
const char *zPageName; /* Name of the wiki page to export */
const char *zFile; /* Name of the output file (0=stdout) */
int rid; /* Artifact ID of the wiki page */
int i; /* Loop counter */
char *zBody = 0; /* Wiki page content */
Blob body; /* Wiki page content */
Manifest *pWiki = 0; /* Parsed wiki page content */
if( (g.argc!=4) && (g.argc!=5) ){
usage("export PAGENAME ?FILE?");
|
| ︙ | ︙ | |||
1089 1090 1091 1092 1093 1094 1095 |
blob_append(&body, "\n", 1);
blob_write_to_file(&body, zFile);
blob_reset(&body);
manifest_destroy(pWiki);
return;
}else if( strncmp(g.argv[2],"commit",n)==0
|| strncmp(g.argv[2],"create",n)==0 ){
| | | | 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 |
blob_append(&body, "\n", 1);
blob_write_to_file(&body, zFile);
blob_reset(&body);
manifest_destroy(pWiki);
return;
}else if( strncmp(g.argv[2],"commit",n)==0
|| strncmp(g.argv[2],"create",n)==0 ){
const char *zPageName; /* page name */
Blob content; /* Input content */
int rid;
Manifest *pWiki = 0; /* Parsed wiki page content */
const char *zMimeType = find_option("mimetype", "M", 1);
if( g.argc!=4 && g.argc!=5 ){
usage("commit|create PAGENAME ?FILE? [-mimetype TEXT-FORMAT]");
}
zPageName = g.argv[3];
if( g.argc==4 ){
blob_read_from_channel(&content, stdin, -1);
}else{
|
| ︙ | ︙ |