以前修改的cvstrac:browse.c//树形目录(限两级)
static void show_dirtree(const char *zName, int level) {
char **az;
int n;
const char *zRoot;
const char *flag = (level==0 ? "" : "<span> |--</span>");
zRoot = db_config("cvsroot","");
az = db_query("SELECT base, isdir FROM file WHERE dir='%q' ORDER BY isdir desc, base", zName);
if( zName[0] ){ zName = mprintf("%s/",zName); }
for(n=0; az[n]; n+=2) {
char *zFilename = 0;
if( atoi(az[n+1]) ) {
zFilename = mprintf("%s%s", zName, az[n]);
@ %s(flag)<span style="font-family:wingdings">0</span> <a href="dir?d=%T(zName)%T(az[n])"><b>%h(az[n])/</b></a><br>
if (level==0) {
show_dirtree(zFilename, 1);
}
} else if((zFilename = mprintf("%s/%s%s,v", zRoot, zName, az[n]))!=0 && access(zFilename,0)==0 ){
@ %s(flag)<a href="rlog?f=%T(zName)%T(az[n])"><span style="font-family:wingdings 2">/</span></a>
@ <a href="getfile/%T(zName)%T(az[n])">%h(az[n])</a><br>
}
if(zFilename!=0) free(zFilename);
}
}
/*
** WEBPAGE: /dir
**
** List all of the repository files in a single directory.
*/
void browse_dir2(void){
const char *zName;
char *zDir;
char *zBase;
login_check_credentials();
if( !g.okCheckout ){ login_needed(); return; }
throttle(1);
history_update(0);
zName = PD("d","");
if( zName==0 ){
zName = "";
}else{
common_replace_menu_item(
mprintf("timeline?x=1&c=2&dm=1&px=%h",zName),
"时间线"
);
}
zDir = mprintf("%s", zName);
zBase = strrchr(zDir, '/');
common_standard_menu("目录", 0);
if( zBase==0 ){
zBase = zDir;
zDir = "";
}else{
*zBase = 0;
zBase++;
}
if( zName[0] )
common_header("目录 /%s", mprintf("%s/",zName));
else
common_header("目录 /%s", zName);
@ <p><a href="dir?d="><span style="font-family:wingdings">0</span> /</a>
if (zName[0]){
@ <a href="dir?d=%T(zDir)"><span style="font-family:wingdings">0</span> ..</a>
}
@</p>
@<p>
show_dirtree(zName, 0);
common_footer();
}
/*
** WEBPAGE: /getfile
**
** Return the complete content of a file
*/
void browse_getfile(void){
const char *zFile = g.zExtra ? g.zExtra : P("f");
const char *zVers = P("v");
char *zDir, *zBase;
char *zReal;
const char *zRoot;
char *zCmd;
FILE *in;
char zLine[2000];
char *zSuffix;
char *zMime = "text/plain"; /* The default MIME type */
/* The following table lists some alternative MIME types based on
** the file suffix
*/
static const struct {
char *zSuffix;
char *zMime;
} aMime[] = {
{ "html", "text/html" },
{ "htm", "text/html" },
{ "gif", "image/gif" },
{ "jpeg", "image/jpeg" },
{ "jpg", "image/jpeg" },
{ "png", "image/png" },
{ "pdf", "application/pdf" },
{ "ps", "application/postscript" },
{ "eps", "application/postscript" },
};
login_check_credentials();
if( !g.okCheckout || zFile==0 ){ login_needed(); return; }
throttle(1);
zRoot = db_config("cvsroot", "");
dehttpize(zFile);
zDir = mprintf("%s/%s", zRoot, zFile);
zBase = strrchr(zDir, '/');
if( zBase ){
*zBase = 0;
zBase++;
}else{
zBase = zDir;
zDir = "";
}
zReal = find_repository_file(zDir, zBase);
if( zReal==0 ){ cgi_redirect("index"); return; }
zCmd = mprintf("co -q '-p%s' '%s'",
quotable_string(zVers), quotable_string(zReal));
in = popen(zCmd, "r");
if( in==0 ){ cgi_redirect("index"); return; }
while( !feof(in) ){
int amt = fread(zLine, 1, sizeof(zLine), in);
if( amt<=0 ) break;
cgi_append_content(zLine, amt);
}
pclose(in);
zSuffix = strrchr(zFile, '.');
if( zSuffix ){
int i;
zSuffix++;
for(i=0; zSuffix[i] && i<sizeof(zLine)-1; i++){
zLine[i] = tolower(zSuffix[i]);
}
zLine[i] = 0;
for(i=0; i<sizeof(aMime)/sizeof(aMime[0]); i++){
if( strcmp(zLine, aMime[i].zSuffix)==0 ){
zMime = aMime[i].zMime;
break;
}
}
}
cgi_set_content_type(zMime);
cgi_set_status(200, "OK");
return;
}
|