Fossil SCM

Merge in changes from Stephan's branch.

drh 2008-02-08 21:51 trunk merge
Commit 8672e243f88d190c674c2cbceceb5d80ef698c78
3 files changed +37 -1 +3 +33 -7
+37 -1
--- src/admin.c
+++ src/admin.c
@@ -50,10 +50,19 @@
5050
}
5151
}
5252
return rc;
5353
}
5454
55
+
56
+void admin_prepare_submenu(){
57
+ if( g.okAdmin ){
58
+ style_submenu_element("Main", "Main admin page", "%s/admin", g.zTop );
59
+ style_submenu_element("SQL", "SQL page", "%s/admin/sql", g.zTop );
60
+ style_submenu_element("Setup", "Setup page", "%s/setup", g.zTop );
61
+ }
62
+}
63
+
5564
5665
/*
5766
** WEBPAGE: /admin/sql
5867
*/
5968
void admin_sql_page(void){
@@ -61,12 +70,13 @@
6170
login_check_credentials();
6271
if( !g.okAdmin ){
6372
login_needed();
6473
return;
6574
}
75
+ admin_prepare_submenu();
6676
style_header("Admin SQL");
67
- @ <hr/><h2>SQL:</h2>
77
+ @ <h2>SQL:</h2>
6878
@ You can enter only SELECT statements here, and some SQL-side functions
6979
@ are also restricted.<br/>
7080
@ <form action='' method='post'>
7181
@ <textarea style='border:2px solid black' name='sql'
7282
@ cols='80' rows='5'>%h(zSql)</textarea>
@@ -77,5 +87,31 @@
7787
db_generic_query_view(zSql, 0);
7888
sqlite3_set_authorizer(g.db, 0, 0);
7989
}
8090
style_footer();
8191
}
92
+
93
+/*
94
+** WEBPAGE: /admin
95
+*/
96
+void admin_page(void){
97
+ login_check_credentials();
98
+ if( !g.okAdmin ){
99
+ login_needed();
100
+ return;
101
+ }
102
+ if( g.zExtra && g.zExtra[0] ){
103
+ if(g.zExtra == strstr(g.zExtra,"sql")) admin_sql_page();
104
+ /* FIXME: ^^^ this ^^^ is an awful lot of work, especially once
105
+ ** the paths deepen. Figure out a way to simplify dispatching.
106
+ */
107
+ return;
108
+ }
109
+ admin_prepare_submenu();
110
+ style_header("Admin");
111
+ @ <h2>Links:</h2>
112
+ @ <ul>
113
+ @ <li><a href='%s(g.zBaseURL)/admin/setup'>Fossil WWW Setup</a></li>
114
+ @ <li><a href='%s(g.zBaseURL)/admin/sql'>Run SQL queries</a></li>
115
+ @ </ul>
116
+ style_footer();
117
+}
82118
--- src/admin.c
+++ src/admin.c
@@ -50,10 +50,19 @@
50 }
51 }
52 return rc;
53 }
54
 
 
 
 
 
 
 
 
 
55
56 /*
57 ** WEBPAGE: /admin/sql
58 */
59 void admin_sql_page(void){
@@ -61,12 +70,13 @@
61 login_check_credentials();
62 if( !g.okAdmin ){
63 login_needed();
64 return;
65 }
 
66 style_header("Admin SQL");
67 @ <hr/><h2>SQL:</h2>
68 @ You can enter only SELECT statements here, and some SQL-side functions
69 @ are also restricted.<br/>
70 @ <form action='' method='post'>
71 @ <textarea style='border:2px solid black' name='sql'
72 @ cols='80' rows='5'>%h(zSql)</textarea>
@@ -77,5 +87,31 @@
77 db_generic_query_view(zSql, 0);
78 sqlite3_set_authorizer(g.db, 0, 0);
79 }
80 style_footer();
81 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
--- src/admin.c
+++ src/admin.c
@@ -50,10 +50,19 @@
50 }
51 }
52 return rc;
53 }
54
55
56 void admin_prepare_submenu(){
57 if( g.okAdmin ){
58 style_submenu_element("Main", "Main admin page", "%s/admin", g.zTop );
59 style_submenu_element("SQL", "SQL page", "%s/admin/sql", g.zTop );
60 style_submenu_element("Setup", "Setup page", "%s/setup", g.zTop );
61 }
62 }
63
64
65 /*
66 ** WEBPAGE: /admin/sql
67 */
68 void admin_sql_page(void){
@@ -61,12 +70,13 @@
70 login_check_credentials();
71 if( !g.okAdmin ){
72 login_needed();
73 return;
74 }
75 admin_prepare_submenu();
76 style_header("Admin SQL");
77 @ <h2>SQL:</h2>
78 @ You can enter only SELECT statements here, and some SQL-side functions
79 @ are also restricted.<br/>
80 @ <form action='' method='post'>
81 @ <textarea style='border:2px solid black' name='sql'
82 @ cols='80' rows='5'>%h(zSql)</textarea>
@@ -77,5 +87,31 @@
87 db_generic_query_view(zSql, 0);
88 sqlite3_set_authorizer(g.db, 0, 0);
89 }
90 style_footer();
91 }
92
93 /*
94 ** WEBPAGE: /admin
95 */
96 void admin_page(void){
97 login_check_credentials();
98 if( !g.okAdmin ){
99 login_needed();
100 return;
101 }
102 if( g.zExtra && g.zExtra[0] ){
103 if(g.zExtra == strstr(g.zExtra,"sql")) admin_sql_page();
104 /* FIXME: ^^^ this ^^^ is an awful lot of work, especially once
105 ** the paths deepen. Figure out a way to simplify dispatching.
106 */
107 return;
108 }
109 admin_prepare_submenu();
110 style_header("Admin");
111 @ <h2>Links:</h2>
112 @ <ul>
113 @ <li><a href='%s(g.zBaseURL)/admin/setup'>Fossil WWW Setup</a></li>
114 @ <li><a href='%s(g.zBaseURL)/admin/sql'>Run SQL queries</a></li>
115 @ </ul>
116 style_footer();
117 }
118
--- src/my_page.c
+++ src/my_page.c
@@ -91,10 +91,13 @@
9191
9292
@ <h2>Welcome, %s(uname)!</h2>
9393
@ Your user ID is: %d(uid)<br/>
9494
@ Your Fossil permissions are: [%s(ucap)]
9595
@ [TODO: explain these]<br/>
96
+ if( g.okAdmin ){
97
+ @ You are an <a href='%s(g.zBaseURL)/admin'>admin</a>.<br/>
98
+ }
9699
@ Your additional info: [%s(uinfo)]
97100
@ [TODO: make this editable]<br/>
98101
99102
mypage_logout_button();
100103
101104
--- src/my_page.c
+++ src/my_page.c
@@ -91,10 +91,13 @@
91
92 @ <h2>Welcome, %s(uname)!</h2>
93 @ Your user ID is: %d(uid)<br/>
94 @ Your Fossil permissions are: [%s(ucap)]
95 @ [TODO: explain these]<br/>
 
 
 
96 @ Your additional info: [%s(uinfo)]
97 @ [TODO: make this editable]<br/>
98
99 mypage_logout_button();
100
101
--- src/my_page.c
+++ src/my_page.c
@@ -91,10 +91,13 @@
91
92 @ <h2>Welcome, %s(uname)!</h2>
93 @ Your user ID is: %d(uid)<br/>
94 @ Your Fossil permissions are: [%s(ucap)]
95 @ [TODO: explain these]<br/>
96 if( g.okAdmin ){
97 @ You are an <a href='%s(g.zBaseURL)/admin'>admin</a>.<br/>
98 }
99 @ Your additional info: [%s(uinfo)]
100 @ [TODO: make this editable]<br/>
101
102 mypage_logout_button();
103
104
+33 -7
--- src/zip.c
+++ src/zip.c
@@ -264,38 +264,64 @@
264264
** resulting ZIP archive contains a single file which is the RID
265265
** object.
266266
**
267267
** If the RID object does not exist in the repository, then
268268
** pZip is zeroed.
269
+**
270
+** zSynthDir is a "synthetic" subdirectory which all zipped files get
271
+** added to as part of the zip file. It may be 0 or an empty string,
272
+** in which case it is ignored. The intention is to create a zip which
273
+** politely expands into a subdir instead of filling your current dir
274
+** with source files. For example, pass a UUID or "ProjectName".
275
+**
269276
*/
270
-void zip_of_baseline(int rid, Blob *pZip){
277
+void zip_of_baseline(int rid, Blob *pZip, char const * zSynthDir ){
271278
int i;
272279
Blob mfile, file, hash;
273280
Manifest m;
274
-
281
+ char const * zDir = (zSynthDir && zSynthDir[0]) ? zSynthDir : "";
275282
content_get(rid, &mfile);
276283
if( blob_size(&mfile)==0 ){
277284
blob_zero(pZip);
278285
return;
279286
}
280287
blob_zero(&file);
281288
blob_zero(&hash);
282289
blob_copy(&file, &mfile);
283290
zip_open();
291
+
292
+ const int dirLen = strlen(zDir);
293
+ char zPrefix[dirLen+2];
294
+ memset(zPrefix, 0, sizeof(zPrefix));
295
+ if( zDir[0] ){
296
+ snprintf( zPrefix, sizeof(zPrefix), "%s/", zDir );
297
+ }
298
+ const int bufsize = 512;
299
+ char aSBuf[bufsize];
300
+ int prxLen = strlen(zPrefix);
301
+ memcpy(aSBuf, zPrefix, prxLen);
302
+ char * zHead = aSBuf + prxLen;
303
+ /* Rather than use a lot of mprintf()s here, we reuse aSBuf as a
304
+ ** buffer for the prefix + current file name. zHead keeps track
305
+ ** of where we should write file names to this buffer.
306
+ */
284307
if( manifest_parse(&m, &mfile) ){
285308
zip_set_timedate(m.rDate);
286
- zip_add_file("manifest", &file);
309
+ snprintf( zHead, bufsize, "manifest" );
310
+ zip_add_file(aSBuf, &file);
287311
sha1sum_blob(&file, &hash);
288312
blob_reset(&file);
289313
blob_append(&hash, "\n", 1);
290
- zip_add_file("manifest.uuid", &hash);
314
+ snprintf( zHead, bufsize, "manifest.uuid" );
315
+ zip_add_file(aSBuf, &hash);
291316
blob_reset(&hash);
292317
for(i=0; i<m.nFile; i++){
293318
int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
294319
if( fid ){
295320
content_get(fid, &file);
296
- zip_add_file(m.aFile[i].zName, &file);
321
+ snprintf( zHead, bufsize, "%s", m.aFile[i].zName );
322
+ zip_add_file( aSBuf, &file);
297323
blob_reset(&file);
298324
}
299325
}
300326
manifest_clear(&m);
301327
}else{
@@ -316,11 +342,11 @@
316342
if( g.argc!=4 ){
317343
usage("UUID ZIPFILE");
318344
}
319345
db_must_be_within_tree();
320346
rid = name_to_rid(g.argv[2]);
321
- zip_of_baseline(rid, &zip);
347
+ zip_of_baseline(rid, &zip, g.argv[2]);
322348
blob_write_to_file(&zip, g.argv[3]);
323349
}
324350
325351
/*
326352
** WEBPAGE: zip
@@ -348,10 +374,10 @@
348374
rid = name_to_rid(zName);
349375
if( rid==0 ){
350376
@ Not found
351377
return;
352378
}
353
- zip_of_baseline(rid, &zip);
379
+ zip_of_baseline(rid, &zip, zName);
354380
cgi_set_content(&zip);
355381
cgi_set_content_type("application/zip");
356382
cgi_reply();
357383
}
358384
--- src/zip.c
+++ src/zip.c
@@ -264,38 +264,64 @@
264 ** resulting ZIP archive contains a single file which is the RID
265 ** object.
266 **
267 ** If the RID object does not exist in the repository, then
268 ** pZip is zeroed.
 
 
 
 
 
 
 
269 */
270 void zip_of_baseline(int rid, Blob *pZip){
271 int i;
272 Blob mfile, file, hash;
273 Manifest m;
274
275 content_get(rid, &mfile);
276 if( blob_size(&mfile)==0 ){
277 blob_zero(pZip);
278 return;
279 }
280 blob_zero(&file);
281 blob_zero(&hash);
282 blob_copy(&file, &mfile);
283 zip_open();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284 if( manifest_parse(&m, &mfile) ){
285 zip_set_timedate(m.rDate);
286 zip_add_file("manifest", &file);
 
287 sha1sum_blob(&file, &hash);
288 blob_reset(&file);
289 blob_append(&hash, "\n", 1);
290 zip_add_file("manifest.uuid", &hash);
 
291 blob_reset(&hash);
292 for(i=0; i<m.nFile; i++){
293 int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
294 if( fid ){
295 content_get(fid, &file);
296 zip_add_file(m.aFile[i].zName, &file);
 
297 blob_reset(&file);
298 }
299 }
300 manifest_clear(&m);
301 }else{
@@ -316,11 +342,11 @@
316 if( g.argc!=4 ){
317 usage("UUID ZIPFILE");
318 }
319 db_must_be_within_tree();
320 rid = name_to_rid(g.argv[2]);
321 zip_of_baseline(rid, &zip);
322 blob_write_to_file(&zip, g.argv[3]);
323 }
324
325 /*
326 ** WEBPAGE: zip
@@ -348,10 +374,10 @@
348 rid = name_to_rid(zName);
349 if( rid==0 ){
350 @ Not found
351 return;
352 }
353 zip_of_baseline(rid, &zip);
354 cgi_set_content(&zip);
355 cgi_set_content_type("application/zip");
356 cgi_reply();
357 }
358
--- src/zip.c
+++ src/zip.c
@@ -264,38 +264,64 @@
264 ** resulting ZIP archive contains a single file which is the RID
265 ** object.
266 **
267 ** If the RID object does not exist in the repository, then
268 ** pZip is zeroed.
269 **
270 ** zSynthDir is a "synthetic" subdirectory which all zipped files get
271 ** added to as part of the zip file. It may be 0 or an empty string,
272 ** in which case it is ignored. The intention is to create a zip which
273 ** politely expands into a subdir instead of filling your current dir
274 ** with source files. For example, pass a UUID or "ProjectName".
275 **
276 */
277 void zip_of_baseline(int rid, Blob *pZip, char const * zSynthDir ){
278 int i;
279 Blob mfile, file, hash;
280 Manifest m;
281 char const * zDir = (zSynthDir && zSynthDir[0]) ? zSynthDir : "";
282 content_get(rid, &mfile);
283 if( blob_size(&mfile)==0 ){
284 blob_zero(pZip);
285 return;
286 }
287 blob_zero(&file);
288 blob_zero(&hash);
289 blob_copy(&file, &mfile);
290 zip_open();
291
292 const int dirLen = strlen(zDir);
293 char zPrefix[dirLen+2];
294 memset(zPrefix, 0, sizeof(zPrefix));
295 if( zDir[0] ){
296 snprintf( zPrefix, sizeof(zPrefix), "%s/", zDir );
297 }
298 const int bufsize = 512;
299 char aSBuf[bufsize];
300 int prxLen = strlen(zPrefix);
301 memcpy(aSBuf, zPrefix, prxLen);
302 char * zHead = aSBuf + prxLen;
303 /* Rather than use a lot of mprintf()s here, we reuse aSBuf as a
304 ** buffer for the prefix + current file name. zHead keeps track
305 ** of where we should write file names to this buffer.
306 */
307 if( manifest_parse(&m, &mfile) ){
308 zip_set_timedate(m.rDate);
309 snprintf( zHead, bufsize, "manifest" );
310 zip_add_file(aSBuf, &file);
311 sha1sum_blob(&file, &hash);
312 blob_reset(&file);
313 blob_append(&hash, "\n", 1);
314 snprintf( zHead, bufsize, "manifest.uuid" );
315 zip_add_file(aSBuf, &hash);
316 blob_reset(&hash);
317 for(i=0; i<m.nFile; i++){
318 int fid = uuid_to_rid(m.aFile[i].zUuid, 0);
319 if( fid ){
320 content_get(fid, &file);
321 snprintf( zHead, bufsize, "%s", m.aFile[i].zName );
322 zip_add_file( aSBuf, &file);
323 blob_reset(&file);
324 }
325 }
326 manifest_clear(&m);
327 }else{
@@ -316,11 +342,11 @@
342 if( g.argc!=4 ){
343 usage("UUID ZIPFILE");
344 }
345 db_must_be_within_tree();
346 rid = name_to_rid(g.argv[2]);
347 zip_of_baseline(rid, &zip, g.argv[2]);
348 blob_write_to_file(&zip, g.argv[3]);
349 }
350
351 /*
352 ** WEBPAGE: zip
@@ -348,10 +374,10 @@
374 rid = name_to_rid(zName);
375 if( rid==0 ){
376 @ Not found
377 return;
378 }
379 zip_of_baseline(rid, &zip, zName);
380 cgi_set_content(&zip);
381 cgi_set_content_type("application/zip");
382 cgi_reply();
383 }
384

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button