Fossil SCM
Update the ZIP archiver to include date information. Provide a function that constructs a ZIP archive from manifest.
Commit
dead090c0bd601124619cbde91215e9a873972bc
Parent
9b780d220be5f2a…
2 files changed
+97
-6
+3
-6
+97
-6
| --- src/zip.c | ||
| +++ src/zip.c | ||
| @@ -46,27 +46,57 @@ | ||
| 46 | 46 | ** Variables in which to accumulate a growing ZIP archive. |
| 47 | 47 | */ |
| 48 | 48 | static Blob body; /* The body of the ZIP archive */ |
| 49 | 49 | static Blob toc; /* The table of contents */ |
| 50 | 50 | static int nEntry; /* Number of files */ |
| 51 | +static int dosTime; /* DOS-format time */ | |
| 52 | +static int dosDate; /* DOS-format date */ | |
| 51 | 53 | |
| 52 | 54 | /* |
| 53 | 55 | ** Initialize a new ZIP archive. |
| 54 | 56 | */ |
| 55 | 57 | void zip_open(void){ |
| 56 | 58 | blob_zero(&body); |
| 57 | 59 | blob_zero(&toc); |
| 58 | 60 | nEntry = 0; |
| 61 | + dosTime = 0; | |
| 62 | + dosDate = 0; | |
| 63 | +} | |
| 64 | + | |
| 65 | +/* | |
| 66 | +** Set the date and time values from an ISO8601 date string. | |
| 67 | +*/ | |
| 68 | +void zip_set_timedate_from_str(const char *zDate){ | |
| 69 | + int y, m, d; | |
| 70 | + int H, M, S; | |
| 71 | + | |
| 72 | + y = atoi(zDate); | |
| 73 | + m = atoi(&zDate[5]); | |
| 74 | + d = atoi(&zDate[8]); | |
| 75 | + H = atoi(&zDate[11]); | |
| 76 | + M = atoi(&zDate[14]); | |
| 77 | + S = atoi(&zDate[17]); | |
| 78 | + dosTime = (H<<11) + (M<<5) + S; | |
| 79 | + dosDate = ((y-1980)<<9) + (m<<5) + d; | |
| 80 | +} | |
| 81 | + | |
| 82 | +/* | |
| 83 | +** Set the date and time from a julian day number. | |
| 84 | +*/ | |
| 85 | +void zip_set_timedate(double rDate){ | |
| 86 | + char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate); | |
| 87 | + zip_set_timedate_from_str(zDate); | |
| 88 | + free(zDate); | |
| 59 | 89 | } |
| 60 | 90 | |
| 61 | 91 | /* |
| 62 | 92 | ** Append a single file to a growing ZIP archive. |
| 63 | 93 | ** |
| 64 | 94 | ** pFile is the file to be appended. zName is the name |
| 65 | 95 | ** that the file should be saved as. |
| 66 | 96 | */ |
| 67 | -int zip_add_file(const char *zName, const Blob *pFile){ | |
| 97 | +void zip_add_file(const char *zName, const Blob *pFile){ | |
| 68 | 98 | z_stream stream; |
| 69 | 99 | int nameLen; |
| 70 | 100 | int skip; |
| 71 | 101 | int toOut; |
| 72 | 102 | int iStart; |
| @@ -83,12 +113,12 @@ | ||
| 83 | 113 | nameLen = strlen(zName); |
| 84 | 114 | put32(&zHdr[0], 0x04034b50); |
| 85 | 115 | put16(&zHdr[4], 0x0014); |
| 86 | 116 | put16(&zHdr[6], 0); |
| 87 | 117 | put16(&zHdr[8], 8); |
| 88 | - put16(&zHdr[10], 0); | |
| 89 | - put16(&zHdr[12], 0); | |
| 118 | + put16(&zHdr[10], dosTime); | |
| 119 | + put16(&zHdr[12], dosDate); | |
| 90 | 120 | put16(&zHdr[26], nameLen); |
| 91 | 121 | put16(&zHdr[28], 0); |
| 92 | 122 | |
| 93 | 123 | /* Write the header and filename. |
| 94 | 124 | */ |
| @@ -154,12 +184,12 @@ | ||
| 154 | 184 | put32(&zBuf[0], 0x02014b50); |
| 155 | 185 | put16(&zBuf[4], 0x0317); |
| 156 | 186 | put16(&zBuf[6], 0x0014); |
| 157 | 187 | put16(&zBuf[8], 0); |
| 158 | 188 | put16(&zBuf[10], 0x0008); |
| 159 | - put16(&zBuf[12], 0); | |
| 160 | - put16(&zBuf[14], 0); | |
| 189 | + put16(&zBuf[12], dosTime); | |
| 190 | + put16(&zBuf[14], dosDate); | |
| 161 | 191 | put32(&zBuf[16], iCRC); |
| 162 | 192 | put32(&zBuf[20], nByteCompr); |
| 163 | 193 | put32(&zBuf[24], nByte); |
| 164 | 194 | put16(&zBuf[28], nameLen); |
| 165 | 195 | put16(&zBuf[30], 0); |
| @@ -175,11 +205,11 @@ | ||
| 175 | 205 | |
| 176 | 206 | |
| 177 | 207 | /* |
| 178 | 208 | ** Write the ZIP archive into the given BLOB. |
| 179 | 209 | */ |
| 180 | -int zip_close(Blob *pZip){ | |
| 210 | +void zip_close(Blob *pZip){ | |
| 181 | 211 | int iTocStart; |
| 182 | 212 | int iTocEnd; |
| 183 | 213 | char zBuf[30]; |
| 184 | 214 | |
| 185 | 215 | iTocStart = blob_size(&body); |
| @@ -223,5 +253,66 @@ | ||
| 223 | 253 | blob_reset(&file); |
| 224 | 254 | } |
| 225 | 255 | zip_close(&zip); |
| 226 | 256 | blob_write_to_file(&zip, g.argv[2]); |
| 227 | 257 | } |
| 258 | + | |
| 259 | +/* | |
| 260 | +** Given the RID for a manifest, construct a ZIP archive containing | |
| 261 | +** all files in the corresponding baseline. | |
| 262 | +** | |
| 263 | +** If RID is for an object that is not a real manifest, then the | |
| 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; | |
| 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_copy(&file, &mfile); | |
| 282 | + zip_open(); | |
| 283 | + if( manifest_parse(&m, &mfile) ){ | |
| 284 | + zip_set_timedate(m.rDate); | |
| 285 | + zip_add_file("manifest", &file); | |
| 286 | + blob_reset(&file); | |
| 287 | + for(i=0; i<m.nFile; i++){ | |
| 288 | + int fid = uuid_to_rid(m.aFile[i].zUuid, 0); | |
| 289 | + if( fid ){ | |
| 290 | + content_get(fid, &file); | |
| 291 | + zip_add_file(m.aFile[i].zName, &file); | |
| 292 | + blob_reset(&file); | |
| 293 | + } | |
| 294 | + } | |
| 295 | + manifest_clear(&m); | |
| 296 | + }else{ | |
| 297 | + blob_reset(&mfile); | |
| 298 | + blob_reset(&file); | |
| 299 | + } | |
| 300 | + zip_close(pZip); | |
| 301 | +} | |
| 302 | + | |
| 303 | +/* | |
| 304 | +** COMMAND: test-baseline-zip | |
| 305 | +** | |
| 306 | +** Generate a ZIP archive for a specified baseline. | |
| 307 | +*/ | |
| 308 | +void baseline_zip_cmd(void){ | |
| 309 | + int rid; | |
| 310 | + Blob zip; | |
| 311 | + if( g.argc!=4 ){ | |
| 312 | + usage("UUID ZIPFILE"); | |
| 313 | + } | |
| 314 | + db_must_be_within_tree(); | |
| 315 | + rid = name_to_rid(g.argv[2]); | |
| 316 | + zip_of_baseline(rid, &zip); | |
| 317 | + blob_write_to_file(&zip, g.argv[3]); | |
| 318 | +} | |
| 228 | 319 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -46,27 +46,57 @@ | |
| 46 | ** Variables in which to accumulate a growing ZIP archive. |
| 47 | */ |
| 48 | static Blob body; /* The body of the ZIP archive */ |
| 49 | static Blob toc; /* The table of contents */ |
| 50 | static int nEntry; /* Number of files */ |
| 51 | |
| 52 | /* |
| 53 | ** Initialize a new ZIP archive. |
| 54 | */ |
| 55 | void zip_open(void){ |
| 56 | blob_zero(&body); |
| 57 | blob_zero(&toc); |
| 58 | nEntry = 0; |
| 59 | } |
| 60 | |
| 61 | /* |
| 62 | ** Append a single file to a growing ZIP archive. |
| 63 | ** |
| 64 | ** pFile is the file to be appended. zName is the name |
| 65 | ** that the file should be saved as. |
| 66 | */ |
| 67 | int zip_add_file(const char *zName, const Blob *pFile){ |
| 68 | z_stream stream; |
| 69 | int nameLen; |
| 70 | int skip; |
| 71 | int toOut; |
| 72 | int iStart; |
| @@ -83,12 +113,12 @@ | |
| 83 | nameLen = strlen(zName); |
| 84 | put32(&zHdr[0], 0x04034b50); |
| 85 | put16(&zHdr[4], 0x0014); |
| 86 | put16(&zHdr[6], 0); |
| 87 | put16(&zHdr[8], 8); |
| 88 | put16(&zHdr[10], 0); |
| 89 | put16(&zHdr[12], 0); |
| 90 | put16(&zHdr[26], nameLen); |
| 91 | put16(&zHdr[28], 0); |
| 92 | |
| 93 | /* Write the header and filename. |
| 94 | */ |
| @@ -154,12 +184,12 @@ | |
| 154 | put32(&zBuf[0], 0x02014b50); |
| 155 | put16(&zBuf[4], 0x0317); |
| 156 | put16(&zBuf[6], 0x0014); |
| 157 | put16(&zBuf[8], 0); |
| 158 | put16(&zBuf[10], 0x0008); |
| 159 | put16(&zBuf[12], 0); |
| 160 | put16(&zBuf[14], 0); |
| 161 | put32(&zBuf[16], iCRC); |
| 162 | put32(&zBuf[20], nByteCompr); |
| 163 | put32(&zBuf[24], nByte); |
| 164 | put16(&zBuf[28], nameLen); |
| 165 | put16(&zBuf[30], 0); |
| @@ -175,11 +205,11 @@ | |
| 175 | |
| 176 | |
| 177 | /* |
| 178 | ** Write the ZIP archive into the given BLOB. |
| 179 | */ |
| 180 | int zip_close(Blob *pZip){ |
| 181 | int iTocStart; |
| 182 | int iTocEnd; |
| 183 | char zBuf[30]; |
| 184 | |
| 185 | iTocStart = blob_size(&body); |
| @@ -223,5 +253,66 @@ | |
| 223 | blob_reset(&file); |
| 224 | } |
| 225 | zip_close(&zip); |
| 226 | blob_write_to_file(&zip, g.argv[2]); |
| 227 | } |
| 228 |
| --- src/zip.c | |
| +++ src/zip.c | |
| @@ -46,27 +46,57 @@ | |
| 46 | ** Variables in which to accumulate a growing ZIP archive. |
| 47 | */ |
| 48 | static Blob body; /* The body of the ZIP archive */ |
| 49 | static Blob toc; /* The table of contents */ |
| 50 | static int nEntry; /* Number of files */ |
| 51 | static int dosTime; /* DOS-format time */ |
| 52 | static int dosDate; /* DOS-format date */ |
| 53 | |
| 54 | /* |
| 55 | ** Initialize a new ZIP archive. |
| 56 | */ |
| 57 | void zip_open(void){ |
| 58 | blob_zero(&body); |
| 59 | blob_zero(&toc); |
| 60 | nEntry = 0; |
| 61 | dosTime = 0; |
| 62 | dosDate = 0; |
| 63 | } |
| 64 | |
| 65 | /* |
| 66 | ** Set the date and time values from an ISO8601 date string. |
| 67 | */ |
| 68 | void zip_set_timedate_from_str(const char *zDate){ |
| 69 | int y, m, d; |
| 70 | int H, M, S; |
| 71 | |
| 72 | y = atoi(zDate); |
| 73 | m = atoi(&zDate[5]); |
| 74 | d = atoi(&zDate[8]); |
| 75 | H = atoi(&zDate[11]); |
| 76 | M = atoi(&zDate[14]); |
| 77 | S = atoi(&zDate[17]); |
| 78 | dosTime = (H<<11) + (M<<5) + S; |
| 79 | dosDate = ((y-1980)<<9) + (m<<5) + d; |
| 80 | } |
| 81 | |
| 82 | /* |
| 83 | ** Set the date and time from a julian day number. |
| 84 | */ |
| 85 | void zip_set_timedate(double rDate){ |
| 86 | char *zDate = db_text(0, "SELECT datetime(%.17g)", rDate); |
| 87 | zip_set_timedate_from_str(zDate); |
| 88 | free(zDate); |
| 89 | } |
| 90 | |
| 91 | /* |
| 92 | ** Append a single file to a growing ZIP archive. |
| 93 | ** |
| 94 | ** pFile is the file to be appended. zName is the name |
| 95 | ** that the file should be saved as. |
| 96 | */ |
| 97 | void zip_add_file(const char *zName, const Blob *pFile){ |
| 98 | z_stream stream; |
| 99 | int nameLen; |
| 100 | int skip; |
| 101 | int toOut; |
| 102 | int iStart; |
| @@ -83,12 +113,12 @@ | |
| 113 | nameLen = strlen(zName); |
| 114 | put32(&zHdr[0], 0x04034b50); |
| 115 | put16(&zHdr[4], 0x0014); |
| 116 | put16(&zHdr[6], 0); |
| 117 | put16(&zHdr[8], 8); |
| 118 | put16(&zHdr[10], dosTime); |
| 119 | put16(&zHdr[12], dosDate); |
| 120 | put16(&zHdr[26], nameLen); |
| 121 | put16(&zHdr[28], 0); |
| 122 | |
| 123 | /* Write the header and filename. |
| 124 | */ |
| @@ -154,12 +184,12 @@ | |
| 184 | put32(&zBuf[0], 0x02014b50); |
| 185 | put16(&zBuf[4], 0x0317); |
| 186 | put16(&zBuf[6], 0x0014); |
| 187 | put16(&zBuf[8], 0); |
| 188 | put16(&zBuf[10], 0x0008); |
| 189 | put16(&zBuf[12], dosTime); |
| 190 | put16(&zBuf[14], dosDate); |
| 191 | put32(&zBuf[16], iCRC); |
| 192 | put32(&zBuf[20], nByteCompr); |
| 193 | put32(&zBuf[24], nByte); |
| 194 | put16(&zBuf[28], nameLen); |
| 195 | put16(&zBuf[30], 0); |
| @@ -175,11 +205,11 @@ | |
| 205 | |
| 206 | |
| 207 | /* |
| 208 | ** Write the ZIP archive into the given BLOB. |
| 209 | */ |
| 210 | void zip_close(Blob *pZip){ |
| 211 | int iTocStart; |
| 212 | int iTocEnd; |
| 213 | char zBuf[30]; |
| 214 | |
| 215 | iTocStart = blob_size(&body); |
| @@ -223,5 +253,66 @@ | |
| 253 | blob_reset(&file); |
| 254 | } |
| 255 | zip_close(&zip); |
| 256 | blob_write_to_file(&zip, g.argv[2]); |
| 257 | } |
| 258 | |
| 259 | /* |
| 260 | ** Given the RID for a manifest, construct a ZIP archive containing |
| 261 | ** all files in the corresponding baseline. |
| 262 | ** |
| 263 | ** If RID is for an object that is not a real manifest, then the |
| 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; |
| 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_copy(&file, &mfile); |
| 282 | zip_open(); |
| 283 | if( manifest_parse(&m, &mfile) ){ |
| 284 | zip_set_timedate(m.rDate); |
| 285 | zip_add_file("manifest", &file); |
| 286 | blob_reset(&file); |
| 287 | for(i=0; i<m.nFile; i++){ |
| 288 | int fid = uuid_to_rid(m.aFile[i].zUuid, 0); |
| 289 | if( fid ){ |
| 290 | content_get(fid, &file); |
| 291 | zip_add_file(m.aFile[i].zName, &file); |
| 292 | blob_reset(&file); |
| 293 | } |
| 294 | } |
| 295 | manifest_clear(&m); |
| 296 | }else{ |
| 297 | blob_reset(&mfile); |
| 298 | blob_reset(&file); |
| 299 | } |
| 300 | zip_close(pZip); |
| 301 | } |
| 302 | |
| 303 | /* |
| 304 | ** COMMAND: test-baseline-zip |
| 305 | ** |
| 306 | ** Generate a ZIP archive for a specified baseline. |
| 307 | */ |
| 308 | void baseline_zip_cmd(void){ |
| 309 | int rid; |
| 310 | Blob zip; |
| 311 | if( g.argc!=4 ){ |
| 312 | usage("UUID ZIPFILE"); |
| 313 | } |
| 314 | db_must_be_within_tree(); |
| 315 | rid = name_to_rid(g.argv[2]); |
| 316 | zip_of_baseline(rid, &zip); |
| 317 | blob_write_to_file(&zip, g.argv[3]); |
| 318 | } |
| 319 |
M
todo.txt
+3
-6
| --- todo.txt | ||
| +++ todo.txt | ||
| @@ -60,25 +60,22 @@ | ||
| 60 | 60 | Information available in the mlink table. Hyperlinks to |
| 61 | 61 | the finfo page for each file. |
| 62 | 62 | + Hyperlinks to diff all files in this version against any |
| 63 | 63 | of the named decendents or ancestors. The unified_diff() |
| 64 | 64 | function will compute a unified diff given to file blobs. |
| 65 | + + Add a link that will download a ZIP archive containing the | |
| 66 | + complete baseline. Use zip_of_baseline() function in | |
| 67 | + zip.c to construct the ZIP archive. | |
| 65 | 68 | |
| 66 | 69 | * A new webpage: "finfo" Information about a particular file |
| 67 | 70 | given its name. |
| 68 | 71 | |
| 69 | 72 | + All historical changes to this file with version number, |
| 70 | 73 | user, and comment, and hyperlink to the vinfo page for |
| 71 | 74 | the version. Information available from the minfo table. |
| 72 | 75 | + Hyperlinks for diffing consecutive versions of the file. |
| 73 | 76 | |
| 74 | - * Given any version uuid, construct a ZIP archive that contains | |
| 75 | - the complete content for that version. Feature should be | |
| 76 | - callable from the command-line or from the www interface. | |
| 77 | - Perhaps a hyperlink on the vinfo page to download the ZIP archive | |
| 78 | - for any version. | |
| 79 | - | |
| 80 | 77 | * Timeline enhanced so that you can specify a range of dates. |
| 81 | 78 | |
| 82 | 79 | * The /xfer handler (for push, pull, and clone) does not do |
| 83 | 80 | delta compression. This results in excess bandwidth usage. |
| 84 | 81 | There are some code in xfer.c that are sketches of ideas on |
| 85 | 82 |
| --- todo.txt | |
| +++ todo.txt | |
| @@ -60,25 +60,22 @@ | |
| 60 | Information available in the mlink table. Hyperlinks to |
| 61 | the finfo page for each file. |
| 62 | + Hyperlinks to diff all files in this version against any |
| 63 | of the named decendents or ancestors. The unified_diff() |
| 64 | function will compute a unified diff given to file blobs. |
| 65 | |
| 66 | * A new webpage: "finfo" Information about a particular file |
| 67 | given its name. |
| 68 | |
| 69 | + All historical changes to this file with version number, |
| 70 | user, and comment, and hyperlink to the vinfo page for |
| 71 | the version. Information available from the minfo table. |
| 72 | + Hyperlinks for diffing consecutive versions of the file. |
| 73 | |
| 74 | * Given any version uuid, construct a ZIP archive that contains |
| 75 | the complete content for that version. Feature should be |
| 76 | callable from the command-line or from the www interface. |
| 77 | Perhaps a hyperlink on the vinfo page to download the ZIP archive |
| 78 | for any version. |
| 79 | |
| 80 | * Timeline enhanced so that you can specify a range of dates. |
| 81 | |
| 82 | * The /xfer handler (for push, pull, and clone) does not do |
| 83 | delta compression. This results in excess bandwidth usage. |
| 84 | There are some code in xfer.c that are sketches of ideas on |
| 85 |
| --- todo.txt | |
| +++ todo.txt | |
| @@ -60,25 +60,22 @@ | |
| 60 | Information available in the mlink table. Hyperlinks to |
| 61 | the finfo page for each file. |
| 62 | + Hyperlinks to diff all files in this version against any |
| 63 | of the named decendents or ancestors. The unified_diff() |
| 64 | function will compute a unified diff given to file blobs. |
| 65 | + Add a link that will download a ZIP archive containing the |
| 66 | complete baseline. Use zip_of_baseline() function in |
| 67 | zip.c to construct the ZIP archive. |
| 68 | |
| 69 | * A new webpage: "finfo" Information about a particular file |
| 70 | given its name. |
| 71 | |
| 72 | + All historical changes to this file with version number, |
| 73 | user, and comment, and hyperlink to the vinfo page for |
| 74 | the version. Information available from the minfo table. |
| 75 | + Hyperlinks for diffing consecutive versions of the file. |
| 76 | |
| 77 | * Timeline enhanced so that you can specify a range of dates. |
| 78 | |
| 79 | * The /xfer handler (for push, pull, and clone) does not do |
| 80 | delta compression. This results in excess bandwidth usage. |
| 81 | There are some code in xfer.c that are sketches of ideas on |
| 82 |