@@ -687,16 +687,15 @@
** * It's uuid
** * date of check-in
** * Comment & user
*/
-static const char *object_description(
+static void object_description(
int rid, /* The artifact ID */
int linkToView /* Add viewer link if true */
){
Stmt q;
int cnt = 0;
int nWiki = 0;
- const char *zMime = 0;
db_prepare(&q,
"SELECT filename.name, datetime(event.mtime), substr(a.uuid,1,10),"
" coalesce(event.ecomment,event.comment),"
" coalesce(event.euser,event.user),"
@@ -719,10 +718,10 @@
@ File <a href="%s(g.zBaseURL)/finfo?name=%T(zName)">%h(zName)</a>
@ uuid %s(zFuuid) part of check-in
hyperlink_to_uuid(zVers);
@ %w(zCom) by %h(zUser) on %s(zDate)
- zMime = mimetype_from_name(zName);
cnt++;
+ break;
}
db_finalize(&q);
db_prepare(&q,
"SELECT substr(tagname, 6, 10000), datetime(event.mtime),"
@@ -744,9 +743,8 @@
@ [<a href="%s(g.zBaseURL)/wiki?name=%t(zPagename)">%h(zPagename)</a>]
@ uuid %s(zUuid) by %h(zUser) on %s(zDate)
nWiki++;
cnt++;
- zMime = 0;
}
db_finalize(&q);
if( nWiki==0 ){
db_prepare(&q,
@@ -782,9 +780,8 @@
@ Control file %s(zUuid).
}else if( linkToView ){
@ <a href="%s(g.zBaseURL)/artifact/%d(rid)">[view]</a>
}
- return zMime;
}
/*
** WEBPAGE: fdiff
@@ -844,8 +841,97 @@
cgi_set_content(&content);
}
/*
+** Render a hex dump of a file.
+*/
+static void hexdump(Blob *pBlob){
+ const unsigned char *x;
+ int n, i, j, k;
+ char zLine[100];
+ static const char zHex[] = "0123456789abcdef";
+
+ x = (const unsigned char*)blob_buffer(pBlob);
+ n = blob_size(pBlob);
+ for(i=0; i<n; i+=16){
+ j = 0;
+ zLine[0] = zHex[(i>>24)&0xf];
+ zLine[1] = zHex[(i>>16)&0xf];
+ zLine[2] = zHex[(i>>8)&0xf];
+ zLine[3] = zHex[i&0xf];
+ zLine[4] = ':';
+ sprintf(zLine, "%04x: ", i);
+ for(j=0; j<16; j++){
+ k = 5+j*3;
+ zLine[k] = ' ';
+ if( i+j<n ){
+ unsigned char c = x[i+j];
+ zLine[k+1] = zHex[c>>4];
+ zLine[k+2] = zHex[c&0xf];
+ }else{
+ zLine[k+1] = ' ';
+ zLine[k+2] = ' ';
+ }
+ }
+ zLine[53] = ' ';
+ zLine[54] = ' ';
+ for(j=0; j<16; j++){
+ k = j+55;
+ if( i+j<n ){
+ unsigned char c = x[i+j];
+ if( c>=0x20 && c<=0x7e ){
+ zLine[k] = c;
+ }else{
+ zLine[k] = '.';
+ }
+ }else{
+ zLine[k] = 0;
+ }
+ }
+ zLine[71] = 0;
+ @ %h(zLine)
+ }
+}
+
+/*
+** WEBPAGE: hexdump
+** URL: /hexdump?name=ARTIFACTID
+**
+** Show the complete content of a file identified by ARTIFACTID
+** as preformatted text.
+*/
+void hexdump_page(void){
+ int rid;
+ Blob content;
+
+ rid = name_to_rid(PD("name","0"));
+ login_check_credentials();
+ if( !g.okRead ){ login_needed(); return; }
+ if( rid==0 ){ cgi_redirect("/home"); }
+ if( g.okAdmin ){
+ const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
+ if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
+ style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
+ g.zTop, zUuid);
+ }else{
+ style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
+ g.zTop, zUuid);
+ }
+ }
+ style_header("Hex Artifact Content");
+ @ <h2>Hexadecimal Content Of:</h2>
+ @ <blockquote>
+ object_description(rid, 0);
+ @ </blockquote>
+ @ <hr>
+ content_get(rid, &content);
+ @ <blockquote><pre>
+ hexdump(&content);
+ @ </pre></blockquote>
+ style_footer();
+}
+
+/*
** WEBPAGE: artifact
** URL: /artifact?name=ARTIFACTID
**
** Show the complete content of a file identified by ARTIFACTID
@@ -872,20 +958,28 @@
}
style_header("Artifact Content");
@ <h2>Content Of:</h2>
@ <blockquote>
- zMime = object_description(rid, 0);
+ object_description(rid, 0);
@ </blockquote>
@ <hr>
- if( zMime && strncmp(zMime, "image/", 6)==0 ){
- @ <img src="%s(g.zBaseURL)/raw?name=%d(rid)&m=%s(zMime)"></img>
- }else{
- @ <blockquote><pre>
- content_get(rid, &content);
+ @ <blockquote>
+ content_get(rid, &content);
+ zMime = mimetype_from_content(&content);
+ if( zMime==0 ){
+ @ <pre>
@ %h(blob_str(&content))
- @ </pre></blockquote>
- blob_reset(&content);
+ @ </pre>
+ style_submenu_element("Hex","Hex", "%s/hexdump?name=%d", g.zTop, rid);
+ }else if( strncmp(zMime, "image/", 6)==0 ){
+ @ <img src="%s(g.zBaseURL)/raw?name=%d(rid)&m=%s(zMime)"></img>
+ style_submenu_element("Hex","Hex", "%s/hexdump?name=%d", g.zTop, rid);
+ }else{
+ @ <pre>
+ hexdump(&content);
+ @ </pre>
}
+ @ </blockquote>
style_footer();
}
/*