Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add ability to append to ticket fields from the fossil ticket command |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | venks-emacs |
Files: | files | file ages | folders |
SHA1: |
35d6029a135669d062af6ccc9d0076f1 |
User & Date: | venkat 2011-06-05 00:04:35.220 |
Context
2011-06-05
| ||
00:09 | Fix minor typo in comment ... (check-in: ac7be7fd user: venkat tags: venks-emacs) | |
00:04 | Add ability to append to ticket fields from the fossil ticket command ... (check-in: 35d6029a user: venkat tags: venks-emacs) | |
2011-06-03
| ||
14:24 | Update the built-in SQLite to the latest 3.7.7 alpha. ... (check-in: 9f9047d6 user: drh tags: trunk) | |
2011-05-19
| ||
00:03 | Make update -verbose print even when there's no update required ... (check-in: acfbfe0d user: venkat tags: venks-emacs) | |
Changes
Changes to Makefile.
︙ | ︙ | |||
56 57 58 59 60 61 62 | # TCLSH = tclsh # You should not need to change anything below this line ############################################################################### # # Automatic platform-specific options. | | > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | # TCLSH = tclsh # You should not need to change anything below this line ############################################################################### # # Automatic platform-specific options. HOST_OS_CMD = uname -s HOST_OS = $(HOST_OS_CMD:sh) LIB.SunOS= -lsocket -lnsl LIB += $(LIB.$(HOST_OS)) TCC.DragonFly += -DUSE_PREAD TCC.FreeBSD += -DUSE_PREAD TCC.NetBSD += -DUSE_PREAD |
︙ | ︙ |
Changes to src/add.c.
︙ | ︙ | |||
114 115 116 117 118 119 120 | char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); db_multi_exec( "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" "VALUES(%d,0,0,0,%Q,%d)", vid, zPath, file_isexe(zFullname)); fossil_free(zFullname); } | | | 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); db_multi_exec( "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe)" "VALUES(%d,0,0,0,%Q,%d)", vid, zPath, file_isexe(zFullname)); fossil_free(zFullname); } fossil_print("ADDED %s\n", zPath); return 1; } /* ** Add all files in the sfile temp table. ** ** Automatically exclude the repository file. |
︙ | ︙ | |||
213 214 215 216 217 218 219 | file_canonical_name(g.argv[i], &fullName); zName = blob_str(&fullName); isDir = file_isdir(zName); if( isDir==1 ){ vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore); }else if( isDir==0 ){ fossil_fatal("not found: %s", zName); | | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | file_canonical_name(g.argv[i], &fullName); zName = blob_str(&fullName); isDir = file_isdir(zName); if( isDir==1 ){ vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore); }else if( isDir==0 ){ fossil_fatal("not found: %s", zName); }else if( file_access(zName, R_OK) ){ fossil_fatal("cannot open %s", zName); }else{ char *zTreeName = &zName[nRoot]; db_multi_exec( "INSERT OR IGNORE INTO sfile(x)" " SELECT %Q WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE pathname=%Q)", zTreeName, zTreeName |
︙ | ︙ | |||
278 279 280 281 282 283 284 | zTreeName, zTreeName, zTreeName ); blob_reset(&treeName); } db_prepare(&loop, "SELECT x FROM sfile"); while( db_step(&loop)==SQLITE_ROW ){ | | | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 | zTreeName, zTreeName, zTreeName ); 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;" "DELETE FROM vfile WHERE rid=0 AND deleted;" ); db_end_transaction(0); |
︙ | ︙ | |||
375 376 377 378 379 380 381 | zFile = db_column_text(&q, 0); zPath = db_column_text(&q, 1); if( !file_isfile(zPath) ){ if( !isTest ){ db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile); } | | | | | 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | zFile = db_column_text(&q, 0); zPath = db_column_text(&q, 1); if( !file_isfile(zPath) ){ if( !isTest ){ db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile); } fossil_print("DELETED %s\n", zFile); nDelete++; } } db_finalize(&q); /* show cmmand summary */ fossil_print("added %d files, deleted %d files\n", nAdd, nDelete); db_end_transaction(isTest); } /* ** Rename a single file. ** ** The original name of the file is zOrig. The new filename is zNew. */ static void mv_one_file(int vid, const char *zOrig, const char *zNew){ fossil_print("RENAME %s %s\n", zOrig, zNew); db_multi_exec( "UPDATE vfile SET pathname='%s' WHERE pathname='%s' AND vid=%d", zNew, zOrig, vid ); } /* |
︙ | ︙ |
Changes to src/allrepo.c.
︙ | ︙ | |||
127 128 129 130 131 132 133 | db_prepare(&q, "SELECT DISTINCT substr(name, 6) COLLATE nocase" " FROM global_config" " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1" ); while( db_step(&q)==SQLITE_ROW ){ const char *zFilename = db_column_text(&q, 0); | | | | | | 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 | db_prepare(&q, "SELECT DISTINCT substr(name, 6) COLLATE nocase" " FROM global_config" " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1" ); while( db_step(&q)==SQLITE_ROW ){ const char *zFilename = db_column_text(&q, 0); if( file_access(zFilename, 0) ){ nMissing++; continue; } if( !file_is_canonical(zFilename) ) nMissing++; if( zCmd[0]=='l' ){ fossil_print("%s\n", zFilename); continue; } zQFilename = quoteFilename(zFilename); zSyscmd = mprintf("%s %s %s", zFossil, zCmd, zQFilename); fossil_print("%s\n", zSyscmd); fflush(stdout); rc = fossil_system(zSyscmd); free(zSyscmd); free(zQFilename); if( stopOnError && rc ){ nMissing = 0; break; } } /* If any repositories whose names appear in the ~/.fossil file could not ** be found, remove those names from the ~/.fossil file. */ if( nMissing ){ db_begin_transaction(); db_reset(&q); while( db_step(&q)==SQLITE_ROW ){ const char *zFilename = db_column_text(&q, 0); if( file_access(zFilename, 0) ){ char *zRepo = mprintf("repo:%s", zFilename); db_unset(zRepo, 1); free(zRepo); }else if( !file_is_canonical(zFilename) ){ Blob cname; char *zRepo = mprintf("repo:%s", zFilename); db_unset(zRepo, 1); |
︙ | ︙ |
Changes to src/bisect.c.
︙ | ︙ | |||
70 71 72 73 74 75 76 | /* ** Return the value of a boolean bisect option. */ int bisect_option(const char *zName){ unsigned int i; int r = -1; for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | /* ** Return the value of a boolean bisect option. */ int bisect_option(const char *zName){ unsigned int i; int r = -1; for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ if( fossil_strcmp(zName, aBisectOption[i].zName)==0 ){ char *zLabel = mprintf("bisect-%s", zName); char *z = db_lget(zLabel, (char*)aBisectOption[i].zDefault); if( is_truth(z) ) r = 1; if( is_false(z) ) r = 0; if( r<0 ) r = is_truth(aBisectOption[i].zDefault); free(zLabel); break; |
︙ | ︙ | |||
135 136 137 138 139 140 141 | n = strlen(zCmd); if( n==0 ) zCmd = "-"; if( memcmp(zCmd, "bad", n)==0 ){ int ridBad; if( g.argc==3 ){ ridBad = db_lget_int("checkout",0); }else{ | | | | 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 | n = strlen(zCmd); if( n==0 ) zCmd = "-"; if( memcmp(zCmd, "bad", n)==0 ){ int ridBad; if( g.argc==3 ){ ridBad = db_lget_int("checkout",0); }else{ ridBad = name_to_typed_rid(g.argv[3], "ci"); } db_lset_int("bisect-bad", ridBad); if( ridBad>0 && bisect_option("auto-next") && db_lget_int("bisect-good",0)>0 ){ zCmd = "next"; n = 4; }else{ return; } }else if( memcmp(zCmd, "good", n)==0 ){ int ridGood; if( g.argc==3 ){ ridGood = db_lget_int("checkout",0); }else{ ridGood = name_to_typed_rid(g.argv[3], "ci"); } db_lset_int("bisect-good", ridGood); if( ridGood>0 && bisect_option("auto-next") && db_lget_int("bisect-bad",0)>0 ){ zCmd = "next"; |
︙ | ︙ | |||
182 183 184 185 186 187 188 | g.fNoSync = 1; update_cmd(); }else if( memcmp(zCmd, "options", n)==0 ){ if( g.argc==3 ){ unsigned int i; for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ char *z = mprintf("bisect-%s", aBisectOption[i].zName); | | | | 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 | g.fNoSync = 1; update_cmd(); }else if( memcmp(zCmd, "options", n)==0 ){ if( g.argc==3 ){ unsigned int i; for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ char *z = mprintf("bisect-%s", aBisectOption[i].zName); fossil_print(" %-15s %-6s ", aBisectOption[i].zName, db_lget(z, (char*)aBisectOption[i].zDefault)); fossil_free(z); comment_print(aBisectOption[i].zDesc, 27, 79); } }else if( g.argc==4 || g.argc==5 ){ unsigned int i; n = strlen(g.argv[3]); for(i=0; i<sizeof(aBisectOption)/sizeof(aBisectOption[0]); i++){ if( memcmp(g.argv[3], aBisectOption[i].zName, n)==0 ){ char *z = mprintf("bisect-%s", aBisectOption[i].zName); if( g.argc==5 ){ db_lset(z, g.argv[4]); } fossil_print("%s\n", db_lget(z, (char*)aBisectOption[i].zDefault)); fossil_free(z); break; } } if( i>=sizeof(aBisectOption)/sizeof(aBisectOption[0]) ){ fossil_fatal("no such bisect option: %s", g.argv[3]); } |
︙ | ︙ | |||
228 229 230 231 232 233 234 | " AND event.type='ci'"); nStep = path_length(); for(p=path_last(), n=0; p; p=p->pFrom, n++){ const char *z; db_bind_int(&s, ":rid", p->rid); if( db_step(&s)==SQLITE_ROW ){ z = db_column_text(&s, 0); | | | | | | | | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | " AND event.type='ci'"); nStep = path_length(); for(p=path_last(), n=0; p; p=p->pFrom, n++){ const char *z; db_bind_int(&s, ":rid", p->rid); if( db_step(&s)==SQLITE_ROW ){ z = db_column_text(&s, 0); fossil_print("%s", z); if( p->rid==bisect.good ) fossil_print(" GOOD"); if( p->rid==bisect.bad ) fossil_print(" BAD"); if( p->rid==vid ) fossil_print(" CURRENT"); if( nStep>1 && n==nStep/2 ) fossil_print(" NEXT"); fossil_print("\n"); } db_reset(&s); } db_finalize(&s); }else{ usage("bad|good|next|reset|vlist ..."); } } |
Changes to src/blob.c.
︙ | ︙ | |||
109 110 111 112 113 114 115 | if( i==' ' || i=='\n' || i=='\t' || i=='\v' || i=='\f' || i=='\r' ){ assert( fossil_isspace((char)i) ); }else{ assert( !fossil_isspace((char)i) ); } } | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | if( i==' ' || i=='\n' || i=='\t' || i=='\v' || i=='\f' || i=='\r' ){ assert( fossil_isspace((char)i) ); }else{ assert( !fossil_isspace((char)i) ); } } fossil_print("All 256 characters OK\n"); } /* ** This routine is called if a blob operation fails because we ** have run out of memory. */ static void blob_panic(void){ |
︙ | ︙ | |||
688 689 690 691 692 693 694 | if( size<0 ){ fossil_fatal("no such file: %s", zFilename); } if( size==0 ){ return 0; } blob_resize(pBlob, size); | | < | | | 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 | if( size<0 ){ fossil_fatal("no such file: %s", zFilename); } if( size==0 ){ return 0; } blob_resize(pBlob, size); in = fossil_fopen(zFilename, "rb"); if( in==0 ){ fossil_panic("cannot open %s for reading", zFilename); } got = fread(blob_buffer(pBlob), 1, size, in); fclose(in); if( got<size ){ blob_resize(pBlob, got); } return got; } /* ** Write the content of a blob into a file. ** ** If the filename is blank or "-" then write to standard output. ** ** Return the number of bytes written. */ int blob_write_to_file(Blob *pBlob, const char *zFilename){ FILE *out; int wrote; if( zFilename[0]==0 || (zFilename[0]=='-' && zFilename[1]==0) ){ fossil_puts(blob_str(pBlob), 0); return blob_size(pBlob); }else{ int i, nName; char *zName, zBuf[1000]; nName = strlen(zFilename); if( nName>=sizeof(zBuf) ){ zName = mprintf("%s", zFilename); |
︙ | ︙ | |||
748 749 750 751 752 753 754 | } #if defined(_WIN32) } #endif zName[i] = '/'; } } | | < | | | 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 | } #if defined(_WIN32) } #endif zName[i] = '/'; } } out = fossil_fopen(zName, "wb"); if( out==0 ){ fossil_fatal_recursive("unable to open file \"%s\" for writing", zName); return 0; } if( zName!=zBuf ) free(zName); } blob_is_init(pBlob); wrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out); fclose(out); if( wrote!=blob_size(pBlob) && out!=stdout ){ fossil_fatal_recursive("short write: %d of %d bytes to %s", wrote, blob_size(pBlob), zFilename); } return wrote; } /* |
︙ | ︙ | |||
923 924 925 926 927 928 929 | if( blob_compare(&b1, &b3) ){ fossil_panic("compress/uncompress cycle failed for %s", g.argv[i]); } blob_reset(&b1); blob_reset(&b2); blob_reset(&b3); } | | | 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 | if( blob_compare(&b1, &b3) ){ fossil_panic("compress/uncompress cycle failed for %s", g.argv[i]); } blob_reset(&b1); blob_reset(&b2); blob_reset(&b3); } fossil_print("ok\n"); } #if defined(_WIN32) /* ** Convert every \n character in the given blob into \r\n. */ void blob_add_cr(Blob *p){ |
︙ | ︙ |
Changes to src/branch.c.
︙ | ︙ | |||
66 67 68 69 70 71 72 | " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%s')", zBranch)!=0 ){ fossil_fatal("branch \"%s\" already exists", zBranch); } user_select(); db_begin_transaction(); | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | " AND tagid=(SELECT tagid FROM tag WHERE tagname='sym-%s')", zBranch)!=0 ){ fossil_fatal("branch \"%s\" already exists", zBranch); } user_select(); db_begin_transaction(); rootid = name_to_typed_rid(g.argv[4], "ci"); if( rootid==0 ){ fossil_fatal("unable to locate check-in off of which to branch"); } pParent = manifest_get(rootid, CFTYPE_MANIFEST); if( pParent==0 ){ fossil_fatal("%s is not a valid check-in", g.argv[4]); |
︙ | ︙ | |||
155 156 157 158 159 160 161 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid); if( manifest_crosslink(brid, &branch)==0 ){ fossil_panic("unable to install new manifest"); } assert( blob_is_reset(&branch) ); content_deltify(rootid, brid, 0); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid); | | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 | db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", brid); if( manifest_crosslink(brid, &branch)==0 ){ fossil_panic("unable to install new manifest"); } assert( blob_is_reset(&branch) ); content_deltify(rootid, brid, 0); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", brid); fossil_print("New branch: %s\n", zUuid); if( g.argc==3 ){ fossil_print( "\n" "Note: the local check-out has not been updated to the new\n" " branch. To begin working on the new branch, do this:\n" "\n" " %s update %s\n", fossil_nameofexe(), zBranch ); |
︙ | ︙ | |||
227 228 229 230 231 232 233 | " AND NOT %z" " ORDER BY value /*sort*/", TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") ); while( db_step(&q)==SQLITE_ROW ){ const char *zBr = db_column_text(&q, 0); int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; | | | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | " AND NOT %z" " ORDER BY value /*sort*/", TAG_BRANCH, leaf_is_closed_sql("tagxref.rid") ); while( db_step(&q)==SQLITE_ROW ){ const char *zBr = db_column_text(&q, 0); int isCur = zCurrent!=0 && fossil_strcmp(zCurrent,zBr)==0; fossil_print("%s%s\n", (isCur ? "* " : " "), zBr); } db_finalize(&q); }else{ fossil_panic("branch subcommand should be one of: " "new list ls"); } } |
︙ | ︙ |
Changes to src/captcha.c.
︙ | ︙ | |||
390 391 392 393 394 395 396 | char *z; for(i=2; i<g.argc; i++){ char zHex[30]; v = (unsigned int)atoi(g.argv[i]); sqlite3_snprintf(sizeof(zHex), zHex, "%x", v); z = captcha_render(zHex); | | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | char *z; for(i=2; i<g.argc; i++){ char zHex[30]; v = (unsigned int)atoi(g.argv[i]); sqlite3_snprintf(sizeof(zHex), zHex, "%x", v); z = captcha_render(zHex); fossil_print("%s:\n%s", zHex, z); free(z); } } /* ** Compute a seed value for a captcha. The seed is public and is sent ** as a hidden parameter with the page that contains the captcha. Knowledge |
︙ | ︙ |
Changes to src/cgi.c.
1 2 3 4 5 6 | /* ** Copyright (c) 2006 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".) | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* ** Copyright (c) 2006 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/ |
︙ | ︙ | |||
189 190 191 192 193 194 195 196 197 198 199 | */ void cgi_set_cookie( const char *zName, /* Name of the cookie */ const char *zValue, /* Value of the cookie. Automatically escaped */ const char *zPath, /* Path cookie applies to. NULL means "/" */ int lifetime /* Expiration of the cookie in seconds from now */ ){ if( zPath==0 ) zPath = g.zTop; if( lifetime>0 ){ lifetime += (int)time(0); blob_appendf(&extraHeader, | > > > > | | | | | 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 | */ void cgi_set_cookie( const char *zName, /* Name of the cookie */ const char *zValue, /* Value of the cookie. Automatically escaped */ const char *zPath, /* Path cookie applies to. NULL means "/" */ int lifetime /* Expiration of the cookie in seconds from now */ ){ char *zSecure = ""; if( zPath==0 ) zPath = g.zTop; if( g.zBaseURL!=0 && strncmp(g.zBaseURL, "https:", 6)==0 ){ zSecure = " secure;"; } if( lifetime>0 ){ lifetime += (int)time(0); blob_appendf(&extraHeader, "Set-Cookie: %s=%t; Path=%s; expires=%z; HttpOnly;%s Version=1\r\n", zName, zValue, zPath, cgi_rfc822_datestamp(lifetime), zSecure); }else{ blob_appendf(&extraHeader, "Set-Cookie: %s=%t; Path=%s; HttpOnly;%s Version=1\r\n", zName, zValue, zPath, zSecure); } } #if 0 /* ** Add an ETag header line */ |
︙ | ︙ | |||
287 288 289 290 291 292 293 294 295 296 297 298 299 300 | }else{ fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus); } if( blob_size(&extraHeader)>0 ){ fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); } if( g.isConst ){ /* constant means that the input URL will _never_ generate anything ** else. In the case of attachments, the contents won't change because ** an attempt to change them generates a new attachment number. In the ** case of most /getfile calls for specific versions, the only way the ** content changes is if someone breaks the SCM. And if that happens, a | > > > > > > > > > > > > > > > > > > | 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | }else{ fprintf(g.httpOut, "Status: %d %s\r\n", iReplyStatus, zReplyStatus); } if( blob_size(&extraHeader)>0 ){ fprintf(g.httpOut, "%s", blob_buffer(&extraHeader)); } /* Add headers to turn on useful security options in browsers. */ fprintf(g.httpOut, "X-Frame-Options: DENY\r\n"); /* This stops fossil pages appearing in frames or iframes, preventing ** click-jacking attacks on supporting browsers. ** ** Other good headers would be ** Strict-Transport-Security: max-age=62208000 ** if we're using https. However, this would break sites which serve different ** content on http and https protocols. Also, ** X-Content-Security-Policy: allow 'self' ** would help mitigate some XSS and data injection attacks, but will break ** deliberate inclusion of external resources, such as JavaScript syntax ** highlighter scripts. ** ** These headers are probably best added by the web server hosting fossil as ** a CGI script. */ if( g.isConst ){ /* constant means that the input URL will _never_ generate anything ** else. In the case of attachments, the contents won't change because ** an attempt to change them generates a new attachment number. In the ** case of most /getfile calls for specific versions, the only way the ** content changes is if someone breaks the SCM. And if that happens, a |
︙ | ︙ | |||
308 309 310 311 312 313 314 | fprintf(g.httpOut, "Cache-control: no-cache, no-store\r\n"); } /* Content intended for logged in users should only be cached in ** the browser, not some shared location. */ fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType); | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | fprintf(g.httpOut, "Cache-control: no-cache, no-store\r\n"); } /* Content intended for logged in users should only be cached in ** the browser, not some shared location. */ fprintf(g.httpOut, "Content-Type: %s; charset=utf-8\r\n", zContentType); if( fossil_strcmp(zContentType,"application/x-fossil")==0 ){ cgi_combine_header_and_body(); blob_compress(&cgiContent[0], &cgiContent[0]); } if( iReplyStatus != 304 ) { total_size = blob_size(&cgiContent[0]) + blob_size(&cgiContent[1]); fprintf(g.httpOut, "Content-Length: %d\r\n", total_size); |
︙ | ︙ | |||
417 418 419 420 421 422 423 | /* ** Replace a parameter with a new value. */ void cgi_replace_parameter(const char *zName, const char *zValue){ int i; for(i=0; i<nUsedQP; i++){ | | | 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 | /* ** Replace a parameter with a new value. */ void cgi_replace_parameter(const char *zName, const char *zValue){ int i; for(i=0; i<nUsedQP; i++){ if( fossil_strcmp(aParamQP[i].zName,zName)==0 ){ aParamQP[i].zValue = zValue; return; } } cgi_set_parameter_nocopy(zName, zValue); } |
︙ | ︙ | |||
679 680 681 682 683 684 685 | z = (char*)P("REMOTE_ADDR"); if( z ) g.zIpAddr = mprintf("%s", z); len = atoi(PD("CONTENT_LENGTH", "0")); g.zContentType = zType = P("CONTENT_TYPE"); if( len>0 && zType ){ blob_zero(&g.cgiIn); | | | | | | | 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 | z = (char*)P("REMOTE_ADDR"); if( z ) g.zIpAddr = mprintf("%s", z); len = atoi(PD("CONTENT_LENGTH", "0")); g.zContentType = zType = P("CONTENT_TYPE"); if( len>0 && zType ){ blob_zero(&g.cgiIn); if( fossil_strcmp(zType,"application/x-www-form-urlencoded")==0 || strncmp(zType,"multipart/form-data",19)==0 ){ z = fossil_malloc( len+1 ); len = fread(z, 1, len, g.httpIn); z[len] = 0; if( zType[0]=='a' ){ add_param_list(z, '&'); }else{ process_multipart_form_data(z, len); } }else if( fossil_strcmp(zType, "application/x-fossil")==0 ){ blob_read_from_channel(&g.cgiIn, g.httpIn, len); blob_uncompress(&g.cgiIn, &g.cgiIn); }else if( fossil_strcmp(zType, "application/x-fossil-debug")==0 ){ blob_read_from_channel(&g.cgiIn, g.httpIn, len); }else if( fossil_strcmp(zType, "application/x-fossil-uncompressed")==0 ){ blob_read_from_channel(&g.cgiIn, g.httpIn, len); } } z = (char*)P("HTTP_COOKIE"); if( z ){ z = mprintf("%s",z); add_param_list(z, ';'); } } /* ** This is the comparison function used to sort the aParamQP[] array of ** query parameters and cookies. */ static int qparam_compare(const void *a, const void *b){ struct QParam *pA = (struct QParam*)a; struct QParam *pB = (struct QParam*)b; int c; c = fossil_strcmp(pA->zName, pB->zName); if( c==0 ){ c = pA->seq - pB->seq; } return c; } /* |
︙ | ︙ | |||
743 744 745 746 747 748 749 | qsort(aParamQP, nUsedQP, sizeof(aParamQP[0]), qparam_compare); sortQP = 0; /* After sorting, remove duplicate parameters. The secondary sort ** key is aParamQP[].seq and we keep the first entry. That means ** with duplicate calls to cgi_set_parameter() the second and ** subsequent calls are effectively no-ops. */ for(i=j=1; i<nUsedQP; i++){ | | | | 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 790 791 792 793 794 795 | qsort(aParamQP, nUsedQP, sizeof(aParamQP[0]), qparam_compare); sortQP = 0; /* After sorting, remove duplicate parameters. The secondary sort ** key is aParamQP[].seq and we keep the first entry. That means ** with duplicate calls to cgi_set_parameter() the second and ** subsequent calls are effectively no-ops. */ for(i=j=1; i<nUsedQP; i++){ if( fossil_strcmp(aParamQP[i].zName,aParamQP[i-1].zName)==0 ){ continue; } if( j<i ){ memcpy(&aParamQP[j], &aParamQP[i], sizeof(aParamQP[j])); } j++; } nUsedQP = j; } /* Do a binary search for a matching query parameter */ lo = 0; hi = nUsedQP-1; while( lo<=hi ){ mid = (lo+hi)/2; c = fossil_strcmp(aParamQP[mid].zName, zName); if( c==0 ){ CGIDEBUG(("mem-match [%s] = [%s]\n", zName, aParamQP[mid].zValue)); return aParamQP[mid].zValue; }else if( c>0 ){ hi = mid-1; }else{ lo = mid+1; |
︙ | ︙ | |||
970 971 972 973 974 975 976 | if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ malformed_request(); } zToken = extract_token(zLine, &z); if( zToken==0 ){ malformed_request(); } | | | | 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 | if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){ malformed_request(); } zToken = extract_token(zLine, &z); if( zToken==0 ){ malformed_request(); } if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0 && fossil_strcmp(zToken,"HEAD")!=0 ){ malformed_request(); } cgi_setenv("GATEWAY_INTERFACE","CGI/1.0"); cgi_setenv("REQUEST_METHOD",zToken); zToken = extract_token(z, &z); if( zToken==0 ){ malformed_request(); |
︙ | ︙ | |||
1011 1012 1013 1014 1015 1016 1017 | while( fossil_isspace(*zVal) ){ zVal++; } i = strlen(zVal); while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; } zVal[i] = 0; for(i=0; zFieldName[i]; i++){ zFieldName[i] = fossil_tolower(zFieldName[i]); } | | | | | | | | | | | 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 | while( fossil_isspace(*zVal) ){ zVal++; } i = strlen(zVal); while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; } zVal[i] = 0; for(i=0; zFieldName[i]; i++){ zFieldName[i] = fossil_tolower(zFieldName[i]); } if( fossil_strcmp(zFieldName,"content-length:")==0 ){ cgi_setenv("CONTENT_LENGTH", zVal); }else if( fossil_strcmp(zFieldName,"content-type:")==0 ){ cgi_setenv("CONTENT_TYPE", zVal); }else if( fossil_strcmp(zFieldName,"cookie:")==0 ){ cgi_setenv("HTTP_COOKIE", zVal); }else if( fossil_strcmp(zFieldName,"https:")==0 ){ cgi_setenv("HTTPS", zVal); }else if( fossil_strcmp(zFieldName,"host:")==0 ){ cgi_setenv("HTTP_HOST", zVal); }else if( fossil_strcmp(zFieldName,"if-none-match:")==0 ){ cgi_setenv("HTTP_IF_NONE_MATCH", zVal); }else if( fossil_strcmp(zFieldName,"if-modified-since:")==0 ){ cgi_setenv("HTTP_IF_MODIFIED_SINCE", zVal); } #if 0 else if( fossil_strcmp(zFieldName,"referer:")==0 ){ cgi_setenv("HTTP_REFERER", zVal); }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){ cgi_setenv("HTTP_USER_AGENT", zVal); } #endif } cgi_init(); } |
︙ | ︙ | |||
1114 1115 1116 1117 1118 1119 1120 | fossil_fatal("unable to open listening socket on any" " port in the range %d..%d", mnPort, mxPort); } } if( iPort>mxPort ) return 1; listen(listener,10); if( iPort>mnPort ){ | | | 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 | fossil_fatal("unable to open listening socket on any" " port in the range %d..%d", mnPort, mxPort); } } if( iPort>mxPort ) return 1; listen(listener,10); if( iPort>mnPort ){ fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); fflush(stdout); } if( zBrowser ){ zBrowser = mprintf(zBrowser, iPort); system(zBrowser); } while( 1 ){ |
︙ | ︙ |
Changes to src/checkin.c.
︙ | ︙ | |||
52 53 54 55 56 57 58 | int isNew = db_column_int(&q,3)==0; int isRenamed = db_column_int(&q,4); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); blob_append(report, zPrefix, nPrefix); if( isDeleted ){ blob_appendf(report, "DELETED %s\n", zPathname); }else if( !file_isfile(zFullName) ){ | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | int isNew = db_column_int(&q,3)==0; int isRenamed = db_column_int(&q,4); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); blob_append(report, zPrefix, nPrefix); if( isDeleted ){ blob_appendf(report, "DELETED %s\n", zPathname); }else if( !file_isfile(zFullName) ){ if( file_access(zFullName, 0)==0 ){ blob_appendf(report, "NOT_A_FILE %s\n", zPathname); if( missingIsFatal ){ fossil_warning("not a file: %s", zPathname); nErr++; } }else{ blob_appendf(report, "MISSING %s\n", zPathname); |
︙ | ︙ | |||
134 135 136 137 138 139 140 | ** --sha1sum Verify file status using SHA1 hashing rather ** than relying on file mtimes. */ void status_cmd(void){ int vid; db_must_be_within_tree(); /* 012345678901234 */ | | | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | ** --sha1sum Verify file status using SHA1 hashing rather ** than relying on file mtimes. */ void status_cmd(void){ int vid; db_must_be_within_tree(); /* 012345678901234 */ fossil_print("repository: %s\n", db_lget("repository","")); fossil_print("local-root: %s\n", g.zLocalRoot); fossil_print("server-code: %s\n", db_get("server-code", "")); vid = db_lget_int("checkout", 0); if( vid ){ show_common_info(vid, "checkout:", 1, 1); } changes_cmd(); } |
︙ | ︙ | |||
174 175 176 177 178 179 180 | const char *zPathname = db_column_text(&q,0); int isDeleted = db_column_int(&q, 1); int isNew = db_column_int(&q,2)==0; int chnged = db_column_int(&q,3); int renamed = db_column_int(&q,4); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); if( isBrief ){ | | | | | | | | | | | 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 | const char *zPathname = db_column_text(&q,0); int isDeleted = db_column_int(&q, 1); int isNew = db_column_int(&q,2)==0; int chnged = db_column_int(&q,3); int renamed = db_column_int(&q,4); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); if( isBrief ){ fossil_print("%s\n", zPathname); }else if( isNew ){ fossil_print("ADDED %s\n", zPathname); }else if( isDeleted ){ fossil_print("DELETED %s\n", zPathname); }else if( !file_isfile(zFullName) ){ if( file_access(zFullName, 0)==0 ){ fossil_print("NOT_A_FILE %s\n", zPathname); }else{ fossil_print("MISSING %s\n", zPathname); } }else if( chnged ){ fossil_print("EDITED %s\n", zPathname); }else if( renamed ){ fossil_print("RENAMED %s\n", zPathname); }else{ fossil_print("UNCHANGED %s\n", zPathname); } free(zFullName); } db_finalize(&q); } /* |
︙ | ︙ | |||
242 243 244 245 246 247 248 | " ORDER BY 1", fossil_all_reserved_names() ); if( file_tree_name(g.zRepositoryName, &repo, 0) ){ db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); } while( db_step(&q)==SQLITE_ROW ){ | | | 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 | " ORDER BY 1", fossil_all_reserved_names() ); if( file_tree_name(g.zRepositoryName, &repo, 0) ){ db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); } while( db_step(&q)==SQLITE_ROW ){ fossil_print("%s\n", db_column_text(&q, 0)); } db_finalize(&q); } /* ** COMMAND: clean ** Usage: %fossil clean ?--force? ?--dotfiles? ?--ignore GLOBPATTERN? |
︙ | ︙ | |||
300 301 302 303 304 305 306 | g.zLocalRoot, fossil_all_reserved_names() ); if( file_tree_name(g.zRepositoryName, &repo, 0) ){ db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); } while( db_step(&q)==SQLITE_ROW ){ if( allFlag ){ | | | | 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | g.zLocalRoot, fossil_all_reserved_names() ); if( file_tree_name(g.zRepositoryName, &repo, 0) ){ db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo); } while( db_step(&q)==SQLITE_ROW ){ if( allFlag ){ file_delete(db_column_text(&q, 0)); }else{ Blob ans; char *prompt = mprintf("remove unmanaged file \"%s\" (y/N)? ", db_column_text(&q, 0)); blob_zero(&ans); prompt_user(prompt, &ans); if( blob_str(&ans)[0]=='y' ){ file_delete(db_column_text(&q, 0)); } } } db_finalize(&q); } /* |
︙ | ︙ | |||
393 394 395 396 397 398 399 | } #if defined(_WIN32) blob_add_cr(&text); #endif blob_write_to_file(&text, zFile); if( zEditor ){ zCmd = mprintf("%s \"%s\"", zEditor, zFile); | | > | > > > > | | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | } #if defined(_WIN32) blob_add_cr(&text); #endif blob_write_to_file(&text, zFile); if( zEditor ){ zCmd = mprintf("%s \"%s\"", zEditor, zFile); fossil_print("%s\n", zCmd); if( fossil_system(zCmd) ){ fossil_panic("editor aborted"); } blob_reset(&text); blob_read_from_file(&text, zFile); }else{ char zIn[300]; blob_reset(&text); while( fgets(zIn, sizeof(zIn), stdin)!=0 ){ char *zUtf8 = fossil_mbcs_to_utf8(zIn); if( zUtf8[0]=='.' && (zUtf8[1]==0 || zUtf8[1]=='\r' || zUtf8[1]=='\n') ){ fossil_mbcs_free(zUtf8); break; } blob_append(&text, zIn, -1); fossil_mbcs_free(zUtf8); } } blob_remove_cr(&text); file_delete(zFile); free(zFile); blob_zero(pComment); while( blob_line(&text, &line) ){ int i, n; char *z; n = blob_size(&line); z = blob_buffer(&line); |
︙ | ︙ | |||
1082 1083 1084 1085 1086 1087 1088 | fossil_panic("trouble committing manifest: %s", g.zErrMsg); } db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); manifest_crosslink(nvid, &manifest); assert( blob_is_reset(&manifest) ); content_deltify(vid, nvid, 0); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); | | | 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 | fossil_panic("trouble committing manifest: %s", g.zErrMsg); } db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid); manifest_crosslink(nvid, &manifest); assert( blob_is_reset(&manifest) ); content_deltify(vid, nvid, 0); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid); fossil_print("New_Version: %s\n", zUuid); if( outputManifest ){ zManifestFile = mprintf("%smanifest.uuid", g.zLocalRoot); blob_zero(&muuid); blob_appendf(&muuid, "%s\n", zUuid); blob_write_to_file(&muuid, zManifestFile); free(zManifestFile); blob_reset(&muuid); |
︙ | ︙ | |||
1151 1152 1153 1154 1155 1156 1157 | } db_end_transaction(0); if( !g.markPrivate ){ autosync(AUTOSYNC_PUSH); } if( count_nonbranch_children(vid)>1 ){ | | | 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 | } db_end_transaction(0); if( !g.markPrivate ){ autosync(AUTOSYNC_PUSH); } if( count_nonbranch_children(vid)>1 ){ fossil_print("**** warning: a fork has occurred *****\n"); } } |
Changes to src/checkout.c.
︙ | ︙ | |||
58 59 60 61 62 63 64 | ** If anything goes wrong, panic. */ int load_vfile(const char *zName){ Blob uuid; int vid; blob_init(&uuid, zName, -1); | | | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | ** If anything goes wrong, panic. */ int load_vfile(const char *zName){ Blob uuid; int vid; blob_init(&uuid, zName, -1); if( name_to_uuid(&uuid, 1, "ci") ){ fossil_panic(g.zErrMsg); } vid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); if( vid==0 ){ fossil_fatal("no such check-in: %s", g.argv[2]); } if( !is_a_version(vid) ){ |
︙ | ︙ | |||
155 156 157 158 159 160 161 | blob_append(&hash, "\n", 1); blob_write_to_file(&hash, zManFile); free(zManFile); blob_reset(&hash); }else{ if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){ zManFile = mprintf("%smanifest", g.zLocalRoot); | | | | 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | blob_append(&hash, "\n", 1); blob_write_to_file(&hash, zManFile); free(zManFile); blob_reset(&hash); }else{ if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest'") ){ zManFile = mprintf("%smanifest", g.zLocalRoot); file_delete(zManFile); free(zManFile); } if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){ zManFile = mprintf("%smanifest.uuid", g.zLocalRoot); file_delete(zManFile); free(zManFile); } } } /* |
︙ | ︙ | |||
247 248 249 250 251 252 253 | db_lset_int("checkout", vid); undo_reset(); db_multi_exec("DELETE FROM vmerge"); if( !keepFlag && db_get_boolean("repo-cksum",1) ){ vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); vfile_aggregate_checksum_disk(vid, &cksum2); if( blob_compare(&cksum1, &cksum2) ){ | | | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | db_lset_int("checkout", vid); undo_reset(); db_multi_exec("DELETE FROM vmerge"); if( !keepFlag && db_get_boolean("repo-cksum",1) ){ vfile_aggregate_checksum_manifest(vid, &cksum1, &cksum1b); vfile_aggregate_checksum_disk(vid, &cksum2); if( blob_compare(&cksum1, &cksum2) ){ fossil_print("WARNING: manifest checksum does not agree with disk\n"); } if( blob_size(&cksum1b) && blob_compare(&cksum1, &cksum1b) ){ fossil_print("WARNING: manifest checksum does not agree with manifest\n"); } } db_end_transaction(0); } /* ** Unlink the local database file */ static void unlink_local_database(int manifestOnly){ const char *zReserved; int i; for(i=0; (zReserved = fossil_reserved_name(i))!=0; i++){ if( manifestOnly==0 || zReserved[0]=='m' ){ char *z; z = mprintf("%s%s", g.zLocalRoot, zReserved); file_delete(z); free(z); } } } /* ** COMMAND: close |
︙ | ︙ |
Changes to src/clearsign.c.
︙ | ︙ | |||
50 51 52 53 54 55 56 | blob_zero(pOut); blob_read_from_file(pOut, zIn); }else{ if( pOut!=pIn ){ blob_copy(pOut, pIn); } } | | | | 50 51 52 53 54 55 56 57 58 59 60 61 62 | blob_zero(pOut); blob_read_from_file(pOut, zIn); }else{ if( pOut!=pIn ){ blob_copy(pOut, pIn); } } file_delete(zOut); file_delete(zIn); free(zOut); free(zIn); return rc; } |
Changes to src/clone.c.
︙ | ︙ | |||
78 79 80 81 82 83 84 | "DELETE FROM private;" ); shun_artifacts(); g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); if( g.zLogin==0 ){ db_create_default_users(1,zDefaultUser); } | | | 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | "DELETE FROM private;" ); shun_artifacts(); g.zLogin = db_text(0, "SELECT login FROM user WHERE cap LIKE '%%s%%'"); if( g.zLogin==0 ){ db_create_default_users(1,zDefaultUser); } fossil_print("Repository cloned into %s\n", g.argv[3]); }else{ db_create_repository(g.argv[3]); db_open_repository(g.argv[3]); db_begin_transaction(); db_record_repository_filename(g.argv[3]); db_initial_setup(0, zDefaultUser, 0); user_select(); |
︙ | ︙ | |||
102 103 104 105 106 107 108 | g.xlinkClusterOnly = 1; nErr = client_sync(0,0,1,bPrivate,CONFIGSET_ALL,0); g.xlinkClusterOnly = 0; verify_cancel(); db_end_transaction(0); db_close(1); if( nErr ){ | | | | | | | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | g.xlinkClusterOnly = 1; nErr = client_sync(0,0,1,bPrivate,CONFIGSET_ALL,0); g.xlinkClusterOnly = 0; verify_cancel(); db_end_transaction(0); db_close(1); if( nErr ){ file_delete(g.argv[3]); fossil_fatal("server returned an error - clone aborted"); } db_open_repository(g.argv[3]); } db_begin_transaction(); fossil_print("Rebuilding repository meta-data...\n"); rebuild_db(0, 1, 0); fossil_print("project-id: %s\n", db_get("project-code", 0)); fossil_print("server-id: %s\n", db_get("server-code", 0)); zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); db_end_transaction(0); } |
Changes to src/comformat.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | char zBuf[400]; int lineCnt = 0; for(;;){ while( fossil_isspace(zText[0]) ){ zText++; } if( zText[0]==0 ){ if( doIndent==0 ){ | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | char zBuf[400]; int lineCnt = 0; for(;;){ while( fossil_isspace(zText[0]) ){ zText++; } if( zText[0]==0 ){ if( doIndent==0 ){ fossil_print("\n"); lineCnt = 1; } return lineCnt; } for(sk=si=i=k=0; zText[i] && k<tlen; i++){ char c = zText[i]; if( fossil_isspace(c) ){ |
︙ | ︙ | |||
62 63 64 65 66 67 68 | si = i+1; sk = k+1; } k++; } } if( doIndent ){ | | | | | | | 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 | si = i+1; sk = k+1; } k++; } } if( doIndent ){ fossil_print("%*s", indent, ""); } doIndent = 1; if( sk>0 && zText[i] ){ zText += si; zBuf[sk++] = '\n'; zBuf[sk] = 0; fossil_print("%s", zBuf); }else{ zText += i; zBuf[k++] = '\n'; zBuf[k] = 0; fossil_print("%s", zBuf); } lineCnt++; } } /* ** Test the comment printing ** ** COMMAND: test-comment-format */ void test_comment_format(void){ int indent; if( g.argc!=4 ){ usage("PREFIX TEXT"); } indent = strlen(g.argv[2]) + 1; fossil_print("%s ", g.argv[2]); fossil_print("(%d lines output)\n", comment_print(g.argv[3], indent, 79)); } |
Changes to src/config.h.
︙ | ︙ | |||
80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # endif #endif #ifndef _RC_COMPILE_ #include "sqlite3.h" /* ** Typedef for a 64-bit integer */ typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; /* | > > > > > > > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | # endif #endif #ifndef _RC_COMPILE_ #include "sqlite3.h" /* ** On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. */ #if defined(__sun__) || defined(sun) #define getpass getpassphrase #endif /* ** Typedef for a 64-bit integer */ typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; /* |
︙ | ︙ |
Changes to src/configure.c.
︙ | ︙ | |||
504 505 506 507 508 509 510 | aType[ii].zPrimKey, azToken[1], azToken[0]); db_multi_exec("%s", blob_str(&sql)); } blob_reset(&sql); }else{ /* Otherwise, the old format */ if( (configure_is_exportable(zName) & groupMask)==0 ) return; | | | 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 | aType[ii].zPrimKey, azToken[1], azToken[0]); db_multi_exec("%s", blob_str(&sql)); } blob_reset(&sql); }else{ /* Otherwise, the old format */ if( (configure_is_exportable(zName) & groupMask)==0 ) return; if( fossil_strcmp(zName, "logo-image")==0 ){ Stmt ins; db_prepare(&ins, "REPLACE INTO config(name, value, mtime) VALUES(:name, :value, now())" ); db_bind_text(&ins, ":name", zName); db_bind_blob(&ins, ":value", pContent); db_step(&ins); |
︙ | ︙ | |||
686 687 688 689 690 691 692 | int n = strlen(z); for(i=0; i<count(aGroupName); i++){ if( strncmp(z, &aGroupName[i].zName[1], n)==0 ){ return aGroupName[i].groupMask; } } if( notFoundIsFatal ){ | | | | 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 | int n = strlen(z); for(i=0; i<count(aGroupName); i++){ if( strncmp(z, &aGroupName[i].zName[1], n)==0 ){ return aGroupName[i].groupMask; } } if( notFoundIsFatal ){ fossil_print("Available configuration areas:\n"); for(i=0; i<count(aGroupName); i++){ fossil_print(" %-10s %s\n", &aGroupName[i].zName[1], aGroupName[i].zHelp); } fossil_fatal("no such configuration area: \"%s\"", z); } return 0; } /* |
︙ | ︙ | |||
881 882 883 884 885 886 887 | }else if( fossil_strcmp(zName,"@shun")==0 ){ db_multi_exec("DELETE FROM shun"); }else if( fossil_strcmp(zName,"@reportfmt")==0 ){ db_multi_exec("DELETE FROM reportfmt"); } } db_end_transaction(0); | | | | 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 | }else if( fossil_strcmp(zName,"@shun")==0 ){ db_multi_exec("DELETE FROM shun"); }else if( fossil_strcmp(zName,"@reportfmt")==0 ){ db_multi_exec("DELETE FROM reportfmt"); } } db_end_transaction(0); fossil_print("Configuration reset to factory defaults.\n"); fossil_print("To recover, use: %s %s import %s\n", fossil_nameofexe(), g.argv[1], zBackup); }else { fossil_fatal("METHOD should be one of:" " export import merge pull push reset"); } } |
Changes to src/content.c.
︙ | ︙ | |||
668 669 670 671 672 673 674 | int rid; Blob content; if( g.argc!=3 ) usage("FILENAME"); db_must_be_within_tree(); user_select(); blob_read_from_file(&content, g.argv[2]); rid = content_put(&content); | | | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 | int rid; Blob content; if( g.argc!=3 ) usage("FILENAME"); db_must_be_within_tree(); user_select(); blob_read_from_file(&content, g.argv[2]); rid = content_put(&content); fossil_print("inserted as record %d\n", rid); } /* ** Make sure the content at rid is the original content and is not a ** delta. */ void content_undelta(int rid){ |
︙ | ︙ | |||
836 837 838 839 840 841 842 | db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid"); total = db_int(0, "SELECT max(rid) FROM blob"); while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); const char *zUuid = db_column_text(&q, 1); int size = db_column_int(&q, 2); n1++; | | | | | | 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 | db_prepare(&q, "SELECT rid, uuid, size FROM blob ORDER BY rid"); total = db_int(0, "SELECT max(rid) FROM blob"); while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); const char *zUuid = db_column_text(&q, 1); int size = db_column_int(&q, 2); n1++; fossil_print(" %d/%d\r", n1, total); fflush(stdout); if( size<0 ){ fossil_print("skip phantom %d %s\n", rid, zUuid); continue; /* Ignore phantoms */ } content_get(rid, &content); if( blob_size(&content)!=size ){ fossil_warning("size mismatch on blob rid=%d: %d vs %d", rid, blob_size(&content), size); } sha1sum_blob(&content, &cksum); if( fossil_strcmp(blob_str(&cksum), zUuid)!=0 ){ fossil_fatal("checksum mismatch on blob rid=%d: %s vs %s", rid, blob_str(&cksum), zUuid); } blob_reset(&cksum); blob_reset(&content); n2++; } db_finalize(&q); fossil_print("%d non-phantom blobs (out of %d total) verified\n", n2, n1); } |
Changes to src/db.c.
︙ | ︙ | |||
164 165 166 167 168 169 170 | if( nBegin ){ sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); nBegin = 0; } busy = 0; db_close(0); for(i=0; i<nDeleteOnFail; i++){ | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | if( nBegin ){ sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0); nBegin = 0; } busy = 0; db_close(0); for(i=0; i<nDeleteOnFail; i++){ file_delete(azDeleteOnFail[i]); } } /* ** Install a commit hook. Hooks are installed in sequence order. ** It is an error to install the same commit hook more than once. ** |
︙ | ︙ | |||
613 614 615 616 617 618 619 | sqlite3_close(db); } /* ** Function to return the number of seconds since 1970. This is ** the same as strftime('%s','now') but is more compact. */ | | | 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 | sqlite3_close(db); } /* ** Function to return the number of seconds since 1970. This is ** the same as strftime('%s','now') but is more compact. */ void db_now_function( sqlite3_context *context, int argc, sqlite3_value **argv ){ sqlite3_result_int64(context, time(0)); } |
︙ | ︙ | |||
693 694 695 696 697 698 699 700 701 702 703 704 705 706 | } } if( zHome==0 ){ fossil_fatal("cannot locate home directory - " "please set the LOCALAPPDATA or APPDATA or HOMEPATH " "environment variables"); } #else zHome = getenv("HOME"); if( zHome==0 ){ fossil_fatal("cannot locate home directory - " "please set the HOME environment variable"); } #endif | > | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 | } } if( zHome==0 ){ fossil_fatal("cannot locate home directory - " "please set the LOCALAPPDATA or APPDATA or HOMEPATH " "environment variables"); } zHome = fossil_mbcs_to_utf8(zHome); #else zHome = getenv("HOME"); if( zHome==0 ){ fossil_fatal("cannot locate home directory - " "please set the HOME environment variable"); } #endif |
︙ | ︙ | |||
738 739 740 741 742 743 744 | ** true. If it is not a valid local database file, return 0. */ static int isValidLocalDb(const char *zDbName){ i64 lsize; int rc; sqlite3_stmt *pStmt; | | | 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 | ** true. If it is not a valid local database file, return 0. */ static int isValidLocalDb(const char *zDbName){ i64 lsize; int rc; sqlite3_stmt *pStmt; if( file_access(zDbName, F_OK) ) return 0; lsize = file_size(zDbName); if( lsize%1024!=0 || lsize<4096 ) return 0; db_open_or_attach(zDbName, "localdb"); g.localOpen = 1; db_open_config(0); db_open_repository(0); |
︙ | ︙ | |||
801 802 803 804 805 806 807 | ** This routine always opens the user database regardless of whether or ** not the repository database is found. If the _FOSSIL_ or .fos file ** is found, it is attached to the open database connection too. */ int db_open_local(void){ int i, n; char zPwd[2000]; | < | < < < < < | | 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 | ** This routine always opens the user database regardless of whether or ** not the repository database is found. If the _FOSSIL_ or .fos file ** is found, it is attached to the open database connection too. */ int db_open_local(void){ int i, n; char zPwd[2000]; static const char *aDbName[] = { "/_FOSSIL_", "/.fos" }; if( g.localOpen) return 1; file_getcwd(zPwd, sizeof(zPwd)-20); n = strlen(zPwd); while( n>0 ){ if( file_access(zPwd, W_OK) ) break; for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){ sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]); if( isValidLocalDb(zPwd) ){ /* Found a valid checkout database file */ zPwd[n] = 0; while( n>1 && zPwd[n-1]=='/' ){ n--; |
︙ | ︙ | |||
851 852 853 854 855 856 857 | if( g.localOpen ){ zDbName = db_lget("repository", 0); } if( zDbName==0 ){ db_err("unable to find the name of a repository database"); } } | | | | | 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 | if( g.localOpen ){ zDbName = db_lget("repository", 0); } if( zDbName==0 ){ db_err("unable to find the name of a repository database"); } } if( file_access(zDbName, R_OK) || file_size(zDbName)<1024 ){ if( file_access(zDbName, 0) ){ fossil_panic("repository does not exist or" " is in an unreadable directory: %s", zDbName); }else if( file_access(zDbName, R_OK) ){ fossil_panic("read permission denied for repository %s", zDbName); }else{ fossil_panic("not a valid repository: %s", zDbName); } } db_open_or_attach(zDbName, "repository"); g.repositoryOpen = 1; |
︙ | ︙ | |||
910 911 912 913 914 915 916 | } } /* ** Return the name of the database "localdb", "configdb", or "repository". */ const char *db_name(const char *zDb){ | | | | | | 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 | } } /* ** Return the name of the database "localdb", "configdb", or "repository". */ const char *db_name(const char *zDb){ assert( fossil_strcmp(zDb,"localdb")==0 || fossil_strcmp(zDb,"configdb")==0 || fossil_strcmp(zDb,"repository")==0 ); if( fossil_strcmp(zDb, g.zMainDbType)==0 ) zDb = "main"; return zDb; } /* ** Return TRUE if the schema is out-of-date */ int db_schema_is_outofdate(void){ |
︙ | ︙ | |||
962 963 964 965 966 967 968 | } if( db_open_local()==0 ){ fossil_fatal("not in a local checkout"); return; } file_canonical_name(g.argv[2], &repo); zRepo = blob_str(&repo); | | | 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 | } if( db_open_local()==0 ){ fossil_fatal("not in a local checkout"); return; } file_canonical_name(g.argv[2], &repo); zRepo = blob_str(&repo); if( file_access(zRepo, 0) ){ fossil_fatal("no such file: %s", zRepo); } db_open_or_attach(zRepo, "test_repo"); db_lset("repository", blob_str(&repo)); db_close(1); } |
︙ | ︙ | |||
1215 1216 1217 1218 1219 1220 1221 | char c = i==argc-1 ? '\n' : ' '; fossil_print("%s%c", sqlite3_value_text(argv[i]), c); } } } static void db_sql_trace(void *notUsed, const char *zSql){ int n = strlen(zSql); | | > > | 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 | char c = i==argc-1 ? '\n' : ' '; fossil_print("%s%c", sqlite3_value_text(argv[i]), c); } } } static void db_sql_trace(void *notUsed, const char *zSql){ int n = strlen(zSql); char *zMsg = mprintf("%s%s\n", zSql, (n>0 && zSql[n-1]==';') ? "" : ";"); fossil_puts(zMsg, 1); fossil_free(zMsg); } /* ** Implement the user() SQL function. user() takes no arguments and ** returns the user ID of the current user. */ static void db_sql_user( |
︙ | ︙ |
Changes to src/deltacmd.c.
︙ | ︙ | |||
50 51 52 53 54 55 56 | */ void delta_create_cmd(void){ Blob orig, target, delta; if( g.argc!=5 ){ usage("ORIGIN TARGET DELTA"); } if( blob_read_from_file(&orig, g.argv[2])<0 ){ | | < | < | < | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | */ void delta_create_cmd(void){ Blob orig, target, delta; if( g.argc!=5 ){ usage("ORIGIN TARGET DELTA"); } if( blob_read_from_file(&orig, g.argv[2])<0 ){ fossil_fatal("cannot read %s\n", g.argv[2]); } if( blob_read_from_file(&target, g.argv[3])<0 ){ fossil_fatal("cannot read %s\n", g.argv[3]); } blob_delta_create(&orig, &target, &delta); if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){ fossil_fatal("cannot write %s\n", g.argv[4]); } blob_reset(&orig); blob_reset(&target); blob_reset(&delta); } /* |
︙ | ︙ | |||
112 113 114 115 116 117 118 | */ void delta_apply_cmd(void){ Blob orig, target, delta; if( g.argc!=5 ){ usage("ORIGIN DELTA TARGET"); } if( blob_read_from_file(&orig, g.argv[2])<0 ){ | | < | < | < | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | */ void delta_apply_cmd(void){ Blob orig, target, delta; if( g.argc!=5 ){ usage("ORIGIN DELTA TARGET"); } if( blob_read_from_file(&orig, g.argv[2])<0 ){ fossil_fatal("cannot read %s\n", g.argv[2]); } if( blob_read_from_file(&delta, g.argv[3])<0 ){ fossil_fatal("cannot read %s\n", g.argv[3]); } blob_delta_apply(&orig, &delta, &target); if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){ fossil_fatal("cannot write %s\n", g.argv[4]); } blob_reset(&orig); blob_reset(&target); blob_reset(&delta); } /* |
︙ | ︙ | |||
150 151 152 153 154 155 156 | blob_delta_create(&f1, &f2, &d12); blob_delta_create(&f2, &f1, &d21); blob_delta_apply(&f1, &d12, &a2); blob_delta_apply(&f2, &d21, &a1); if( blob_compare(&f1,&a1) || blob_compare(&f2, &a2) ){ fossil_panic("delta test failed"); } | | | 144 145 146 147 148 149 150 151 152 | blob_delta_create(&f1, &f2, &d12); blob_delta_create(&f2, &f1, &d21); blob_delta_apply(&f1, &d12, &a2); blob_delta_apply(&f2, &d21, &a1); if( blob_compare(&f1,&a1) || blob_compare(&f2, &a2) ){ fossil_panic("delta test failed"); } fossil_print("ok\n"); } |
Changes to src/descendants.c.
︙ | ︙ | |||
240 241 242 243 244 245 246 | Stmt q; int base; db_must_be_within_tree(); if( g.argc==2 ){ base = db_lget_int("checkout", 0); }else{ | | | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | Stmt q; int base; db_must_be_within_tree(); if( g.argc==2 ){ base = db_lget_int("checkout", 0); }else{ base = name_to_typed_rid(g.argv[2], "ci"); } if( base==0 ) return; compute_leaves(base, 0); db_prepare(&q, "%s" " AND event.objid IN (SELECT rid FROM leaves)" " ORDER BY event.mtime DESC", |
︙ | ︙ |
Changes to src/diff.c.
︙ | ︙ | |||
588 589 590 591 592 593 594 | Blob a, b; int r; int i; int *R; if( g.argc<4 ) usage("FILE1 FILE2 ..."); blob_read_from_file(&a, g.argv[2]); for(i=3; i<g.argc; i++){ | | | | 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 | Blob a, b; int r; int i; int *R; if( g.argc<4 ) usage("FILE1 FILE2 ..."); blob_read_from_file(&a, g.argv[2]); for(i=3; i<g.argc; i++){ if( i>3 ) fossil_print("-------------------------------\n"); blob_read_from_file(&b, g.argv[i]); R = text_diff(&a, &b, 0, 0, 0); for(r=0; R[r] || R[r+1] || R[r+2]; r += 3){ fossil_print(" copy %4d delete %4d insert %4d\n", R[r], R[r+1], R[r+2]); } /* free(R); */ blob_reset(&b); } } /* |
︙ | ︙ | |||
741 742 743 744 745 746 747 | if( annotation_step(&x, &b, g.argv[i-1]) ){ fossil_fatal("binary file"); } } for(i=0; i<x.nOrig; i++){ const char *zSrc = x.aOrig[i].zSrc; if( zSrc==0 ) zSrc = g.argv[g.argc-1]; | | | 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 | if( annotation_step(&x, &b, g.argv[i-1]) ){ fossil_fatal("binary file"); } } for(i=0; i<x.nOrig; i++){ const char *zSrc = x.aOrig[i].zSrc; if( zSrc==0 ) zSrc = g.argv[g.argc-1]; fossil_print("%10s: %.*s\n", zSrc, x.aOrig[i].n, x.aOrig[i].z); } } /* Annotation flags */ #define ANN_FILE_VERS 0x001 /* Show file version rather than commit version */ /* |
︙ | ︙ | |||
835 836 837 838 839 840 841 | int i; int iLimit; int annFlags = 0; Annotator ann; login_check_credentials(); if( !g.okRead ){ login_needed(); return; } | | | 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 | int i; int iLimit; int annFlags = 0; Annotator ann; login_check_credentials(); if( !g.okRead ){ login_needed(); return; } mid = name_to_typed_rid(PD("checkin","0"),"ci"); fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", P("filename")); if( mid==0 || fnid==0 ){ fossil_redirect_home(); } iLimit = atoi(PD("limit","-1")); if( !db_exists("SELECT 1 FROM mlink WHERE mid=%d AND fnid=%d",mid,fnid) ){ fossil_redirect_home(); } style_header("File Annotation"); |
︙ | ︙ | |||
924 925 926 927 928 929 930 | if( showLog ){ for(i=0; i<ann.nVers; i++){ printf("version %3d: %s\n", i+1, ann.azVers[i]); } printf("---------------------------------------------------\n"); } for(i=0; i<ann.nOrig; i++){ | > | | 924 925 926 927 928 929 930 931 932 933 934 | if( showLog ){ for(i=0; i<ann.nVers; i++){ printf("version %3d: %s\n", i+1, ann.azVers[i]); } printf("---------------------------------------------------\n"); } for(i=0; i<ann.nOrig; i++){ fossil_print("%s: %.*s\n", ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z); } } |
Changes to src/diffcmd.c.
︙ | ︙ | |||
98 99 100 101 102 103 104 | /* Construct a temporary file to hold pFile1 based on the name of ** zFile2 */ blob_zero(&nameFile1); do{ blob_reset(&nameFile1); blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++); | | | | 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 | /* Construct a temporary file to hold pFile1 based on the name of ** zFile2 */ blob_zero(&nameFile1); do{ blob_reset(&nameFile1); blob_appendf(&nameFile1, "%s~%d", zFile2, cnt++); }while( file_access(blob_str(&nameFile1),0)==0 ); blob_write_to_file(pFile1, blob_str(&nameFile1)); /* Construct the external diff command */ blob_zero(&cmd); blob_appendf(&cmd, "%s ", zDiffCmd); shell_escape(&cmd, blob_str(&nameFile1)); blob_append(&cmd, " ", 1); shell_escape(&cmd, zFile2); /* Run the external diff command */ fossil_system(blob_str(&cmd)); /* Delete the temporary file and clean up memory used */ file_delete(blob_str(&nameFile1)); blob_reset(&nameFile1); blob_reset(&cmd); } } /* ** Show the difference between two files, both in memory. |
︙ | ︙ | |||
166 167 168 169 170 171 172 | blob_append(&cmd, " ", 1); shell_escape(&cmd, zTemp2); /* Run the external diff command */ fossil_system(blob_str(&cmd)); /* Delete the temporary file and clean up memory used */ | | | | 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | blob_append(&cmd, " ", 1); shell_escape(&cmd, zTemp2); /* Run the external diff command */ fossil_system(blob_str(&cmd)); /* Delete the temporary file and clean up memory used */ file_delete(zTemp1); file_delete(zTemp2); blob_reset(&cmd); } } /* ** Do a diff against a single file named in g.argv[2] from version zFrom ** against the same file on disk. |
︙ | ︙ | |||
213 214 215 216 217 218 219 | ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0; asNewFile = (diffFlags & DIFF_NEWFILE)!=0; vid = db_lget_int("checkout", 0); vfile_check_signature(vid, 1, 0); blob_zero(&sql); db_begin_transaction(); if( zFrom ){ | | | 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | ignoreEolWs = (diffFlags & DIFF_NOEOLWS)!=0; asNewFile = (diffFlags & DIFF_NEWFILE)!=0; vid = db_lget_int("checkout", 0); vfile_check_signature(vid, 1, 0); blob_zero(&sql); db_begin_transaction(); if( zFrom ){ int rid = name_to_typed_rid(zFrom, "ci"); if( !is_a_version(rid) ){ fossil_fatal("no such check-in: %s", zFrom); } load_vfile_from_rid(rid); blob_appendf(&sql, "SELECT v2.pathname, v2.deleted, v2.chnged, v2.rid==0, v1.rid" " FROM vfile v1, vfile v2 " |
︙ | ︙ | |||
261 262 263 264 265 266 267 | int srcid = db_column_int(&q, 4); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); char *zToFree = zFullName; int showDiff = 1; if( isDeleted ){ diff_printf("DELETED %s\n", zPathname); if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; } | | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | int srcid = db_column_int(&q, 4); char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); char *zToFree = zFullName; int showDiff = 1; if( isDeleted ){ diff_printf("DELETED %s\n", zPathname); if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; } }else if( file_access(zFullName, 0) ){ diff_printf("MISSING %s\n", zPathname); if( !asNewFile ){ showDiff = 0; } }else if( isNew ){ diff_printf("ADDED %s\n", zPathname); srcid = 0; if( !asNewFile ){ showDiff = 0; } }else if( isChnged==3 ){ |
︙ | ︙ |
Changes to src/doc.c.
︙ | ︙ | |||
137 138 139 140 141 142 143 144 145 146 | { "f90", 3, "text/plain" }, { "fli", 3, "video/fli" }, { "flv", 3, "video/flv" }, { "gif", 3, "image/gif" }, { "gl", 2, "video/gl" }, { "gtar", 4, "application/x-gtar" }, { "gz", 2, "application/x-gzip" }, { "hdf", 3, "application/x-hdf" }, { "hh", 2, "text/plain" }, { "hqx", 3, "application/mac-binhex40" }, | > < | | < > | | | < | 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 | { "f90", 3, "text/plain" }, { "fli", 3, "video/fli" }, { "flv", 3, "video/flv" }, { "gif", 3, "image/gif" }, { "gl", 2, "video/gl" }, { "gtar", 4, "application/x-gtar" }, { "gz", 2, "application/x-gzip" }, { "h", 1, "text/plain" }, { "hdf", 3, "application/x-hdf" }, { "hh", 2, "text/plain" }, { "hqx", 3, "application/mac-binhex40" }, { "htm", 3, "text/html" }, { "html", 4, "text/html" }, { "ice", 3, "x-conference/x-cooltalk" }, { "ief", 3, "image/ief" }, { "iges", 4, "model/iges" }, { "igs", 3, "model/iges" }, { "ips", 3, "application/x-ipscript" }, { "ipx", 3, "application/x-ipix" }, { "jad", 3, "text/vnd.sun.j2me.app-descriptor" }, { "jar", 3, "application/java-archive" }, { "jpe", 3, "image/jpeg" }, { "jpeg", 4, "image/jpeg" }, { "jpg", 3, "image/jpeg" }, { "js", 2, "application/x-javascript" }, { "kar", 3, "audio/midi" }, { "latex", 5, "application/x-latex" }, { "lha", 3, "application/octet-stream" }, { "lsp", 3, "application/x-lisp" }, { "lzh", 3, "application/octet-stream" }, { "m", 1, "text/plain" }, { "m3u", 3, "audio/x-mpegurl" }, { "man", 3, "application/x-troff-man" }, { "me", 2, "application/x-troff-me" }, { "mesh", 4, "model/mesh" }, { "mid", 3, "audio/midi" }, { "midi", 4, "audio/midi" }, { "mif", 3, "application/x-mif" }, { "mime", 4, "www/mime" }, { "mov", 3, "video/quicktime" }, { "movie", 5, "video/x-sgi-movie" }, { "mp2", 3, "audio/mpeg" }, { "mp3", 3, "audio/mpeg" }, { "mpe", 3, "video/mpeg" }, { "mpeg", 4, "video/mpeg" }, { "mpg", 3, "video/mpeg" }, { "mpga", 4, "audio/mpeg" }, { "ms", 2, "application/x-troff-ms" }, { "msh", 3, "model/mesh" }, { "nc", 2, "application/x-netcdf" }, { "oda", 3, "application/oda" }, { "ogg", 3, "application/ogg" }, { "ogm", 3, "application/ogg" }, { "pbm", 3, "image/x-portable-bitmap" }, |
︙ | ︙ | |||
207 208 209 210 211 212 213 | { "prt", 3, "application/pro_eng" }, { "ps", 2, "application/postscript" }, { "qt", 2, "video/quicktime" }, { "ra", 2, "audio/x-realaudio" }, { "ram", 3, "audio/x-pn-realaudio" }, { "rar", 3, "application/x-rar-compressed" }, { "ras", 3, "image/cmu-raster" }, | < < | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | { "prt", 3, "application/pro_eng" }, { "ps", 2, "application/postscript" }, { "qt", 2, "video/quicktime" }, { "ra", 2, "audio/x-realaudio" }, { "ram", 3, "audio/x-pn-realaudio" }, { "rar", 3, "application/x-rar-compressed" }, { "ras", 3, "image/cmu-raster" }, { "rgb", 3, "image/x-rgb" }, { "rm", 2, "audio/x-pn-realaudio" }, { "roff", 4, "application/x-troff" }, { "rpm", 3, "audio/x-pn-realaudio-plugin" }, { "rtf", 3, "text/rtf" }, { "rtx", 3, "text/richtext" }, { "scm", 3, "application/x-lotusscreencam" }, { "set", 3, "application/set" }, { "sgm", 3, "text/sgml" }, { "sgml", 4, "text/sgml" }, { "sh", 2, "application/x-sh" }, { "shar", 4, "application/x-shar" }, { "silo", 4, "model/mesh" }, { "sit", 3, "application/x-stuffit" }, { "skd", 3, "application/x-koan" }, { "skm", 3, "application/x-koan" }, { "skp", 3, "application/x-koan" }, |
︙ | ︙ | |||
247 248 249 250 251 252 253 | { "t", 1, "application/x-troff" }, { "tar", 3, "application/x-tar" }, { "tcl", 3, "application/x-tcl" }, { "tex", 3, "application/x-tex" }, { "texi", 4, "application/x-texinfo" }, { "texinfo", 7, "application/x-texinfo" }, { "tgz", 3, "application/x-tar-gz" }, | | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | { "t", 1, "application/x-troff" }, { "tar", 3, "application/x-tar" }, { "tcl", 3, "application/x-tcl" }, { "tex", 3, "application/x-tex" }, { "texi", 4, "application/x-texinfo" }, { "texinfo", 7, "application/x-texinfo" }, { "tgz", 3, "application/x-tar-gz" }, { "tif", 3, "image/tiff" }, { "tiff", 4, "image/tiff" }, { "tr", 2, "application/x-troff" }, { "tsi", 3, "audio/TSP-audio" }, { "tsp", 3, "application/dsptype" }, { "tsv", 3, "text/tab-separated-values" }, { "txt", 3, "text/plain" }, { "unv", 3, "application/i-deas" }, { "ustar", 5, "application/x-ustar" }, |
︙ | ︙ | |||
281 282 283 284 285 286 287 288 289 290 291 292 293 294 | { "xlw", 3, "application/vnd.ms-excel" }, { "xml", 3, "text/xml" }, { "xpm", 3, "image/x-xpixmap" }, { "xwd", 3, "image/x-xwindowdump" }, { "xyz", 3, "chemical/x-pdb" }, { "zip", 3, "application/zip" }, }; z = zName; for(i=0; zName[i]; i++){ if( zName[i]=='.' ) z = &zName[i+1]; } len = strlen(z); if( len<sizeof(zSuffix)-1 ){ | > > > > > > > > > > > > > > > | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | { "xlw", 3, "application/vnd.ms-excel" }, { "xml", 3, "text/xml" }, { "xpm", 3, "image/x-xpixmap" }, { "xwd", 3, "image/x-xwindowdump" }, { "xyz", 3, "chemical/x-pdb" }, { "zip", 3, "application/zip" }, }; #ifdef FOSSIL_DEBUG /* This is test code to make sure the table above is in the correct ** order */ if( fossil_strcmp(zName, "mimetype-test")==0 ){ for(i=1; i<sizeof(aMime)/sizeof(aMime[0]); i++){ if( fossil_strcmp(aMime[i-1].zSuffix,aMime[i].zSuffix)>=0 ){ fossil_fatal("mimetypes out of sequence: %s before %s", aMime[i-1].zSuffix, aMime[i].zSuffix); } } return "ok"; } #endif z = zName; for(i=0; zName[i]; i++){ if( zName[i]=='.' ) z = &zName[i+1]; } len = strlen(z); if( len<sizeof(zSuffix)-1 ){ |
︙ | ︙ | |||
306 307 308 309 310 311 312 313 314 315 316 317 318 319 | }else{ first = i+1; } } } return "application/x-fossil-artifact"; } /* ** WEBPAGE: doc ** URL: /doc?name=BASELINE/PATH ** URL: /doc/BASELINE/PATH ** ** BASELINE can be either a baseline uuid prefix or magic words "tip" | > > > > > > > > > > > > > > > > > > | 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | }else{ first = i+1; } } } return "application/x-fossil-artifact"; } /* ** COMMAND: test-mimetype ** ** Usage: %fossil test-mimetype FILENAME... ** ** Return the deduced mimetype for each file listed. ** ** If Fossil is compiled with -DFOSSIL_DEBUG then the "mimetype-test" ** filename is special and verifies the integrity of the mimetype table. ** It should return "ok". */ void mimetype_test_cmd(void){ int i; for(i=2; i<g.argc; i++){ fossil_print("%-20s -> %s\n", g.argv[i], mimetype_from_name(g.argv[i])); } } /* ** WEBPAGE: doc ** URL: /doc?name=BASELINE/PATH ** URL: /doc/BASELINE/PATH ** ** BASELINE can be either a baseline uuid prefix or magic words "tip" |
︙ | ︙ | |||
364 365 366 367 368 369 370 | } }else{ db_begin_transaction(); if( fossil_strcmp(zBaseline,"tip")==0 ){ vid = db_int(0, "SELECT objid FROM event WHERE type='ci'" " ORDER BY mtime DESC LIMIT 1"); }else{ | | | 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | } }else{ db_begin_transaction(); if( fossil_strcmp(zBaseline,"tip")==0 ){ vid = db_int(0, "SELECT objid FROM event WHERE type='ci'" " ORDER BY mtime DESC LIMIT 1"); }else{ vid = name_to_typed_rid(zBaseline, "ci"); } /* Create the baseline cache if it does not already exist */ db_multi_exec( "CREATE TABLE IF NOT EXISTS vcache(\n" " vid INTEGER, -- baseline ID\n" " fname TEXT, -- filename\n" |
︙ | ︙ |
Changes to src/encode.c.
︙ | ︙ | |||
338 339 340 341 342 343 344 | ** Usage: %fossil test-encode64 STRING */ void test_encode64_cmd(void){ char *z; int i; for(i=2; i<g.argc; i++){ z = encode64(g.argv[i], -1); | | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | ** Usage: %fossil test-encode64 STRING */ void test_encode64_cmd(void){ char *z; int i; for(i=2; i<g.argc; i++){ z = encode64(g.argv[i], -1); fossil_print("%s\n", z); free(z); } } /* ** This function treats its input as a base-64 string and returns the |
︙ | ︙ | |||
403 404 405 406 407 408 409 | ** Usage: %fossil test-decode64 STRING */ void test_decode64_cmd(void){ char *z; int i, n; for(i=2; i<g.argc; i++){ z = decode64(g.argv[i], &n); | | | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | ** Usage: %fossil test-decode64 STRING */ void test_decode64_cmd(void){ char *z; int i, n; for(i=2; i<g.argc; i++){ z = decode64(g.argv[i], &n); fossil_print("%d: %s\n", n, z); free(z); } } /* ** The base-16 encoding using the following characters: ** |
︙ | ︙ | |||
577 578 579 580 581 582 583 | */ void test_obscure_cmd(void){ int i; char *z, *z2; for(i=2; i<g.argc; i++){ z = obscure(g.argv[i]); z2 = unobscure(z); | | | | 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | */ void test_obscure_cmd(void){ int i; char *z, *z2; for(i=2; i<g.argc; i++){ z = obscure(g.argv[i]); z2 = unobscure(z); fossil_print("OBSCURE: %s -> %s (%s)\n", g.argv[i], z, z2); free(z); free(z2); z = unobscure(g.argv[i]); fossil_print("UNOBSCURE: %s -> %s\n", g.argv[i], z); free(z); } } |
Changes to src/file.c.
︙ | ︙ | |||
45 46 47 48 49 50 51 | ** Return the number of errors. No error messages are generated. */ static int getStat(const char *zFilename){ int rc = 0; if( zFilename==0 ){ if( fileStatValid==0 ) rc = 1; }else{ | > | > | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | ** Return the number of errors. No error messages are generated. */ static int getStat(const char *zFilename){ int rc = 0; if( zFilename==0 ){ if( fileStatValid==0 ) rc = 1; }else{ char *zMbcs = fossil_utf8_to_mbcs(zFilename); if( stat(zMbcs, &fileStat)!=0 ){ fileStatValid = 0; rc = 1; }else{ fileStatValid = 1; rc = 0; } fossil_mbcs_free(zMbcs); } return rc; } /* ** Return the size of a file in bytes. Return -1 if the file does not |
︙ | ︙ | |||
118 119 120 121 122 123 124 125 126 127 128 129 130 131 | rc = getStat(zFN); free(zFN); }else{ rc = getStat(0); } return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2); } /* ** Find an unused filename similar to zBase with zSuffix appended. ** ** Make the name relative to the working directory if relFlag is true. ** ** Space to hold the new filename is obtained form mprintf() and should | > > > > > > > > > > | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | rc = getStat(zFN); free(zFN); }else{ rc = getStat(0); } return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2); } /* ** Wrapper around the access() system call. */ int file_access(const char *zFilename, int flags){ char *zMbcs = fossil_utf8_to_mbcs(zFilename); int rc = access(zMbcs, flags); fossil_mbcs_free(zMbcs); return rc; } /* ** Find an unused filename similar to zBase with zSuffix appended. ** ** Make the name relative to the working directory if relFlag is true. ** ** Space to hold the new filename is obtained form mprintf() and should |
︙ | ︙ | |||
164 165 166 167 168 169 170 | /* ** Copy the content of a file from one place to another. */ void file_copy(const char *zFrom, const char *zTo){ FILE *in, *out; int got; char zBuf[8192]; | | | | 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | /* ** Copy the content of a file from one place to another. */ void file_copy(const char *zFrom, const char *zTo){ FILE *in, *out; int got; char zBuf[8192]; in = fossil_fopen(zFrom, "rb"); if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom); out = fossil_fopen(zTo, "wb"); if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo); while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){ fwrite(zBuf, 1, got, out); } fclose(in); fclose(out); } |
︙ | ︙ | |||
198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 | chmod(zFilename, buf.st_mode & ~0111); rc = 1; } } #endif /* _WIN32 */ return rc; } /* ** Create the directory named in the argument, if it does not already ** exist. If forceFlag is 1, delete any prior non-directory object ** with the same name. ** ** Return the number of errors. */ int file_mkdir(const char *zName, int forceFlag){ int rc = file_isdir(zName); if( rc==2 ){ if( !forceFlag ) return 1; | > > > > > > > > > | > > > > | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 | chmod(zFilename, buf.st_mode & ~0111); rc = 1; } } #endif /* _WIN32 */ return rc; } /* ** Delete a file. */ void file_delete(const char *zFilename){ char *z = fossil_utf8_to_mbcs(zFilename); unlink(z); fossil_mbcs_free(z); } /* ** Create the directory named in the argument, if it does not already ** exist. If forceFlag is 1, delete any prior non-directory object ** with the same name. ** ** Return the number of errors. */ int file_mkdir(const char *zName, int forceFlag){ int rc = file_isdir(zName); if( rc==2 ){ if( !forceFlag ) return 1; file_delete(zName); } if( rc!=1 ){ #if defined(_WIN32) int rc; char *zMbcs = fossil_utf8_to_mbcs(zName); rc = mkdir(zMbcs); fossil_mbcs_free(zMbcs); return rc; #else return mkdir(zName, 0755); #endif } return 0; } |
︙ | ︙ | |||
348 349 350 351 352 353 354 | ** Print the simplified versions of each FILENAME. */ void cmd_test_simplify_name(void){ int i; char *z; for(i=2; i<g.argc; i++){ z = mprintf("%s", g.argv[i]); | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 | ** Print the simplified versions of each FILENAME. */ void cmd_test_simplify_name(void){ int i; char *z; for(i=2; i<g.argc; i++){ z = mprintf("%s", g.argv[i]); fossil_print("[%s] -> ", z); file_simplify_name(z, -1); fossil_print("[%s]\n", z); fossil_free(z); } } /* ** Get the current working directory. ** ** On windows, the name is converted from MBCS to UTF8 and all '\\' ** characters are converted to '/'. No conversions are needed on ** unix. */ void file_getcwd(char *zBuf, int nBuf){ #ifdef _WIN32 char *zPwdUtf8; int nPwd; int i; char zPwd[2000]; if( getcwd(zPwd, sizeof(zPwd)-1)==0 ){ fossil_fatal("pwd too big: max %d\n", (int)sizeof(zPwd)-1); } zPwdUtf8 = fossil_mbcs_to_utf8(zPwd); nPwd = strlen(zPwdUtf8); if( nPwd > nBuf-1 ){ fossil_fatal("pwd too big: max %d\n", nBuf-1); } for(i=0; zPwdUtf8[i]; i++) if( zPwdUtf8[i]=='\\' ) zPwdUtf8[i] = '/'; memcpy(zBuf, zPwdUtf8, nPwd+1); fossil_mbcs_free(zPwdUtf8); #else if( getcwd(zBuf, nBuf-1)==0 ){ fossil_fatal("pwd too big: max %d\n", nBuf-1); } #endif } /* ** Compute a canonical pathname for a file or directory. ** Make the name absolute if it is relative. ** Remove redundant / characters ** Remove all /./ path elements. ** Convert /A/../ to just / */ void file_canonical_name(const char *zOrigName, Blob *pOut){ if( zOrigName[0]=='/' #if defined(_WIN32) || zOrigName[0]=='\\' || (strlen(zOrigName)>3 && zOrigName[1]==':' && (zOrigName[2]=='\\' || zOrigName[2]=='/')) #endif ){ blob_set(pOut, zOrigName); blob_materialize(pOut); }else{ char zPwd[2000]; file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName)); blob_zero(pOut); blob_appendf(pOut, "%//%/", zPwd, zOrigName); } blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); } /* |
︙ | ︙ | |||
399 400 401 402 403 404 405 | int i; Blob x; blob_zero(&x); for(i=2; i<g.argc; i++){ char zBuf[100]; const char *zName = g.argv[i]; file_canonical_name(zName, &x); | | | | | | | | 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | int i; Blob x; blob_zero(&x); for(i=2; i<g.argc; i++){ char zBuf[100]; const char *zName = g.argv[i]; file_canonical_name(zName, &x); fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x)); blob_reset(&x); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_size(zName)); fossil_print(" file_size = %s\n", zBuf); sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_mtime(zName)); fossil_print(" file_mtime = %s\n", zBuf); fossil_print(" file_isfile = %d\n", file_isfile(zName)); fossil_print(" file_isexe = %d\n", file_isexe(zName)); fossil_print(" file_isdir = %d\n", file_isdir(zName)); } } /* ** Return TRUE if the given filename is canonical. ** ** Canonical names are full pathnames using "/" not "\" and which |
︙ | ︙ | |||
450 451 452 453 454 455 456 | blob_set(pOut, zOrigName); blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); zPath = blob_buffer(pOut); if( zPath[0]=='/' ){ int i, j; Blob tmp; char zPwd[2000]; | | < < < | 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 | blob_set(pOut, zOrigName); blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); zPath = blob_buffer(pOut); if( zPath[0]=='/' ){ int i, j; Blob tmp; char zPwd[2000]; file_getcwd(zPwd, sizeof(zPwd)-20); for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){} if( zPath[i]==0 ){ blob_reset(pOut); if( zPwd[i]==0 ){ blob_append(pOut, ".", 1); }else{ blob_append(pOut, "..", 2); |
︙ | ︙ | |||
500 501 502 503 504 505 506 | */ void cmd_test_relative_name(void){ int i; Blob x; blob_zero(&x); for(i=2; i<g.argc; i++){ file_relative_name(g.argv[i], &x); | | | 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 | */ void cmd_test_relative_name(void){ int i; Blob x; blob_zero(&x); for(i=2; i<g.argc; i++){ file_relative_name(g.argv[i], &x); fossil_print("%s\n", blob_buffer(&x)); blob_reset(&x); } } /* ** Compute a pathname for a file relative to the root of the local ** tree. Return TRUE on success. On failure, print and error |
︙ | ︙ | |||
555 556 557 558 559 560 561 | */ void cmd_test_tree_name(void){ int i; Blob x; blob_zero(&x); for(i=2; i<g.argc; i++){ if( file_tree_name(g.argv[i], &x, 1) ){ | | | 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 | */ void cmd_test_tree_name(void){ int i; Blob x; blob_zero(&x); for(i=2; i<g.argc; i++){ if( file_tree_name(g.argv[i], &x, 1) ){ fossil_print("%s\n", blob_buffer(&x)); blob_reset(&x); } } } /* ** Parse a URI into scheme, host, port, and path. |
︙ | ︙ | |||
618 619 620 621 622 623 624 | ".", }; static const unsigned char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; unsigned int i, j; | < | < < | | 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 | ".", }; static const unsigned char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; unsigned int i, j; const char *zDir = "."; for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){ if( !file_isdir(azDirs[i]) ) continue; zDir = azDirs[i]; break; } /* Check that the output buffer is large enough for the temporary file ** name. If it is not, return SQLITE_ERROR. */ if( (strlen(zDir) + 17) >= (size_t)nBuf ){ fossil_fatal("insufficient space for temporary filename"); } do{ sqlite3_snprintf(nBuf-17, zBuf, "%s/", zDir); j = (int)strlen(zBuf); sqlite3_randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; }while( file_size(zBuf)<0 ); } /* ** Return true if a file named zName exists and has identical content ** to the blob pContent. If zName does not exist or if the content is ** different in any way, then return false. |
︙ | ︙ | |||
666 667 668 669 670 671 672 | if( iSize<0 ) return 0; if( iSize!=blob_size(pContent) ) return 0; blob_read_from_file(&onDisk, zName); rc = blob_compare(&onDisk, pContent); blob_reset(&onDisk); return rc==0; } | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 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 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 | if( iSize<0 ) return 0; if( iSize!=blob_size(pContent) ) return 0; blob_read_from_file(&onDisk, zName); rc = blob_compare(&onDisk, pContent); blob_reset(&onDisk); return rc==0; } /************************************************************************** ** The following routines translate between MBCS and UTF8 on windows. ** Since everything is always UTF8 on unix, these routines are no-ops ** there. */ #ifdef _WIN32 # include <windows.h> #endif /* ** Translate MBCS to UTF8. Return a pointer to the translated text. ** Call fossil_mbcs_free() to deallocate any memory used to store the ** returned pointer when done. */ char *fossil_mbcs_to_utf8(const char *zMbcs){ #ifdef _WIN32 extern char *sqlite3_win32_mbcs_to_utf8(const char*); return sqlite3_win32_mbcs_to_utf8(zMbcs); #else return (char*)zMbcs; /* No-op on unix */ #endif } /* ** Translate UTF8 to MBCS for use in system calls. Return a pointer to the ** translated text.. Call fossil_mbcs_free() to deallocate any memory ** used to store the returned pointer when done. */ char *fossil_utf8_to_mbcs(const char *zUtf8){ #ifdef _WIN32 extern char *sqlite3_win32_utf8_to_mbcs(const char*); return sqlite3_win32_utf8_to_mbcs(zUtf8); #else return (char*)zUtf8; /* No-op on unix */ #endif } /* ** Translate UTF8 to MBCS for display on the console. Return a pointer to the ** translated text.. Call fossil_mbcs_free() to deallocate any memory ** used to store the returned pointer when done. */ char *fossil_utf8_to_console(const char *zUtf8){ #ifdef _WIN32 int nChar, nByte; WCHAR *zUnicode; /* Unicode version of zUtf8 */ char *zConsole; /* Console version of zUtf8 */ int codepage; /* Console code page */ nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0); zUnicode = malloc( nChar*sizeof(zUnicode[0]) ); if( zUnicode==0 ){ return 0; } nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar); if( nChar==0 ){ free(zUnicode); return 0; } codepage = GetConsoleCP(); nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, 0, 0, 0, 0); zConsole = malloc( nByte ); if( zConsole==0 ){ free(zUnicode); return 0; } nByte = WideCharToMultiByte(codepage, 0, zUnicode, -1, zConsole, nByte, 0, 0); free(zUnicode); if( nByte == 0 ){ free(zConsole); zConsole = 0; } return zConsole; #else return (char*)zUtf8; /* No-op on unix */ #endif } /* ** Translate MBCS to UTF8. Return a pointer. Call fossil_mbcs_free() ** to deallocate any memory used to store the returned pointer when done. */ void fossil_mbcs_free(char *zOld){ #ifdef _WIN32 free(zOld); #else /* No-op on unix */ #endif } /* ** Like fopen() but always takes a UTF8 argument. */ FILE *fossil_fopen(const char *zName, const char *zMode){ char *zMbcs = fossil_utf8_to_mbcs(zName); FILE *f = fopen(zMbcs, zMode); fossil_mbcs_free(zMbcs); return f; } |
Changes to src/finfo.c.
︙ | ︙ | |||
87 88 89 90 91 92 93 | blob_appendf(&line, " "); blob_appendf(&line, " %10.10s", blob_str(&uuid)); blob_reset(&uuid); }else{ blob_appendf(&line, "unknown 0000000000"); } db_finalize(&q); | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | blob_appendf(&line, " "); blob_appendf(&line, " %10.10s", blob_str(&uuid)); blob_reset(&uuid); }else{ blob_appendf(&line, "unknown 0000000000"); } db_finalize(&q); fossil_print("%s\n", blob_str(&line)); blob_reset(&fname); blob_reset(&line); }else if( find_option("print","p",0) ){ Blob record; Blob fname; const char *zRevision = find_option("revision", "r", 1); |
︙ | ︙ | |||
150 151 152 153 154 155 156 | " AND event.objid=mlink.mid" " AND event.objid=ci.rid" " ORDER BY event.mtime DESC LIMIT %d OFFSET %d", zFilename, iLimit, iOffset ); blob_zero(&line); if( iBrief ){ | | | | 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 | " AND event.objid=mlink.mid" " AND event.objid=ci.rid" " ORDER BY event.mtime DESC LIMIT %d OFFSET %d", zFilename, iLimit, iOffset ); blob_zero(&line); if( iBrief ){ fossil_print("History of %s\n", blob_str(&fname)); } while( db_step(&q)==SQLITE_ROW ){ const char *zFileUuid = db_column_text(&q, 0); const char *zCiUuid = db_column_text(&q,1); const char *zDate = db_column_text(&q, 2); const char *zCom = db_column_text(&q, 3); const char *zUser = db_column_text(&q, 4); char *zOut; if( iBrief ){ fossil_print("%s ", zDate); zOut = sqlite3_mprintf("[%.10s] %s (user: %s, artifact: [%.10s])", zCiUuid, zCom, zUser, zFileUuid); comment_print(zOut, 11, 79); sqlite3_free(zOut); }else{ blob_reset(&line); blob_appendf(&line, "%.10s ", zCiUuid); |
︙ | ︙ |
Changes to src/glob.c.
︙ | ︙ | |||
56 57 58 59 60 61 62 | }else{ cTerm = ','; } for(i=0; zGlobList[i] && zGlobList[i]!=cTerm; i++){} if( cTerm==',' ){ while( i>0 && fossil_isspace(zGlobList[i-1]) ){ i--; } } | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | }else{ cTerm = ','; } for(i=0; zGlobList[i] && zGlobList[i]!=cTerm; i++){} if( cTerm==',' ){ while( i>0 && fossil_isspace(zGlobList[i-1]) ){ i--; } } blob_appendf(&expr, "%s%s GLOB '%#q'", zSep, zVal, i, zGlobList); zSep = " OR "; if( cTerm!=',' && zGlobList[i] ) i++; zGlobList += i; if( zGlobList[0] ) zGlobList++; nTerm++; } if( nTerm ){ |
︙ | ︙ | |||
248 249 250 251 252 253 254 | ** PATTERN is a comma-separated list of glob patterns. Show which of ** the STRINGs that follow match the PATTERN. */ void glob_test_cmd(void){ Glob *pGlob; int i; if( g.argc<4 ) usage("PATTERN STRING ..."); | | | | | 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | ** PATTERN is a comma-separated list of glob patterns. Show which of ** the STRINGs that follow match the PATTERN. */ void glob_test_cmd(void){ Glob *pGlob; int i; if( g.argc<4 ) usage("PATTERN STRING ..."); fossil_print("SQL expression: %s\n", glob_expr("x", g.argv[2])); pGlob = glob_create(g.argv[2]); for(i=0; i<pGlob->nPattern; i++){ fossil_print("pattern[%d] = [%s]\n", i, pGlob->azPattern[i]); } for(i=3; i<g.argc; i++){ fossil_print("%d %s\n", glob_match(pGlob, g.argv[i]), g.argv[i]); } glob_free(pGlob); } |
Changes to src/http.c.
︙ | ︙ | |||
37 38 39 40 41 42 43 | Blob nonce; /* The nonce */ const char *zLogin; /* The user login name */ const char *zPw; /* The user password */ Blob pw; /* The nonce with user password appended */ Blob sig; /* The signature field */ blob_zero(pLogin); | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | Blob nonce; /* The nonce */ const char *zLogin; /* The user login name */ const char *zPw; /* The user password */ Blob pw; /* The nonce with user password appended */ Blob sig; /* The signature field */ blob_zero(pLogin); if( g.urlUser==0 || fossil_strcmp(g.urlUser, "anonymous")==0 ){ return; /* If no login card for users "nobody" and "anonymous" */ } if( g.urlIsSsh ){ return; /* If no login card for SSH: */ } blob_zero(&nonce); blob_zero(&pw); |
︙ | ︙ | |||
231 232 233 234 235 236 237 | closeConnection = 0; } }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){ int i, j; for(i=9; zLine[i] && zLine[i]==' '; i++){} if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine); j = strlen(zLine) - 1; | | | 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 | closeConnection = 0; } }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){ int i, j; for(i=9; zLine[i] && zLine[i]==' '; i++){} if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine); j = strlen(zLine) - 1; while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){ j -= 4; zLine[j] = 0; } fossil_print("redirect to %s\n", &zLine[i]); url_parse(&zLine[i]); transport_close(); return http_exchange(pSend, pReply, useLogin); |
︙ | ︙ |
Changes to src/http_ssl.c.
︙ | ︙ | |||
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 | } if( SSL_get_verify_result(ssl) != X509_V_OK ){ char *desc, *prompt; char *warning = ""; Blob ans; BIO *mem; mem = BIO_new(BIO_s_mem()); X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE); BIO_puts(mem, "\n\nIssued By:\n\n"); X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE); BIO_write(mem, "", 1); // null-terminate mem buffer BIO_get_mem_data(mem, &desc); if( hasSavedCertificate ){ warning = "WARNING: Certificate doesn't match the " "saved certificate for this host!"; } | > > > > > > > > > | 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 | } if( SSL_get_verify_result(ssl) != X509_V_OK ){ char *desc, *prompt; char *warning = ""; Blob ans; BIO *mem; unsigned char md[32]; unsigned int mdLength = 31; mem = BIO_new(BIO_s_mem()); X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE); BIO_puts(mem, "\n\nIssued By:\n\n"); X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE); BIO_puts(mem, "\n\nSHA1 Fingerprint:\n\n "); if(X509_digest(cert, EVP_sha1(), md, &mdLength)){ int j; for( j = 0; j < mdLength; ++j ) { BIO_printf(mem, " %02x", md[j]); } } BIO_write(mem, "", 1); // null-terminate mem buffer BIO_get_mem_data(mem, &desc); if( hasSavedCertificate ){ warning = "WARNING: Certificate doesn't match the " "saved certificate for this host!"; } |
︙ | ︙ |
Changes to src/http_transport.c.
︙ | ︙ | |||
118 119 120 121 122 123 124 | if( g.urlPort!=g.urlDfltPort ){ #ifdef __MINGW32__ blob_appendf(&zCmd, " -P %d", g.urlPort); #else blob_appendf(&zCmd, " -p %d", g.urlPort); #endif } | | | | | 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 | if( g.urlPort!=g.urlDfltPort ){ #ifdef __MINGW32__ blob_appendf(&zCmd, " -P %d", g.urlPort); #else blob_appendf(&zCmd, " -p %d", g.urlPort); #endif } fossil_print("%s", blob_str(&zCmd)); /* Show the base of the SSH command */ if( g.urlUser && g.urlUser[0] ){ zHost = mprintf("%s@%s", g.urlUser, g.urlName); #ifdef __MINGW32__ /* Only win32 (and specifically PLINK.EXE) support the -pw option */ if( g.urlPasswd && g.urlPasswd[0] ){ Blob pw; blob_zero(&pw); if( g.urlPasswd[0]=='*' ){ char *zPrompt; zPrompt = mprintf("Password for [%s]: ", zHost); prompt_for_password(zPrompt, &pw, 0); free(zPrompt); }else{ blob_init(&pw, g.urlPasswd, -1); } blob_append(&zCmd, " -pw ", -1); shell_escape(&zCmd, blob_str(&pw)); blob_reset(&pw); fossil_print(" -pw ********"); /* Do not show the password text */ } #endif }else{ zHost = mprintf("%s", g.urlName); } blob_append(&zCmd, " ", 1); shell_escape(&zCmd, zHost); fossil_print(" %s\n", zHost); /* Show the conclusion of the SSH command */ free(zHost); popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid); if( sshPid==0 ){ fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd); } blob_reset(&zCmd); |
︙ | ︙ | |||
244 245 246 247 248 249 250 | ssl_close(); #endif }else if( g.urlIsFile ){ if( transport.pFile ){ fclose(transport.pFile); transport.pFile = 0; } | | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | ssl_close(); #endif }else if( g.urlIsFile ){ if( transport.pFile ){ fclose(transport.pFile); transport.pFile = 0; } file_delete(transport.zInFile); file_delete(transport.zOutFile); free(transport.zInFile); free(transport.zOutFile); }else{ socket_close(); } transport.isOpen = 0; } |
︙ | ︙ |
Changes to src/import.c.
︙ | ︙ | |||
203 204 205 206 207 208 209 | /* ** Compare two ImportFile objects for sorting */ static int mfile_cmp(const void *pLeft, const void *pRight){ const ImportFile *pA = (const ImportFile*)pLeft; const ImportFile *pB = (const ImportFile*)pRight; | | | 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | /* ** Compare two ImportFile objects for sorting */ static int mfile_cmp(const void *pLeft, const void *pRight){ const ImportFile *pA = (const ImportFile*)pLeft; const ImportFile *pB = (const ImportFile*)pRight; return fossil_strcmp(pA->zName, pB->zName); } /* Forward reference */ static void import_prior_files(void); /* ** Use data accumulated in gg from a "commit" record to add a new |
︙ | ︙ | |||
495 496 497 498 499 500 501 | }else if( memcmp(zLine, "option", 6)==0 ){ gg.xFinish(); }else if( memcmp(zLine, "progress ", 9)==0 ){ gg.xFinish(); trim_newline(&zLine[9]); | | | 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 | }else if( memcmp(zLine, "option", 6)==0 ){ gg.xFinish(); }else if( memcmp(zLine, "progress ", 9)==0 ){ gg.xFinish(); trim_newline(&zLine[9]); fossil_print("%s\n", &zLine[9]); fflush(stdout); }else if( memcmp(zLine, "data ", 5)==0 ){ fossil_free(gg.aData); gg.aData = 0; gg.nData = atoi(&zLine[5]); if( gg.nData ){ int got; |
︙ | ︙ | |||
695 696 697 698 699 700 701 | if( g.argc==4 ){ pIn = fopen(g.argv[3], "rb"); }else{ pIn = stdin; fossil_binary_mode(pIn); } if( !incrFlag ){ | | | 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 | if( g.argc==4 ){ pIn = fopen(g.argv[3], "rb"); }else{ pIn = stdin; fossil_binary_mode(pIn); } if( !incrFlag ){ if( forceFlag ) file_delete(g.argv[2]); db_create_repository(g.argv[2]); } db_open_repository(g.argv[2]); db_open_config(0); /* The following temp-tables are used to hold information needed for ** the import. |
︙ | ︙ | |||
740 741 742 743 744 745 746 | db_ephemeral_blob(&q, 0, &record); fast_insert_content(&record, 0, 0); import_reset(0); } db_finalize(&q); db_end_transaction(0); db_begin_transaction(); | | | | | | | | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 | db_ephemeral_blob(&q, 0, &record); fast_insert_content(&record, 0, 0); import_reset(0); } db_finalize(&q); db_end_transaction(0); db_begin_transaction(); fossil_print("Rebuilding repository meta-data...\n"); rebuild_db(0, 1, !incrFlag); verify_cancel(); db_end_transaction(0); fossil_print("Vacuuming..."); fflush(stdout); db_multi_exec("VACUUM"); fossil_print(" ok\n"); if( !incrFlag ){ fossil_print("project-id: %s\n", db_get("project-code", 0)); fossil_print("server-id: %s\n", db_get("server-code", 0)); zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword); } } |
Changes to src/info.c.
︙ | ︙ | |||
65 66 67 68 69 70 71 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); if( zUuid ){ zDate = db_text(0, "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", rid ); /* 01234567890123 */ | | | | | | | 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 | zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); if( zUuid ){ zDate = db_text(0, "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", rid ); /* 01234567890123 */ fossil_print("%-13s %s %s\n", zUuidName, zUuid, zDate ? zDate : ""); free(zUuid); free(zDate); } if( zUuid && showComment ){ zComment = db_text(0, "SELECT coalesce(ecomment,comment) || " " ' (user: ' || coalesce(euser,user,'?') || ')' " " FROM event WHERE objid=%d", rid ); } if( showFamily ){ db_prepare(&q, "SELECT uuid, pid FROM plink JOIN blob ON pid=rid " " WHERE cid=%d", rid); while( db_step(&q)==SQLITE_ROW ){ const char *zUuid = db_column_text(&q, 0); zDate = db_text("", "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", db_column_int(&q, 1) ); fossil_print("parent: %s %s\n", zUuid, zDate); free(zDate); } db_finalize(&q); db_prepare(&q, "SELECT uuid, cid FROM plink JOIN blob ON cid=rid " " WHERE pid=%d", rid); while( db_step(&q)==SQLITE_ROW ){ const char *zUuid = db_column_text(&q, 0); zDate = db_text("", "SELECT datetime(mtime) || ' UTC' FROM event WHERE objid=%d", db_column_int(&q, 1) ); fossil_print("child: %s %s\n", zUuid, zDate); free(zDate); } db_finalize(&q); } zTags = info_tags_of_checkin(rid, 0); if( zTags && zTags[0] ){ fossil_print("tags: %s\n", zTags); } free(zTags); if( zComment ){ fossil_print("comment: "); comment_print(zComment, 14, 79); free(zComment); } } /* |
︙ | ︙ | |||
139 140 141 142 143 144 145 | if( g.argc!=2 && g.argc!=3 ){ usage("?FILENAME|ARTIFACT-ID?"); } if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){ db_open_config(0); db_record_repository_filename(g.argv[2]); db_open_repository(g.argv[2]); | | | | | | | | | | | | 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 | if( g.argc!=2 && g.argc!=3 ){ usage("?FILENAME|ARTIFACT-ID?"); } if( g.argc==3 && (fsize = file_size(g.argv[2]))>0 && (fsize&0x1ff)==0 ){ db_open_config(0); db_record_repository_filename(g.argv[2]); db_open_repository(g.argv[2]); fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); fossil_print("project-code: %s\n", db_get("project-code", "<none>")); fossil_print("server-code: %s\n", db_get("server-code", "<none>")); return; } db_must_be_within_tree(); if( g.argc==2 ){ int vid; /* 012345678901234 */ db_record_repository_filename(0); fossil_print("project-name: %s\n", db_get("project-name", "<unnamed>")); fossil_print("repository: %s\n", db_lget("repository", "")); fossil_print("local-root: %s\n", g.zLocalRoot); #if defined(_WIN32) if( g.zHome ){ fossil_print("user-home: %s\n", g.zHome); } #endif fossil_print("project-code: %s\n", db_get("project-code", "")); fossil_print("server-code: %s\n", db_get("server-code", "")); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_print("checkout: nil\n"); }else{ show_common_info(vid, "checkout:", 1, 1); } }else{ int rid; rid = name_to_rid(g.argv[2]); if( rid==0 ){ |
︙ | ︙ | |||
218 219 220 221 222 223 224 | if( zOrigUuid && zOrigUuid[0] ){ @ inherited from hyperlink_to_uuid(zOrigUuid); }else{ @ propagates to descendants } #if 0 | | | 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | if( zOrigUuid && zOrigUuid[0] ){ @ inherited from hyperlink_to_uuid(zOrigUuid); }else{ @ propagates to descendants } #if 0 if( zValue && fossil_strcmp(zTagname,"branch")==0 ){ @ @ <a href="%s(g.zTop)/timeline?r=%T(zValue)">branch timeline</a> } #endif } if( zSrcUuid && zSrcUuid[0] ){ if( tagtype==0 ){ |
︙ | ︙ | |||
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 | ** Write a line of web-page output that shows changes that have occurred ** to a file between two check-ins. */ static void append_file_change_line( const char *zName, /* Name of the file that has changed */ const char *zOld, /* blob.uuid before change. NULL for added files */ const char *zNew, /* blob.uuid after change. NULL for deletes */ int showDiff, /* Show edit diffs if true */ int mperm /* EXE permission for zNew */ ){ if( !g.okHistory ){ if( zNew==0 ){ @ <p>Deleted %h(zName)</p> }else if( zOld==0 ){ @ <p>Added %h(zName)</p> }else if( fossil_strcmp(zNew, zOld)==0 ){ @ <p>Execute permission %s(mperm?"set":"cleared") for %h(zName)</p> }else{ @ <p>Changes to %h(zName)</p> } if( showDiff ){ @ <blockquote><pre> append_diff(zOld, zNew); @ </pre></blockquote> } }else{ if( zOld && zNew ){ if( fossil_strcmp(zOld, zNew)!=0 ){ @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> }else{ @ <p>Execute permission %s(mperm?"set":"cleared") for @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> } }else if( zOld ){ @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> }else{ @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a> } if( showDiff ){ @ <blockquote><pre> append_diff(zOld, zNew); @ </pre></blockquote> | > > > > > > > | | 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 | ** Write a line of web-page output that shows changes that have occurred ** to a file between two check-ins. */ static void append_file_change_line( const char *zName, /* Name of the file that has changed */ const char *zOld, /* blob.uuid before change. NULL for added files */ const char *zNew, /* blob.uuid after change. NULL for deletes */ const char *zOldName, /* Prior name. NULL if no name change. */ int showDiff, /* Show edit diffs if true */ int mperm /* EXE permission for zNew */ ){ if( !g.okHistory ){ if( zNew==0 ){ @ <p>Deleted %h(zName)</p> }else if( zOld==0 ){ @ <p>Added %h(zName)</p> }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ @ <p>Name change from %h(zOldName) to %h(zName) }else if( fossil_strcmp(zNew, zOld)==0 ){ @ <p>Execute permission %s(mperm?"set":"cleared") for %h(zName)</p> }else{ @ <p>Changes to %h(zName)</p> } if( showDiff ){ @ <blockquote><pre> append_diff(zOld, zNew); @ </pre></blockquote> } }else{ if( zOld && zNew ){ if( fossil_strcmp(zOld, zNew)!=0 ){ @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> @ from <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> @ to <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)].</a> }else if( zOldName!=0 && fossil_strcmp(zName,zOldName)!=0 ){ @ <p>Name change from @ from <a href="%s(g.zTop)/finfo?name=%T(zOldName)">%h(zOldName)</a> @ to <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>. }else{ @ <p>Execute permission %s(mperm?"set":"cleared") for @ <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> } }else if( zOld ){ @ <p>Deleted <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> @ version <a href="%s(g.zTop)/artifact/%s(zOld)">[%S(zOld)]</a> }else{ @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a> @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a> } if( showDiff ){ @ <blockquote><pre> append_diff(zOld, zNew); @ </pre></blockquote> }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){ @ @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&v2=%S(zNew)">[diff]</a> } @ </p> } } |
︙ | ︙ | |||
509 510 511 512 513 514 515 | }else{ @ <a href="%s(g.zTop)/vinfo/%T(zName)">[show diffs]</a> } } @ @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/> db_prepare(&q, | | > | > > | | 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 | }else{ @ <a href="%s(g.zTop)/vinfo/%T(zName)">[show diffs]</a> } } @ @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/> db_prepare(&q, "SELECT name," " mperm," " (SELECT uuid FROM blob WHERE rid=mlink.pid)," " (SELECT uuid FROM blob WHERE rid=mlink.fid)," " (SELECT name FROM filename WHERE filename.fnid=mlink.pfnid)" " FROM mlink JOIN filename ON filename.fnid=mlink.fnid" " WHERE mlink.mid=%d" " ORDER BY name", rid ); while( db_step(&q)==SQLITE_ROW ){ const char *zName = db_column_text(&q,0); int mperm = db_column_int(&q, 1); const char *zOld = db_column_text(&q,2); const char *zNew = db_column_text(&q,3); const char *zOldName = db_column_text(&q, 4); append_file_change_line(zName, zOld, zNew, zOldName, showDiff, mperm); } db_finalize(&q); } style_footer(); } /* |
︙ | ︙ | |||
713 714 715 716 717 718 719 | }else if( pFileTo==0 ){ cmp = -1; }else{ cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); } if( cmp<0 ){ append_file_change_line(pFileFrom->zName, | | | | | 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 | }else if( pFileTo==0 ){ cmp = -1; }else{ cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName); } if( cmp<0 ){ append_file_change_line(pFileFrom->zName, pFileFrom->zUuid, 0, 0, 0, 0); pFileFrom = manifest_file_next(pFrom, 0); }else if( cmp>0 ){ append_file_change_line(pFileTo->zName, 0, pFileTo->zUuid, 0, 0, manifest_file_mperm(pFileTo)); pFileTo = manifest_file_next(pTo, 0); }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){ /* No changes */ pFileFrom = manifest_file_next(pFrom, 0); pFileTo = manifest_file_next(pTo, 0); }else{ append_file_change_line(pFileFrom->zName, pFileFrom->zUuid, pFileTo->zUuid, 0, showDetail, manifest_file_mperm(pFileTo)); pFileFrom = manifest_file_next(pFrom, 0); pFileTo = manifest_file_next(pTo, 0); } } manifest_destroy(pFrom); manifest_destroy(pTo); |
︙ | ︙ | |||
1384 1385 1386 1387 1388 1389 1390 | } if( db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'event-%q*'", zName) ){ event_page(); return; } } blob_set(&uuid, zName); | | | 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 | } if( db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'event-%q*'", zName) ){ event_page(); return; } } blob_set(&uuid, zName); rc = name_to_uuid(&uuid, -1, "*"); if( rc==1 ){ style_header("No Such Object"); @ <p>No such object: %h(zName)</p> style_footer(); return; }else if( rc==2 ){ cgi_set_parameter("src","info"); |
︙ | ︙ | |||
1574 1575 1576 1577 1578 1579 1580 | int fNewPropagateColor; /* True if color propagates after edit */ char *zUuid; Blob comment; Stmt q; login_check_credentials(); if( !g.okWrite ){ login_needed(); return; } | | | 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 | int fNewPropagateColor; /* True if color propagates after edit */ char *zUuid; Blob comment; Stmt q; login_check_credentials(); if( !g.okWrite ){ login_needed(); return; } rid = name_to_typed_rid(P("r"), "ci"); zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid); zComment = db_text(0, "SELECT coalesce(ecomment,comment)" " FROM event WHERE objid=%d", rid); if( zComment==0 ) fossil_redirect_home(); if( P("cancel") ){ cgi_redirectf("ci?name=%s", zUuid); } |
︙ | ︙ | |||
1617 1618 1619 1620 1621 1622 1623 | login_verify_csrf_secret(); blob_zero(&ctrl); zNow = date_in_standard_format("now"); blob_appendf(&ctrl, "D %s\n", zNow); db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); if( zNewColor[0] | | | 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 | login_verify_csrf_secret(); blob_zero(&ctrl); zNow = date_in_standard_format("now"); blob_appendf(&ctrl, "D %s\n", zNow); db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)"); if( zNewColor[0] && (fPropagateColor!=fNewPropagateColor || fossil_strcmp(zColor,zNewColor)!=0) ){ char *zPrefix = "+"; if( fNewPropagateColor ){ zPrefix = "*"; } db_multi_exec("REPLACE INTO newtags VALUES('bgcolor',%Q,%Q)", zPrefix, zNewColor); |
︙ | ︙ |
Changes to src/login.c.
︙ | ︙ | |||
150 151 152 153 154 155 156 | ){ const char *zCS; /* The captcha seed value */ const char *zPw; /* The correct password shown in the captcha */ int uid; /* The user ID of anonymous */ if( zUsername==0 ) return 0; if( zPassword==0 ) return 0; | | | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | ){ const char *zCS; /* The captcha seed value */ const char *zPw; /* The correct password shown in the captcha */ int uid; /* The user ID of anonymous */ if( zUsername==0 ) return 0; if( zPassword==0 ) return 0; if( fossil_strcmp(zUsername,"anonymous")!=0 ) return 0; zCS = P("cs"); /* The "cs" parameter is the "captcha seed" */ if( zCS==0 ) return 0; zPw = captcha_decode((unsigned int)atoi(zCS)); if( fossil_stricmp(zPw, zPassword)!=0 ) return 0; uid = db_int(0, "SELECT uid FROM user WHERE login='anonymous'" " AND length(pw)>0 AND length(cap)>0"); return uid; |
︙ | ︙ | |||
478 479 480 481 482 483 484 485 486 487 488 489 490 491 | "SELECT value FROM config WHERE name='peer-repo-%q'", zCode ); if( zOtherRepo==0 ) return 0; /* No such peer repository */ rc = sqlite3_open(zOtherRepo, &pOther); if( rc==SQLITE_OK ){ zSQL = mprintf( "SELECT cexpire FROM user" " WHERE cookie=%Q" " AND ipaddr=%Q" " AND login=%Q" " AND length(cap)>0" " AND length(pw)>0" | > > | 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 | "SELECT value FROM config WHERE name='peer-repo-%q'", zCode ); if( zOtherRepo==0 ) return 0; /* No such peer repository */ rc = sqlite3_open(zOtherRepo, &pOther); if( rc==SQLITE_OK ){ sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0); sqlite3_busy_timeout(pOther, 5000); zSQL = mprintf( "SELECT cexpire FROM user" " WHERE cookie=%Q" " AND ipaddr=%Q" " AND login=%Q" " AND length(cap)>0" " AND length(pw)>0" |
︙ | ︙ | |||
559 560 561 562 563 564 565 | ** local login is disabled and if we are using HTTP and not HTTPS, ** then there is no need to check user credentials. ** ** This feature allows the "fossil ui" command to give the user ** full access rights without having to log in. */ zRemoteAddr = ipPrefix(zIpAddr = PD("REMOTE_ADDR","nil")); | | | 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 | ** local login is disabled and if we are using HTTP and not HTTPS, ** then there is no need to check user credentials. ** ** This feature allows the "fossil ui" command to give the user ** full access rights without having to log in. */ zRemoteAddr = ipPrefix(zIpAddr = PD("REMOTE_ADDR","nil")); if( fossil_strcmp(zIpAddr, "127.0.0.1")==0 && g.useLocalauth && db_get_int("localauth",0)==0 && P("HTTPS")==0 ){ uid = db_int(0, "SELECT uid FROM user WHERE cap LIKE '%%s%%'"); g.zLogin = db_text("?", "SELECT login FROM user WHERE uid=%d", uid); zCap = "sx"; |
︙ | ︙ | |||
592 593 594 595 596 597 598 | zUser = &zHash[i]; break; } } } if( zUser==0 ){ /* Invalid cookie */ | | | 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 | zUser = &zHash[i]; break; } } } if( zUser==0 ){ /* Invalid cookie */ }else if( fossil_strcmp(zUser, "anonymous")==0 ){ /* Cookies of the form "HASH/TIME/anonymous". The TIME must not be ** too old and the sha1 hash of TIME/IPADDR/SECRET must match HASH. ** SECRET is the "captcha-secret" value in the repository. */ double rTime = atof(zArg); Blob b; blob_zero(&b); |
︙ | ︙ | |||
961 962 963 964 965 966 967 | @ <p><span class="loginError"> @ All fields are obligatory. @ </span></p> }else if( strlen(zPasswd) < 6){ @ <p><span class="loginError"> @ Password too weak. @ </span></p> | | | 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 | @ <p><span class="loginError"> @ All fields are obligatory. @ </span></p> }else if( strlen(zPasswd) < 6){ @ <p><span class="loginError"> @ Password too weak. @ </span></p> }else if( fossil_strcmp(zPasswd,zConfirm)!=0 ){ @ <p><span class="loginError"> @ The two copies of your new passwords do not match. @ </span></p> }else if( fossil_stricmp(zPw, zCap)!=0 ){ @ <p><span class="loginError"> @ Captcha text invalid. @ </span></p> |
︙ | ︙ | |||
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 | sqlite3_errmsg(pPeer), zSuffix); nErr++; sqlite3_close(pPeer); continue; } sqlite3_create_function(pPeer, "shared_secret", 3, SQLITE_UTF8, 0, sha1_shared_secret_sql_function, 0, 0); zErr = 0; rc = sqlite3_exec(pPeer, zSql, 0, 0, &zErr); if( zErr ){ blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName, zErr, zSuffix); sqlite3_free(zErr); nErr++; }else if( rc!=SQLITE_OK ){ | > > | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 | sqlite3_errmsg(pPeer), zSuffix); nErr++; sqlite3_close(pPeer); continue; } sqlite3_create_function(pPeer, "shared_secret", 3, SQLITE_UTF8, 0, sha1_shared_secret_sql_function, 0, 0); sqlite3_create_function(pPeer, "now", 0,SQLITE_ANY,0,db_now_function,0,0); sqlite3_busy_timeout(pPeer, 5000); zErr = 0; rc = sqlite3_exec(pPeer, zSql, 0, 0, &zErr); if( zErr ){ blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName, zErr, zSuffix); sqlite3_free(zErr); nErr++; }else if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
1190 1191 1192 1193 1194 1195 1196 | zSelfProjCode = db_get("project-code", "unknown"); zSelfLabel = db_get("project-name", 0); if( zSelfLabel==0 ){ zSelfLabel = zSelfProjCode; } /* Make sure we are not trying to join ourselves */ | | | 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 | zSelfProjCode = db_get("project-code", "unknown"); zSelfLabel = db_get("project-name", 0); if( zSelfLabel==0 ){ zSelfLabel = zSelfProjCode; } /* Make sure we are not trying to join ourselves */ if( fossil_strcmp(zRepo, zSelfRepo)==0 ){ *pzErrMsg = mprintf("The \"other\" repository is the same as this one."); return; } /* Make sure the other repository is a valid Fossil database */ if( file_size(zRepo)<0 ){ *pzErrMsg = mprintf("repository file \"%s\" does not exist", zRepo); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
63 64 65 66 67 68 69 70 71 72 73 74 75 76 | char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ int fHttpTrace; /* Trace outbound HTTP requests */ int fNoSync; /* Do not do an autosync even. --nosync */ char *zPath; /* Name of webpage being served */ char *zExtra; /* Extra path information past the webpage name */ char *zBaseURL; /* Full text of the URL being served */ char *zTop; /* Parent directory of zPath */ const char *zContentType; /* The content type of the input HTTP request */ int iErrPriority; /* Priority of current error message */ | > | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | char *zLocalRoot; /* The directory holding the local database */ int minPrefix; /* Number of digits needed for a distinct UUID */ int fSqlTrace; /* True if --sqltrace flag is present */ int fSqlStats; /* True if --sqltrace or --sqlstats are present */ int fSqlPrint; /* True if -sqlprint flag is present */ int fQuiet; /* True if -quiet flag is present */ int fHttpTrace; /* Trace outbound HTTP requests */ int fSystemTrace; /* Trace calls to fossil_system(), --systemtrace */ int fNoSync; /* Do not do an autosync even. --nosync */ char *zPath; /* Name of webpage being served */ char *zExtra; /* Extra path information past the webpage name */ char *zBaseURL; /* Full text of the URL being served */ char *zTop; /* Parent directory of zPath */ const char *zContentType; /* The content type of the input HTTP request */ int iErrPriority; /* Priority of current error message */ |
︙ | ︙ | |||
193 194 195 196 197 198 199 | int upr, lwr, cnt, m, i; int n = strlen(zName); lwr = 0; upr = nMap-1; while( lwr<=upr ){ int mid, c; mid = (upr+lwr)/2; | | | 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | int upr, lwr, cnt, m, i; int n = strlen(zName); lwr = 0; upr = nMap-1; while( lwr<=upr ){ int mid, c; mid = (upr+lwr)/2; c = fossil_strcmp(zName, aMap[mid].zName); if( c==0 ){ *pIndex = mid; return 0; }else if( c<0 ){ upr = mid - 1; }else{ lwr = mid + 1; |
︙ | ︙ | |||
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | /* ** This procedure runs first. */ int main(int argc, char **argv){ const char *zCmdName = "unknown"; int idx; int rc; sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); g.now = time(0); g.argc = argc; g.argv = argv; if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ zCmdName = "cgi"; }else if( argc<2 ){ | > > | | | | < > | | < | | | | < | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | /* ** This procedure runs first. */ int main(int argc, char **argv){ const char *zCmdName = "unknown"; int idx; int rc; int i; sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0); g.now = time(0); g.argc = argc; g.argv = argv; for(i=0; i<argc; i++) g.argv[i] = fossil_mbcs_to_utf8(argv[i]); if( getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){ zCmdName = "cgi"; }else if( argc<2 ){ fossil_fatal("Usage: %s COMMAND ...\n" "\"%s help\" for a list of available commands\n" "\"%s help COMMAND\" for specific details\n", argv[0], argv[0], argv[0]); }else{ g.fQuiet = find_option("quiet", 0, 0)!=0; g.fSqlTrace = find_option("sqltrace", 0, 0)!=0; g.fSqlStats = find_option("sqlstats", 0, 0)!=0; g.fSystemTrace = find_option("systemtrace", 0, 0)!=0; if( g.fSqlTrace ) g.fSqlStats = 1; g.fSqlPrint = find_option("sqlprint", 0, 0)!=0; g.fHttpTrace = find_option("httptrace", 0, 0)!=0; g.zLogin = find_option("user", "U", 1); if( find_option("help",0,0)!=0 ){ /* --help anywhere on the command line is translated into ** "fossil help argv[1] argv[2]..." */ int i; char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+2) ); for(i=1; i<g.argc; i++) zNewArgv[i+1] = argv[i]; zNewArgv[i+1] = 0; zNewArgv[0] = argv[0]; zNewArgv[1] = "help"; g.argc++; g.argv = zNewArgv; } zCmdName = g.argv[1]; } rc = name_search(zCmdName, aCommand, count(aCommand), &idx); if( rc==1 ){ fossil_fatal("%s: unknown command: %s\n" "%s: use \"help\" for more information\n", argv[0], zCmdName, argv[0]); }else if( rc==2 ){ int i, n; Blob couldbe; blob_zero(&couldbe); n = strlen(zCmdName); for(i=0; i<count(aCommand); i++){ if( memcmp(zCmdName, aCommand[i].zName, n)==0 ){ blob_appendf(&couldbe, " %s", aCommand[i].zName); } } fossil_fatal("%s: ambiguous command prefix: %s\n" "%s: could be any of:%s\n" "%s: use \"help\" for more information\n", argv[0], zCmdName, argv[0], blob_str(&couldbe), argv[0]); } aCommand[idx].xFunc(); fossil_exit(0); /*NOT_REACHED*/ return 0; } |
︙ | ︙ | |||
331 332 333 334 335 336 337 | z = vmprintf(zFormat, ap); va_end(ap); if( g.cgiOutput && once ){ once = 0; cgi_printf("<p class=\"generalError\">%h</p>", z); cgi_reply(); }else{ | | > | > | 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | z = vmprintf(zFormat, ap); va_end(ap); if( g.cgiOutput && once ){ once = 0; cgi_printf("<p class=\"generalError\">%h</p>", z); cgi_reply(); }else{ char *zOut = mprintf("%s: %s\n", fossil_nameofexe(), z); fossil_puts(zOut, 1); } db_force_rollback(); fossil_exit(1); } void fossil_fatal(const char *zFormat, ...){ char *z; va_list ap; mainInFatalError = 1; va_start(ap, zFormat); z = vmprintf(zFormat, ap); va_end(ap); if( g.cgiOutput ){ g.cgiOutput = 0; cgi_printf("<p class=\"generalError\">%h</p>", z); cgi_reply(); }else{ char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); fossil_puts(zOut, 1); } db_force_rollback(); fossil_exit(1); } /* This routine works like fossil_fatal() except that if called ** recursively, the recursive call is a no-op. |
︙ | ︙ | |||
376 377 378 379 380 381 382 | z = vmprintf(zFormat, ap); va_end(ap); if( g.cgiOutput ){ g.cgiOutput = 0; cgi_printf("<p class=\"generalError\">%h</p>", z); cgi_reply(); }else{ | | > | > > | 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 | z = vmprintf(zFormat, ap); va_end(ap); if( g.cgiOutput ){ g.cgiOutput = 0; cgi_printf("<p class=\"generalError\">%h</p>", z); cgi_reply(); }else{ char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); fossil_puts(zOut, 1); } db_force_rollback(); fossil_exit(1); } /* Print a warning message */ void fossil_warning(const char *zFormat, ...){ char *z; va_list ap; va_start(ap, zFormat); z = vmprintf(zFormat, ap); va_end(ap); if( g.cgiOutput ){ cgi_printf("<p class=\"generalError\">%h</p>", z); }else{ char *zOut = mprintf("\r%s: %s\n", fossil_nameofexe(), z); fossil_puts(zOut, 1); free(zOut); } } /* ** Malloc and free routines that cannot fail */ void *fossil_malloc(size_t n){ |
︙ | ︙ | |||
424 425 426 427 428 429 430 | int fossil_system(const char *zOrigCmd){ int rc; #if defined(_WIN32) /* On windows, we have to put double-quotes around the entire command. ** Who knows why - this is just the way windows works. */ char *zNewCmd = mprintf("\"%s\"", zOrigCmd); | > > | > > < < < < < < < < < < < < < < < | 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | int fossil_system(const char *zOrigCmd){ int rc; #if defined(_WIN32) /* On windows, we have to put double-quotes around the entire command. ** Who knows why - this is just the way windows works. */ char *zNewCmd = mprintf("\"%s\"", zOrigCmd); char *zMbcs = fossil_utf8_to_mbcs(zNewCmd); if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zMbcs); rc = system(zMbcs); fossil_mbcs_free(zMbcs); free(zNewCmd); #else /* On unix, evaluate the command directly. */ if( g.fSystemTrace ) fprintf(stderr, "SYSTEM: %s\n", zOrigCmd); rc = system(zOrigCmd); #endif return rc; } /* ** Turn off any NL to CRNL translation on the stream given as an ** argument. This is a no-op on unix but is necessary on windows. */ void fossil_binary_mode(FILE *p){ #if defined(_WIN32) _setmode(_fileno(p), _O_BINARY); |
︙ | ︙ | |||
505 506 507 508 509 510 511 | fossil_warning("%s: %s", sqlite_error_code_name(iCode), zErrmsg); } /* ** Print a usage comment and quit */ void usage(const char *zFormat){ | | < | 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 | fossil_warning("%s: %s", sqlite_error_code_name(iCode), zErrmsg); } /* ** Print a usage comment and quit */ void usage(const char *zFormat){ fossil_fatal("Usage: %s %s %s\n", fossil_nameofexe(), g.argv[1], zFormat); } /* ** Remove n elements from g.argv beginning with the i-th element. */ void remove_from_argv(int i, int n){ int j; |
︙ | ︙ | |||
599 600 601 602 603 604 605 | } nCol = 80/(mxLen+2); if( nCol==0 ) nCol = 1; nRow = (nWord + nCol - 1)/nCol; for(i=0; i<nRow; i++){ const char *zSpacer = ""; for(j=i; j<nWord; j+=nRow){ | | | | 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | } nCol = 80/(mxLen+2); if( nCol==0 ) nCol = 1; nRow = (nWord + nCol - 1)/nCol; for(i=0; i<nRow; i++){ const char *zSpacer = ""; for(j=i; j<nWord; j+=nRow){ fossil_print("%s%-*s", zSpacer, mxLen, azWord[j]); zSpacer = " "; } fossil_print("\n"); } } /* ** List of commands starting with zPrefix, or all commands if zPrefix is NULL. */ static void cmd_cmd_list(const char *zPrefix){ |
︙ | ︙ | |||
648 649 650 651 652 653 654 | ** COMMAND: version ** ** Usage: %fossil version ** ** Print the source code version number for the fossil executable. */ void version_cmd(void){ | > | | | | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 | ** COMMAND: version ** ** Usage: %fossil version ** ** Print the source code version number for the fossil executable. */ void version_cmd(void){ fossil_print("This is fossil version " MANIFEST_VERSION " " MANIFEST_DATE " UTC\n"); } /* ** COMMAND: help ** ** Usage: %fossil help COMMAND ** ** Display information on how to use COMMAND */ void help_cmd(void){ int rc, idx; const char *z; if( g.argc<3 ){ fossil_print("Usage: %s help COMMAND.\nAvailable COMMANDs:\n", fossil_nameofexe()); cmd_cmd_list(0); version_cmd(); return; } rc = name_search(g.argv[2], aCommand, count(aCommand), &idx); if( rc==1 ){ fossil_print("unknown command: %s\nAvailable commands:\n", g.argv[2]); |
︙ | ︙ | |||
687 688 689 690 691 692 693 | z = aCmdHelp[idx]; if( z==0 ){ fossil_fatal("no help available for the %s command", aCommand[idx].zName); } while( *z ){ if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){ | | | 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 | z = aCmdHelp[idx]; if( z==0 ){ fossil_fatal("no help available for the %s command", aCommand[idx].zName); } while( *z ){ if( *z=='%' && strncmp(z, "%fossil", 7)==0 ){ fossil_print("%s", fossil_nameofexe()); z += 7; }else{ putchar(*z); z++; } } putchar('\n'); |
︙ | ︙ | |||
916 917 918 919 920 921 922 | zRepo[j] = '_'; } } if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; } szFile = file_size(zRepo); if( zPathInfo[i]=='/' && szFile<0 ){ | | | 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 | zRepo[j] = '_'; } } if( zRepo[0]=='/' && zRepo[1]=='/' ){ zRepo++; j--; } szFile = file_size(zRepo); if( zPathInfo[i]=='/' && szFile<0 ){ assert( fossil_strcmp(&zRepo[j], ".fossil")==0 ); zRepo[j] = 0; if( file_isdir(zRepo)==1 ){ fossil_free(zToFree); i++; continue; } zRepo[j] = '.'; |
︙ | ︙ | |||
1175 1176 1177 1178 1179 1180 1181 | set_base_url(); if( zName==0 ){ zName = P("SCRIPT_NAME"); if( zName && zName[0]=='/' ) zName++; } if( zName && validate16(zName, strlen(zName)) ){ for(i=0; i<nRedirect; i++){ | | | 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 | set_base_url(); if( zName==0 ){ zName = P("SCRIPT_NAME"); if( zName && zName[0]=='/' ) zName++; } if( zName && validate16(zName, strlen(zName)) ){ for(i=0; i<nRedirect; i++){ if( fossil_strcmp(azRedirect[i*2],"*")==0 ){ zNotFound = azRedirect[i*2+1]; continue; } db_open_repository(azRedirect[i*2]); if( db_exists("SELECT 1 FROM blob WHERE uuid GLOB '%s*'", zName) ){ cgi_redirectf(azRedirect[i*2+1], zName); return; |
︙ | ︙ | |||
1279 1280 1281 1282 1283 1284 1285 | if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost); g.cgiOutput = 1; if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ fossil_fatal("no repository specified"); } g.fullHttpReply = 1; if( g.argc==6 ){ | | | | 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 | if( zHost ) cgi_replace_parameter("HTTP_HOST",zHost); g.cgiOutput = 1; if( g.argc!=2 && g.argc!=3 && g.argc!=6 ){ fossil_fatal("no repository specified"); } g.fullHttpReply = 1; if( g.argc==6 ){ g.httpIn = fossil_fopen(g.argv[3], "rb"); g.httpOut = fossil_fopen(g.argv[4], "wb"); zIpAddr = g.argv[5]; }else{ g.httpIn = stdin; g.httpOut = stdout; zIpAddr = 0; } find_server_repository(0); |
︙ | ︙ | |||
1325 1326 1327 1328 1329 1330 1331 | char *zFull; int i; int bExists; while( zPath && zPath[0] ){ while( zPath[0]==':' ) zPath++; for(i=0; zPath[i] && zPath[i]!=':'; i++){} zFull = mprintf("%.*s/%s", i, zPath, zBinary); | | | 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 | char *zFull; int i; int bExists; while( zPath && zPath[0] ){ while( zPath[0]==':' ) zPath++; for(i=0; zPath[i] && zPath[i]!=':'; i++){} zFull = mprintf("%.*s/%s", i, zPath, zBinary); bExists = file_access(zFull, X_OK); free(zFull); if( bExists==0 ) return 1; zPath += i; } return 0; } #endif |
︙ | ︙ | |||
1453 1454 1455 1456 1457 1458 1459 | ** ** Echo all command-line arguments (enclosed in [...]) to the screen so that ** wildcard expansion behavior of the host shell can be investigated. */ void test_echo_cmd(void){ int i; for(i=0; i<g.argc; i++){ | | | 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 | ** ** Echo all command-line arguments (enclosed in [...]) to the screen so that ** wildcard expansion behavior of the host shell can be investigated. */ void test_echo_cmd(void){ int i; for(i=0; i<g.argc; i++){ fossil_print("argv[%d] = [%s]\n", i, g.argv[i]); } } |
Changes to src/manifest.c.
︙ | ︙ | |||
918 919 920 921 922 923 924 | ** Given a checkin name, load and parse the manifest for that checkin. ** Throw a fatal error if anything goes wrong. */ Manifest *manifest_get_by_name(const char *zName, int *pRid){ int rid; Manifest *p; | | | 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 | ** Given a checkin name, load and parse the manifest for that checkin. ** Throw a fatal error if anything goes wrong. */ Manifest *manifest_get_by_name(const char *zName, int *pRid){ int rid; Manifest *p; rid = name_to_typed_rid(zName, "ci"); if( !is_a_version(rid) ){ fossil_fatal("no such checkin: %s", zName); } if( pRid ) *pRid = rid; p = manifest_get(rid, CFTYPE_MANIFEST); if( p==0 ){ fossil_fatal("cannot parse manifest for checkin: %s", zName); |
︙ | ︙ | |||
1321 1322 1323 1324 1325 1326 1327 | if( pParentFile->zUuid ) continue; pChildFile = manifest_file_seek(pChild, pParentFile->zName); if( pChildFile ){ add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, isPublic, manifest_file_mperm(pChildFile)); } } | | | 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 | if( pParentFile->zUuid ) continue; pChildFile = manifest_file_seek(pChild, pParentFile->zName); if( pChildFile ){ add_one_mlink(cid, 0, pChildFile->zUuid, pChildFile->zName, 0, isPublic, manifest_file_mperm(pChildFile)); } } }else if( pChild->zBaseline==0 && pParent->zBaseline!=0 ){ /* Parent is a delta but pChild is a baseline. Look for files that are ** present in pParent but which are missing from pChild and mark them ** has having been deleted. */ manifest_file_rewind(pParent); while( (pParentFile = manifest_file_next(pParent,0))!=0 ){ pChildFile = manifest_file_seek(pChild, pParentFile->zName); if( pChildFile==0 && pParentFile->zUuid!=0 ){ |
︙ | ︙ |
Changes to src/md5.c.
︙ | ︙ | |||
374 375 376 377 378 379 380 | */ int md5sum_file(const char *zFilename, Blob *pCksum){ FILE *in; MD5Context ctx; unsigned char zResult[16]; char zBuf[10240]; | | | 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 | */ int md5sum_file(const char *zFilename, Blob *pCksum){ FILE *in; MD5Context ctx; unsigned char zResult[16]; char zBuf[10240]; in = fossil_fopen(zFilename,"rb"); if( in==0 ){ return 1; } MD5Init(&ctx); for(;;){ int n; n = fread(zBuf, 1, sizeof(zBuf), in); |
︙ | ︙ | |||
436 437 438 439 440 441 442 | for(i=2; i<g.argc; i++){ if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ blob_read_from_channel(&in, stdin, -1); md5sum_blob(&in, &cksum); }else{ md5sum_file(g.argv[i], &cksum); } | | | 436 437 438 439 440 441 442 443 444 445 446 | for(i=2; i<g.argc; i++){ if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ blob_read_from_channel(&in, stdin, -1); md5sum_blob(&in, &cksum); }else{ md5sum_file(g.argv[i], &cksum); } fossil_print("%s %s\n", blob_str(&cksum), g.argv[i]); blob_reset(&cksum); } } |
Changes to src/merge.c.
︙ | ︙ | |||
94 95 96 97 98 99 100 | } db_must_be_within_tree(); if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_fatal("nothing is checked out"); } | | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | } db_must_be_within_tree(); if( zBinGlob==0 ) zBinGlob = db_get("binary-glob",0); vid = db_lget_int("checkout", 0); if( vid==0 ){ fossil_fatal("nothing is checked out"); } mid = name_to_typed_rid(g.argv[2], "ci"); if( mid==0 || !is_a_version(mid) ){ fossil_fatal("not a version: %s", g.argv[2]); } if( zPivot ){ pid = name_to_typed_rid(zPivot, "ci"); if( pid==0 || !is_a_version(pid) ){ fossil_fatal("not a version: %s", zPivot); } if( pickFlag ){ fossil_fatal("incompatible options: --cherrypick & --baseline"); } /* pickFlag = 1; // Using --baseline is really like doing a cherrypick */ |
︙ | ︙ | |||
247 248 249 250 251 252 253 | ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, isexe FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ | | | | | | | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnp, fnm, chnged, ridv, ridp, ridm, isexe FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ fossil_print("%3d: ridv=%-4d ridp=%-4d ridm=%-4d chnged=%d isexe=%d\n", db_column_int(&q, 0), db_column_int(&q, 5), db_column_int(&q, 6), db_column_int(&q, 7), db_column_int(&q, 4), db_column_int(&q, 8)); fossil_print(" fn = [%s]\n", db_column_text(&q, 1)); fossil_print(" fnp = [%s]\n", db_column_text(&q, 2)); fossil_print(" fnm = [%s]\n", db_column_text(&q, 3)); } db_finalize(&q); } /* ** Find files in M and V but not in P and report conflicts. ** The file in M will be ignored. It will be treated as if it ** does not exist. */ db_prepare(&q, "SELECT idm FROM fv WHERE idp=0 AND idv>0 AND idm>0" ); while( db_step(&q)==SQLITE_ROW ){ int idm = db_column_int(&q, 0); char *zName = db_text(0, "SELECT pathname FROM vfile WHERE id=%d", idm); fossil_warning("WARNING - no common ancestor: %s\n", zName); free(zName); db_multi_exec("UPDATE fv SET idm=0 WHERE idm=%d", idm); } db_finalize(&q); /* ** Add to V files that are not in V or P but are in M |
︙ | ︙ | |||
298 299 300 301 302 303 304 | "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,pathname)" " SELECT %d,3,0,rid,mrid,isexe,pathname FROM vfile WHERE id=%d", vid, idm ); idv = db_last_insert_rowid(); db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); zName = db_column_text(&q, 2); | | | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,pathname)" " SELECT %d,3,0,rid,mrid,isexe,pathname FROM vfile WHERE id=%d", vid, idm ); idv = db_last_insert_rowid(); db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid); zName = db_column_text(&q, 2); fossil_print("ADDED %s\n", zName); if( !nochangeFlag ){ undo_save(zName); vfile_to_disk(0, idm, 0, 0); } } db_finalize(&q); |
︙ | ︙ | |||
320 321 322 323 324 325 326 | " AND ridm!=ridp AND ridv=ridp AND NOT chnged" ); while( db_step(&q)==SQLITE_ROW ){ int idv = db_column_int(&q, 0); int ridm = db_column_int(&q, 1); const char *zName = db_column_text(&q, 2); /* Copy content from idm over into idv. Overwrite idv. */ | | | 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 | " AND ridm!=ridp AND ridv=ridp AND NOT chnged" ); while( db_step(&q)==SQLITE_ROW ){ int idv = db_column_int(&q, 0); int ridm = db_column_int(&q, 1); const char *zName = db_column_text(&q, 2); /* Copy content from idm over into idv. Overwrite idv. */ fossil_print("UPDATE %s\n", zName); if( !nochangeFlag ){ undo_save(zName); db_multi_exec( "UPDATE vfile SET mtime=0, mrid=%d, chnged=2 WHERE id=%d", ridm, idv ); vfile_to_disk(0, idv, 0, 0); } |
︙ | ︙ | |||
353 354 355 356 357 358 359 | const char *zName = db_column_text(&q, 5); int isExe = db_column_int(&q, 6); int rc; char *zFullPath; Blob m, p, r; /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ if( detailFlag ){ | | > | | | | 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 | const char *zName = db_column_text(&q, 5); int isExe = db_column_int(&q, 6); int rc; char *zFullPath; Blob m, p, r; /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ if( detailFlag ){ fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", zName, ridp, ridm, ridv); }else{ fossil_print("MERGE %s\n", zName); } undo_save(zName); zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); content_get(ridp, &p); content_get(ridm, &m); if( isBinary ){ rc = -1; blob_zero(&r); }else{ rc = merge_3way(&p, zFullPath, &m, &r); } if( rc>=0 ){ if( !nochangeFlag ){ blob_write_to_file(&r, zFullPath); file_setexe(zFullPath, isExe); } db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv); if( rc>0 ){ fossil_print("***** %d merge conflicts in %s\n", rc, zName); nConflict++; } }else{ fossil_print("***** Cannot merge binary file %s\n", zName); nConflict++; } blob_reset(&p); blob_reset(&m); blob_reset(&r); db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(%d,%d)", idv,ridm); |
︙ | ︙ | |||
401 402 403 404 405 406 407 | " WHERE idp>0 AND idv>0 AND idm=0" ); while( db_step(&q)==SQLITE_ROW ){ int idv = db_column_int(&q, 0); const char *zName = db_column_text(&q, 1); int chnged = db_column_int(&q, 2); /* Delete the file idv */ | | | | | | > | | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 | " WHERE idp>0 AND idv>0 AND idm=0" ); while( db_step(&q)==SQLITE_ROW ){ int idv = db_column_int(&q, 0); const char *zName = db_column_text(&q, 1); int chnged = db_column_int(&q, 2); /* Delete the file idv */ fossil_print("DELETE %s\n", zName); if( chnged ){ fossil_warning("WARNING: local edits lost for %s\n", zName); nConflict++; } undo_save(zName); db_multi_exec( "UPDATE vfile SET deleted=1 WHERE id=%d", idv ); if( !nochangeFlag ){ char *zFullPath = mprintf("%s%s", g.zLocalRoot, zName); file_delete(zFullPath); free(zFullPath); } } db_finalize(&q); /* ** Rename files that have taken a rename on P->M but which keep the same ** name o P->V. If a file is renamed on P->V only or on both P->V and ** P->M then we retain the V name of the file. */ db_prepare(&q, "SELECT idv, fnp, fnm FROM fv" " WHERE idv>0 AND idp>0 AND idm>0 AND fnp=fn AND fnm!=fnp" ); while( db_step(&q)==SQLITE_ROW ){ int idv = db_column_int(&q, 0); const char *zOldName = db_column_text(&q, 1); const char *zNewName = db_column_text(&q, 2); fossil_print("RENAME %s -> %s\n", zOldName, zNewName); undo_save(zOldName); undo_save(zNewName); db_multi_exec( "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)" " WHERE id=%d AND vid=%d", zNewName, idv, vid ); if( !nochangeFlag ){ char *zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName); char *zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); file_copy(zFullOldPath, zFullNewPath); file_delete(zFullOldPath); free(zFullNewPath); free(zFullOldPath); } } db_finalize(&q); /* Report on conflicts */ if( nConflict && !nochangeFlag ){ fossil_warning( "WARNING: merge conflicts - see messages above for details.\n"); } /* ** Clean up the mid and pid VFILE entries. Then commit the changes. */ db_multi_exec("DELETE FROM vfile WHERE vid!=%d", vid); if( !pickFlag ){ db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid); } undo_finish(); db_end_transaction(nochangeFlag); } |
Changes to src/merge3.c.
︙ | ︙ | |||
312 313 314 315 316 317 318 | */ void delta_3waymerge_cmd(void){ Blob pivot, v1, v2, merged; if( g.argc!=6 ){ usage("PIVOT V1 V2 MERGED"); } if( blob_read_from_file(&pivot, g.argv[2])<0 ){ | | < | < | < | < | 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | */ void delta_3waymerge_cmd(void){ Blob pivot, v1, v2, merged; if( g.argc!=6 ){ usage("PIVOT V1 V2 MERGED"); } if( blob_read_from_file(&pivot, g.argv[2])<0 ){ fossil_fatal("cannot read %s\n", g.argv[2]); } if( blob_read_from_file(&v1, g.argv[3])<0 ){ fossil_fatal("cannot read %s\n", g.argv[3]); } if( blob_read_from_file(&v2, g.argv[4])<0 ){ fossil_fatal("cannot read %s\n", g.argv[4]); } blob_merge(&pivot, &v1, &v2, &merged); if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){ fossil_fatal("cannot write %s\n", g.argv[4]); } blob_reset(&pivot); blob_reset(&v1); blob_reset(&v2); blob_reset(&merged); } |
︙ | ︙ | |||
426 427 428 429 430 431 432 | azSubst[4] = "%merge"; azSubst[5] = zOther; azSubst[6] = "%output"; azSubst[7] = zOut; zCmd = string_subst(zGMerge, 8, azSubst); printf("%s\n", zCmd); fflush(stdout); fossil_system(zCmd); if( file_size(zOut)>=0 ){ blob_read_from_file(pOut, zOut); | | | | | | 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | azSubst[4] = "%merge"; azSubst[5] = zOther; azSubst[6] = "%output"; azSubst[7] = zOut; zCmd = string_subst(zGMerge, 8, azSubst); printf("%s\n", zCmd); fflush(stdout); fossil_system(zCmd); if( file_size(zOut)>=0 ){ blob_read_from_file(pOut, zOut); file_delete(zPivot); file_delete(zOrig); file_delete(zOther); file_delete(zOut); } fossil_free(zCmd); fossil_free(zOut); } fossil_free(zPivot); fossil_free(zOrig); fossil_free(zOther); } blob_reset(&v1); return rc; } |
Changes to src/name.c.
︙ | ︙ | |||
38 39 40 41 42 43 44 | ** string YYYY-MM-DD HH:MM:SS and pick the nearest check-in to that date. ** If the input is of the form "date:*" or "localtime:*" or "utc:*" then ** always resolve the name as a date. ** ** Return 0 on success. Return 1 if the name cannot be resolved. ** Return 2 name is ambiguous. */ | | | | | | 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 | ** string YYYY-MM-DD HH:MM:SS and pick the nearest check-in to that date. ** If the input is of the form "date:*" or "localtime:*" or "utc:*" then ** always resolve the name as a date. ** ** Return 0 on success. Return 1 if the name cannot be resolved. ** Return 2 name is ambiguous. */ int name_to_uuid(Blob *pName, int iErrPriority, const char *zType){ int rc; int sz; sz = blob_size(pName); if( sz>UUID_SIZE || sz<4 || !validate16(blob_buffer(pName), sz) ){ char *zUuid; const char *zName = blob_str(pName); if( memcmp(zName, "tag:", 4)==0 ){ zName += 4; zUuid = tag_to_uuid(zName, zType); }else{ zUuid = tag_to_uuid(zName, zType); if( zUuid==0 ){ zUuid = date_to_uuid(zName, zType); } } if( zUuid ){ blob_reset(pName); blob_append(pName, zUuid, -1); free(zUuid); return 0; |
︙ | ︙ | |||
77 78 79 80 81 82 83 | } }else if( sz<UUID_SIZE && sz>=4 ){ Stmt q; db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName); if( db_step(&q)!=SQLITE_ROW ){ char *zUuid; db_finalize(&q); | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | } }else if( sz<UUID_SIZE && sz>=4 ){ Stmt q; db_prepare(&q, "SELECT uuid FROM blob WHERE uuid GLOB '%b*'", pName); if( db_step(&q)!=SQLITE_ROW ){ char *zUuid; db_finalize(&q); zUuid = tag_to_uuid(blob_str(pName), "*"); if( zUuid ){ blob_reset(pName); blob_append(pName, zUuid, -1); free(zUuid); return 0; } fossil_error(iErrPriority, "no artifacts match the prefix \"%b\"", pName); |
︙ | ︙ | |||
139 140 141 142 143 144 145 | ** not older than 'date'. ** ** An input of "tip" returns the most recent check-in. ** ** Memory to hold the returned string comes from malloc() and needs to ** be freed by the caller. */ | | | > > | > | | 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 | ** not older than 'date'. ** ** An input of "tip" returns the most recent check-in. ** ** Memory to hold the returned string comes from malloc() and needs to ** be freed by the caller. */ char *tag_to_uuid(const char *zTag, const char *zType){ int vid; char *zUuid; if( zType==0 || zType[0]==0 ) zType = "*"; zUuid = db_text(0, "SELECT blob.uuid" " FROM tag, tagxref, event, blob" " WHERE tag.tagname='sym-%q' " " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " " AND event.objid=tagxref.rid " " AND blob.rid=event.objid " " AND event.type GLOB '%q'" " ORDER BY event.mtime DESC ", zTag, zType ); if( zUuid==0 ){ int nTag = strlen(zTag); int i; for(i=0; i<nTag-10; i++){ if( zTag[i]==':' && is_date(&zTag[i+1]) ){ char *zDate = mprintf("%s", &zTag[i+1]); |
︙ | ︙ | |||
174 175 176 177 178 179 180 181 | "SELECT blob.uuid" " FROM tag, tagxref, event, blob" " WHERE tag.tagname='sym-%q' " " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " " AND event.objid=tagxref.rid " " AND blob.rid=event.objid " " AND event.mtime<=julianday(%Q %s)" " ORDER BY event.mtime DESC ", | > | | 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | "SELECT blob.uuid" " FROM tag, tagxref, event, blob" " WHERE tag.tagname='sym-%q' " " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 " " AND event.objid=tagxref.rid " " AND blob.rid=event.objid " " AND event.mtime<=julianday(%Q %s)" " AND event.type GLOB '%q'" " ORDER BY event.mtime DESC ", zTagBase, zDate, (useUtc ? "" : ",'utc'"), zType ); break; } } if( zUuid==0 && fossil_strcmp(zTag, "tip")==0 ){ zUuid = db_text(0, "SELECT blob.uuid" |
︙ | ︙ | |||
220 221 222 223 224 225 226 | ** date:DATE ** local:DATE ** utc:DATE ** ** The DATE is interpreted as localtime unless the "utc:" prefix is used ** or a "utc" string appears at the end of the DATE string. */ | | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | ** date:DATE ** local:DATE ** utc:DATE ** ** The DATE is interpreted as localtime unless the "utc:" prefix is used ** or a "utc" string appears at the end of the DATE string. */ char *date_to_uuid(const char *zDate, const char *zType){ int useUtc = 0; int n; char *zCopy = 0; char *zUuid; if( memcmp(zDate, "date:", 5)==0 ){ zDate += 5; |
︙ | ︙ | |||
243 244 245 246 247 248 249 250 251 252 | if( n>4 && sqlite3_strnicmp(&zDate[n-3], "utc", 3)==0 ){ zCopy = mprintf("%s", zDate); zCopy[n-3] = 0; zDate = zCopy; n -= 3; useUtc = 1; } zUuid = db_text(0, "SELECT (SELECT uuid FROM blob WHERE rid=event.objid)" " FROM event" | > | | | | | | | | > > > | 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | if( n>4 && sqlite3_strnicmp(&zDate[n-3], "utc", 3)==0 ){ zCopy = mprintf("%s", zDate); zCopy[n-3] = 0; zDate = zCopy; n -= 3; useUtc = 1; } if( zType==0 || zType[0]==0 ) zType = "*"; zUuid = db_text(0, "SELECT (SELECT uuid FROM blob WHERE rid=event.objid)" " FROM event" " WHERE mtime<=julianday(%Q %s) AND type GLOB '%q'" " ORDER BY mtime DESC LIMIT 1", zDate, useUtc ? "" : ",'utc'", zType ); free(zCopy); return zUuid; } /* ** COMMAND: test-name-to-id ** ** Convert a name to a full artifact ID. */ void test_name_to_id(void){ int i; Blob name; db_must_be_within_tree(); for(i=2; i<g.argc; i++){ blob_init(&name, g.argv[i], -1); fossil_print("%s -> ", g.argv[i]); if( name_to_uuid(&name, 1, "*") ){ fossil_print("ERROR: %s\n", g.zErrMsg); fossil_error_reset(); }else{ fossil_print("%s\n", blob_buffer(&name)); } blob_reset(&name); } } /* ** Convert a name to a rid. If the name is a small integer value then ** just use atoi() to do the conversion. If the name contains alphabetic ** characters or is not an existing rid, then use name_to_uuid then ** convert the uuid to a rid. ** ** This routine is used by command-line routines to resolve command-line inputs ** into a rid. */ int name_to_typed_rid(const char *zName, const char *zType){ int i; int rid; Blob name; if( zName==0 || zName[0]==0 ) return 0; blob_init(&name, zName, -1); if( name_to_uuid(&name, -1, zType) ){ blob_reset(&name); for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){} if( zName[i]==0 ){ rid = atoi(zName); if( db_exists("SELECT 1 FROM blob WHERE rid=%d", rid) ){ return rid; } } fossil_error(1, "no such artifact: %s", zName); return 0; }else{ rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name); blob_reset(&name); } return rid; } int name_to_rid(const char *zName){ return name_to_typed_rid(zName, "*"); } /* ** WEBPAGE: ambiguous ** URL: /ambiguous?name=UUID&src=WEBPAGE ** ** The UUID given by the name paramager is ambiguous. Display a page ** that shows all possible choices and let the user select between them. |
︙ | ︙ | |||
359 360 361 362 363 364 365 | int i, rc; int rid; const char *zName = P(zParamName); Blob name; if( zName==0 || zName[0]==0 ) return 0; blob_init(&name, zName, -1); | | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | int i, rc; int rid; const char *zName = P(zParamName); Blob name; if( zName==0 || zName[0]==0 ) return 0; blob_init(&name, zName, -1); rc = name_to_uuid(&name, -1, "*"); if( rc==1 ){ blob_reset(&name); for(i=0; zName[i] && fossil_isdigit(zName[i]); i++){} if( zName[i]==0 ){ rid = atoi(zName); if( db_exists("SELECT 1 FROM blob WHERE rid=%d", rid) ){ return rid; |
︙ | ︙ |
Changes to src/path.c.
︙ | ︙ | |||
211 212 213 214 215 216 217 | for(n=1, p=path.pStart; p; p=p->u.pTo, n++){ char *z; z = db_text(0, "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" " FROM blob, event" " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", p->rid, p->rid); | | > | | | 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | for(n=1, p=path.pStart; p; p=p->u.pTo, n++){ char *z; z = db_text(0, "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" " FROM blob, event" " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", p->rid, p->rid); fossil_print("%4d: %s", n, z); fossil_free(z); if( p->u.pTo ){ fossil_print(" is a %s of\n", p->u.pTo->fromIsParent ? "parent" : "child"); }else{ fossil_print("\n"); } } } /* ** Find the closest common ancestor of two nodes. "Closest" means the ** fewest number of arcs. |
︙ | ︙ | |||
310 311 312 313 314 315 316 | for(n=1, p=path.pStart; p; p=p->u.pTo, n++){ char *z; z = db_text(0, "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" " FROM blob, event" " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", p->rid, p->rid); | | | | | | | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 | for(n=1, p=path.pStart; p; p=p->u.pTo, n++){ char *z; z = db_text(0, "SELECT substr(uuid,1,12) || ' ' || datetime(mtime)" " FROM blob, event" " WHERE blob.rid=%d AND event.objid=%d AND event.type='ci'", p->rid, p->rid); fossil_print("%4d: %s", n, z); fossil_free(z); if( p->rid==iFrom ) fossil_print(" VERSION1"); if( p->rid==iTo ) fossil_print(" VERSION2"); if( p->rid==iPivot ) fossil_print(" PIVOT"); fossil_print("\n"); } } /* ** A record of a file rename operation. */ |
︙ | ︙ | |||
443 444 445 446 447 448 449 | iTo = name_to_rid(g.argv[3]); find_filename_changes(iFrom, iTo, &nChng, &aChng); for(i=0; i<nChng; i++){ char *zFrom, *zTo; zFrom = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]); zTo = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2+1]); | | | 444 445 446 447 448 449 450 451 452 453 454 455 456 | iTo = name_to_rid(g.argv[3]); find_filename_changes(iFrom, iTo, &nChng, &aChng); for(i=0; i<nChng; i++){ char *zFrom, *zTo; zFrom = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2]); zTo = db_text(0, "SELECT name FROM filename WHERE fnid=%d", aChng[i*2+1]); fossil_print("[%s] -> [%s]\n", zFrom, zTo); fossil_free(zFrom); fossil_free(zTo); } fossil_free(aChng); } |
Changes to src/printf.c.
︙ | ︙ | |||
795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 | g.iErrPriority = iPriority; } void fossil_error_reset(void){ free(g.zErrMsg); g.zErrMsg = 0; g.iErrPriority = 0; } /* ** Write output for user consumption. If g.cgiOutput is enabled, then ** send the output as part of the CGI reply. If g.cgiOutput is false, ** then write on standard output. */ void fossil_print(const char *zFormat, ...){ va_list ap; va_start(ap, zFormat); if( g.cgiOutput ){ cgi_vprintf(zFormat, ap); }else{ Blob b = empty_blob; vxprintf(&b, zFormat, ap); | > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > | 795 796 797 798 799 800 801 802 803 804 805 806 807 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 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 | g.iErrPriority = iPriority; } void fossil_error_reset(void){ free(g.zErrMsg); g.zErrMsg = 0; g.iErrPriority = 0; } /* ** Write to standard output or standard error. ** ** On windows, transform the output into the current terminal encoding ** if the output is going to the screen. If output is redirected into ** a file, no translation occurs. No translation ever occurs on unix. */ void fossil_puts(const char *z, int toStdErr){ #if defined(_WIN32) static int once = 1; static int istty[2]; char *zToFree = 0; if( once ){ istty[0] = _isatty(fileno(stdout)); istty[1] = _isatty(fileno(stderr)); once = 0; } assert( toStdErr==0 || toStdErr==1 ); if( istty[toStdErr] ) z = zToFree = fossil_utf8_to_console(z); fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); free(zToFree); #else fwrite(z, 1, strlen(z), toStdErr ? stderr : stdout); #endif } /* ** Write output for user consumption. If g.cgiOutput is enabled, then ** send the output as part of the CGI reply. If g.cgiOutput is false, ** then write on standard output. */ void fossil_print(const char *zFormat, ...){ va_list ap; va_start(ap, zFormat); if( g.cgiOutput ){ cgi_vprintf(zFormat, ap); }else{ Blob b = empty_blob; vxprintf(&b, zFormat, ap); fossil_puts(blob_str(&b), 0); blob_reset(&b); } } /* ** Like strcmp() except that it accepts NULL pointers. NULL sorts before ** all non-NULL string pointers. Also, this strcmp() is a binary comparison ** that does not consider locale. */ int fossil_strcmp(const char *zA, const char *zB){ if( zA==0 ){ if( zB==0 ) return 0; return -1; }else if( zB==0 ){ return +1; }else{ int a, b; do{ a = *zA++; b = *zB++; }while( a==b && a!=0 ); return a - b; } } /* ** Case insensitive string comparison. */ int fossil_strnicmp(const char *zA, const char *zB, int nByte){ if( zA==0 ){ if( zB==0 ) return 0; |
︙ | ︙ |
Changes to src/rebuild.c.
︙ | ︙ | |||
174 175 176 177 178 179 180 | /* ** Draw the percent-complete message. ** The input is actually the permill complete. */ static void percent_complete(int permill){ static int lastOutput = -1; if( permill>lastOutput ){ | | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 | /* ** Draw the percent-complete message. ** The input is actually the permill complete. */ static void percent_complete(int permill){ static int lastOutput = -1; if( permill>lastOutput ){ fossil_print(" %d.%d%% complete...\r", permill/10, permill%10); fflush(stdout); lastOutput = permill; } } /* |
︙ | ︙ | |||
418 419 420 421 422 423 424 | } if( doClustering ) create_cluster(); if( !g.fQuiet && totalSize>0 ){ processCnt += incrSize; percent_complete((processCnt*1000)/totalSize); } if(!g.fQuiet && ttyOutput ){ | | | 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 | } if( doClustering ) create_cluster(); if( !g.fQuiet && totalSize>0 ){ processCnt += incrSize; percent_complete((processCnt*1000)/totalSize); } if(!g.fQuiet && ttyOutput ){ fossil_print("\n"); } return errCnt; } /* ** Attempt to convert more full-text blobs into delta-blobs for ** storage efficiency. |
︙ | ︙ | |||
547 548 549 550 551 552 553 | errCnt = rebuild_db(randomizeFlag, 1, doClustering); db_multi_exec( "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());" "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());", CONTENT_SCHEMA, AUX_SCHEMA ); if( errCnt && !forceFlag ){ | > | | > | | | | | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 | errCnt = rebuild_db(randomizeFlag, 1, doClustering); db_multi_exec( "REPLACE INTO config(name,value,mtime) VALUES('content-schema','%s',now());" "REPLACE INTO config(name,value,mtime) VALUES('aux-schema','%s',now());", CONTENT_SCHEMA, AUX_SCHEMA ); if( errCnt && !forceFlag ){ fossil_print( "%d errors. Rolling back changes. Use --force to force a commit.\n", errCnt ); db_end_transaction(1); }else{ if( runCompress ){ fossil_print("Extra delta compression... "); fflush(stdout); extra_deltification(); runVacuum = 1; } if( omitVerify ) verify_cancel(); db_end_transaction(0); if( runCompress ) fossil_print("done\n"); db_close(0); db_open_repository(g.zRepositoryName); if( newPagesize ){ db_multi_exec("PRAGMA page_size=%d", newPagesize); runVacuum = 1; } if( runVacuum ){ fossil_print("Vacuuming the database... "); fflush(stdout); db_multi_exec("VACUUM"); fossil_print("done\n"); } if( activateWal ){ db_multi_exec("PRAGMA journal_mode=WAL;"); } } } |
︙ | ︙ | |||
676 677 678 679 680 681 682 | } } manifest_destroy(p); } n = db_int(0, "SELECT count(*) FROM /*scan*/" " (SELECT rid FROM blob EXCEPT SELECT x FROM xdone)"); if( n==0 ){ | | | | | 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | } } manifest_destroy(p); } n = db_int(0, "SELECT count(*) FROM /*scan*/" " (SELECT rid FROM blob EXCEPT SELECT x FROM xdone)"); if( n==0 ){ fossil_print("all artifacts reachable through clusters\n"); }else{ fossil_print("%d unreachable artifacts:\n", n); db_prepare(&q, "SELECT rid, uuid FROM blob WHERE rid NOT IN xdone"); while( db_step(&q)==SQLITE_ROW ){ fossil_print(" %3d %s\n", db_column_int(&q,0), db_column_text(&q,1)); } db_finalize(&q); } } /* ** COMMAND: scrub |
︙ | ︙ | |||
771 772 773 774 775 776 777 778 | ** every file read as a new artifact in the repository. */ void recon_read_dir(char *zPath){ DIR *d; struct dirent *pEntry; Blob aContent; /* content of the just read artifact */ static int nFileRead = 0; | > > > | > | > | > | | | | 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 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 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 | ** every file read as a new artifact in the repository. */ void recon_read_dir(char *zPath){ DIR *d; struct dirent *pEntry; Blob aContent; /* content of the just read artifact */ static int nFileRead = 0; char *zMbcsPath; char *zUtf8Name; zMbcsPath = fossil_utf8_to_mbcs(zPath); d = opendir(zMbcsPath); if( d ){ while( (pEntry=readdir(d))!=0 ){ Blob path; char *zSubpath; if( pEntry->d_name[0]=='.' ){ continue; } zUtf8Name = fossil_mbcs_to_utf8(pEntry->d_name); zSubpath = mprintf("%s/%s", zPath, zUtf8Name); fossil_mbcs_free(zUtf8Name); if( file_isdir(zSubpath)==1 ){ recon_read_dir(zSubpath); } blob_init(&path, 0, 0); blob_appendf(&path, "%s", zSubpath); if( blob_read_from_file(&aContent, blob_str(&path))==-1 ){ fossil_panic("some unknown error occurred while reading \"%s\"", blob_str(&path)); } content_put(&aContent); blob_reset(&path); blob_reset(&aContent); free(zSubpath); fossil_print("\r%d", ++nFileRead); fflush(stdout); } closedir(d); }else { fossil_panic("encountered error %d while trying to open \"%s\".", errno, g.argv[3]); } fossil_mbcs_free(zMbcsPath); } /* ** COMMAND: reconstruct ** ** Usage: %fossil reconstruct FILENAME DIRECTORY ** ** This command studies the artifacts (files) in DIRECTORY and ** reconstructs the fossil record from them. It places the new ** fossil repository in FILENAME. Subdirectories are read, files ** with leading '.' in the filename are ignored. ** */ void reconstruct_cmd(void) { char *zPassword; if( g.argc!=4 ){ usage("FILENAME DIRECTORY"); } if( file_isdir(g.argv[3])!=1 ){ fossil_print("\"%s\" is not a directory\n\n", g.argv[3]); usage("FILENAME DIRECTORY"); } db_create_repository(g.argv[2]); db_open_repository(g.argv[2]); db_open_config(0); db_begin_transaction(); db_initial_setup(0, 0, 1); fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]); recon_read_dir(g.argv[3]); fossil_print("\nBuilding the Fossil repository...\n"); rebuild_db(0, 1, 1); /* Reconstruct the private table. The private table contains the rid ** of every manifest that is tagged with "private" and every file that ** is not used by a manifest that is not private. */ |
︙ | ︙ | |||
859 860 861 862 863 864 865 | /* Skip the verify_before_commit() step on a reconstruct. Most artifacts ** will have been changed and verification therefore takes a really, really ** long time. */ verify_cancel(); db_end_transaction(0); | | | | | 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 | /* Skip the verify_before_commit() step on a reconstruct. Most artifacts ** will have been changed and verification therefore takes a really, really ** long time. */ verify_cancel(); db_end_transaction(0); fossil_print("project-id: %s\n", db_get("project-code", 0)); fossil_print("server-id: %s\n", db_get("server-code", 0)); zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin); fossil_print("admin-user: %s (initial password is \"%s\")\n", g.zLogin, zPassword); } /* ** COMMAND: deconstruct ** ** Usage %fossil deconstruct ?OPTIONS? DESTIONATION ** |
︙ | ︙ | |||
907 908 909 910 911 912 913 | if( zPrefixOpt[0]>='0' && zPrefixOpt[0]<='9' && !zPrefixOpt[1] ){ prefixLength = (int)(*zPrefixOpt-'0'); }else{ fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt); } } #ifndef _WIN32 | | | | 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 | if( zPrefixOpt[0]>='0' && zPrefixOpt[0]<='9' && !zPrefixOpt[1] ){ prefixLength = (int)(*zPrefixOpt-'0'); }else{ fossil_fatal("N(%s) is not a a valid prefix length!",zPrefixOpt); } } #ifndef _WIN32 if( file_access(zDestDir, W_OK) ){ fossil_fatal("DESTINATION(%s) is not writeable!",zDestDir); } #else /* write access on windows is not checked, errors will be ** dected on blob_write_to_file */ #endif if( prefixLength ){ zFNameFormat = mprintf("%s/%%.%ds/%%s",zDestDir,prefixLength); }else{ zFNameFormat = mprintf("%s/%%s",zDestDir); } /* open repository and open query for all artifacts */ db_find_and_open_repository(OPEN_ANY_SCHEMA, 0); bag_init(&bagDone); ttyOutput = 1; processCnt = 0; if (!g.fQuiet) { fossil_print("0 (0%%)...\r"); fflush(stdout); } totalSize = db_int(0, "SELECT count(*) FROM blob"); db_prepare(&s, "SELECT rid, size FROM blob /*scan*/" " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)" " AND NOT EXISTS(SELECT 1 FROM delta WHERE rid=blob.rid)" |
︙ | ︙ | |||
962 963 964 965 966 967 968 | content_get(rid, &content); rebuild_step(rid, size, &content); } } } db_finalize(&s); if(!g.fQuiet && ttyOutput ){ | | | 970 971 972 973 974 975 976 977 978 979 980 981 982 983 | content_get(rid, &content); rebuild_step(rid, size, &content); } } } db_finalize(&s); if(!g.fQuiet && ttyOutput ){ fossil_print("\n"); } /* free filename format string */ free(zFNameFormat); zFNameFormat = 0; } |
Changes to src/report.c.
︙ | ︙ | |||
642 643 644 645 646 647 648 | ** rows in the table. */ pState->nCol = 0; pState->isMultirow = 0; pState->iNewRow = -1; pState->iBg = -1; for(i=0; i<nArg; i++){ | | | 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 | ** rows in the table. */ pState->nCol = 0; pState->isMultirow = 0; pState->iNewRow = -1; pState->iBg = -1; for(i=0; i<nArg; i++){ if( azName[i][0]=='b' && fossil_strcmp(azName[i],"bgcolor")==0 ){ pState->iBg = i; continue; } if( g.okWrite && azName[i][0]=='#' ){ pState->nCol++; } if( !pState->isMultirow ){ |
︙ | ︙ | |||
945 946 947 948 949 950 951 | if( !tabs ){ struct GenerateHTML sState; db_multi_exec("PRAGMA empty_result_callbacks=ON"); style_submenu_element("Raw", "Raw", "rptview?tablist=1&%h", PD("QUERY_STRING","")); if( g.okAdmin | | | 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 | if( !tabs ){ struct GenerateHTML sState; db_multi_exec("PRAGMA empty_result_callbacks=ON"); style_submenu_element("Raw", "Raw", "rptview?tablist=1&%h", PD("QUERY_STRING","")); if( g.okAdmin || (g.okTktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){ style_submenu_element("Edit", "Edit", "rptedit?rn=%d", rn); } if( g.okTktFmt ){ style_submenu_element("SQL", "SQL", "rptsql?rn=%d",rn); } if( g.okNewTkt ){ style_submenu_element("New Ticket", "Create a new ticket", |
︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 | ** 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; char const aRptOutFrmt[] = "%s\t%s\n"; | | | | | | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 | ** 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; char const 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); const char *zTitle = db_column_text(&q, 1); fossil_print(aRptOutFrmt,zRn,zTitle); } db_finalize(&q); } /* ** user defined separator used by ticket show command */ |
︙ | ︙ | |||
1035 1036 1037 1038 1039 1040 1041 | static void output_no_tabs_file(const char *z){ switch( tktEncode ){ case tktFossilize: { char *zFosZ; if( z && *z ){ zFosZ = fossilize(z,-1); | | | | | 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | static void output_no_tabs_file(const char *z){ switch( tktEncode ){ case tktFossilize: { char *zFosZ; if( z && *z ){ zFosZ = fossilize(z,-1); fossil_print("%s",zFosZ); free(zFosZ); } break; } default: while( z && z[0] ){ int i, j; for(i=0; z[i] && (!fossil_isspace(z[i]) || z[i]==' '); i++){} if( i>0 ){ fossil_print("%.*s", i, z); } for(j=i; fossil_isspace(z[j]); j++){} if( j>i ){ fossil_print("%*s", j-i, ""); } z += j; } break; } } |
︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 | ){ int *pCount = (int*)pUser; int i; if( *pCount==0 ){ for(i=0; i<nArg; i++){ output_no_tabs_file(azName[i]); | | | | 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 | ){ int *pCount = (int*)pUser; int i; if( *pCount==0 ){ for(i=0; i<nArg; i++){ output_no_tabs_file(azName[i]); fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); } } ++*pCount; for(i=0; i<nArg; i++){ output_no_tabs_file(azArg[i]); fossil_print("%s", i<nArg-1 ? (zSep?zSep:"\t") : "\n"); } return 0; } /* ** Generate a report. The rn query parameter is the report number. ** The output is written to stdout as flat file. The zFilter paramater |
︙ | ︙ |
Changes to src/setup.c.
︙ | ︙ | |||
434 435 436 437 438 439 440 | if( strchr(zCap, 'w') ) oaw = " checked=\"checked\""; if( strchr(zCap, 'x') ) oax = " checked=\"checked\""; if( strchr(zCap, 'z') ) oaz = " checked=\"checked\""; } /* figure out inherited permissions */ memset(inherit, 0, sizeof(inherit)); | | | | | | 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 | if( strchr(zCap, 'w') ) oaw = " checked=\"checked\""; if( strchr(zCap, 'x') ) oax = " checked=\"checked\""; if( strchr(zCap, 'z') ) oaz = " checked=\"checked\""; } /* figure out inherited permissions */ memset(inherit, 0, sizeof(inherit)); if( fossil_strcmp(zLogin, "developer") ){ char *z1, *z2; z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='developer'"); while( z1 && *z1 ){ inherit[0x7f & *(z1++)] = "<span class=\"ueditInheritDeveloper\">•</span>"; } free(z2); } if( fossil_strcmp(zLogin, "reader") ){ char *z1, *z2; z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='reader'"); while( z1 && *z1 ){ inherit[0x7f & *(z1++)] = "<span class=\"ueditInheritReader\">•</span>"; } free(z2); } if( fossil_strcmp(zLogin, "anonymous") ){ char *z1, *z2; z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='anonymous'"); while( z1 && *z1 ){ inherit[0x7f & *(z1++)] = "<span class=\"ueditInheritAnonymous\">•</span>"; } free(z2); } if( fossil_strcmp(zLogin, "nobody") ){ char *z1, *z2; z1 = z2 = db_text(0,"SELECT cap FROM user WHERE login='nobody'"); while( z1 && *z1 ){ inherit[0x7f & *(z1++)] = "<span class=\"ueditInheritNobody\">•</span>"; } free(z2); |
︙ | ︙ | |||
739 740 741 742 743 744 745 | ){ const char *zQ = P(zQParm); int iVal = db_get_boolean(zVar, dfltVal); if( zQ==0 && P("submit") ){ zQ = "off"; } if( zQ ){ | | | 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 | ){ const char *zQ = P(zQParm); int iVal = db_get_boolean(zVar, dfltVal); if( zQ==0 && P("submit") ){ 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; } } if( iVal ){ |
︙ | ︙ | |||
766 767 768 769 770 771 772 | int width, /* Width of the entry box */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQParm, /* The query parameter */ char *zDflt /* Default value if VAR table entry does not exist */ ){ const char *zVal = db_get(zVar, zDflt); const char *zQ = P(zQParm); | | | 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 | int width, /* Width of the entry box */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQParm, /* The query parameter */ char *zDflt /* Default value if VAR table entry does not exist */ ){ 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" name="%s(zQParm)" value="%h(zVal)" size="%d(width)" /> @ <b>%s(zLabel)</b> } |
︙ | ︙ | |||
788 789 790 791 792 793 794 | int cols, /* Columns in the textarea */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQP, /* The query parameter */ const char *zDflt /* Default value if VAR table entry does not exist */ ){ const char *z = db_get(zVar, (char*)zDflt); const char *zQ = P(zQP); | | | 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 | int cols, /* Columns in the textarea */ const char *zVar, /* The corresponding row in the VAR table */ const char *zQP, /* The query parameter */ const char *zDflt /* Default value if VAR table entry does not exist */ ){ const char *z = db_get(zVar, (char*)zDflt); const char *zQ = P(zQP); if( zQ && fossil_strcmp(zQ,z)!=0 ){ login_verify_csrf_secret(); db_set(zVar, zQ, 0); z = zQ; } if( rows>0 && cols>0 ){ @ <textarea name="%s(zQP)" rows="%d(rows)" cols="%d(cols)">%h(z)</textarea> if (zLabel && *zLabel) |
︙ | ︙ |
Changes to src/sha1.c.
︙ | ︙ | |||
264 265 266 267 268 269 270 | */ int sha1sum_file(const char *zFilename, Blob *pCksum){ FILE *in; SHA1Context ctx; unsigned char zResult[20]; char zBuf[10240]; | | | 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 | */ int sha1sum_file(const char *zFilename, Blob *pCksum){ FILE *in; SHA1Context ctx; unsigned char zResult[20]; char zBuf[10240]; in = fossil_fopen(zFilename,"rb"); if( in==0 ){ return 1; } SHA1Init(&ctx); for(;;){ int n; n = fread(zBuf, 1, sizeof(zBuf), in); |
︙ | ︙ | |||
428 429 430 431 432 433 434 | blob_init(&cksum, "************** not found ***************", -1); if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ blob_read_from_channel(&in, stdin, -1); sha1sum_blob(&in, &cksum); }else{ sha1sum_file(g.argv[i], &cksum); } | | | 428 429 430 431 432 433 434 435 436 437 438 | blob_init(&cksum, "************** not found ***************", -1); if( g.argv[i][0]=='-' && g.argv[i][1]==0 ){ blob_read_from_channel(&in, stdin, -1); sha1sum_blob(&in, &cksum); }else{ sha1sum_file(g.argv[i], &cksum); } fossil_print("%s %s\n", blob_str(&cksum), g.argv[i]); blob_reset(&cksum); } } |
Changes to src/shell.c.
︙ | ︙ | |||
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #if defined(_WIN32_WCE) /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() * thus we always assume that we have a console. That can be * overridden with the -batch command line option. */ #define isatty(x) 1 #endif #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) #include <sys/time.h> #include <sys/resource.h> /* Saved resource information for the beginning of an operation */ static struct rusage sBegin; | > > > < < < | 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 | #if defined(_WIN32_WCE) /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty() * thus we always assume that we have a console. That can be * overridden with the -batch command line option. */ #define isatty(x) 1 #endif /* True if the timer is enabled */ static int enableTimer = 0; #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL) #include <sys/time.h> #include <sys/resource.h> /* Saved resource information for the beginning of an operation */ static struct rusage sBegin; /* ** Begin timing an operation */ static void beginTimer(void){ if( enableTimer ){ getrusage(RUSAGE_SELF, &sBegin); } |
︙ | ︙ | |||
120 121 122 123 124 125 126 | /* Saved resource information for the beginning of an operation */ static HANDLE hProcess; static FILETIME ftKernelBegin; static FILETIME ftUserBegin; typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); static GETPROCTIMES getProcessTimesAddr = NULL; | < < < | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | /* Saved resource information for the beginning of an operation */ static HANDLE hProcess; static FILETIME ftKernelBegin; static FILETIME ftUserBegin; typedef BOOL (WINAPI *GETPROCTIMES)(HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME); static GETPROCTIMES getProcessTimesAddr = NULL; /* ** Check to see if we have timer support. Return 1 if necessary ** support found (or found previously). */ static int hasTimer(void){ if( getProcessTimesAddr ){ return 1; |
︙ | ︙ | |||
2195 2196 2197 2198 2199 2200 2201 | int testctrl = -1; int rc = 0; int i, n; open_db(p); /* convert testctrl text option to value. allow any unique prefix ** of the option name, or a numerical value. */ | | | | 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 | int testctrl = -1; int rc = 0; int i, n; open_db(p); /* convert testctrl text option to value. allow any unique prefix ** of the option name, or a numerical value. */ n = strlen30(azArg[1]); for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){ if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){ if( testctrl<0 ){ testctrl = aCtrl[i].ctrlCode; }else{ fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]); testctrl = -1; break; |
︙ | ︙ | |||
2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 | if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){ enableTimer = booleanValue(azArg[1]); }else if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ int j; assert( nArg<=ArraySize(azArg) ); for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ p->colWidth[j-1] = atoi(azArg[j]); } }else | > > > > > | 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 | if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0 && nArg==2 ){ enableTimer = booleanValue(azArg[1]); }else if( c=='v' && strncmp(azArg[0], "version", n)==0 ){ printf("SQLite %s %s\n", sqlite3_libversion(), sqlite3_sourceid()); }else if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){ int j; assert( nArg<=ArraySize(azArg) ); for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){ p->colWidth[j-1] = atoi(azArg[j]); } }else |
︙ | ︙ | |||
2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 | ** Initialize the state information in data */ static void main_init(struct callback_data *data) { memset(data, 0, sizeof(*data)); data->mode = MODE_List; memcpy(data->separator,"|", 2); data->showHeader = 0; sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); } int main(int argc, char **argv){ char *zErrMsg = 0; struct callback_data data; const char *zInitFile = 0; char *zFirstCmd = 0; int i; int rc = 0; Argv0 = argv[0]; main_init(&data); stdin_is_interactive = isatty(0); /* Make sure we have a valid signal handler early, before anything ** else is done. */ | > > > > > > | 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 | ** Initialize the state information in data */ static void main_init(struct callback_data *data) { memset(data, 0, sizeof(*data)); data->mode = MODE_List; memcpy(data->separator,"|", 2); data->showHeader = 0; sqlite3_config(SQLITE_CONFIG_URI, 1); sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data); sqlite3_snprintf(sizeof(mainPrompt), mainPrompt,"sqlite> "); sqlite3_snprintf(sizeof(continuePrompt), continuePrompt," ...> "); sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); } int main(int argc, char **argv){ char *zErrMsg = 0; struct callback_data data; const char *zInitFile = 0; char *zFirstCmd = 0; int i; int rc = 0; if( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)!=0 ){ fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n", sqlite3_sourceid(), SQLITE_SOURCE_ID); exit(1); } Argv0 = argv[0]; main_init(&data); stdin_is_interactive = isatty(0); /* Make sure we have a valid signal handler early, before anything ** else is done. */ |
︙ | ︙ | |||
2835 2836 2837 2838 2839 2840 2841 | }else if( strcmp(z,"-echo")==0 ){ data.echoOn = 1; }else if( strcmp(z,"-stats")==0 ){ data.statsOn = 1; }else if( strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( strcmp(z,"-version")==0 ){ | | | 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 | }else if( strcmp(z,"-echo")==0 ){ data.echoOn = 1; }else if( strcmp(z,"-stats")==0 ){ data.statsOn = 1; }else if( strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( strcmp(z,"-version")==0 ){ printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); return 0; }else if( strcmp(z,"-interactive")==0 ){ stdin_is_interactive = 1; }else if( strcmp(z,"-batch")==0 ){ stdin_is_interactive = 0; }else if( strcmp(z,"-heap")==0 ){ i++; |
︙ | ︙ | |||
2880 2881 2882 2883 2884 2885 2886 | /* Run commands received from standard input */ if( stdin_is_interactive ){ char *zHome; char *zHistory = 0; int nHistory; printf( | | | | 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 | /* Run commands received from standard input */ if( stdin_is_interactive ){ char *zHome; char *zHistory = 0; int nHistory; printf( "SQLite version %s %.19s\n" "Enter \".help\" for instructions\n" "Enter SQL statements terminated with a \";\"\n", sqlite3_libversion(), sqlite3_sourceid() ); zHome = find_home_dir(); if( zHome ){ nHistory = strlen30(zHome) + 20; if( (zHistory = malloc(nHistory))!=0 ){ sqlite3_snprintf(nHistory, zHistory,"%s/.sqlite_history", zHome); } |
︙ | ︙ |
Changes to src/skins.c.
︙ | ︙ | |||
1051 1052 1053 1054 1055 1056 1057 | } setDefaultSkin(); zCurrent = getSkin(0); if( P("save")!=0 && (zName = skinVarName(P("save"),0))!=0 ){ if( db_exists("SELECT 1 FROM config WHERE name=%Q", zName) | | | | | 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 | } setDefaultSkin(); zCurrent = getSkin(0); if( P("save")!=0 && (zName = skinVarName(P("save"),0))!=0 ){ if( db_exists("SELECT 1 FROM config WHERE name=%Q", zName) || fossil_strcmp(zName, "Default")==0 ){ zErr = mprintf("Skin name \"%h\" already exists. " "Choose a different name.", P("sn")); }else{ db_multi_exec("INSERT INTO config(name,value,mtime) VALUES(%Q,%Q,now())", zName, zCurrent ); } } /* The user pressed the "Use This Skin" button. */ if( P("load") && (z = P("sn"))!=0 && z[0] ){ int seen = 0; for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ if( fossil_strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ seen = 1; break; } } if( !seen ){ seen = db_exists("SELECT 1 FROM config WHERE name GLOB 'skin:*'" " AND value=%Q", zCurrent); } if( !seen ){ db_multi_exec( "INSERT INTO config(name,value,mtime) VALUES(" " strftime('skin:Backup On %%Y-%%m-%%d %%H:%%M:%%S')," " %Q,now())", zCurrent ); } seen = 0; for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ if( fossil_strcmp(aBuiltinSkin[i].zName, z)==0 ){ seen = 1; zCurrent = aBuiltinSkin[i].zValue; db_multi_exec("%s", zCurrent); break; } } if( !seen ){ |
︙ | ︙ | |||
1109 1110 1111 1112 1113 1114 1115 | @ <a href="setup_logo">Logo</a> that determines the look and feel @ of the web interface.</p> @ @ <h2>Available Skins:</h2> @ <ol> for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ z = aBuiltinSkin[i].zName; | | | | 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 | @ <a href="setup_logo">Logo</a> that determines the look and feel @ of the web interface.</p> @ @ <h2>Available Skins:</h2> @ <ol> for(i=0; i<sizeof(aBuiltinSkin)/sizeof(aBuiltinSkin[0]); i++){ z = aBuiltinSkin[i].zName; if( fossil_strcmp(aBuiltinSkin[i].zValue, zCurrent)==0 ){ @ <li><p>%h(z). <b>Currently In Use</b></p> }else{ @ <li><form action="%s(g.zTop)/setup_skin" method="post"><div> @ %h(z). @ <input type="hidden" name="sn" value="%h(z)" /> @ <input type="submit" name="load" value="Use This Skin" /> @ </div></form></li> } } db_prepare(&q, "SELECT substr(name, 6), value FROM config" " WHERE name GLOB 'skin:*'" " ORDER BY name" ); while( db_step(&q)==SQLITE_ROW ){ const char *zN = db_column_text(&q, 0); const char *zV = db_column_text(&q, 1); if( fossil_strcmp(zV, zCurrent)==0 ){ @ <li><p>%h(zN). <b>Currently In Use</b></p> }else{ @ <li><form action="%s(g.zTop)/setup_skin" method="post"> @ %h(zN). @ <input type="hidden" name="sn" value="%h(zN)"> @ <input type="submit" name="load" value="Use This Skin"> @ <input type="submit" name="del1" value="Delete This Skin"> |
︙ | ︙ |
Changes to src/sqlite3.c.
︙ | ︙ | |||
648 649 650 651 652 653 654 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.7" #define SQLITE_VERSION_NUMBER 3007007 | | | 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.7" #define SQLITE_VERSION_NUMBER 3007007 #define SQLITE_SOURCE_ID "2011-06-03 14:19:10 0206bc6f87bb9393218a380fc5b18039d334a8d8" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. | > > | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. |
︙ | ︙ | |||
1303 1304 1305 1306 1307 1308 1309 | ** ** Mutexes are created using [sqlite3_mutex_alloc()]. */ typedef struct sqlite3_mutex sqlite3_mutex; /* ** CAPI3REF: OS Interface Object | < | > | 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 | ** ** Mutexes are created using [sqlite3_mutex_alloc()]. */ typedef struct sqlite3_mutex sqlite3_mutex; /* ** CAPI3REF: OS Interface Object ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" ** in the name of the object stands for "virtual file system". See ** the [VFS | VFS documentation] for further information. ** ** The value of the iVersion field is initially 1 but may be larger in ** future versions of SQLite. Additional fields may be appended to this ** object when the iVersion value is increased. Note that the structure ** of the sqlite3_vfs object changes in the transaction between ** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not ** modified. |
︙ | ︙ | |||
8492 8493 8494 8495 8496 8497 8498 | SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); | | > | 8494 8495 8496 8497 8498 8499 8500 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 | SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); #endif SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); |
︙ | ︙ | |||
9830 9831 9832 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 | */ struct VTable { sqlite3 *db; /* Database connection associated with this table */ Module *pMod; /* Pointer to module implementation */ sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ VTable *pNext; /* Next in linked list (see above) */ }; /* ** Each SQL table is represented in memory by an instance of the ** following structure. ** | > | 9833 9834 9835 9836 9837 9838 9839 9840 9841 9842 9843 9844 9845 9846 9847 | */ struct VTable { sqlite3 *db; /* Database connection associated with this table */ Module *pMod; /* Pointer to module implementation */ sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ int iSavepoint; /* Depth of the SAVEPOINT stack */ VTable *pNext; /* Next in linked list (see above) */ }; /* ** Each SQL table is represented in memory by an instance of the ** following structure. ** |
︙ | ︙ | |||
10824 10825 10826 10827 10828 10829 10830 | u8 disableTriggers; /* True to disable triggers */ double nQueryLoop; /* Estimated number of iterations of a query */ /* Above is constant between recursions. Below is reset before and after ** each recursion */ int nVar; /* Number of '?' variables seen in the SQL so far */ | < | | | 10828 10829 10830 10831 10832 10833 10834 10835 10836 10837 10838 10839 10840 10841 10842 10843 | u8 disableTriggers; /* True to disable triggers */ double nQueryLoop; /* Estimated number of iterations of a query */ /* Above is constant between recursions. Below is reset before and after ** each recursion */ int nVar; /* Number of '?' variables seen in the SQL so far */ int nzVar; /* Number of available slots in azVar[] */ char **azVar; /* Pointers to names of parameters */ Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ int nAlias; /* Number of aliased result set columns */ int nAliasAlloc; /* Number of allocated slots for aAlias[] */ int *aAlias; /* Register used to hold aliased result */ u8 explain; /* True if the EXPLAIN flag is found on the query */ Token sNameToken; /* Token with unqualified schema object name */ Token sLastToken; /* The last token parsed */ |
︙ | ︙ | |||
12759 12760 12761 12762 12763 12764 12765 12766 12767 12768 12769 | u32 magic; /* Magic number for sanity checking */ char *zErrMsg; /* Error message written here */ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ VdbeCursor **apCsr; /* One element of this array for each open cursor */ Mem *aVar; /* Values for the OP_Variable opcode. */ char **azVar; /* Name of variables */ ynVar nVar; /* Number of entries in aVar[] */ u32 cacheCtr; /* VdbeCursor row cache generation counter */ int pc; /* The program counter */ int rc; /* Value to return */ u8 errorAction; /* Recovery action to do in case of an error */ | > < | 12762 12763 12764 12765 12766 12767 12768 12769 12770 12771 12772 12773 12774 12775 12776 12777 12778 12779 12780 | u32 magic; /* Magic number for sanity checking */ char *zErrMsg; /* Error message written here */ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ VdbeCursor **apCsr; /* One element of this array for each open cursor */ Mem *aVar; /* Values for the OP_Variable opcode. */ char **azVar; /* Name of variables */ ynVar nVar; /* Number of entries in aVar[] */ ynVar nzVar; /* Number of entries in azVar[] */ u32 cacheCtr; /* VdbeCursor row cache generation counter */ int pc; /* The program counter */ int rc; /* Value to return */ u8 errorAction; /* Recovery action to do in case of an error */ u8 explain; /* True if EXPLAIN present on SQL command */ u8 changeCntOn; /* True to update the change-counter */ u8 expired; /* True if the VM needs to be recompiled */ u8 runOnlyOnce; /* Automatically expire on reset */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 inVtabMethod; /* See comments above */ u8 usesStmtJournal; /* True if uses a statement journal */ |
︙ | ︙ | |||
27961 27962 27963 27964 27965 27966 27967 | */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ sqlite3_mutex *mutex; /* Mutex to access this object */ char *zFilename; /* Name of the mmapped file */ int h; /* Open file descriptor */ int szRegion; /* Size of shared-memory regions */ | | > | 27964 27965 27966 27967 27968 27969 27970 27971 27972 27973 27974 27975 27976 27977 27978 27979 | */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ sqlite3_mutex *mutex; /* Mutex to access this object */ char *zFilename; /* Name of the mmapped file */ int h; /* Open file descriptor */ int szRegion; /* Size of shared-memory regions */ u16 nRegion; /* Size of array apRegion */ u8 isReadonly; /* True if read-only */ char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ #ifdef SQLITE_DEBUG u8 exclMask; /* Mask of exclusive locks held */ u8 sharedMask; /* Mask of shared locks held */ u8 nextShmId; /* Next available unixShm.id value */ |
︙ | ︙ | |||
28208 28209 28210 28211 28212 28213 28214 | goto shm_open_err; } if( pInode->bProcessLock==0 ){ pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, (sStat.st_mode & 0777)); if( pShmNode->h<0 ){ | > > > > > > > > | | > | 28212 28213 28214 28215 28216 28217 28218 28219 28220 28221 28222 28223 28224 28225 28226 28227 28228 28229 28230 28231 28232 28233 28234 28235 28236 | goto shm_open_err; } if( pInode->bProcessLock==0 ){ pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, (sStat.st_mode & 0777)); if( pShmNode->h<0 ){ const char *zRO; zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); if( zRO && sqlite3GetBoolean(zRO) ){ pShmNode->h = robust_open(zShmFilename, O_RDONLY, (sStat.st_mode & 0777)); pShmNode->isReadonly = 1; } if( pShmNode->h<0 ){ rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); goto shm_open_err; } } /* Check to see if another process is holding the dead-man switch. ** If not, truncate the file to zero length. */ rc = SQLITE_OK; if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ |
︙ | ︙ | |||
28348 28349 28350 28351 28352 28353 28354 | rc = SQLITE_IOERR_NOMEM; goto shmpage_out; } pShmNode->apRegion = apNew; while(pShmNode->nRegion<=iRegion){ void *pMem; if( pShmNode->h>=0 ){ | | > | 28361 28362 28363 28364 28365 28366 28367 28368 28369 28370 28371 28372 28373 28374 28375 28376 | rc = SQLITE_IOERR_NOMEM; goto shmpage_out; } pShmNode->apRegion = apNew; while(pShmNode->nRegion<=iRegion){ void *pMem; if( pShmNode->h>=0 ){ pMem = mmap(0, szRegion, pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion ); if( pMem==MAP_FAILED ){ rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); goto shmpage_out; } }else{ |
︙ | ︙ | |||
28374 28375 28376 28377 28378 28379 28380 28381 28382 28383 28384 28385 28386 28387 | shmpage_out: if( pShmNode->nRegion>iRegion ){ *pp = pShmNode->apRegion[iRegion]; }else{ *pp = 0; } sqlite3_mutex_leave(pShmNode->mutex); return rc; } /* ** Change the lock state for a shared-memory segment. ** | > | 28388 28389 28390 28391 28392 28393 28394 28395 28396 28397 28398 28399 28400 28401 28402 | shmpage_out: if( pShmNode->nRegion>iRegion ){ *pp = pShmNode->apRegion[iRegion]; }else{ *pp = 0; } if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; sqlite3_mutex_leave(pShmNode->mutex); return rc; } /* ** Change the lock state for a shared-memory segment. ** |
︙ | ︙ | |||
34871 34872 34873 34874 34875 34876 34877 34878 34879 34880 34881 34882 34883 34884 | ); pCache->pSynced = pPg; if( !pPg ){ for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); } if( pPg ){ int rc; rc = pCache->xStress(pCache->pStress, pPg); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ return rc; } } pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2); | > > > > > > > | 34886 34887 34888 34889 34890 34891 34892 34893 34894 34895 34896 34897 34898 34899 34900 34901 34902 34903 34904 34905 34906 | ); pCache->pSynced = pPg; if( !pPg ){ for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); } if( pPg ){ int rc; #ifdef SQLITE_LOG_CACHE_SPILL sqlite3_log(SQLITE_FULL, "spill page %d making room for %d - cache used: %d/%d", pPg->pgno, pgno, sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), pCache->nMax); #endif rc = pCache->xStress(pCache->pStress, pPg); if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ return rc; } } pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, 2); |
︙ | ︙ | |||
42470 42471 42472 42473 42474 42475 42476 | ** function has already been called, it is mostly a no-op. However, any ** backup in progress needs to be restarted. */ sqlite3BackupRestart(pPager->pBackup); }else{ if( pagerUseWal(pPager) ){ PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); | > | > > > > > > > > > | 42492 42493 42494 42495 42496 42497 42498 42499 42500 42501 42502 42503 42504 42505 42506 42507 42508 42509 42510 42511 42512 42513 42514 42515 42516 42517 42518 42519 42520 | ** function has already been called, it is mostly a no-op. However, any ** backup in progress needs to be restarted. */ sqlite3BackupRestart(pPager->pBackup); }else{ if( pagerUseWal(pPager) ){ PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); PgHdr *pPageOne = 0; if( pList==0 ){ /* Must have at least one page for the WAL commit flag. ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ rc = sqlite3PagerGet(pPager, 1, &pPageOne); pList = pPageOne; pList->pDirty = 0; } assert( rc==SQLITE_OK ); if( ALWAYS(pList) ){ rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, (pPager->fullSync ? pPager->syncFlags : 0) ); } sqlite3PagerUnref(pPageOne); if( rc==SQLITE_OK ){ sqlite3PcacheCleanAll(pPager->pPCache); } }else{ /* The following block updates the change-counter. Exactly how it ** does this depends on whether or not the atomic-update optimization ** was enabled at compile time, and if this transaction meets the |
︙ | ︙ | |||
43965 43966 43967 43968 43969 43970 43971 | int nWiData; /* Size of array apWiData */ volatile u32 **apWiData; /* Pointer to wal-index content in memory */ u32 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ | | > > > > > > > | 43997 43998 43999 44000 44001 44002 44003 44004 44005 44006 44007 44008 44009 44010 44011 44012 44013 44014 44015 44016 44017 44018 44019 44020 44021 44022 44023 44024 44025 44026 44027 44028 44029 44030 44031 44032 44033 | int nWiData; /* Size of array apWiData */ volatile u32 **apWiData; /* Pointer to wal-index content in memory */ u32 szPage; /* Database page size */ i16 readLock; /* Which read lock is being held. -1 for none */ u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ u8 writeLock; /* True if in a write transaction */ u8 ckptLock; /* True if holding a checkpoint lock */ u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ WalIndexHdr hdr; /* Wal-index header for current transaction */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ #ifdef SQLITE_DEBUG u8 lockError; /* True if a locking error has occurred */ #endif }; /* ** Candidate values for Wal.exclusiveMode. */ #define WAL_NORMAL_MODE 0 #define WAL_EXCLUSIVE_MODE 1 #define WAL_HEAPMEMORY_MODE 2 /* ** Possible values for WAL.readOnly */ #define WAL_RDWR 0 /* Normal read/write connection */ #define WAL_RDONLY 1 /* The WAL file is readonly */ #define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ /* ** Each page of the wal-index mapping contains a hash-table made up of ** an array of HASHTABLE_NSLOT elements of the following type. */ typedef u16 ht_slot; /* |
︙ | ︙ | |||
44074 44075 44076 44077 44078 44079 44080 44081 44082 44083 44084 44085 44086 44087 | if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; }else{ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); } } *ppPage = pWal->apWiData[iPage]; assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); return rc; } | > > > > | 44113 44114 44115 44116 44117 44118 44119 44120 44121 44122 44123 44124 44125 44126 44127 44128 44129 44130 | if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; }else{ rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); if( rc==SQLITE_READONLY ){ pWal->readOnly |= WAL_SHM_RDONLY; rc = SQLITE_OK; } } } *ppPage = pWal->apWiData[iPage]; assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); return rc; } |
︙ | ︙ | |||
44821 44822 44823 44824 44825 44826 44827 | pRet->zWalName = zWalName; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); /* Open file handle on the write-ahead log file. */ flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ | | | 44864 44865 44866 44867 44868 44869 44870 44871 44872 44873 44874 44875 44876 44877 44878 | pRet->zWalName = zWalName; pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE); /* Open file handle on the write-ahead log file. */ flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ pRet->readOnly = WAL_RDONLY; } if( rc!=SQLITE_OK ){ walIndexClose(pRet, 0); sqlite3OsClose(pRet->pWalFd); sqlite3_free(pRet); }else{ |
︙ | ︙ | |||
45462 45463 45464 45465 45466 45467 45468 | */ badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); /* If the first attempt failed, it might have been due to a race ** with a writer. So get a WRITE lock and try again. */ assert( badHdr==0 || pWal->writeLock==0 ); | > > > > > > | | | | | | | | | | | | | | | > | 45505 45506 45507 45508 45509 45510 45511 45512 45513 45514 45515 45516 45517 45518 45519 45520 45521 45522 45523 45524 45525 45526 45527 45528 45529 45530 45531 45532 45533 45534 45535 45536 45537 45538 45539 45540 | */ badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); /* If the first attempt failed, it might have been due to a race ** with a writer. So get a WRITE lock and try again. */ assert( badHdr==0 || pWal->writeLock==0 ); if( badHdr ){ if( pWal->readOnly & WAL_SHM_RDONLY ){ if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ walUnlockShared(pWal, WAL_WRITE_LOCK); rc = SQLITE_READONLY_RECOVERY; } }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ pWal->writeLock = 1; if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ badHdr = walIndexTryHdr(pWal, pChanged); if( badHdr ){ /* If the wal-index header is still malformed even while holding ** a WRITE lock, it can only mean that the header is corrupted and ** needs to be reconstructed. So run recovery to do exactly that. */ rc = walIndexRecover(pWal); *pChanged = 1; } } pWal->writeLock = 0; walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); } } /* If the header is read successfully, check the version number to make ** sure the wal-index was not constructed with some future format that ** this version of SQLite cannot understand. */ if( badHdr==0 && pWal->hdr.iVersion!=WALINDEX_MAX_VERSION ){ |
︙ | ︙ | |||
45663 45664 45665 45666 45667 45668 45669 | assert( thisMark!=READMARK_NOT_USED ); mxReadMark = thisMark; mxI = i; } } /* There was once an "if" here. The extra "{" is to preserve indentation. */ { | > | > | | | 45713 45714 45715 45716 45717 45718 45719 45720 45721 45722 45723 45724 45725 45726 45727 45728 45729 45730 45731 45732 45733 45734 45735 45736 45737 45738 45739 45740 45741 45742 45743 45744 | assert( thisMark!=READMARK_NOT_USED ); mxReadMark = thisMark; mxI = i; } } /* There was once an "if" here. The extra "{" is to preserve indentation. */ { if( (pWal->readOnly & WAL_SHM_RDONLY)==0 && (mxReadMark<pWal->hdr.mxFrame || mxI==0) ){ for(i=1; i<WAL_NREADER; i++){ rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); if( rc==SQLITE_OK ){ mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; mxI = i; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); break; }else if( rc!=SQLITE_BUSY ){ return rc; } } } if( mxI==0 ){ assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; } rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); if( rc ){ return rc==SQLITE_BUSY ? WAL_RETRY : rc; } /* Now that the read-lock has been obtained, check that neither the |
︙ | ︙ | |||
46084 46085 46086 46087 46088 46089 46090 46091 46092 46093 46094 46095 46096 46097 46098 46099 46100 46101 | /* Limit the size of WAL file if the journal_size_limit PRAGMA is ** set to a non-negative value. Log errors encountered ** during the truncation attempt. */ if( pWal->mxWalSize>=0 ){ i64 sz; int rx; rx = sqlite3OsFileSize(pWal->pWalFd, &sz); if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); } if( rx ){ sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); } } pWal->nCkpt++; pWal->hdr.mxFrame = 0; | > > | 46136 46137 46138 46139 46140 46141 46142 46143 46144 46145 46146 46147 46148 46149 46150 46151 46152 46153 46154 46155 | /* Limit the size of WAL file if the journal_size_limit PRAGMA is ** set to a non-negative value. Log errors encountered ** during the truncation attempt. */ if( pWal->mxWalSize>=0 ){ i64 sz; int rx; sqlite3BeginBenignMalloc(); rx = sqlite3OsFileSize(pWal->pWalFd, &sz); if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); } sqlite3EndBenignMalloc(); if( rx ){ sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); } } pWal->nCkpt++; pWal->hdr.mxFrame = 0; |
︙ | ︙ | |||
46318 46319 46320 46321 46322 46323 46324 46325 46326 46327 46328 46329 46330 46331 | int rc; /* Return code */ int isChanged = 0; /* True if a new wal-index header is loaded */ int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ assert( pWal->ckptLock==0 ); assert( pWal->writeLock==0 ); WALTRACE(("WAL%p: checkpoint begins\n", pWal)); rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* Usually this is SQLITE_BUSY meaning that another thread or process ** is already running a checkpoint, or maybe a recovery. But it might ** also be SQLITE_IOERR. */ return rc; | > | 46372 46373 46374 46375 46376 46377 46378 46379 46380 46381 46382 46383 46384 46385 46386 | int rc; /* Return code */ int isChanged = 0; /* True if a new wal-index header is loaded */ int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ assert( pWal->ckptLock==0 ); assert( pWal->writeLock==0 ); if( pWal->readOnly ) return SQLITE_READONLY; WALTRACE(("WAL%p: checkpoint begins\n", pWal)); rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc ){ /* Usually this is SQLITE_BUSY meaning that another thread or process ** is already running a checkpoint, or maybe a recovery. But it might ** also be SQLITE_IOERR. */ return rc; |
︙ | ︙ | |||
52800 52801 52802 52803 52804 52805 52806 | ** The cell content is not freed or deallocated. It is assumed that ** the cell content has been copied someplace else. This routine just ** removes the reference to the cell from pPage. ** ** "sz" must be the number of bytes in the cell. */ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ | < > | 52855 52856 52857 52858 52859 52860 52861 52862 52863 52864 52865 52866 52867 52868 52869 52870 52871 52872 | ** The cell content is not freed or deallocated. It is assumed that ** the cell content has been copied someplace else. This routine just ** removes the reference to the cell from pPage. ** ** "sz" must be the number of bytes in the cell. */ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ u32 pc; /* Offset to cell content of cell being deleted */ u8 *data; /* pPage->aData */ u8 *ptr; /* Used to move bytes around within data[] */ u8 *endPtr; /* End of loop */ int rc; /* The return code */ int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ if( *pRC ) return; assert( idx>=0 && idx<pPage->nCell ); assert( sz==cellSize(pPage, idx) ); |
︙ | ︙ | |||
52828 52829 52830 52831 52832 52833 52834 | return; } rc = freeSpace(pPage, pc, sz); if( rc ){ *pRC = rc; return; } | | > > | 52883 52884 52885 52886 52887 52888 52889 52890 52891 52892 52893 52894 52895 52896 52897 52898 52899 52900 52901 | return; } rc = freeSpace(pPage, pc, sz); if( rc ){ *pRC = rc; return; } endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; while( ptr<endPtr ){ ptr[0] = ptr[2]; ptr[1] = ptr[3]; ptr += 2; } pPage->nCell--; put2byte(&data[hdr+3], pPage->nCell); pPage->nFree += 2; } /* |
︙ | ︙ | |||
58813 58814 58815 58816 58817 58818 58819 | }else{ *pnByte += nByte; } return pBuf; } /* | < < | < | < < < < < < < < < < | < < < < < < < < > | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | < < < | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > | | | | | | | | < < < < < < < < < < | < < < < < < < < | < < < < < < | 58870 58871 58872 58873 58874 58875 58876 58877 58878 58879 58880 58881 58882 58883 58884 58885 58886 58887 58888 58889 58890 58891 58892 58893 58894 58895 58896 58897 58898 58899 58900 58901 58902 58903 58904 58905 58906 58907 58908 58909 58910 58911 58912 58913 58914 58915 58916 58917 58918 58919 58920 58921 58922 58923 58924 58925 58926 58927 58928 58929 58930 58931 58932 58933 58934 58935 58936 58937 58938 58939 58940 58941 58942 58943 58944 58945 58946 58947 58948 58949 58950 58951 58952 58953 58954 58955 58956 58957 58958 58959 58960 58961 58962 58963 58964 58965 58966 58967 58968 58969 58970 58971 58972 58973 58974 58975 58976 58977 58978 58979 58980 58981 58982 58983 58984 58985 58986 58987 58988 58989 58990 58991 58992 58993 58994 58995 58996 58997 58998 58999 59000 59001 59002 59003 59004 59005 59006 59007 59008 59009 59010 59011 59012 59013 59014 59015 59016 59017 59018 59019 59020 59021 59022 59023 59024 59025 59026 59027 59028 59029 59030 59031 59032 59033 59034 59035 59036 59037 59038 59039 | }else{ *pnByte += nByte; } return pBuf; } /* ** Rewind the VDBE back to the beginning in preparation for ** running it. */ SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) int i; #endif assert( p!=0 ); assert( p->magic==VDBE_MAGIC_INIT ); /* There should be at least one opcode. */ assert( p->nOp>0 ); /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ p->magic = VDBE_MAGIC_RUN; #ifdef SQLITE_DEBUG for(i=1; i<p->nMem; i++){ assert( p->aMem[i].db==p->db ); } #endif p->pc = -1; p->rc = SQLITE_OK; p->errorAction = OE_Abort; p->magic = VDBE_MAGIC_RUN; p->nChange = 0; p->cacheCtr = 1; p->minWriteFileFormat = 255; p->iStatement = 0; p->nFkConstraint = 0; #ifdef VDBE_PROFILE for(i=0; i<p->nOp; i++){ p->aOp[i].cnt = 0; p->aOp[i].cycles = 0; } #endif } /* ** Prepare a virtual machine for execution for the first time after ** creating the virtual machine. This involves things such ** as allocating stack space and initializing the program counter. ** After the VDBE has be prepped, it can be executed by one or more ** calls to sqlite3VdbeExec(). ** ** This function may be called exact once on a each virtual machine. ** After this routine is called the VM has been "packaged" and is ready ** to run. After this routine is called, futher calls to ** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects ** the Vdbe from the Parse object that helped generate it so that the ** the Vdbe becomes an independent entity and the Parse object can be ** destroyed. ** ** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back ** to its initial state after it has been run. */ SQLITE_PRIVATE void sqlite3VdbeMakeReady( Vdbe *p, /* The VDBE */ Parse *pParse /* Parsing context */ ){ sqlite3 *db; /* The database connection */ int nVar; /* Number of parameters */ int nMem; /* Number of VM memory registers */ int nCursor; /* Number of cursors required */ int nArg; /* Number of arguments in subprograms */ int n; /* Loop counter */ u8 *zCsr; /* Memory available for allocation */ u8 *zEnd; /* First byte past allocated memory */ int nByte; /* How much extra memory is needed */ assert( p!=0 ); assert( p->nOp>0 ); assert( pParse!=0 ); assert( p->magic==VDBE_MAGIC_INIT ); db = p->db; assert( db->mallocFailed==0 ); nVar = pParse->nVar; nMem = pParse->nMem; nCursor = pParse->nTab; nArg = pParse->nMaxArg; /* For each cursor required, also allocate a memory cell. Memory ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by ** the vdbe program. Instead they are used to allocate space for ** VdbeCursor/BtCursor structures. The blob of memory associated with ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) ** stores the blob of memory associated with cursor 1, etc. ** ** See also: allocateCursor(). */ nMem += nCursor; /* Allocate space for memory registers, SQL variables, VDBE cursors and ** an array to marshal SQL function arguments in. */ zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */ resolveP2Values(p, &nArg); p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); if( pParse->explain && nMem<10 ){ nMem = 10; } memset(zCsr, 0, zEnd-zCsr); zCsr += (zCsr - (u8*)0)&7; assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); /* Memory for registers, parameters, cursor, etc, is allocated in two ** passes. On the first pass, we try to reuse unused space at the ** end of the opcode array. If we are unable to satisfy all memory ** requirements by reusing the opcode array tail, then the second ** pass will fill in the rest using a fresh allocation. ** ** This two-pass approach that reuses as much memory as possible from ** the leftover space at the end of the opcode array can significantly ** reduce the amount of memory held by a prepared statement. */ do { nByte = 0; p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte); if( nByte ){ p->pFree = sqlite3DbMallocZero(db, nByte); } zCsr = p->pFree; zEnd = &zCsr[nByte]; }while( nByte && !db->mallocFailed ); p->nCursor = (u16)nCursor; if( p->aVar ){ p->nVar = (ynVar)nVar; for(n=0; n<nVar; n++){ p->aVar[n].flags = MEM_Null; p->aVar[n].db = db; } } if( p->azVar ){ p->nzVar = pParse->nzVar; memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); } if( p->aMem ){ p->aMem--; /* aMem[] goes from 1..nMem */ p->nMem = nMem; /* not from 0..nMem-1 */ for(n=1; n<=nMem; n++){ p->aMem[n].flags = MEM_Null; p->aMem[n].db = db; } } p->explain = pParse->explain; sqlite3VdbeRewind(p); } /* ** Close a VDBE cursor and release all the resources that cursor ** happens to hold. */ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ |
︙ | ︙ | |||
59624 59625 59626 59627 59628 59629 59630 | } /* If eStatementOp is non-zero, then a statement transaction needs to ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to ** do so. If this operation returns an error, and the current statement ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the ** current statement error code. | < < < < < < | | 59702 59703 59704 59705 59706 59707 59708 59709 59710 59711 59712 59713 59714 59715 59716 59717 59718 59719 59720 | } /* If eStatementOp is non-zero, then a statement transaction needs to ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to ** do so. If this operation returns an error, and the current statement ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the ** current statement error code. */ if( eStatementOp ){ rc = sqlite3VdbeCloseStatement(p, eStatementOp); if( rc ){ if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){ p->rc = rc; sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } invalidateCursorsOnModifiedBtrees(db); sqlite3RollbackAll(db); sqlite3CloseSavepoints(db); |
︙ | ︙ | |||
59827 59828 59829 59830 59831 59832 59833 59834 59835 59836 59837 59838 59839 59840 59841 59842 59843 59844 59845 59846 59847 59848 | ** Free all memory associated with the Vdbe passed as the second argument. ** The difference between this function and sqlite3VdbeDelete() is that ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with ** the database connection. */ SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; assert( p->db==0 || p->db==db ); releaseMemArray(p->aVar, p->nVar); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); for(pSub=p->pProgram; pSub; pSub=pNext){ pNext = pSub->pNext; vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } vdbeFreeOpArray(db, p->aOp, p->nOp); sqlite3DbFree(db, p->aLabel); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); sqlite3DbFree(db, p->pFree); sqlite3DbFree(db, p); } | > > | 59899 59900 59901 59902 59903 59904 59905 59906 59907 59908 59909 59910 59911 59912 59913 59914 59915 59916 59917 59918 59919 59920 59921 59922 | ** Free all memory associated with the Vdbe passed as the second argument. ** The difference between this function and sqlite3VdbeDelete() is that ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with ** the database connection. */ SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; int i; assert( p->db==0 || p->db==db ); releaseMemArray(p->aVar, p->nVar); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); for(pSub=p->pProgram; pSub; pSub=pNext){ pNext = pSub->pNext; vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); sqlite3DbFree(db, pSub); } for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); vdbeFreeOpArray(db, p->aOp, p->nOp); sqlite3DbFree(db, p->aLabel); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); sqlite3DbFree(db, p->pFree); sqlite3DbFree(db, p); } |
︙ | ︙ | |||
60280 60281 60282 60283 60284 60285 60286 | u = 0; while( idx<szHdr && u<p->nField && d<=nKey ){ u32 serial_type; idx += getVarint32(&aKey[idx], serial_type); pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; | | > > | 60354 60355 60356 60357 60358 60359 60360 60361 60362 60363 60364 60365 60366 60367 60368 60369 60370 60371 60372 60373 60374 60375 60376 60377 60378 60379 60380 60381 60382 60383 60384 60385 60386 60387 60388 60389 60390 60391 60392 60393 60394 60395 60396 60397 | u = 0; while( idx<szHdr && u<p->nField && d<=nKey ){ u32 serial_type; idx += getVarint32(&aKey[idx], serial_type); pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ pMem->zMalloc = 0; d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; u++; } assert( u<=pKeyInfo->nField + 1 ); p->nField = u; return (void*)p; } /* ** This routine destroys a UnpackedRecord object. */ SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ #ifdef SQLITE_DEBUG int i; Mem *pMem; assert( p!=0 ); assert( p->flags & UNPACKED_NEED_DESTROY ); for(i=0, pMem=p->aMem; i<p->nField; i++, pMem++){ /* The unpacked record is always constructed by the ** sqlite3VdbeUnpackRecord() function above, which makes all ** strings and blobs static. And none of the elements are ** ever transformed, so there is never anything to delete. */ if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); } #endif if( p->flags & UNPACKED_NEED_FREE ){ sqlite3DbFree(p->pKeyInfo->db, p); } } /* ** This function compares the two table rows or index records |
︙ | ︙ | |||
60743 60744 60745 60746 60747 60748 60749 | int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v); | | | 60819 60820 60821 60822 60823 60824 60825 60826 60827 60828 60829 60830 60831 60832 60833 | int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v); sqlite3VdbeRewind(v); assert( (rc & (v->db->errMask))==rc ); rc = sqlite3ApiExit(v->db, rc); sqlite3_mutex_leave(v->db->mutex); } return rc; } |
︙ | ︙ | |||
61808 61809 61810 61811 61812 61813 61814 | ** This routine is added to support DBD::SQLite. */ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; return p ? p->nVar : 0; } | < < < < < < < < < < < < < < < < < < < < < < < < < < | < < | | 61884 61885 61886 61887 61888 61889 61890 61891 61892 61893 61894 61895 61896 61897 61898 61899 61900 61901 61902 61903 61904 61905 61906 61907 61908 61909 61910 61911 61912 61913 61914 61915 61916 61917 61918 61919 61920 61921 61922 61923 | ** This routine is added to support DBD::SQLite. */ SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; return p ? p->nVar : 0; } /* ** Return the name of a wildcard parameter. Return NULL if the index ** is out of range or if the wildcard is unnamed. ** ** The result is always UTF-8. */ SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; if( p==0 || i<1 || i>p->nzVar ){ return 0; } return p->azVar[i-1]; } /* ** Given a wildcard parameter name, return the index of the variable ** with that name. If there is no variable with the given name, ** return 0. */ SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ int i; if( p==0 ){ return 0; } if( zName ){ for(i=0; i<p->nzVar; i++){ const char *z = p->azVar[i]; if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){ return i+1; } } } return 0; |
︙ | ︙ | |||
63185 63186 63187 63188 63189 63190 63191 63192 63193 63194 63195 63196 63197 63198 | int i; sqlite_int64 rowid; Mem **apArg; Mem *pX; } cm; struct OP_Trace_stack_vars { char *zTrace; } cn; } u; /* End automatically generated code ********************************************************************/ assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ sqlite3VdbeEnter(p); | > | 63233 63234 63235 63236 63237 63238 63239 63240 63241 63242 63243 63244 63245 63246 63247 | int i; sqlite_int64 rowid; Mem **apArg; Mem *pX; } cm; struct OP_Trace_stack_vars { char *zTrace; char *z; } cn; } u; /* End automatically generated code ********************************************************************/ assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ sqlite3VdbeEnter(p); |
︙ | ︙ | |||
63611 63612 63613 63614 63615 63616 63617 63618 63619 63620 63621 63622 63623 63624 | */ case OP_Variable: { /* out2-prerelease */ #if 0 /* local variables moved into u.ab */ Mem *pVar; /* Value being transferred */ #endif /* local variables moved into u.ab */ assert( pOp->p1>0 && pOp->p1<=p->nVar ); u.ab.pVar = &p->aVar[pOp->p1 - 1]; if( sqlite3VdbeMemTooBig(u.ab.pVar) ){ goto too_big; } sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static); UPDATE_MAX_BLOBSIZE(pOut); break; | > | 63660 63661 63662 63663 63664 63665 63666 63667 63668 63669 63670 63671 63672 63673 63674 | */ case OP_Variable: { /* out2-prerelease */ #if 0 /* local variables moved into u.ab */ Mem *pVar; /* Value being transferred */ #endif /* local variables moved into u.ab */ assert( pOp->p1>0 && pOp->p1<=p->nVar ); assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); u.ab.pVar = &p->aVar[pOp->p1 - 1]; if( sqlite3VdbeMemTooBig(u.ab.pVar) ){ goto too_big; } sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static); UPDATE_MAX_BLOBSIZE(pOut); break; |
︙ | ︙ | |||
64403 64404 64405 64406 64407 64408 64409 | u16 flags3; /* Copy of initial value of pIn3->flags */ #endif /* local variables moved into u.ai */ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; u.ai.flags1 = pIn1->flags; u.ai.flags3 = pIn3->flags; | | | | 64453 64454 64455 64456 64457 64458 64459 64460 64461 64462 64463 64464 64465 64466 64467 64468 64469 64470 64471 64472 64473 64474 64475 | u16 flags3; /* Copy of initial value of pIn3->flags */ #endif /* local variables moved into u.ai */ pIn1 = &aMem[pOp->p1]; pIn3 = &aMem[pOp->p3]; u.ai.flags1 = pIn1->flags; u.ai.flags3 = pIn3->flags; if( (u.ai.flags1 | u.ai.flags3)&MEM_Null ){ /* One or both operands are NULL */ if( pOp->p5 & SQLITE_NULLEQ ){ /* If SQLITE_NULLEQ is set (which will only happen if the operator is ** OP_Eq or OP_Ne) then take the jump or not depending on whether ** or not both operands are null. */ assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); u.ai.res = (u.ai.flags1 & u.ai.flags3 & MEM_Null)==0; }else{ /* SQLITE_NULLEQ is clear and at least one operand is NULL, ** then the result is always NULL. ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. */ if( pOp->p5 & SQLITE_STOREP2 ){ pOut = &aMem[pOp->p2]; |
︙ | ︙ | |||
65237 65238 65239 65240 65241 65242 65243 65244 65245 65246 65247 65248 | */ sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - " "SQL statements in progress"); rc = SQLITE_BUSY; }else{ u.aq.nName = sqlite3Strlen30(u.aq.zName); /* This call is Ok even if this savepoint is actually a transaction ** savepoint (and therefore should not prompt xSavepoint()) callbacks. ** If this is a transaction savepoint being opened, it is guaranteed ** that the db->aVTrans[] array is empty. */ assert( db->autoCommit==0 || db->nVTrans==0 ); | > | > > | 65287 65288 65289 65290 65291 65292 65293 65294 65295 65296 65297 65298 65299 65300 65301 65302 65303 65304 65305 65306 65307 65308 65309 65310 | */ sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - " "SQL statements in progress"); rc = SQLITE_BUSY; }else{ u.aq.nName = sqlite3Strlen30(u.aq.zName); #ifndef SQLITE_OMIT_VIRTUALTABLE /* This call is Ok even if this savepoint is actually a transaction ** savepoint (and therefore should not prompt xSavepoint()) callbacks. ** If this is a transaction savepoint being opened, it is guaranteed ** that the db->aVTrans[] array is empty. */ assert( db->autoCommit==0 || db->nVTrans==0 ); rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, db->nStatement+db->nSavepoint); if( rc!=SQLITE_OK ) goto abort_due_to_error; #endif /* Create a new savepoint structure. */ u.aq.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.aq.nName+1); if( u.aq.pNew ){ u.aq.pNew->zName = (char *)&u.aq.pNew[1]; memcpy(u.aq.pNew->zName, u.aq.zName, u.aq.nName+1); |
︙ | ︙ | |||
65496 65497 65498 65499 65500 65501 65502 | assert( sqlite3BtreeIsInTrans(u.as.pBt) ); if( p->iStatement==0 ){ assert( db->nStatement>=0 && db->nSavepoint>=0 ); db->nStatement++; p->iStatement = db->nSavepoint + db->nStatement; } | | | 65549 65550 65551 65552 65553 65554 65555 65556 65557 65558 65559 65560 65561 65562 65563 | assert( sqlite3BtreeIsInTrans(u.as.pBt) ); if( p->iStatement==0 ){ assert( db->nStatement>=0 && db->nSavepoint>=0 ); db->nStatement++; p->iStatement = db->nSavepoint + db->nStatement; } rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); if( rc==SQLITE_OK ){ rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement); } /* Store the current value of the database handles deferred constraint ** counter. If the statement transaction needs to be rolled back, ** the value of this counter needs to be restored too. */ |
︙ | ︙ | |||
68629 68630 68631 68632 68633 68634 68635 68636 68637 | ** ** If tracing is enabled (by the sqlite3_trace()) interface, then ** the UTF-8 string contained in P4 is emitted on the trace callback. */ case OP_Trace: { #if 0 /* local variables moved into u.cn */ char *zTrace; #endif /* local variables moved into u.cn */ | > | < < | | | | | > > | | < | 68682 68683 68684 68685 68686 68687 68688 68689 68690 68691 68692 68693 68694 68695 68696 68697 68698 68699 68700 68701 68702 68703 68704 68705 68706 68707 68708 68709 68710 | ** ** If tracing is enabled (by the sqlite3_trace()) interface, then ** the UTF-8 string contained in P4 is emitted on the trace callback. */ case OP_Trace: { #if 0 /* local variables moved into u.cn */ char *zTrace; char *z; #endif /* local variables moved into u.cn */ if( db->xTrace && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ u.cn.z = sqlite3VdbeExpandSql(p, u.cn.zTrace); db->xTrace(db->pTraceArg, u.cn.z); sqlite3DbFree(db, u.cn.z); } #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); } #endif /* SQLITE_DEBUG */ break; } #endif /* Opcode: Noop * * * * * ** |
︙ | ︙ | |||
69068 69069 69070 69071 69072 69073 69074 | ** always return an SQL NULL. This is useful because it means ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); sqlite3VdbeChangeP2(v, 7, pTab->nCol); if( !db->mallocFailed ){ | > > > | | 69121 69122 69123 69124 69125 69126 69127 69128 69129 69130 69131 69132 69133 69134 69135 69136 69137 69138 | ** always return an SQL NULL. This is useful because it means ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); sqlite3VdbeChangeP2(v, 7, pTab->nCol); if( !db->mallocFailed ){ pParse->nVar = 1; pParse->nMem = 1; pParse->nTab = 1; sqlite3VdbeMakeReady(v, pParse); } } pBlob->flags = flags; pBlob->iCol = iCol; pBlob->db = db; sqlite3BtreeLeaveAll(db); |
︙ | ︙ | |||
71635 71636 71637 71638 71639 71640 71641 | z = pExpr->u.zToken; assert( z!=0 ); assert( z[0]!=0 ); if( z[1]==0 ){ /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); pExpr->iColumn = (ynVar)(++pParse->nVar); | > > > | | | | | | | | | | | | | > | | | | | | | | | | < < | | < < | | | | < | > | < | > | < > | > | < | | | | 71691 71692 71693 71694 71695 71696 71697 71698 71699 71700 71701 71702 71703 71704 71705 71706 71707 71708 71709 71710 71711 71712 71713 71714 71715 71716 71717 71718 71719 71720 71721 71722 71723 71724 71725 71726 71727 71728 71729 71730 71731 71732 71733 71734 71735 71736 71737 71738 71739 71740 71741 71742 71743 71744 71745 71746 71747 71748 71749 71750 71751 | z = pExpr->u.zToken; assert( z!=0 ); assert( z[0]!=0 ); if( z[1]==0 ){ /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); pExpr->iColumn = (ynVar)(++pParse->nVar); }else{ ynVar x = 0; u32 n = sqlite3Strlen30(z); if( z[0]=='?' ){ /* Wildcard of the form "?nnn". Convert "nnn" to an integer and ** use it as the variable number */ i64 i; int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); pExpr->iColumn = x = (ynVar)i; testcase( i==0 ); testcase( i==1 ); testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); x = 0; } if( i>pParse->nVar ){ pParse->nVar = (int)i; } }else{ /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable ** number as the prior appearance of the same name, or if the name ** has never appeared before, reuse the same variable number */ ynVar i; for(i=0; i<pParse->nzVar; i++){ if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){ pExpr->iColumn = x = (ynVar)i+1; break; } } if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); } if( x>0 ){ if( x>pParse->nzVar ){ char **a; a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); if( a==0 ) return; /* Error reported through db->mallocFailed */ pParse->azVar = a; memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); pParse->nzVar = x; } if( z[0]!='?' || pParse->azVar[x-1]==0 ){ sqlite3DbFree(db, pParse->azVar[x-1]); pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); } } } if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ sqlite3ErrorMsg(pParse, "too many SQL variables"); } } |
︙ | ︙ | |||
73425 73426 73427 73428 73429 73430 73431 | #endif case TK_VARIABLE: { assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( pExpr->u.zToken!=0 ); assert( pExpr->u.zToken[0]!=0 ); sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); if( pExpr->u.zToken[1]!=0 ){ | > > | | 73481 73482 73483 73484 73485 73486 73487 73488 73489 73490 73491 73492 73493 73494 73495 73496 73497 | #endif case TK_VARIABLE: { assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( pExpr->u.zToken!=0 ); assert( pExpr->u.zToken[0]!=0 ); sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); if( pExpr->u.zToken[1]!=0 ){ assert( pExpr->u.zToken[0]=='?' || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); } break; } case TK_REGISTER: { inReg = pExpr->iTable; break; } |
︙ | ︙ | |||
77396 77397 77398 77399 77400 77401 77402 | FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqlite3VdbeTrace(v, trace); #endif assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; | | < < | 77454 77455 77456 77457 77458 77459 77460 77461 77462 77463 77464 77465 77466 77467 77468 | FILE *trace = (db->flags & SQLITE_VdbeTrace)!=0 ? stdout : 0; sqlite3VdbeTrace(v, trace); #endif assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; sqlite3VdbeMakeReady(v, pParse); pParse->rc = SQLITE_DONE; pParse->colNamesSet = 0; }else{ pParse->rc = SQLITE_ERROR; } pParse->nTab = 0; pParse->nMem = 0; |
︙ | ︙ | |||
81815 81816 81817 81818 81819 81820 81821 81822 81823 81824 81825 81826 81827 81828 | /* Delete the row */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); sqlite3MayAbort(pParse); }else #endif { int count = (pParse->nested==0); /* True to count changes */ sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default); } | > | 81871 81872 81873 81874 81875 81876 81877 81878 81879 81880 81881 81882 81883 81884 81885 | /* Delete the row */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); sqlite3VdbeChangeP5(v, OE_Abort); sqlite3MayAbort(pParse); }else #endif { int count = (pParse->nested==0); /* True to count changes */ sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default); } |
︙ | ︙ | |||
87935 87936 87937 87938 87939 87940 87941 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. */ | < < < < | 87992 87993 87994 87995 87996 87997 87998 87999 88000 88001 88002 88003 88004 88005 | ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code used to implement the PRAGMA command. */ /* ** Interpret the given string as a safety level. Return 0 for OFF, ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or ** unrecognized string argument. ** ** Note that the values returned are one less that the values that ** should be passed into sqlite3BtreeSetSafetyLevel(). The is done |
︙ | ︙ | |||
87974 87975 87976 87977 87978 87979 87980 87981 87982 87983 87984 87985 87986 87987 | /* ** Interpret the given string as a boolean value. */ SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z){ return getSafetyLevel(z)&1; } /* ** Interpret the given string as a locking mode value. */ static int getLockingMode(const char *z){ if( z ){ if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE; | > > > > > > | 88027 88028 88029 88030 88031 88032 88033 88034 88035 88036 88037 88038 88039 88040 88041 88042 88043 88044 88045 88046 | /* ** Interpret the given string as a boolean value. */ SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z){ return getSafetyLevel(z)&1; } /* The sqlite3GetBoolean() function is used by other modules but the ** remainder of this file is specific to PRAGMA processing. So omit ** the rest of the file if PRAGMAs are omitted from the build. */ #if !defined(SQLITE_OMIT_PRAGMA) /* ** Interpret the given string as a locking mode value. */ static int getLockingMode(const char *z){ if( z ){ if( 0==sqlite3StrICmp(z, "exclusive") ) return PAGER_LOCKINGMODE_EXCLUSIVE; |
︙ | ︙ | |||
97680 97681 97682 97683 97684 97685 97686 | sqlite3ErrorMsg(pParse, "%s", zErr); } sqlite3DbFree(db, zErr); } return rc; } | < | > | > > > > > > > > < | 97739 97740 97741 97742 97743 97744 97745 97746 97747 97748 97749 97750 97751 97752 97753 97754 97755 97756 97757 97758 97759 97760 97761 97762 97763 97764 97765 97766 97767 97768 97769 97770 97771 97772 97773 97774 97775 97776 97777 97778 97779 97780 97781 97782 | sqlite3ErrorMsg(pParse, "%s", zErr); } sqlite3DbFree(db, zErr); } return rc; } /* ** Grow the db->aVTrans[] array so that there is room for at least one ** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. */ static int growVTrans(sqlite3 *db){ const int ARRAY_INCR = 5; /* Grow the sqlite3.aVTrans array if required */ if( (db->nVTrans%ARRAY_INCR)==0 ){ VTable **aVTrans; int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR); aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); if( !aVTrans ){ return SQLITE_NOMEM; } memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); db->aVTrans = aVTrans; } return SQLITE_OK; } /* ** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should ** have already been reserved using growVTrans(). */ static void addToVTrans(sqlite3 *db, VTable *pVTab){ /* Add pVtab to the end of sqlite3.aVTrans */ db->aVTrans[db->nVTrans++] = pVTab; sqlite3VtabLock(pVTab); } /* ** This function is invoked by the vdbe to call the xCreate method ** of the virtual table named zTab in database iDb. ** ** If an error occurs, *pzErr is set to point an an English language |
︙ | ︙ | |||
97740 97741 97742 97743 97744 97745 97746 | }else{ rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); } /* Justification of ALWAYS(): The xConstructor method is required to ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ | > > | > | 97806 97807 97808 97809 97810 97811 97812 97813 97814 97815 97816 97817 97818 97819 97820 97821 97822 97823 | }else{ rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); } /* Justification of ALWAYS(): The xConstructor method is required to ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ rc = growVTrans(db); if( rc==SQLITE_OK ){ addToVTrans(db, sqlite3GetVTable(db, pTab)); } } return rc; } /* ** This function is used to set the schema of a virtual table. It is only |
︙ | ︙ | |||
97856 97857 97858 97859 97860 97861 97862 97863 97864 97865 97866 97867 97868 97869 | VTable *pVTab = db->aVTrans[i]; sqlite3_vtab *p = pVTab->pVtab; if( p ){ int (*x)(sqlite3_vtab *); x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); if( x ) x(p); } sqlite3VtabUnlock(pVTab); } sqlite3DbFree(db, db->aVTrans); db->nVTrans = 0; db->aVTrans = 0; } } | > | 97925 97926 97927 97928 97929 97930 97931 97932 97933 97934 97935 97936 97937 97938 97939 | VTable *pVTab = db->aVTrans[i]; sqlite3_vtab *p = pVTab->pVtab; if( p ){ int (*x)(sqlite3_vtab *); x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); if( x ) x(p); } pVTab->iSavepoint = 0; sqlite3VtabUnlock(pVTab); } sqlite3DbFree(db, db->aVTrans); db->nVTrans = 0; db->aVTrans = 0; } } |
︙ | ︙ | |||
97945 97946 97947 97948 97949 97950 97951 | /* If pVtab is already in the aVTrans array, return early */ for(i=0; i<db->nVTrans; i++){ if( db->aVTrans[i]==pVTab ){ return SQLITE_OK; } } | | > > > | | | > | 98015 98016 98017 98018 98019 98020 98021 98022 98023 98024 98025 98026 98027 98028 98029 98030 98031 98032 98033 98034 98035 98036 | /* If pVtab is already in the aVTrans array, return early */ for(i=0; i<db->nVTrans; i++){ if( db->aVTrans[i]==pVTab ){ return SQLITE_OK; } } /* Invoke the xBegin method. If successful, add the vtab to the ** sqlite3.aVTrans[] array. */ rc = growVTrans(db); if( rc==SQLITE_OK ){ rc = pModule->xBegin(pVTab->pVtab); if( rc==SQLITE_OK ){ addToVTrans(db, pVTab); } } } return rc; } /* ** Invoke either the xSavepoint, xRollbackTo or xRelease method of all |
︙ | ︙ | |||
97973 97974 97975 97976 97977 97978 97979 97980 97981 97982 | ** function immediately. If all calls to virtual table methods are successful, ** SQLITE_OK is returned. */ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ int rc = SQLITE_OK; assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); if( db->aVTrans ){ int i; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ | > > | > > | > | 98047 98048 98049 98050 98051 98052 98053 98054 98055 98056 98057 98058 98059 98060 98061 98062 98063 98064 98065 98066 98067 98068 98069 98070 98071 98072 98073 98074 98075 98076 98077 98078 98079 98080 98081 98082 98083 | ** function immediately. If all calls to virtual table methods are successful, ** SQLITE_OK is returned. */ SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ int rc = SQLITE_OK; assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); assert( iSavepoint>=0 ); if( db->aVTrans ){ int i; for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ VTable *pVTab = db->aVTrans[i]; const sqlite3_module *pMod = pVTab->pMod->pModule; if( pMod->iVersion>=2 ){ int (*xMethod)(sqlite3_vtab *, int); switch( op ){ case SAVEPOINT_BEGIN: xMethod = pMod->xSavepoint; pVTab->iSavepoint = iSavepoint+1; break; case SAVEPOINT_ROLLBACK: xMethod = pMod->xRollbackTo; break; default: xMethod = pMod->xRelease; break; } if( xMethod && pVTab->iSavepoint>iSavepoint ){ rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint); } } } } return rc; } /* |
︙ | ︙ | |||
107252 107253 107254 107255 107256 107257 107258 | if( pEngine==0 ){ db->mallocFailed = 1; return SQLITE_NOMEM; } assert( pParse->pNewTable==0 ); assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); | | < | | 107331 107332 107333 107334 107335 107336 107337 107338 107339 107340 107341 107342 107343 107344 107345 107346 | if( pEngine==0 ){ db->mallocFailed = 1; return SQLITE_NOMEM; } assert( pParse->pNewTable==0 ); assert( pParse->pNewTrigger==0 ); assert( pParse->nVar==0 ); assert( pParse->nzVar==0 ); assert( pParse->azVar==0 ); enableLookaside = db->lookaside.bEnabled; if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; while( !db->mallocFailed && zSql[i]!=0 ){ assert( i>=0 ); pParse->sLastToken.z = &zSql[i]; pParse->sLastToken.n = sqlite3GetToken((unsigned char*)&zSql[i],&tokenType); i += pParse->sLastToken.n; |
︙ | ︙ | |||
107348 107349 107350 107351 107352 107353 107354 | ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ sqlite3DeleteTable(db, pParse->pNewTable); } sqlite3DeleteTrigger(db, pParse->pNewTrigger); | > | | 107426 107427 107428 107429 107430 107431 107432 107433 107434 107435 107436 107437 107438 107439 107440 107441 | ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ sqlite3DeleteTable(db, pParse->pNewTable); } sqlite3DeleteTrigger(db, pParse->pNewTrigger); for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); sqlite3DbFree(db, pParse->azVar); sqlite3DbFree(db, pParse->aAlias); while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; pParse->pAinc = p->pNext; sqlite3DbFree(db, p); } while( pParse->pZombieTab ){ |
︙ | ︙ | |||
109680 109681 109682 109683 109684 109685 109686 | if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ zVfs = zVal; }else{ struct OpenMode { const char *z; int mode; } *aMode = 0; | | | | | 109759 109760 109761 109762 109763 109764 109765 109766 109767 109768 109769 109770 109771 109772 109773 109774 109775 | if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ zVfs = zVal; }else{ struct OpenMode { const char *z; int mode; } *aMode = 0; char *zModeType = 0; int mask = 0; int limit = 0; if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ static struct OpenMode aCacheMode[] = { { "shared", SQLITE_OPEN_SHAREDCACHE }, { "private", SQLITE_OPEN_PRIVATECACHE }, { 0, 0 } }; |
︙ | ︙ | |||
111674 111675 111676 111677 111678 111679 111680 111681 111682 111683 111684 111685 111686 111687 111688 111689 111690 111691 111692 | /* ** Internal types used by SQLite. */ typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ typedef short int i16; /* 2-byte (or larger) signed integer */ typedef unsigned int u32; /* 4-byte unsigned integer */ typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ /* ** Macro used to suppress compiler warnings for unused parameters. */ #define UNUSED_PARAMETER(x) (void)(x) #endif typedef struct Fts3Table Fts3Table; typedef struct Fts3Cursor Fts3Cursor; typedef struct Fts3Expr Fts3Expr; typedef struct Fts3Phrase Fts3Phrase; typedef struct Fts3PhraseToken Fts3PhraseToken; | > > > > > > > > > > > > > > > > > > > > | 111753 111754 111755 111756 111757 111758 111759 111760 111761 111762 111763 111764 111765 111766 111767 111768 111769 111770 111771 111772 111773 111774 111775 111776 111777 111778 111779 111780 111781 111782 111783 111784 111785 111786 111787 111788 111789 111790 111791 | /* ** Internal types used by SQLite. */ typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ typedef short int i16; /* 2-byte (or larger) signed integer */ typedef unsigned int u32; /* 4-byte unsigned integer */ typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ /* ** Macro used to suppress compiler warnings for unused parameters. */ #define UNUSED_PARAMETER(x) (void)(x) /* ** Activate assert() only if SQLITE_TEST is enabled. */ #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) # define NDEBUG 1 #endif /* ** The TESTONLY macro is used to enclose variable declarations or ** other bits of code that are needed to support the arguments ** within testcase() and assert() macros. */ #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) # define TESTONLY(X) X #else # define TESTONLY(X) #endif #endif /* SQLITE_AMALGAMATION */ typedef struct Fts3Table Fts3Table; typedef struct Fts3Cursor Fts3Cursor; typedef struct Fts3Expr Fts3Expr; typedef struct Fts3Phrase Fts3Phrase; typedef struct Fts3PhraseToken Fts3PhraseToken; |
︙ | ︙ | |||
111733 111734 111735 111736 111737 111738 111739 111740 111741 111742 111743 111744 111745 111746 | ** automatically. Variable iPrevDocid is the docid of the most recently ** inserted record. */ int nMaxPendingData; int nPendingData; sqlite_int64 iPrevDocid; Fts3Hash pendingTerms; }; /* ** When the core wants to read from the virtual table, it creates a ** virtual table cursor (an instance of the following structure) using ** the xOpen method. Cursors are destroyed using the xClose method. */ | > > > > > > > > > > | 111832 111833 111834 111835 111836 111837 111838 111839 111840 111841 111842 111843 111844 111845 111846 111847 111848 111849 111850 111851 111852 111853 111854 111855 | ** automatically. Variable iPrevDocid is the docid of the most recently ** inserted record. */ int nMaxPendingData; int nPendingData; sqlite_int64 iPrevDocid; Fts3Hash pendingTerms; #if defined(SQLITE_DEBUG) /* State variables used for validating that the transaction control ** methods of the virtual table are called at appropriate times. These ** values do not contribution to the FTS computation; they are used for ** verifying the SQLite core. */ int inTransaction; /* True after xBegin but before xCommit/xRollback */ int mxSavepoint; /* Largest valid xSavepoint integer */ #endif }; /* ** When the core wants to read from the virtual table, it creates a ** virtual table cursor (an instance of the following structure) using ** the xOpen method. Cursors are destroyed using the xClose method. */ |
︙ | ︙ | |||
112643 112644 112645 112646 112647 112648 112649 112650 112651 112652 112653 112654 112655 112656 | p->nPendingData = 0; p->azColumn = (char **)&p[1]; p->pTokenizer = pTokenizer; p->nNodeSize = 1000; p->nMaxPendingData = FTS3_MAX_PENDING_DATA; p->bHasDocsize = (isFts4 && bNoDocsize==0); p->bHasStat = isFts4; fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1); /* Fill in the zName and zDb fields of the vtab structure. */ zCsr = (char *)&p->azColumn[nCol]; p->zName = zCsr; memcpy(zCsr, argv[2], nName); zCsr += nName; | > > | 112752 112753 112754 112755 112756 112757 112758 112759 112760 112761 112762 112763 112764 112765 112766 112767 | p->nPendingData = 0; p->azColumn = (char **)&p[1]; p->pTokenizer = pTokenizer; p->nNodeSize = 1000; p->nMaxPendingData = FTS3_MAX_PENDING_DATA; p->bHasDocsize = (isFts4 && bNoDocsize==0); p->bHasStat = isFts4; TESTONLY( p->inTransaction = -1 ); TESTONLY( p->mxSavepoint = -1 ); fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1); /* Fill in the zName and zDb fields of the vtab structure. */ zCsr = (char *)&p->azColumn[nCol]; p->zName = zCsr; memcpy(zCsr, argv[2], nName); zCsr += nName; |
︙ | ︙ | |||
114940 114941 114942 114943 114944 114945 114946 | } /* ** Implementation of xBegin() method. This is a no-op. */ static int fts3BeginMethod(sqlite3_vtab *pVtab){ UNUSED_PARAMETER(pVtab); | > | > > > > | > > > > | > > > | 115051 115052 115053 115054 115055 115056 115057 115058 115059 115060 115061 115062 115063 115064 115065 115066 115067 115068 115069 115070 115071 115072 115073 115074 115075 115076 115077 115078 115079 115080 115081 115082 115083 115084 115085 115086 115087 115088 115089 115090 115091 115092 115093 115094 115095 115096 115097 | } /* ** Implementation of xBegin() method. This is a no-op. */ static int fts3BeginMethod(sqlite3_vtab *pVtab){ UNUSED_PARAMETER(pVtab); TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); assert( p->nPendingData==0 ); assert( p->inTransaction!=1 ); TESTONLY( p->inTransaction = 1 ); TESTONLY( p->mxSavepoint = -1; ); return SQLITE_OK; } /* ** Implementation of xCommit() method. This is a no-op. The contents of ** the pending-terms hash-table have already been flushed into the database ** by fts3SyncMethod(). */ static int fts3CommitMethod(sqlite3_vtab *pVtab){ UNUSED_PARAMETER(pVtab); TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); assert( p->nPendingData==0 ); assert( p->inTransaction!=0 ); TESTONLY( p->inTransaction = 0 ); TESTONLY( p->mxSavepoint = -1; ); return SQLITE_OK; } /* ** Implementation of xRollback(). Discard the contents of the pending-terms ** hash-table. Any changes made to the database are reverted by SQLite. */ static int fts3RollbackMethod(sqlite3_vtab *pVtab){ Fts3Table *p = (Fts3Table*)pVtab; sqlite3Fts3PendingTermsClear(p); assert( p->inTransaction!=0 ); TESTONLY( p->inTransaction = 0 ); TESTONLY( p->mxSavepoint = -1; ); return SQLITE_OK; } /* ** Load the doclist associated with expression pExpr to pExpr->aDoclist. ** The loaded doclist contains positions as well as the document ids. ** This is used by the matchinfo(), snippet() and offsets() auxillary |
︙ | ︙ | |||
115316 115317 115318 115319 115320 115321 115322 | "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", p->zDb, p->zName, zName ); return rc; } static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ | > > > > > | > > > > > > > > > > > | | 115439 115440 115441 115442 115443 115444 115445 115446 115447 115448 115449 115450 115451 115452 115453 115454 115455 115456 115457 115458 115459 115460 115461 115462 115463 115464 115465 115466 115467 115468 115469 115470 115471 115472 115473 115474 115475 | "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", p->zDb, p->zName, zName ); return rc; } static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts3Table *p = (Fts3Table*)pVtab; UNUSED_PARAMETER(iSavepoint); assert( p->inTransaction ); assert( p->mxSavepoint < iSavepoint ); TESTONLY( p->mxSavepoint = iSavepoint ); return sqlite3Fts3PendingTermsFlush(p); } static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); UNUSED_PARAMETER(iSavepoint); UNUSED_PARAMETER(pVtab); assert( p->inTransaction ); assert( p->mxSavepoint >= iSavepoint ); TESTONLY( p->mxSavepoint = iSavepoint-1 ); return SQLITE_OK; } static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts3Table *p = (Fts3Table*)pVtab; UNUSED_PARAMETER(iSavepoint); assert( p->inTransaction ); assert( p->mxSavepoint >= iSavepoint ); TESTONLY( p->mxSavepoint = iSavepoint ); sqlite3Fts3PendingTermsClear(p); return SQLITE_OK; } static const sqlite3_module fts3Module = { /* iVersion */ 2, /* xCreate */ fts3CreateMethod, /* xConnect */ fts3ConnectMethod, |
︙ | ︙ | |||
115821 115822 115823 115824 115825 115826 115827 115828 115829 115830 115831 115832 115833 115834 | ){ Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; int rc; int isScan; UNUSED_PARAMETER(nVal); assert( idxStr==0 ); assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) ); isScan = (idxNum!=FTS4AUX_EQ_CONSTRAINT); | > | 115960 115961 115962 115963 115964 115965 115966 115967 115968 115969 115970 115971 115972 115973 115974 | ){ Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; int rc; int isScan; UNUSED_PARAMETER(nVal); UNUSED_PARAMETER(idxStr); assert( idxStr==0 ); assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) ); isScan = (idxNum!=FTS4AUX_EQ_CONSTRAINT); |
︙ | ︙ | |||
115938 115939 115940 115941 115942 115943 115944 | fts3auxRowidMethod, /* xRowid */ 0, /* xUpdate */ 0, /* xBegin */ 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindFunction */ | | > > > | 116078 116079 116080 116081 116082 116083 116084 116085 116086 116087 116088 116089 116090 116091 116092 116093 116094 116095 | fts3auxRowidMethod, /* xRowid */ 0, /* xUpdate */ 0, /* xBegin */ 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindFunction */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0 /* xRollbackTo */ }; int rc; /* Return code */ rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); return rc; } |
︙ | ︙ | |||
125917 125918 125919 125920 125921 125922 125923 | rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } static sqlite3_module rtreeModule = { | | | > > > | 126060 126061 126062 126063 126064 126065 126066 126067 126068 126069 126070 126071 126072 126073 126074 126075 126076 126077 126078 126079 126080 126081 126082 126083 126084 126085 126086 126087 126088 126089 126090 126091 126092 126093 126094 126095 126096 | rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); sqlite3_free(zSql); } return rc; } static sqlite3_module rtreeModule = { 0, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ rtreeDisconnect, /* xDisconnect - Disconnect from a table */ rtreeDestroy, /* xDestroy - Drop a table */ rtreeOpen, /* xOpen - open a cursor */ rtreeClose, /* xClose - close a cursor */ rtreeFilter, /* xFilter - configure scan constraints */ rtreeNext, /* xNext - advance a cursor */ rtreeEof, /* xEof */ rtreeColumn, /* xColumn - read data */ rtreeRowid, /* xRowid - read data */ rtreeUpdate, /* xUpdate - write data */ 0, /* xBegin - begin transaction */ 0, /* xSync - sync transaction */ 0, /* xCommit - commit transaction */ 0, /* xRollback - rollback transaction */ 0, /* xFindFunction - function overloading */ rtreeRename, /* xRename - rename the table */ 0, /* xSavepoint */ 0, /* xRelease */ 0 /* xRollbackTo */ }; static int rtreeSqlInit( Rtree *pRtree, sqlite3 *db, const char *zDb, const char *zPrefix, |
︙ | ︙ |
Changes to src/sqlite3.h.
︙ | ︙ | |||
105 106 107 108 109 110 111 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.7" #define SQLITE_VERSION_NUMBER 3007007 | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.7.7" #define SQLITE_VERSION_NUMBER 3007007 #define SQLITE_SOURCE_ID "2011-06-03 14:19:10 0206bc6f87bb9393218a380fc5b18039d334a8d8" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version, sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
︙ | ︙ | |||
455 456 457 458 459 460 461 462 463 464 465 466 467 468 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. | > > | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8)) #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) /* ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the ** 3rd parameter to the [sqlite3_open_v2()] interface and ** in the 4th parameter to the [sqlite3_vfs.xOpen] method. |
︙ | ︙ | |||
760 761 762 763 764 765 766 | ** ** Mutexes are created using [sqlite3_mutex_alloc()]. */ typedef struct sqlite3_mutex sqlite3_mutex; /* ** CAPI3REF: OS Interface Object | < | > | 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 | ** ** Mutexes are created using [sqlite3_mutex_alloc()]. */ typedef struct sqlite3_mutex sqlite3_mutex; /* ** CAPI3REF: OS Interface Object ** ** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" ** in the name of the object stands for "virtual file system". See ** the [VFS | VFS documentation] for further information. ** ** The value of the iVersion field is initially 1 but may be larger in ** future versions of SQLite. Additional fields may be appended to this ** object when the iVersion value is increased. Note that the structure ** of the sqlite3_vfs object changes in the transaction between ** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not ** modified. |
︙ | ︙ |
Changes to src/stash.c.
︙ | ︙ | |||
183 184 185 186 187 188 189 | Blob delta; undo_save(zNew); blob_zero(&delta); if( rid==0 ){ db_ephemeral_blob(&q, 5, &delta); blob_write_to_file(&delta, zNPath); file_setexe(zNPath, isExec); | | | | | | | | | | 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | Blob delta; undo_save(zNew); blob_zero(&delta); if( rid==0 ){ db_ephemeral_blob(&q, 5, &delta); blob_write_to_file(&delta, zNPath); file_setexe(zNPath, isExec); fossil_print("ADD %s\n", zNew); }else if( isRemoved ){ fossil_print("DELETE %s\n", zOrig); file_delete(zOPath); }else{ Blob a, b, out, disk; db_ephemeral_blob(&q, 5, &delta); blob_read_from_file(&disk, zOPath); content_get(rid, &a); blob_delta_apply(&a, &delta, &b); if( blob_compare(&disk, &a)==0 ){ blob_write_to_file(&b, zNPath); file_setexe(zNPath, isExec); fossil_print("UPDATE %s\n", zNew); }else{ int rc = merge_3way(&a, zOPath, &b, &out); blob_write_to_file(&out, zNPath); file_setexe(zNPath, isExec); if( rc ){ fossil_print("CONFLICT %s\n", zNew); nConflict++; }else{ fossil_print("MERGE %s\n", zNew); } blob_reset(&out); } blob_reset(&a); blob_reset(&b); blob_reset(&disk); } blob_reset(&delta); if( fossil_strcmp(zOrig,zNew)!=0 ){ undo_save(zOrig); file_delete(zOPath); } } db_finalize(&q); if( nConflict ){ fossil_print("WARNING: merge conflicts - see messages above for details.\n"); } } /* ** Show the diffs associate with a single stash. */ static void stash_diff(int stashid, const char *zDiffCmd){ |
︙ | ︙ | |||
246 247 248 249 250 251 252 | int isRemoved = db_column_int(&q, 1); const char *zOrig = db_column_text(&q, 3); const char *zNew = db_column_text(&q, 4); char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); Blob delta; if( rid==0 ){ db_ephemeral_blob(&q, 5, &delta); | | | | | 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 | int isRemoved = db_column_int(&q, 1); const char *zOrig = db_column_text(&q, 3); const char *zNew = db_column_text(&q, 4); char *zOPath = mprintf("%s%s", g.zLocalRoot, zOrig); Blob delta; if( rid==0 ){ db_ephemeral_blob(&q, 5, &delta); fossil_print("ADDED %s\n", zNew); diff_print_index(zNew); diff_file_mem(&empty, &delta, zNew, zDiffCmd, 0); }else if( isRemoved ){ fossil_print("DELETE %s\n", zOrig); blob_read_from_file(&delta, zOPath); diff_print_index(zNew); diff_file_mem(&delta, &empty, zOrig, zDiffCmd, 0); }else{ Blob a, b, disk; db_ephemeral_blob(&q, 5, &delta); blob_read_from_file(&disk, zOPath); content_get(rid, &a); blob_delta_apply(&a, &delta, &b); fossil_print("CHANGED %s\n", zNew); diff_file_mem(&disk, &b, zNew, zDiffCmd, 0); blob_reset(&a); blob_reset(&b); blob_reset(&disk); } blob_reset(&delta); } |
︙ | ︙ | |||
411 412 413 414 415 416 417 | "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid)," " comment, datetime(ctime) FROM stash" " ORDER BY ctime DESC" ); while( db_step(&q)==SQLITE_ROW ){ const char *zCom; n++; | | | | | 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 | "SELECT stashid, (SELECT uuid FROM blob WHERE rid=vid)," " comment, datetime(ctime) FROM stash" " ORDER BY ctime DESC" ); while( db_step(&q)==SQLITE_ROW ){ const char *zCom; n++; fossil_print("%5d: [%.14s] on %s\n", db_column_int(&q, 0), db_column_text(&q, 1), db_column_text(&q, 3) ); zCom = db_column_text(&q, 2); if( zCom && zCom[0] ){ fossil_print(" "); comment_print(zCom, 7, 79); } } db_finalize(&q); if( n==0 ) fossil_print("empty stash\n"); }else if( memcmp(zCmd, "drop", nCmd)==0 ){ int allFlag = find_option("all", 0, 0)!=0; if( g.argc>4 ) usage("stash apply STASHID"); if( allFlag ){ db_multi_exec("DELETE FROM stash; DELETE FROM stashfile;"); }else{ |
︙ | ︙ |
Changes to src/sync.c.
︙ | ︙ | |||
41 42 43 44 45 46 47 48 49 50 51 52 53 54 | const char *zUrl; const char *zAutosync; const char *zPw; int rc; int configSync = 0; /* configuration changes transferred */ if( g.fNoSync ){ return 0; } zAutosync = db_get("autosync", 0); if( zAutosync ){ if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ return 0; /* Do not auto-push when autosync=pullonly */ } if( is_false(zAutosync) ){ | > > > | 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | const char *zUrl; const char *zAutosync; const char *zPw; int rc; int configSync = 0; /* configuration changes transferred */ if( g.fNoSync ){ return 0; } if( flags==AUTOSYNC_PUSH && db_get_boolean("dont-push",0) ){ return 0; } zAutosync = db_get("autosync", 0); if( zAutosync ){ if( (flags & AUTOSYNC_PUSH)!=0 && memcmp(zAutosync,"pull",4)==0 ){ return 0; /* Do not auto-push when autosync=pullonly */ } if( is_false(zAutosync) ){ |
︙ | ︙ | |||
74 75 76 77 78 79 80 | ** TODO: What happens if the shun list gets really big? ** Maybe the shunning list should only be pulled on every 10th ** autosync, or something? */ configSync = CONFIGSET_SHUN; } #endif | | | 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | ** TODO: What happens if the shun list gets really big? ** Maybe the shunning list should only be pulled on every 10th ** autosync, or something? */ configSync = CONFIGSET_SHUN; } #endif fossil_print("Autosync: %s\n", g.urlCanonical); url_enable_proxy("via proxy: "); rc = client_sync((flags & AUTOSYNC_PUSH)!=0, 1, 0, 0, configSync, 0); if( rc ) fossil_warning("Autosync failed"); return rc; } /* |
︙ | ︙ | |||
122 123 124 125 126 127 128 | } if( !g.dontKeepUrl ){ db_set("last-sync-url", g.urlCanonical, 0); if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); } user_select(); if( g.argc==2 ){ | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | } if( !g.dontKeepUrl ){ db_set("last-sync-url", g.urlCanonical, 0); if( g.urlPasswd ) db_set("last-sync-pw", obscure(g.urlPasswd), 0); } user_select(); if( g.argc==2 ){ fossil_print("Server: %s\n", g.urlCanonical); } url_enable_proxy("via proxy: "); *pConfigSync = configSync; } /* ** COMMAND: pull |
︙ | ︙ | |||
183 184 185 186 187 188 189 190 191 192 193 194 195 196 | ** ** See also: clone, pull, sync, remote-url */ void push_cmd(void){ int syncFlags; int bPrivate; process_sync_args(&syncFlags, &bPrivate); client_sync(1,0,0,bPrivate,0,0); } /* ** COMMAND: sync ** | > > > | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | ** ** See also: clone, pull, sync, remote-url */ void push_cmd(void){ int syncFlags; int bPrivate; process_sync_args(&syncFlags, &bPrivate); if( db_get_boolean("dont-push",0) ){ fossil_fatal("pushing is prohibited: the 'dont-push' option is set"); } client_sync(1,0,0,bPrivate,0,0); } /* ** COMMAND: sync ** |
︙ | ︙ | |||
217 218 219 220 221 222 223 224 | ** remote repository. ** ** See also: clone, push, pull, remote-url */ void sync_cmd(void){ int syncFlags; int bPrivate; process_sync_args(&syncFlags, &bPrivate); | > > | > > > | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 | ** remote repository. ** ** See also: clone, push, pull, remote-url */ void sync_cmd(void){ int syncFlags; int bPrivate; int pushFlag = 1; process_sync_args(&syncFlags, &bPrivate); if( db_get_boolean("dont-push",0) ) pushFlag = 0; client_sync(pushFlag,1,0,bPrivate,syncFlags,0); if( pushFlag==0 ){ fossil_warning("pull only: the 'dont-push' option is set"); } } /* ** COMMAND: remote-url ** ** Usage: %fossil remote-url ?URL|off? ** |
︙ | ︙ | |||
261 262 263 264 265 266 267 | }else{ db_unset("last-sync-pw", 0); } } } zUrl = db_get("last-sync-url", 0); if( zUrl==0 ){ | | | | 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | }else{ db_unset("last-sync-pw", 0); } } } zUrl = db_get("last-sync-url", 0); if( zUrl==0 ){ fossil_print("off\n"); return; }else{ url_parse(zUrl); fossil_print("%s\n", g.urlCanonical); } } |
Changes to src/tag.c.
︙ | ︙ | |||
294 295 296 297 298 299 300 | Blob cksum; static const char zTagtype[] = { '-', '+', '*' }; assert( tagtype>=0 && tagtype<=2 ); user_select(); blob_zero(&uuid); blob_append(&uuid, zObjName, -1); | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | Blob cksum; static const char zTagtype[] = { '-', '+', '*' }; assert( tagtype>=0 && tagtype<=2 ); user_select(); blob_zero(&uuid); blob_append(&uuid, zObjName, -1); if( name_to_uuid(&uuid, 9, "*") ){ fossil_fatal("%s", g.zErrMsg); return; } rid = name_to_rid(blob_str(&uuid)); g.markPrivate = content_is_private(rid); blob_zero(&ctrl); |
︙ | ︙ | |||
346 347 348 349 350 351 352 | ** the tag value propages to all descendants of CHECK-IN ** ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN ** ** Remove the tag TAGNAME from CHECK-IN, and also remove ** the propagation of the tag to any descendants. ** | | | > | 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | ** the tag value propages to all descendants of CHECK-IN ** ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN ** ** Remove the tag TAGNAME from CHECK-IN, and also remove ** the propagation of the tag to any descendants. ** ** %fossil tag find ?--raw? ?--type TYPE? TAGNAME ** ** List all objects that use TAGNAME. TYPE can be "ci" for ** checkins or "e" for events. ** ** %fossil tag list ?--raw? ?CHECK-IN? ** ** List all tags, or if CHECK-IN is supplied, list ** all tags and their values for CHECK-IN. ** ** The option --raw allows the manipulation of all types of tags |
︙ | ︙ | |||
424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | db_begin_transaction(); tag_add_artifact(zPrefix, g.argv[3], g.argv[4], 0, 0, 0, 0); db_end_transaction(0); }else if( strncmp(g.argv[2],"find",n)==0 ){ Stmt q; if( g.argc!=4 ){ usage("find ?--raw? TAGNAME"); } if( fRaw ){ db_prepare(&q, "SELECT blob.uuid FROM tagxref, blob" " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" " AND tagxref.tagtype>0" " AND blob.rid=tagxref.rid", g.argv[3] ); while( db_step(&q)==SQLITE_ROW ){ | > > | > | | | | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 | db_begin_transaction(); tag_add_artifact(zPrefix, g.argv[3], g.argv[4], 0, 0, 0, 0); db_end_transaction(0); }else if( strncmp(g.argv[2],"find",n)==0 ){ Stmt q; const char *zType = find_option("type","t",1); if( zType==0 || zType[0]==0 ) zType = "*"; if( g.argc!=4 ){ usage("find ?--raw? TAGNAME"); } if( fRaw ){ db_prepare(&q, "SELECT blob.uuid FROM tagxref, blob" " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)" " AND tagxref.tagtype>0" " AND blob.rid=tagxref.rid", g.argv[3] ); while( db_step(&q)==SQLITE_ROW ){ fossil_print("%s\n", db_column_text(&q, 0)); } db_finalize(&q); }else{ int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", g.argv[3]); if( tagid>0 ){ db_prepare(&q, "%s" " AND event.type GLOB '%q'" " AND blob.rid IN (" " SELECT rid FROM tagxref" " WHERE tagtype>0 AND tagid=%d" ")" " ORDER BY event.mtime DESC", timeline_query_for_tty(), zType, tagid ); print_timeline(&q, 2000); db_finalize(&q); } } }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 ){ const char *zName = db_column_text(&q, 0); if( fRaw ){ fossil_print("%s\n", zName); }else if( strncmp(zName, "sym-", 4)==0 ){ fossil_print("%s\n", &zName[4]); } } db_finalize(&q); }else if( g.argc==4 ){ int rid = name_to_rid(g.argv[3]); db_prepare(&q, "SELECT tagname, value FROM tagxref, tag" |
︙ | ︙ | |||
495 496 497 498 499 500 501 | const char *zName = db_column_text(&q, 0); const char *zValue = db_column_text(&q, 1); if( fRaw==0 ){ if( strncmp(zName, "sym-", 4)!=0 ) continue; zName += 4; } if( zValue && zValue[0] ){ | | | | 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 | const char *zName = db_column_text(&q, 0); const char *zValue = db_column_text(&q, 1); if( fRaw==0 ){ if( strncmp(zName, "sym-", 4)!=0 ) continue; zName += 4; } if( zValue && zValue[0] ){ fossil_print("%s=%s\n", zName, zValue); }else{ fossil_print("%s\n", zName); } } db_finalize(&q); }else{ usage("tag list ?CHECK-IN?"); } }else |
︙ | ︙ |
Changes to src/tar.c.
︙ | ︙ | |||
94 95 96 97 98 99 100 | int nName, /* Characters in zName */ unsigned int mTime /* Modification time */ ){ int i; for(i=nName-1; i>0 && zName[i]!='/'; i--){} if( i<=0 ) return; if( tball.zPrevDir[i]==0 && memcmp(tball.zPrevDir, zName, i)==0 ) return; | | | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | int nName, /* Characters in zName */ unsigned int mTime /* Modification time */ ){ int i; for(i=nName-1; i>0 && zName[i]!='/'; i--){} if( i<=0 ) return; if( tball.zPrevDir[i]==0 && memcmp(tball.zPrevDir, zName, i)==0 ) return; db_multi_exec("INSERT OR IGNORE INTO dir VALUES('%#q')", i, zName); if( sqlite3_changes(g.db)==0 ) return; tar_add_directory_of(zName, i-1, mTime); tar_add_header(zName, i, 0755, mTime, 0, 5); memcpy(tball.zPrevDir, zName, i); tball.zPrevDir[i] = 0; } |
︙ | ︙ | |||
271 272 273 274 275 276 277 | Blob tarball; const char *zName; zName = find_option("name", 0, 1); db_find_and_open_repository(0, 0); if( g.argc!=4 ){ usage("VERSION OUTPUTFILE"); } | | | 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 | Blob tarball; const char *zName; zName = find_option("name", 0, 1); db_find_and_open_repository(0, 0); if( g.argc!=4 ){ usage("VERSION OUTPUTFILE"); } rid = name_to_typed_rid(g.argv[2], "ci"); if( zName==0 ){ zName = db_text("default-name", "SELECT replace(%Q,' ','_') " " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) " " || substr(blob.uuid, 1, 10)" " FROM event, blob" " WHERE event.objid=%d" |
︙ | ︙ | |||
307 308 309 310 311 312 313 | login_check_credentials(); if( !g.okZip ){ login_needed(); return; } zName = mprintf("%s", PD("name","")); nName = strlen(zName); zRid = mprintf("%s", PD("uuid","")); nRid = strlen(zRid); | | | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 | login_check_credentials(); if( !g.okZip ){ login_needed(); return; } zName = mprintf("%s", PD("name","")); nName = strlen(zName); zRid = mprintf("%s", PD("uuid","")); nRid = strlen(zRid); if( nName>7 && fossil_strcmp(&zName[nName-7], ".tar.gz")==0 ){ /* Special case: Remove the ".tar.gz" suffix. */ nName -= 7; zName[nName] = 0; }else{ /* If the file suffix is not ".tar.gz" then just remove the ** suffix up to and including the last "." */ for(nName=strlen(zName)-1; nName>5; nName--){ |
︙ | ︙ |
Changes to src/th_main.c.
︙ | ︙ | |||
206 207 208 209 210 211 212 | ){ int rc; if( argc!=2 ){ return Th_WrongNumArgs(interp, "hascap STRING"); } rc = login_has_capability((char*)argv[1],argl[1]); if( g.thTrace ){ | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | ){ int rc; if( argc!=2 ){ return Th_WrongNumArgs(interp, "hascap STRING"); } rc = login_has_capability((char*)argv[1],argl[1]); if( g.thTrace ){ Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); } Th_SetResultInt(interp, rc); return TH_OK; } /* ** TH command: anycap STRING |
︙ | ︙ | |||
233 234 235 236 237 238 239 | if( argc!=2 ){ return Th_WrongNumArgs(interp, "anycap STRING"); } for(i=0; rc==0 && i<argl[1]; i++){ rc = login_has_capability((char*)&argv[1][i],1); } if( g.thTrace ){ | | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | if( argc!=2 ){ return Th_WrongNumArgs(interp, "anycap STRING"); } for(i=0; rc==0 && i<argl[1]; i++){ rc = login_has_capability((char*)&argv[1][i],1); } if( g.thTrace ){ Th_Trace("[hascap %#h] => %d<br />\n", argl[1], argv[1], rc); } Th_SetResultInt(interp, rc); return TH_OK; } /* ** TH1 command: combobox NAME TEXT-LIST NUMLINES |
︙ | ︙ |
Changes to src/timeline.c.
︙ | ︙ | |||
298 299 300 301 302 303 304 | const char *z = zTagList; Blob links; blob_zero(&links); while( z && z[0] ){ for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ blob_appendf(&links, | | | | 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | const char *z = zTagList; Blob links; blob_zero(&links); while( z && z[0] ){ for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){} if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){ blob_appendf(&links, "<a href=\"%s/timeline?r=%#t&nd&c=%s\">%#h</a>%.2s", g.zTop, i, z, zDate, i, z, &z[i] ); }else{ blob_appendf(&links, "%#h", i+2, z); } if( z[i]==0 ) break; z += i+2; } @ tags: %s(blob_str(&links))) blob_reset(&links); }else{ |
︙ | ︙ | |||
780 781 782 783 784 785 786 | ** If n= is missing, the default count is 20. */ void page_timeline(void){ Stmt q; /* Query used to generate the timeline */ Blob sql; /* text of SQL used to generate timeline */ Blob desc; /* Description of the timeline */ int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ | | | | | | | | | 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 | ** If n= is missing, the default count is 20. */ void page_timeline(void){ Stmt q; /* Query used to generate the timeline */ Blob sql; /* text of SQL used to generate timeline */ Blob desc; /* Description of the timeline */ int nEntry = atoi(PD("n","20")); /* Max number of entries on timeline */ int p_rid = name_to_typed_rid(P("p"),"ci"); /* artifact p and its parents */ int d_rid = name_to_typed_rid(P("d"),"ci"); /* artifact d and descendants */ int f_rid = name_to_typed_rid(P("f"),"ci"); /* artifact f and close family */ const char *zUser = P("u"); /* All entries by this user if not NULL */ const char *zType = PD("y","all"); /* Type of events. All if NULL */ const char *zAfter = P("a"); /* Events after this time */ const char *zBefore = P("b"); /* Events before this time */ const char *zCirca = P("c"); /* Events near this time */ const char *zTagName = P("t"); /* Show events with this tag */ const char *zBrName = P("r"); /* Show events related to this tag */ const char *zSearch = P("s"); /* Search string */ int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */ int tagid; /* Tag ID */ int tmFlags; /* Timeline flags */ const char *zThisTag = 0; /* Suppress links to this tag */ const char *zThisUser = 0; /* Suppress links to this user */ HQuery url; /* URL for various branch links */ int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */ int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */ int noMerge = P("nomerge")!=0; /* Do not follow merge links */ int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */ int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */ /* To view the timeline, must have permission to read project data. */ login_check_credentials(); if( !g.okRead && !g.okRdTkt && !g.okRdWiki ){ login_needed(); return; } if( zTagName && g.okRead ){ tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName); |
︙ | ︙ | |||
1201 1202 1203 1204 1205 1206 1207 | char *zFree = 0; int n = 0; char zPrefix[80]; char zUuid[UUID_SIZE+1]; sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); if( memcmp(zDate, zPrevDate, 10) ){ | | | | 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 | char *zFree = 0; int n = 0; char zPrefix[80]; char zUuid[UUID_SIZE+1]; sqlite3_snprintf(sizeof(zUuid), zUuid, "%.10s", zId); if( memcmp(zDate, zPrevDate, 10) ){ fossil_print("=== %.10s ===\n", zDate); memcpy(zPrevDate, zDate, 10); nLine++; } if( zCom==0 ) zCom = ""; fossil_print("%.8s ", &zDate[11]); zPrefix[0] = 0; if( nParent>1 ){ sqlite3_snprintf(sizeof(zPrefix), zPrefix, "*MERGE* "); n = strlen(zPrefix); } if( nChild>1 ){ const char *zBrType; |
︙ | ︙ | |||
1348 1349 1350 1351 1352 1353 1354 | zOrigin = g.argv[2]; }else{ zOrigin = "now"; } k = strlen(zOrigin); blob_zero(&uuid); blob_append(&uuid, zOrigin, -1); | | | | 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 | zOrigin = g.argv[2]; }else{ zOrigin = "now"; } k = strlen(zOrigin); blob_zero(&uuid); blob_append(&uuid, zOrigin, -1); if( fossil_strcmp(zOrigin, "now")==0 ){ if( mode==3 || mode==4 ){ fossil_fatal("cannot compute descendants or ancestors of a date"); } zDate = mprintf("(SELECT datetime('now'))"); }else if( strncmp(zOrigin, "current", k)==0 ){ if( !g.localOpen ){ fossil_fatal("must be within a local checkout to use 'current'"); } objid = db_lget_int("checkout",0); zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); }else if( name_to_uuid(&uuid, 0, "*")==0 ){ objid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &uuid); zDate = mprintf("(SELECT mtime FROM plink WHERE cid=%d)", objid); }else{ const char *zShift = ""; if( mode==3 || mode==4 ){ fossil_fatal("cannot compute descendants or ancestors of a date"); } |
︙ | ︙ | |||
1451 1452 1453 1454 1455 1456 1457 | " (SELECT uuid FROM blob WHERE rid=c.cid)," " datetime(p.mtime), datetime(c.mtime)" " FROM plink p, plink c" " WHERE p.cid=c.pid AND p.mtime>c.mtime" ); while( db_step(&q)==SQLITE_ROW ){ if( !showDetail ){ | | | | 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 | " (SELECT uuid FROM blob WHERE rid=c.cid)," " datetime(p.mtime), datetime(c.mtime)" " FROM plink p, plink c" " WHERE p.cid=c.pid AND p.mtime>c.mtime" ); while( db_step(&q)==SQLITE_ROW ){ if( !showDetail ){ fossil_print("%s\n", db_column_text(&q, 1)); }else{ fossil_print("%.14s -> %.14s %s -> %s\n", db_column_text(&q, 0), db_column_text(&q, 1), db_column_text(&q, 2), db_column_text(&q, 3)); } } db_finalize(&q); |
︙ | ︙ |
Changes to src/tkt.c.
︙ | ︙ | |||
32 33 34 35 36 37 38 | static char **azValue = 0; /* Original values */ static char **azAppend = 0; /* Value to be appended */ /* ** Compare two entries in azField for sorting purposes */ static int nameCmpr(const void *a, const void *b){ | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | static char **azValue = 0; /* Original values */ static char **azAppend = 0; /* Value to be appended */ /* ** Compare two entries in azField for sorting purposes */ static int nameCmpr(const void *a, const void *b){ return fossil_strcmp(*(char**)a, *(char**)b); } /* ** Obtain a list of all fields of the TICKET table. Put them ** in sorted order in azField[]. ** ** Also allocate space for azValue[] and azAppend[] and initialize |
︙ | ︙ | |||
73 74 75 76 77 78 79 | /* ** Return the index into azField[] of the given field name. ** Return -1 if zField is not in azField[]. */ static int fieldId(const char *zField){ int i; for(i=0; i<nField; i++){ | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | /* ** Return the index into azField[] of the given field name. ** Return -1 if zField is not in azField[]. */ static int fieldId(const char *zField){ int i; for(i=0; i<nField; i++){ if( fossil_strcmp(azField[i], zField)==0 ) return i; } return -1; } /* ** Query the database for all TICKET fields for the specific ** ticket whose name is given by the "name" CGI parameter. |
︙ | ︙ | |||
113 114 115 116 117 118 119 | char *zRevealed = 0; if( zVal==0 ){ zVal = ""; }else if( strncmp(zName, "private_", 8)==0 ){ zVal = zRevealed = db_reveal(zVal); } for(j=0; j<nField; j++){ | | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | char *zRevealed = 0; if( zVal==0 ){ zVal = ""; }else if( strncmp(zName, "private_", 8)==0 ){ zVal = zRevealed = db_reveal(zVal); } for(j=0; j<nField; j++){ if( fossil_strcmp(azField[j],zName)==0 ){ azValue[j] = mprintf("%s", zVal); break; } } if( Th_Fetch(zName, &size)==0 ){ Th_Store(zName, zVal); } |
︙ | ︙ | |||
214 215 216 217 218 219 220 | */ void ticket_rebuild_entry(const char *zTktUuid){ char *zTag = mprintf("tkt-%s", zTktUuid); int tagid = tag_findid(zTag, 1); Stmt q; Manifest *pTicket; int createFlag = 1; | | > | 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 | */ void ticket_rebuild_entry(const char *zTktUuid){ char *zTag = mprintf("tkt-%s", zTktUuid); int tagid = tag_findid(zTag, 1); Stmt q; Manifest *pTicket; int createFlag = 1; fossil_free(zTag); db_multi_exec( "DELETE FROM ticket WHERE tkt_uuid=%Q", zTktUuid ); db_prepare(&q, "SELECT rid FROM tagxref WHERE tagid=%d ORDER BY mtime",tagid); while( db_step(&q)==SQLITE_ROW ){ int rid = db_column_int(&q, 0); pTicket = manifest_get(rid, CFTYPE_TICKET); |
︙ | ︙ | |||
886 887 888 889 890 891 892 893 894 895 896 897 898 899 | ** change ticket identified by TICKETUUID and set the value of ** field FIELD to VALUE. Valid field descriptions are: ** status, type, severity, priority, resolution, ** foundin, private_contact, resolution, title or comment ** Field names given above are the ones, defined in a standard ** fossil environment. If you have added, deleted columns, you ** change the all your configured columns. ** You can use more than one field/value pair on the commandline. ** Using -q|--quote enables the special character decoding as ** in "ticket show". So it's possible, to set multiline text or ** text with special characters. ** ** %fossil ticket add FIELD VALUE ?FIELD VALUE .. ? ?-q|--quote? ** | > | 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 | ** change ticket identified by TICKETUUID and set the value of ** field FIELD to VALUE. Valid field descriptions are: ** status, type, severity, priority, resolution, ** foundin, private_contact, resolution, title or comment ** Field names given above are the ones, defined in a standard ** fossil environment. If you have added, deleted columns, you ** change the all your configured columns. ** If you use +FIELD, the VLUE Is appended to the field FIELD. ** You can use more than one field/value pair on the commandline. ** Using -q|--quote enables the special character decoding as ** in "ticket show". So it's possible, to set multiline text or ** text with special characters. ** ** %fossil ticket add FIELD VALUE ?FIELD VALUE .. ? ?-q|--quote? ** |
︙ | ︙ | |||
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 | } getAllTicketFields(); /* read commandline and assign fields in the azValue array */ while( i<g.argc ){ char *zFName; char *zFValue; int j; zFName = g.argv[i++]; if( i==g.argc ){ fossil_fatal("missing value for '%s'!",zFName); } zFValue = g.argv[i++]; | > < > > > > > > > > | > | > > > | | > > > > > | | | | | | | | | < | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 | } getAllTicketFields(); /* read commandline and assign fields in the azValue array */ while( i<g.argc ){ char *zFName; char *zFValue; int j; int append = 0; zFName = g.argv[i++]; if( i==g.argc ){ fossil_fatal("missing value for '%s'!",zFName); } zFValue = g.argv[i++]; if( tktEncoding == tktFossilize ){ zFValue=mprintf("%s",zFValue); defossilize(zFValue); } append = (zFName[0] == '+'); if (append){ zFName++; } j = fieldId(zFName); if( j == -1 ){ fossil_fatal("unknown field name '%s'!",zFName); }else{ if (append) { azAppend[j] = zFValue; } else { azValue[j] = zFValue; } } } /* now add the needed artifacts to the repository */ blob_zero(&tktchng); { /* add the time to the ticket manifest */ char *zDate; zDate = date_in_standard_format("now"); blob_appendf(&tktchng, "D %s\n", zDate); free(zDate); } /* append defined elements */ for(i=0; i<nField; i++){ char *zValue = 0; char *zPfx; if (azAppend[i] && azAppend[i][0] ){ zPfx = " +"; zValue = azAppend[i]; } else if( azValue[i] && azValue[i][0] ){ zPfx = " "; zValue = azValue[i]; } else { continue; } if( strncmp(azField[i], "private_", 8)==0 ){ zValue = db_conceal(zValue, strlen(zValue)); blob_appendf(&tktchng, "J%s%s %s\n", zPfx, azField[i], zValue); }else{ blob_appendf(&tktchng, "J%s%s %#F\n", zPfx, azField[i], strlen(zValue), zValue); } if( tktEncoding == tktFossilize ){ free(azValue[i]); } } blob_appendf(&tktchng, "K %s\n", zTktUuid); blob_appendf(&tktchng, "U %F\n", g.zLogin); md5sum_blob(&tktchng, &cksum); blob_appendf(&tktchng, "Z %b\n", &cksum); rid = content_put(&tktchng); |
︙ | ︙ |
Changes to src/undo.c.
︙ | ︙ | |||
56 57 58 59 60 61 62 | old_exists = db_column_int(&q, 1); old_exe = db_column_int(&q, 2); if( old_exists ){ db_ephemeral_blob(&q, 0, &new); } if( old_exists ){ if( new_exists ){ | | | | | | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | old_exists = db_column_int(&q, 1); old_exe = db_column_int(&q, 2); if( old_exists ){ db_ephemeral_blob(&q, 0, &new); } if( old_exists ){ if( new_exists ){ fossil_print("%s %s\n", redoFlag ? "REDO" : "UNDO", zPathname); }else{ fossil_print("NEW %s\n", zPathname); } blob_write_to_file(&new, zFullname); file_setexe(zFullname, old_exe); }else{ fossil_print("DELETE %s\n", zPathname); file_delete(zFullname); } blob_reset(&new); free(zFullname); db_finalize(&q); db_prepare(&q, "UPDATE undo SET content=:c, existsflag=%d, isExe=%d," " redoflag=NOT redoflag" |
︙ | ︙ | |||
295 296 297 298 299 300 301 | /* ** Complete the undo process is one is currently in process. */ void undo_finish(void){ if( undoActive ){ if( undoNeedRollback ){ | | | 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 | /* ** Complete the undo process is one is currently in process. */ void undo_finish(void){ if( undoActive ){ if( undoNeedRollback ){ fossil_print("\"fossil undo\" is available to undo changes" " to the working checkout.\n"); } undoActive = 0; undoNeedRollback = 0; } } |
︙ | ︙ | |||
317 318 319 320 321 322 323 | ** was locked or had permissions turned off. */ void undo_rollback(void){ if( !undoNeedRollback ) return; assert( undoActive ); undoNeedRollback = 0; undoActive = 0; | | | 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | ** was locked or had permissions turned off. */ void undo_rollback(void){ if( !undoNeedRollback ) return; assert( undoActive ); undoNeedRollback = 0; undoActive = 0; fossil_print("Rolling back prior filesystem changes...\n"); undo_all_filesystem(0); } /* ** COMMAND: undo ** COMMAND: redo ** |
︙ | ︙ | |||
358 359 360 361 362 363 364 | const char *zCmd = isRedo ? "redo" : "undo"; db_must_be_within_tree(); verify_all_options(); db_begin_transaction(); undo_available = db_lget_int("undo_available", 0); if( explainFlag ){ if( undo_available==0 ){ | | | > | | | | | | 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | const char *zCmd = isRedo ? "redo" : "undo"; db_must_be_within_tree(); verify_all_options(); db_begin_transaction(); undo_available = db_lget_int("undo_available", 0); if( explainFlag ){ if( undo_available==0 ){ fossil_print("No undo or redo is available\n"); }else{ Stmt q; int nChng = 0; zCmd = undo_available==1 ? "undo" : "redo"; fossil_print("A %s is available for the following command:\n\n" " %s %s\n\n", zCmd, g.argv[0], db_lget("undo_cmdline", "???")); db_prepare(&q, "SELECT existsflag, pathname FROM undo ORDER BY pathname" ); while( db_step(&q)==SQLITE_ROW ){ if( nChng==0 ){ fossil_print("The following file changes would occur if the " "command above is %sne:\n\n", zCmd); } nChng++; fossil_print("%s %s\n", db_column_int(&q,0) ? "UPDATE" : "DELETE", db_column_text(&q, 1) ); } db_finalize(&q); if( nChng==0 ){ fossil_print("No file changes would occur with this undo/redo.\n"); } } }else{ int vid1 = db_lget_int("checkout", 0); int vid2; if( g.argc==2 ){ if( undo_available!=(1+isRedo) ){ |
︙ | ︙ | |||
408 409 410 411 412 413 414 | file_tree_name(zFile, &path, 1); undo_one(blob_str(&path), isRedo); blob_reset(&path); } } vid2 = db_lget_int("checkout", 0); if( vid1!=vid2 ){ | | | 409 410 411 412 413 414 415 416 417 418 419 420 421 | file_tree_name(zFile, &path, 1); undo_one(blob_str(&path), isRedo); blob_reset(&path); } } vid2 = db_lget_int("checkout", 0); if( vid1!=vid2 ){ fossil_print("--------------------\n"); show_common_info(vid2, "updated-to:", 1, 0); } } db_end_transaction(0); } |
Changes to src/update.c.
︙ | ︙ | |||
117 118 119 120 121 122 123 | fossil_fatal("cannot update an uncommitted merge"); } if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); if( internalUpdate ){ tid = internalUpdate; }else if( g.argc>=3 ){ | | | | | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | fossil_fatal("cannot update an uncommitted merge"); } if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); if( internalUpdate ){ tid = internalUpdate; }else if( g.argc>=3 ){ if( fossil_strcmp(g.argv[2], "current")==0 ){ /* If VERSION is "current", then use the same algorithm to find the ** target as if VERSION were omitted. */ }else if( fossil_strcmp(g.argv[2], "latest")==0 ){ /* If VERSION is "latest", then use the same algorithm to find the ** target as if VERSION were omitted and the --latest flag is present. */ latestFlag = 1; }else{ tid = name_to_typed_rid(g.argv[2],"ci"); if( tid==0 ){ fossil_fatal("no such version: %s", g.argv[2]); }else if( !is_a_version(tid) ){ fossil_fatal("no such version: %s", g.argv[2]); } } } |
︙ | ︙ | |||
173 174 175 176 177 178 179 180 181 | db_finalize(&q); fossil_fatal("Multiple descendants"); } } tid = db_int(0, "SELECT rid FROM leaves, event" " WHERE event.objid=leaves.rid" " ORDER BY event.mtime DESC"); } | > > > > > | | 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | db_finalize(&q); fossil_fatal("Multiple descendants"); } } tid = db_int(0, "SELECT rid FROM leaves, event" " WHERE event.objid=leaves.rid" " ORDER BY event.mtime DESC"); if( tid==0 ) tid = vid; } if( tid==0 ){ fossil_panic("Internal Error: unable to find a version to update to."); } if( tid==vid && !verboseFlag ) return; /* Nothing to update */ db_begin_transaction(); vfile_check_signature(vid, 1, 0); if( !nochangeFlag && !internalUpdate ) undo_begin(); load_vfile_from_rid(tid); /* ** The record.fn field is used to match files against each other. The |
︙ | ︙ | |||
251 252 253 254 255 256 257 | ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ | | | | | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | ); if( debugFlag ){ db_prepare(&q, "SELECT rowid, fn, fnt, chnged, ridv, ridt, isexe FROM fv" ); while( db_step(&q)==SQLITE_ROW ){ fossil_print("%3d: ridv=%-4d ridt=%-4d chnged=%d isexe=%d\n", db_column_int(&q, 0), db_column_int(&q, 4), db_column_int(&q, 5), db_column_int(&q, 3), db_column_int(&q, 6)); fossil_print(" fnv = [%s]\n", db_column_text(&q, 1)); fossil_print(" fnt = [%s]\n", db_column_text(&q, 2)); } db_finalize(&q); } /* If FILES appear on the command-line, remove from the "fv" table ** every entry that is not named on the command-line or which is not ** in a directory named on the command-line. |
︙ | ︙ | |||
329 330 331 332 333 334 335 | zFullPath = mprintf("%s%s", g.zLocalRoot, zName); zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); nameChng = fossil_strcmp(zName, zNewName); if( idv>0 && ridv==0 && idt>0 && ridt>0 ){ /* Conflict. This file has been added to the current checkout ** but also exists in the target checkout. Use the current version. */ | | | | | | > | | | | | | | | | | | | 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 | zFullPath = mprintf("%s%s", g.zLocalRoot, zName); zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); nameChng = fossil_strcmp(zName, zNewName); if( idv>0 && ridv==0 && idt>0 && ridt>0 ){ /* Conflict. This file has been added to the current checkout ** but also exists in the target checkout. Use the current version. */ fossil_print("CONFLICT %s\n", zName); nConflict++; }else if( idt>0 && idv==0 ){ /* File added in the target. */ fossil_print("ADD %s\n", zName); undo_save(zName); if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ /* The file is unedited. Change it to the target version */ undo_save(zName); fossil_print("UPDATE %s\n", zName); if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){ /* The file missing from the local check-out. Restore it to the ** version that appears in the target. */ fossil_print("UPDATE %s\n", zName); undo_save(zName); if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); }else if( idt==0 && idv>0 ){ if( ridv==0 ){ /* Added in current checkout. Continue to hold the file as ** as an addition */ db_multi_exec("UPDATE vfile SET vid=%d WHERE id=%d", tid, idv); }else if( chnged ){ /* Edited locally but deleted from the target. Do not track the ** file but keep the edited version around. */ fossil_print("CONFLICT %s - edited locally but deleted by update\n", zName); nConflict++; }else{ fossil_print("REMOVE %s\n", zName); undo_save(zName); if( !nochangeFlag ) file_delete(zFullPath); } }else if( idt>0 && idv>0 && ridt!=ridv && chnged ){ /* Merge the changes in the current tree into the target version */ Blob r, t, v; int rc; if( nameChng ){ fossil_print("MERGE %s -> %s\n", zName, zNewName); }else{ fossil_print("MERGE %s\n", zName); } undo_save(zName); content_get(ridt, &t); content_get(ridv, &v); rc = merge_3way(&v, zFullPath, &t, &r); if( rc>=0 ){ if( !nochangeFlag ){ blob_write_to_file(&r, zFullNewPath); file_setexe(zFullNewPath, isexe); } if( rc>0 ){ fossil_print("***** %d merge conflicts in %s\n", rc, zNewName); nConflict++; } }else{ if( !nochangeFlag ){ blob_write_to_file(&t, zFullNewPath); file_setexe(zFullNewPath, isexe); } fossil_print("***** Cannot merge binary file %s\n", zNewName); nConflict++; } if( nameChng && !nochangeFlag ) file_delete(zFullPath); blob_reset(&v); blob_reset(&t); blob_reset(&r); }else{ if( chnged ){ if( verboseFlag ) fossil_print("EDITED %s\n", zName); }else{ db_bind_int(&mtimeXfer, ":idv", idv); db_bind_int(&mtimeXfer, ":idt", idt); db_step(&mtimeXfer); db_reset(&mtimeXfer); if( verboseFlag ) fossil_print("UNCHANGED %s\n", zName); } } free(zFullPath); free(zFullNewPath); } db_finalize(&q); db_finalize(&mtimeXfer); fossil_print("--------------\n"); show_common_info(tid, "updated-to:", 1, 0); /* Report on conflicts */ if( nConflict && !nochangeFlag ){ if( internalUpdate ){ internalConflictCnt = nConflict; }else{ fossil_print("WARNING: %d merge conflicts - see messages above for details.\n", nConflict); } } /* ** Clean up the mid and pid VFILE entries. Then commit the changes. */ |
︙ | ︙ | |||
465 466 467 468 469 470 471 | int errCode /* Error code if file not found. Panic if 0. */ ){ Manifest *pManifest; ManifestFile *pFile; int rid=0; if( revision ){ | | | 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 | int errCode /* Error code if file not found. Panic if 0. */ ){ Manifest *pManifest; ManifestFile *pFile; int rid=0; if( revision ){ rid = name_to_typed_rid(revision,"ci"); }else{ rid = db_lget_int("checkout", 0); } if( !is_a_version(rid) ){ if( errCode>0 ) return errCode; fossil_fatal("no such checkin: %s", revision); } |
︙ | ︙ | |||
568 569 570 571 572 573 574 | int isExe = 0; char *zFull; zFile = db_column_text(&q, 0); zFull = mprintf("%/%/", g.zLocalRoot, zFile); errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2); if( errCode==2 ){ if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ | | | | | | 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 | int isExe = 0; char *zFull; zFile = db_column_text(&q, 0); zFull = mprintf("%/%/", g.zLocalRoot, zFile); errCode = historical_version_of_file(zRevision, zFile, &record, &isExe,2); if( errCode==2 ){ if( db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFile)==0 ){ fossil_print("UNMANAGE: %s\n", zFile); }else{ undo_save(zFile); file_delete(zFull); fossil_print("DELETE: %s\n", zFile); } db_multi_exec("DELETE FROM vfile WHERE pathname=%Q", zFile); }else{ sqlite3_int64 mtime; undo_save(zFile); blob_write_to_file(&record, zFull); file_setexe(zFull, isExe); fossil_print("REVERTED: %s\n", zFile); mtime = file_mtime(zFull); db_multi_exec( "UPDATE vfile" " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, mrid=rid," " pathname=coalesce(origname,pathname), origname=NULL" " WHERE pathname=%Q", mtime, isExe, zFile |
︙ | ︙ |
Changes to src/url.c.
︙ | ︙ | |||
206 207 208 209 210 211 212 | int i; url_proxy_options(); if( g.argc!=3 && g.argc!=4 ){ usage("URL"); } url_parse(g.argv[2]); for(i=0; i<2; i++){ | | | | | | | | | | | | | | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | int i; url_proxy_options(); if( g.argc!=3 && g.argc!=4 ){ usage("URL"); } url_parse(g.argv[2]); for(i=0; i<2; i++){ fossil_print("g.urlIsFile = %d\n", g.urlIsFile); fossil_print("g.urlIsHttps = %d\n", g.urlIsHttps); fossil_print("g.urlIsSsh = %d\n", g.urlIsSsh); fossil_print("g.urlProtocol = %s\n", g.urlProtocol); fossil_print("g.urlName = %s\n", g.urlName); fossil_print("g.urlPort = %d\n", g.urlPort); fossil_print("g.urlDfltPort = %d\n", g.urlDfltPort); fossil_print("g.urlHostname = %s\n", g.urlHostname); fossil_print("g.urlPath = %s\n", g.urlPath); fossil_print("g.urlUser = %s\n", g.urlUser); fossil_print("g.urlPasswd = %s\n", g.urlPasswd); fossil_print("g.urlCanonical = %s\n", g.urlCanonical); fossil_print("g.urlFossil = %s\n", g.urlFossil); if( g.urlIsFile || g.urlIsSsh ) break; if( i==0 ){ fossil_print("********\n"); url_enable_proxy("Using proxy: "); } } } /* ** Proxy specified on the command-line using the --proxy option. |
︙ | ︙ | |||
274 275 276 277 278 279 280 | char *zOriginalUrl = g.urlCanonical; char *zOriginalHost = g.urlHostname; char *zOriginalUser = g.urlUser; char *zOriginalPasswd = g.urlPasswd; g.urlUser = 0; g.urlPasswd = ""; url_parse(zProxy); | | | 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | char *zOriginalUrl = g.urlCanonical; char *zOriginalHost = g.urlHostname; char *zOriginalUser = g.urlUser; char *zOriginalPasswd = g.urlPasswd; g.urlUser = 0; g.urlPasswd = ""; url_parse(zProxy); if( zMsg ) fossil_print("%s%s\n", zMsg, g.urlCanonical); g.urlPath = zOriginalUrl; g.urlHostname = zOriginalHost; if( g.urlUser ){ char *zCredentials1 = mprintf("%s:%s", g.urlUser, g.urlPasswd); char *zCredentials2 = encode64(zCredentials1, -1); g.urlProxyAuth = mprintf("Basic %z", zCredentials2); free(zCredentials1); |
︙ | ︙ | |||
338 339 340 341 342 343 344 | const char *zSep = "?"; int i; blob_reset(&p->url); blob_appendf(&p->url, "%s/%s", g.zTop, p->zBase); for(i=0; i<p->nParam; i++){ const char *z = p->azValue[i]; | | | | 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | const char *zSep = "?"; int i; blob_reset(&p->url); blob_appendf(&p->url, "%s/%s", g.zTop, p->zBase); for(i=0; i<p->nParam; i++){ const char *z = p->azValue[i]; if( zName1 && fossil_strcmp(zName1,p->azName[i])==0 ){ zName1 = 0; z = zValue1; if( z==0 ) continue; } if( zName2 && fossil_strcmp(zName2,p->azName[i])==0 ){ zName2 = 0; z = zValue2; if( z==0 ) continue; } blob_appendf(&p->url, "%s%s", zSep, p->azName[i]); if( z && z[0] ) blob_appendf(&p->url, "=%T", z); zSep = "&"; |
︙ | ︙ |
Changes to src/user.c.
︙ | ︙ | |||
115 116 117 118 119 120 121 | blob_zero(&secondTry); while(1){ prompt_for_passphrase(zPrompt, pPassphrase); if( verify==0 ) break; if( verify==1 && blob_size(pPassphrase)==0 ) break; prompt_for_passphrase("Retype new password: ", &secondTry); if( blob_compare(pPassphrase, &secondTry) ){ | | | | 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 | blob_zero(&secondTry); while(1){ prompt_for_passphrase(zPrompt, pPassphrase); if( verify==0 ) break; if( verify==1 && blob_size(pPassphrase)==0 ) break; prompt_for_passphrase("Retype new password: ", &secondTry); if( blob_compare(pPassphrase, &secondTry) ){ fossil_print("Passphrases do not match. Try again...\n"); }else{ break; } } blob_reset(&secondTry); } /* ** Prompt the user to enter a single line of text. */ void prompt_user(const char *zPrompt, Blob *pIn){ char *z; char zLine[1000]; blob_zero(pIn); fossil_print("%s", zPrompt); fflush(stdout); z = fgets(zLine, sizeof(zLine), stdin); if( z ){ strip_string(pIn, z); } } |
︙ | ︙ | |||
210 211 212 213 214 215 216 | "VALUES(%B,%Q,%B,%B,now())", &login, zPw, &caps, &contact ); free(zPw); }else if( n>=2 && strncmp(g.argv[2],"default",n)==0 ){ user_select(); if( g.argc==3 ){ | | | | | 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | "VALUES(%B,%Q,%B,%B,now())", &login, zPw, &caps, &contact ); free(zPw); }else if( n>=2 && strncmp(g.argv[2],"default",n)==0 ){ user_select(); if( g.argc==3 ){ fossil_print("%s\n", g.zLogin); }else{ if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.argv[3]) ){ fossil_fatal("no such user: %s", g.argv[3]); } if( g.localOpen ){ db_lset("default-user", g.argv[3]); }else{ db_set("default-user", g.argv[3], 0); } } }else if( n>=2 && strncmp(g.argv[2],"list",n)==0 ){ Stmt q; db_prepare(&q, "SELECT login, info FROM user ORDER BY login"); while( db_step(&q)==SQLITE_ROW ){ fossil_print("%-12s %s\n", db_column_text(&q, 0), db_column_text(&q, 1)); } db_finalize(&q); }else if( n>=2 && strncmp(g.argv[2],"password",2)==0 ){ char *zPrompt; int uid; Blob pw; if( g.argc!=4 && g.argc!=5 ) usage("password USERNAME ?NEW-PASSWORD?"); uid = db_int(0, "SELECT uid FROM user WHERE login=%Q", g.argv[3]); if( uid==0 ){ fossil_fatal("no such user: %s", g.argv[3]); } if( g.argc==5 ){ blob_init(&pw, g.argv[4], -1); }else{ zPrompt = mprintf("New password for %s: ", g.argv[3]); prompt_for_password(zPrompt, &pw, 1); } if( blob_size(&pw)==0 ){ fossil_print("password unchanged\n"); }else{ char *zSecret = sha1_shared_secret(blob_str(&pw), g.argv[3], 0); db_multi_exec("UPDATE user SET pw=%Q, mtime=now() WHERE uid=%d", zSecret, uid); free(zSecret); } }else if( n>=2 && strncmp(g.argv[2],"capabilities",2)==0 ){ |
︙ | ︙ | |||
266 267 268 269 270 271 272 | } if( g.argc==5 ){ db_multi_exec( "UPDATE user SET cap=%Q, mtime=now() WHERE uid=%d", g.argv[4], uid ); } | | | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | } if( g.argc==5 ){ db_multi_exec( "UPDATE user SET cap=%Q, mtime=now() WHERE uid=%d", g.argv[4], uid ); } fossil_print("%s\n", db_text(0, "SELECT cap FROM user WHERE uid=%d", uid)); }else{ fossil_panic("user subcommand should be one of: " "capabilities default list new password"); } } /* |
︙ | ︙ |
Changes to src/vfile.c.
︙ | ︙ | |||
262 263 264 265 266 267 268 | cReply = 'y'; } if( cReply=='n' || cReply=='N' ){ blob_reset(&content); continue; } } | | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | cReply = 'y'; } if( cReply=='n' || cReply=='N' ){ blob_reset(&content); continue; } } if( verbose ) fossil_print("%s\n", &zName[nRepos]); blob_write_to_file(&content, zName); file_setexe(zName, isExe); blob_reset(&content); db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", file_mtime(zName), id); } db_finalize(&q); |
︙ | ︙ | |||
284 285 286 287 288 289 290 | Stmt q; db_prepare(&q, "SELECT %Q || pathname FROM vfile" " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid); while( db_step(&q)==SQLITE_ROW ){ const char *zName; zName = db_column_text(&q, 0); | | | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | Stmt q; db_prepare(&q, "SELECT %Q || pathname FROM vfile" " WHERE vid=%d AND mrid>0", g.zLocalRoot, vid); while( db_step(&q)==SQLITE_ROW ){ const char *zName; zName = db_column_text(&q, 0); file_delete(zName); } db_finalize(&q); db_multi_exec("UPDATE vfile SET mtime=NULL WHERE vid=%d AND mrid>0", vid); } /* ** Check to see if the directory named in zPath is the top of a checkout. |
︙ | ︙ | |||
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | DIR *d; int origSize; const char *zDir; struct dirent *pEntry; int skipAll = 0; static Stmt ins; static int depth = 0; origSize = blob_size(pPath); if( pIgnore ){ blob_appendf(pPath, "/"); if( glob_match(pIgnore, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1; blob_resize(pPath, origSize); } if( skipAll ) return; if( depth==0 ){ db_prepare(&ins, "INSERT OR IGNORE INTO sfile(x) SELECT :file" " WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE pathname=:file)" ); } depth++; zDir = blob_str(pPath); | > > | > > | > > | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 | DIR *d; int origSize; const char *zDir; struct dirent *pEntry; int skipAll = 0; static Stmt ins; static int depth = 0; char *zMbcs; origSize = blob_size(pPath); if( pIgnore ){ blob_appendf(pPath, "/"); if( glob_match(pIgnore, &blob_str(pPath)[nPrefix+1]) ) skipAll = 1; blob_resize(pPath, origSize); } if( skipAll ) return; if( depth==0 ){ db_prepare(&ins, "INSERT OR IGNORE INTO sfile(x) SELECT :file" " WHERE NOT EXISTS(SELECT 1 FROM vfile WHERE pathname=:file)" ); } depth++; zDir = blob_str(pPath); zMbcs = fossil_utf8_to_mbcs(zDir); d = opendir(zMbcs); if( d ){ while( (pEntry=readdir(d))!=0 ){ char *zPath; char *zUtf8; if( pEntry->d_name[0]=='.' ){ if( !allFlag ) continue; if( pEntry->d_name[1]==0 ) continue; if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue; } zUtf8 = fossil_mbcs_to_utf8(pEntry->d_name); blob_appendf(pPath, "/%s", zUtf8); fossil_mbcs_free(zUtf8); zPath = blob_str(pPath); if( glob_match(pIgnore, &zPath[nPrefix+1]) ){ /* do nothing */ }else if( file_isdir(zPath)==1 ){ if( !vfile_top_of_checkout(zPath) ){ vfile_scan(pPath, nPrefix, allFlag, pIgnore); } }else if( file_isfile(zPath) ){ db_bind_text(&ins, ":file", &zPath[nPrefix+1]); db_step(&ins); db_reset(&ins); } blob_resize(pPath, origSize); } closedir(d); } fossil_mbcs_free(zMbcs); depth--; if( depth==0 ){ db_finalize(&ins); } } |
︙ | ︙ | |||
426 427 428 429 430 431 432 | while( db_step(&q)==SQLITE_ROW ){ const char *zFullpath = db_column_text(&q, 0); const char *zName = db_column_text(&q, 1); int isSelected = db_column_int(&q, 3); if( isSelected ){ md5sum_step_text(zName, -1); | | | 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 | while( db_step(&q)==SQLITE_ROW ){ const char *zFullpath = db_column_text(&q, 0); const char *zName = db_column_text(&q, 1); int isSelected = db_column_int(&q, 3); if( isSelected ){ md5sum_step_text(zName, -1); in = fossil_fopen(zFullpath,"rb"); if( in==0 ){ md5sum_step_text(" 0\n", -1); continue; } fseek(in, 0L, SEEK_END); sqlite3_snprintf(sizeof(zBuf), zBuf, " %ld\n", ftell(in)); fseek(in, 0L, SEEK_SET); |
︙ | ︙ | |||
489 490 491 492 493 494 495 | const char *zFullpath = db_column_text(&q, 0); const char *zName = db_column_text(&q, 1); int rid = db_column_int(&q, 2); blob_zero(&disk); rc = blob_read_from_file(&disk, zFullpath); if( rc<0 ){ | | | > | | | 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 | const char *zFullpath = db_column_text(&q, 0); const char *zName = db_column_text(&q, 1); int rid = db_column_int(&q, 2); blob_zero(&disk); rc = blob_read_from_file(&disk, zFullpath); if( rc<0 ){ fossil_print("ERROR: cannot read file [%s]\n", zFullpath); blob_reset(&disk); continue; } blob_zero(&repo); content_get(rid, &repo); if( blob_size(&repo)!=blob_size(&disk) ){ fossil_print("ERROR: [%s] is %d bytes on disk but %d in the repository\n", zName, blob_size(&disk), blob_size(&repo)); blob_reset(&disk); blob_reset(&repo); continue; } if( blob_compare(&repo, &disk) ){ fossil_print( "ERROR: [%s] is different on disk compared to the repository\n", zName); } blob_reset(&disk); blob_reset(&repo); } db_finalize(&q); } |
︙ | ︙ |
Changes to src/wiki.c.
︙ | ︙ | |||
83 84 85 86 87 88 89 | char *zPageName = db_get("project-name",0); char *zIndexPage = db_get("index-page",0); login_check_credentials(); if( zIndexPage ){ const char *zPathInfo = P("PATH_INFO"); while( zIndexPage[0]=='/' ) zIndexPage++; while( zPathInfo[0]=='/' ) zPathInfo++; | | | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | char *zPageName = db_get("project-name",0); char *zIndexPage = db_get("index-page",0); login_check_credentials(); if( zIndexPage ){ const char *zPathInfo = P("PATH_INFO"); while( zIndexPage[0]=='/' ) zIndexPage++; while( zPathInfo[0]=='/' ) zPathInfo++; if( fossil_strcmp(zIndexPage, zPathInfo)==0 ) zIndexPage = 0; } if( zIndexPage ){ cgi_redirectf("%s/%s", g.zTop, zIndexPage); } if( !g.okRdWiki ){ cgi_redirectf("%s/login?g=%s/home", g.zTop, g.zTop); } |
︙ | ︙ | |||
413 414 415 416 417 418 419 | zDate = db_text(0, "SELECT datetime('now')"); zId = db_text(0, "SELECT lower(hex(randomblob(8)))"); blob_appendf(p, "\n\n<hr><div id=\"%s\"><i>On %s UTC %h", zId, zDate, g.zLogin); free(zDate); zUser = PD("u",g.zLogin); | | | 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 | zDate = db_text(0, "SELECT datetime('now')"); zId = db_text(0, "SELECT lower(hex(randomblob(8)))"); blob_appendf(p, "\n\n<hr><div id=\"%s\"><i>On %s UTC %h", zId, zDate, g.zLogin); free(zDate); zUser = PD("u",g.zLogin); if( zUser[0] && fossil_strcmp(zUser,g.zLogin) ){ blob_appendf(p, " (claiming to be %h)", zUser); } zRemark = PD("r",""); blob_appendf(p, " added:</i><br />\n%s</div id=\"%s\">", zRemark, zId); } /* |
︙ | ︙ | |||
914 915 916 917 918 919 920 | zFile = (g.argc==4) ? 0 : g.argv[4]; if( zFile ){ FILE * zF; short doClose = 0; if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){ zF = stdout; }else{ | | | | | | | 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 | zFile = (g.argc==4) ? 0 : g.argv[4]; if( zFile ){ FILE * zF; short doClose = 0; if( (1 == strlen(zFile)) && ('-'==zFile[0]) ){ zF = stdout; }else{ zF = fossil_fopen( zFile, "w" ); doClose = zF ? 1 : 0; } if( ! zF ){ fossil_fatal("wiki export could not open output file for writing."); } fprintf(zF,"%.*s\n", i, zBody); if( doClose ) fclose(zF); }else{ fossil_print("%.*s\n", i, zBody); } manifest_destroy(pWiki); return; }else if( strncmp(g.argv[2],"commit",n)==0 || strncmp(g.argv[2],"create",n)==0 ){ char *zPageName; Blob content; if( g.argc!=4 && g.argc!=5 ){ usage("commit PAGENAME ?FILE?"); } zPageName = g.argv[3]; if( g.argc==4 ){ blob_read_from_channel(&content, stdin, -1); }else{ blob_read_from_file(&content, g.argv[4]); } if( g.argv[2][1]=='r' ){ wiki_cmd_commit(zPageName, 1, &content); fossil_print("Created new wiki page %s.\n", zPageName); }else{ wiki_cmd_commit(zPageName, 0, &content); fossil_print("Updated wiki page %s.\n", zPageName); } blob_reset(&content); }else if( strncmp(g.argv[2],"delete",n)==0 ){ if( g.argc!=5 ){ usage("delete PAGENAME"); } fossil_fatal("delete not yet implemented."); }else if( strncmp(g.argv[2],"list",n)==0 ){ Stmt q; db_prepare(&q, "SELECT substr(tagname, 6) FROM tag WHERE tagname GLOB 'wiki-*'" " ORDER BY lower(tagname) /*sort*/" ); while( db_step(&q)==SQLITE_ROW ){ const char *zName = db_column_text(&q, 0); fossil_print( "%s\n",zName); } db_finalize(&q); }else { goto wiki_cmd_usage; } return; wiki_cmd_usage: usage("export|create|commit|list ..."); } |
Changes to src/wikiformat.c.
︙ | ︙ | |||
129 130 131 132 133 134 135 | */ static int findAttr(const char *z){ int i, c, first, last; first = 1; last = sizeof(aAttribute)/sizeof(aAttribute[0]) - 1; while( first<=last ){ i = (first+last)/2; | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | */ static int findAttr(const char *z){ int i, c, first, last; first = 1; last = sizeof(aAttribute)/sizeof(aAttribute[0]) - 1; while( first<=last ){ i = (first+last)/2; c = fossil_strcmp(aAttribute[i].zName, z); if( c==0 ){ return i; }else if( c<0 ){ first = i+1; }else{ last = i-1; } |
︙ | ︙ | |||
328 329 330 331 332 333 334 | */ static int findTag(const char *z){ int i, c, first, last; first = 1; last = sizeof(aMarkup)/sizeof(aMarkup[0]) - 1; while( first<=last ){ i = (first+last)/2; | | | 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 | */ static int findTag(const char *z){ int i, c, first, last; first = 1; last = sizeof(aMarkup)/sizeof(aMarkup[0]) - 1; while( first<=last ){ i = (first+last)/2; c = fossil_strcmp(aMarkup[i].zName, z); if( c==0 ){ assert( aMarkup[i].iCode==i ); return i; }else if( c<0 ){ first = i+1; }else{ last = i-1; |
︙ | ︙ | |||
878 879 880 881 882 883 884 | */ static int findTagWithId(Renderer *p, int iTag, const char *zId){ int i; assert( zId!=0 ); for(i=p->nStack-1; i>=0; i--){ if( p->aStack[i].iCode!=iTag ) continue; if( p->aStack[i].zId==0 ) continue; | | | 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 | */ static int findTagWithId(Renderer *p, int iTag, const char *zId){ int i; assert( zId!=0 ); for(i=p->nStack-1; i>=0; i--){ if( p->aStack[i].iCode!=iTag ) continue; if( p->aStack[i].zId==0 ) continue; if( fossil_strcmp(zId, p->aStack[i].zId)!=0 ) continue; break; } return i; } /* ** Pop the stack until the top-most element of the stack |
︙ | ︙ | |||
1116 1117 1118 1119 1120 1121 1122 | char *z; assert( p->inVerbatim ); if( pMarkup->iCode!=MARKUP_VERBATIM ) return 0; if( !pMarkup->endTag ) return 0; if( p->zVerbatimId==0 ) return 1; if( pMarkup->nAttr!=1 ) return 0; z = pMarkup->aAttr[0].zValue; | | | 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 | char *z; assert( p->inVerbatim ); if( pMarkup->iCode!=MARKUP_VERBATIM ) return 0; if( !pMarkup->endTag ) return 0; if( p->zVerbatimId==0 ) return 1; if( pMarkup->nAttr!=1 ) return 0; z = pMarkup->aAttr[0].zValue; return fossil_strcmp(z, p->zVerbatimId)==0; } /* ** Return the MUTYPE for the top of the stack. */ static int stackTopType(Renderer *p){ if( p->nStack<=0 ) return 0; |
︙ | ︙ | |||
1142 1143 1144 1145 1146 1147 1148 | ParsedMarkup markup; int n; int inlineOnly = (p->state & INLINE_MARKUP_ONLY)!=0; int wikiUseHtml = (p->state & WIKI_USE_HTML)!=0; /* Make sure the attribute constants and names still align ** following changes in the attribute list. */ | | | 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 | ParsedMarkup markup; int n; int inlineOnly = (p->state & INLINE_MARKUP_ONLY)!=0; int wikiUseHtml = (p->state & WIKI_USE_HTML)!=0; /* Make sure the attribute constants and names still align ** following changes in the attribute list. */ assert( fossil_strcmp(aAttribute[ATTR_WIDTH].zName, "width")==0 ); while( z[0] ){ if( wikiUseHtml ){ n = nextRawToken(z, p, &tokenType); }else{ n = nextWikiToken(z, p, &tokenType); } |
︙ | ︙ | |||
1732 1733 1734 1735 1736 1737 1738 1739 | } default: { break; } } z += n; } } | > | 1732 1733 1734 1735 1736 1737 1738 1739 1740 | } default: { break; } } z += n; } free(renderer.aStack); } |
Changes to src/winhttp.c.
︙ | ︙ | |||
90 91 92 93 94 95 96 | z = strstr(zHdr, "\r\n\r\n"); if( z ){ wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt; break; } } if( amt>=sizeof(zHdr) ) goto end_request; | | | | | | 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 | z = strstr(zHdr, "\r\n\r\n"); if( z ){ wanted = find_content_length(zHdr) + (&z[4]-zHdr) - amt; break; } } if( amt>=sizeof(zHdr) ) goto end_request; out = fossil_fopen(zRequestFName, "wb"); if( out==0 ) goto end_request; fwrite(zHdr, 1, amt, out); while( wanted>0 ){ got = recv(p->s, zHdr, sizeof(zHdr), 0); if( got==SOCKET_ERROR ) goto end_request; if( got ){ fwrite(zHdr, 1, got, out); }else{ break; } wanted -= got; } fclose(out); out = 0; sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http \"%s\" %s %s %s --nossl%s", fossil_nameofexe(), g.zRepositoryName, zRequestFName, zReplyFName, inet_ntoa(p->addr.sin_addr), p->zOptions ); fossil_system(zCmd); in = fossil_fopen(zReplyFName, "rb"); if( in ){ while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){ send(p->s, zHdr, got, 0); } } end_request: if( out ) fclose(out); if( in ) fclose(in); closesocket(p->s); file_delete(zRequestFName); file_delete(zReplyFName); free(p); } /* ** Start a listening socket and process incoming HTTP requests on ** that socket. */ |
︙ | ︙ | |||
144 145 146 147 148 149 150 | WSADATA wd; SOCKET s = INVALID_SOCKET; SOCKADDR_IN addr; int idCnt = 0; int iPort = mnPort; Blob options; | | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | WSADATA wd; SOCKET s = INVALID_SOCKET; SOCKADDR_IN addr; int idCnt = 0; int iPort = mnPort; Blob options; if( zStopper ) file_delete(zStopper); blob_zero(&options); if( zNotFound ){ blob_appendf(&options, " --notfound %s", zNotFound); } if( g.useLocalauth ){ blob_appendf(&options, " --localauth"); } |
︙ | ︙ | |||
188 189 190 191 192 193 194 | fossil_fatal("unable to open listening socket on ports %d", mnPort); }else{ fossil_fatal("unable to open listening socket on any" " port in the range %d..%d", mnPort, mxPort); } } zTempPrefix = mprintf("fossil_server_P%d_", iPort); | | | | | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | fossil_fatal("unable to open listening socket on ports %d", mnPort); }else{ fossil_fatal("unable to open listening socket on any" " port in the range %d..%d", mnPort, mxPort); } } zTempPrefix = mprintf("fossil_server_P%d_", iPort); fossil_print("Listening for HTTP requests on TCP port %d\n", iPort); if( zBrowser ){ zBrowser = mprintf(zBrowser, iPort); fossil_print("Launch webbrowser: %s\n", zBrowser); fossil_system(zBrowser); } fossil_print("Type Ctrl-C to stop the HTTP server\n"); for(;;){ SOCKET client; SOCKADDR_IN client_addr; HttpRequest *p; int len = sizeof(client_addr); client = accept(s, (struct sockaddr*)&client_addr, &len); |
︙ | ︙ |
Changes to src/xfer.c.
︙ | ︙ | |||
547 548 549 550 551 552 553 | */ int check_login(Blob *pLogin, Blob *pNonce, Blob *pSig){ Stmt q; int rc = -1; char *zLogin = blob_terminate(pLogin); defossilize(zLogin); | | | 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 | */ int check_login(Blob *pLogin, Blob *pNonce, Blob *pSig){ Stmt q; int rc = -1; char *zLogin = blob_terminate(pLogin); defossilize(zLogin); if( fossil_strcmp(zLogin, "nobody")==0 || fossil_strcmp(zLogin,"anonymous")==0 ){ return 0; /* Anybody is allowed to sync as "nobody" or "anonymous" */ } if( fossil_strcmp(P("REMOTE_USER"), zLogin)==0 ){ return 0; /* Accept Basic Authorization */ } db_prepare(&q, "SELECT pw, cap, uid FROM user" |
︙ | ︙ | |||
805 806 807 808 809 810 811 | int deltaFlag = 0; int isClone = 0; int nGimme = 0; int size; int recvConfig = 0; char *zNow; | | | 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | int deltaFlag = 0; int isClone = 0; int nGimme = 0; int size; int recvConfig = 0; char *zNow; if( fossil_strcmp(PD("REQUEST_METHOD","POST"),"POST") ){ fossil_redirect_home(); } g.zLogin = "anonymous"; login_set_anon_nobody_capabilities(); login_check_credentials(); memset(&xfer, 0, sizeof(xfer)); blobarray_zero(xfer.aToken, count(xfer.aToken)); |
︙ | ︙ | |||
1204 1205 1206 1207 1208 1209 1210 | if( g.argc!=2 && g.argc!=3 ){ usage("?MESSAGEFILE?"); } blob_zero(&g.cgiIn); blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]); disableLogin = 1; page_xfer(); | | | 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 | if( g.argc!=2 && g.argc!=3 ){ usage("?MESSAGEFILE?"); } blob_zero(&g.cgiIn); blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]); disableLogin = 1; page_xfer(); fossil_print("%s\n", cgi_extract_content(¬Used)); } /* ** Format strings for progress reporting. */ static const char zLabelFormat[] = "%-10s %10s %10s %10s %10s\n"; static const char zValueFormat[] = "\r%-10s %10d %10d %10d %10d\n"; |
︙ | ︙ | |||
1388 1389 1390 1391 1392 1393 1394 | nCardSent = 0; nCardRcvd = 0; xfer.nFileSent = 0; xfer.nDeltaSent = 0; xfer.nGimmeSent = 0; xfer.nIGotSent = 0; if( !g.cgiOutput && !g.fQuiet ){ | | | 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 | nCardSent = 0; nCardRcvd = 0; xfer.nFileSent = 0; xfer.nDeltaSent = 0; xfer.nGimmeSent = 0; xfer.nIGotSent = 0; if( !g.cgiOutput && !g.fQuiet ){ fossil_print("waiting for server..."); } fflush(stdout); if( http_exchange(&send, &recv, cloneFlag==0 || nCycle>0) ){ nErr++; break; } lastPctDone = -1; |
︙ | ︙ | |||
1444 1445 1446 1447 1448 1449 1450 | continue; } xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); nCardRcvd++; if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ pctDone = (recv.iCursor*100)/recv.nUsed; if( pctDone!=lastPctDone ){ | | | 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 | continue; } xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken)); nCardRcvd++; if( !g.cgiOutput && !g.fQuiet && recv.nUsed>0 ){ pctDone = (recv.iCursor*100)/recv.nUsed; if( pctDone!=lastPctDone ){ fossil_print("\rprocessed: %d%% ", pctDone); lastPctDone = pctDone; fflush(stdout); } } /* file UUID SIZE \n CONTENT ** file UUID DELTASRC SIZE \n CONTENT |
︙ | ︙ | |||
1630 1631 1632 1633 1634 1635 1636 | ** subsequent messages should be OK. Nevertheless, we need to ignore ** the error card on the first message of a clone. */ if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ if( !cloneFlag || nCycle>0 ){ char *zMsg = blob_terminate(&xfer.aToken[1]); defossilize(zMsg); | | | 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 | ** subsequent messages should be OK. Nevertheless, we need to ignore ** the error card on the first message of a clone. */ if( blob_eq(&xfer.aToken[0],"error") && xfer.nToken==2 ){ if( !cloneFlag || nCycle>0 ){ char *zMsg = blob_terminate(&xfer.aToken[1]); defossilize(zMsg); if( fossil_strcmp(zMsg, "login failed")==0 ){ if( nCycle<2 ){ if( !g.dontKeepUrl ) db_unset("last-sync-pw", 0); go = 1; } }else{ blob_appendf(&xfer.err, "\rserver says: %s", zMsg); } |
︙ | ︙ |
Changes to src/zip.c.
︙ | ︙ | |||
96 97 98 99 100 101 102 | int i, c; int j; for(i=0; zName[i]; i++){ if( zName[i]=='/' ){ c = zName[i+1]; zName[i+1] = 0; for(j=0; j<nDir; j++){ | | | 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | int i, c; int j; for(i=0; zName[i]; i++){ if( zName[i]=='/' ){ c = zName[i+1]; zName[i+1] = 0; for(j=0; j<nDir; j++){ if( fossil_strcmp(zName, azDir[j])==0 ) break; } if( j>=nDir ){ nDir++; azDir = fossil_realloc(azDir, sizeof(azDir[0])*nDir); azDir[j] = mprintf("%s", zName); zip_add_file(zName, 0, 0); } |
︙ | ︙ | |||
390 391 392 393 394 395 396 | Blob zip; const char *zName; zName = find_option("name", 0, 1); db_find_and_open_repository(0, 0); if( g.argc!=4 ){ usage("VERSION OUTPUTFILE"); } | | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | Blob zip; const char *zName; zName = find_option("name", 0, 1); db_find_and_open_repository(0, 0); if( g.argc!=4 ){ usage("VERSION OUTPUTFILE"); } rid = name_to_typed_rid(g.argv[2],"ci"); if( zName==0 ){ zName = db_text("default-name", "SELECT replace(%Q,' ','_') " " || strftime('_%%Y-%%m-%%d_%%H%%M%%S_', event.mtime) " " || substr(blob.uuid, 1, 10)" " FROM event, blob" " WHERE event.objid=%d" |
︙ | ︙ | |||
431 432 433 434 435 436 437 | nRid = strlen(zRid); for(nName=strlen(zName)-1; nName>5; nName--){ if( zName[nName]=='.' ){ zName[nName] = 0; break; } } | | | 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 | nRid = strlen(zRid); for(nName=strlen(zName)-1; nName>5; nName--){ if( zName[nName]=='.' ){ zName[nName] = 0; break; } } rid = name_to_typed_rid(nRid?zRid:zName,"ci"); if( rid==0 ){ @ Not found return; } if( nRid==0 && nName>10 ) zName[10] = 0; zip_of_baseline(rid, &zip, zName); free( zName ); free( zRid ); cgi_set_content(&zip); cgi_set_content_type("application/zip"); } |
Changes to www/build-icons/mac.gif.
cannot compute difference between binary files
Changes to www/fossil_logo_small.gif.
cannot compute difference between binary files