CVSTrac Legacy Code

Check-in [0538777a0b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:(#797) download current folder as tarball feature, structure for all SCM, Subversion implementation trough =svntar=.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:0538777a0b24241722eba5b6f91943437c31d750
User & Date: ono 2009-05-14 11:48:17
Context
2009-05-14
12:01
(#798) Remove trailing spaces from rlog Author/Committer names, drop Commiter info if is the person as Author. check-in: e811e9226a user: ono tags: trunk
11:48
(#797) download current folder as tarball feature, structure for all SCM, Subversion implementation trough =svntar=. check-in: 0538777a0b user: ono tags: trunk
11:22
(#740) take the SRCDIR path from the platform.mk file placement, a do not hardcode SRCDIR anymore. check-in: 586b227c9a user: ono tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to browse.c.

38
39
40
41
42
43
44



45
46
47
48
49
50
51
...
958
959
960
961
962
963
964





































































*/
static void output_breadcrumb(const char *zPath, int isdir){
  if( zPath && zPath[0] ){
    const char* zDef = default_browse_url();
    char *zDirUrl;
    char *zDirName;
    int i;



    @ <ul id="breadcrumb">
    @ <li><a class="root" href="%T(zDef)">/</a></li>

    zDirUrl = mprintf("%s", zPath);
    zDirName = zDirUrl;
    for(i=0; zDirUrl[i]; i++){
      if( zDirUrl[i]=='/' ){
................................................................................
  if( zVers && zVers[0] ){
    g.isConst = 1;
  }
  cgi_set_content_type(zMime);
  cgi_set_status(200, "OK");
  return;
}












































































>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
...
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
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
*/
static void output_breadcrumb(const char *zPath, int isdir){
  if( zPath && zPath[0] ){
    const char* zDef = default_browse_url();
    char *zDirUrl;
    char *zDirName;
    int i;
    if( isdir && g.scm.pxDownload ){
      @ <a class="download" href="download?d=%T(zPath)">Download</a>
    }
    @ <ul id="breadcrumb">
    @ <li><a class="root" href="%T(zDef)">/</a></li>

    zDirUrl = mprintf("%s", zPath);
    zDirName = zDirUrl;
    for(i=0; zDirUrl[i]; i++){
      if( zDirUrl[i]=='/' ){
................................................................................
  if( zVers && zVers[0] ){
    g.isConst = 1;
  }
  cgi_set_content_type(zMime);
  cgi_set_status(200, "OK");
  return;
}

/*
** WEBPAGE: /download
**
** Return the tar.bz2 stream of the folder
*/
void browse_download(void){
  char *zDir = (char *)(g.zExtra ? g.zExtra : P("d"));
  const char *zVers = P("v");
  char *zName, *zTmp;
  char *zMime = "application/x-bzip-compressed-tar";  /* The default MIME type */

  login_check_credentials();
  if( !g.okCheckout || zDir==0 ){ login_needed(); return; }
  throttle(1,0);

  if( zVers!= 0 ){
    /* A database query is almost definitely going to be faster than having
    ** to pull from from the repository, so we might as well try this first.
    */
    char *z = db_short_query("SELECT chng.date FROM filechng, chng "
                             "WHERE filechng.filename='%q' "
                             "      AND filechng.vers='%q' "
                             "      AND filechng.cn=chng.cn ",
                             zDir, zVers);
    if( z ){
      cgi_modified_since(atoi(z));
      cgi_append_header(mprintf("Last-Modified: %h\r\n",
                        cgi_rfc822_datestamp(atoi(z))));
      free(z);
    }
  }

  if( dump_version(zVers,zDir,1) ){
    cgi_redirect("index");
    return;
  }

  /* Remove trailing slashes from directory */
  if( (zTmp = strrchr(zDir, '/')) ){
    while( zTmp >= zDir && (*zTmp == '/') ){
      *(zTmp--) = 0;
    }
  }
  zTmp = zName = mprintf("%s-%s.tar.bz2", g.zName, (*zDir == '/') ? (zDir + 1) : zDir);
  /* Change slashes into dashes */
  while( *zTmp ){
    if( *zTmp == '/' ){
      *zTmp = '-';
    }
    zTmp++;
  }
  cgi_append_header(mprintf("Content-disposition: attachment; "
        "filename=\"%T\"\r\n", zName));

  if( zVers && zVers[0] ){
    g.isConst = 1;
  }
  cgi_set_content_type(zMime);
  cgi_set_status(200, "OK");
  cgi_reply();
  fflush(stdout);

  if( g.scm.pxDownload ){
    g.scm.pxDownload( zDir, zVers, COMPRESSION_TAR_BZ2 );
  }

  exit(0);
}

Changes to main.c.

46
47
48
49
50
51
52





53
54
55
56
57
58
59
..
61
62
63
64
65
66
67

68
69
70
71
72
73
74
#if INTERFACE

/*
** Maximum number of distinct aux() values
*/
#define MX_AUX 10






struct Scm {
  const char *zSCM;       /* Which SCM subsystem is supported (i.e. "cvs") */
  const char *zName;      /* User-readable SCM name (i.e. "Subversion") */
  int canFilterModules;   /* non-zero if the SCM can filter modules */

  int (*pxHistoryUpdate)(int isReread);
  int (*pxHistoryReconstructPrep)();
................................................................................
  int (*pxDiffVersions)(const char *zOldVersion, const char *zNewVersion,
                        const char *zFile);
  int (*pxDiffChng)(int cn, int bRaw);
  int (*pxIsFileAvailable)(const char *zFile);
  int (*pxDumpVersion)(const char *zVers, const char *zFile, int bRaw);
  int (*pxUserRead)(void);
  int (*pxUserWrite)(const char *zOmit);

};

/*
** All global variables are in this structure.
*/
struct Global {
  int argc; char **argv;  /* Command-line arguments to the program */







>
>
>
>
>







 







>







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#if INTERFACE

/*
** Maximum number of distinct aux() values
*/
#define MX_AUX 10

#define COMPRESSION_TAR     0
#define COMPRESSION_TAR_GZ  1
#define COMPRESSION_TAR_BZ2 2
#define COMPRESSION_ZIP     3

struct Scm {
  const char *zSCM;       /* Which SCM subsystem is supported (i.e. "cvs") */
  const char *zName;      /* User-readable SCM name (i.e. "Subversion") */
  int canFilterModules;   /* non-zero if the SCM can filter modules */

  int (*pxHistoryUpdate)(int isReread);
  int (*pxHistoryReconstructPrep)();
................................................................................
  int (*pxDiffVersions)(const char *zOldVersion, const char *zNewVersion,
                        const char *zFile);
  int (*pxDiffChng)(int cn, int bRaw);
  int (*pxIsFileAvailable)(const char *zFile);
  int (*pxDumpVersion)(const char *zVers, const char *zFile, int bRaw);
  int (*pxUserRead)(void);
  int (*pxUserWrite)(const char *zOmit);
  int (*pxDownload)(const char *zDir, const char *zVersion, int compression);
};

/*
** All global variables are in this structure.
*/
struct Global {
  int argc; char **argv;  /* Command-line arguments to the program */

Changes to svn.c.

950
951
952
953
954
955
956































957
958
959
960
961
962
963
964
965
966

967
968
    "  SELECT id, id, '', pswd,"
    "      cap_or((SELECT capabilities FROM user WHERE id='anonymous'),cap) "
    "  FROM tuser;"
    "COMMIT;"
  );
  return 0;
}
































void init_svn(void){
  g.scm.zSCM = "svn";
  g.scm.zName = "Subversion";
  g.scm.pxHistoryUpdate = svn_history_update;
  g.scm.pxDiffVersions = svn_diff_versions;
  g.scm.pxDiffChng = svn_diff_chng;
  g.scm.pxIsFileAvailable = 0;  /* use the database */
  g.scm.pxDumpVersion = svn_dump_version;
  g.scm.pxUserRead = svn_user_read;

}








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>










>


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
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
    "  SELECT id, id, '', pswd,"
    "      cap_or((SELECT capabilities FROM user WHERE id='anonymous'),cap) "
    "  FROM tuser;"
    "COMMIT;"
  );
  return 0;
}

static int svn_download(const char *zDir, const char *zVersion, int compression){
  FILE *in;
  char *zCmd, zBuf[1024];
  size_t nRead;
  char *zSvnRoot = (char *)db_config("cvsroot",""), *zTmp = zSvnRoot;

  if( compression != COMPRESSION_TAR_BZ2 ){
    return -1;
  }
  /* Ensure we got only slashes in SVNROOT which is expected format for svntar */
  while( *zTmp ){
    if( *zTmp == '\\' ) *zTmp = '/';
    zTmp ++;
  }
  zCmd = mprintf(OS_VAL("svntar -j -- - 'file:%s/%s' 2>/dev/null",
                        "svntar -j -- - \"file:%s/%s\" 2>NUL"), quotable_string(zSvnRoot), quotable_string(zDir));
  in = popen(zCmd, "rb");
  if( in==0 ){
    return -1;
  }
  free(zCmd);
  while( (nRead = fread(zBuf, 1, sizeof(zBuf), in)) ){
    if( (fwrite(zBuf, 1, nRead, stdout) < nRead) || (nRead < sizeof(zBuf)) ){
      break;
    }
    fflush(stdout);
  }
  pclose(in);
  return 0;
}

void init_svn(void){
  g.scm.zSCM = "svn";
  g.scm.zName = "Subversion";
  g.scm.pxHistoryUpdate = svn_history_update;
  g.scm.pxDiffVersions = svn_diff_versions;
  g.scm.pxDiffChng = svn_diff_chng;
  g.scm.pxIsFileAvailable = 0;  /* use the database */
  g.scm.pxDumpVersion = svn_dump_version;
  g.scm.pxUserRead = svn_user_read;
  g.scm.pxDownload = svn_download;
}