0000: 2f 2a 0a 20 2a 20 67 7a 6c 6f 67 2e 63 0a 20 2a /*. * gzlog.c. *
0010: 20 43 6f 70 79 72 69 67 68 74 20 28 43 29 20 32 Copyright (C) 2
0020: 30 30 34 2c 20 32 30 30 38 20 4d 61 72 6b 20 41 004, 2008 Mark A
0030: 64 6c 65 72 2c 20 61 6c 6c 20 72 69 67 68 74 73 dler, all rights
0040: 20 72 65 73 65 72 76 65 64 0a 20 2a 20 46 6f 72 reserved. * For
0050: 20 63 6f 6e 64 69 74 69 6f 6e 73 20 6f 66 20 64 conditions of d
0060: 69 73 74 72 69 62 75 74 69 6f 6e 20 61 6e 64 20 istribution and
0070: 75 73 65 2c 20 73 65 65 20 63 6f 70 79 72 69 67 use, see copyrig
0080: 68 74 20 6e 6f 74 69 63 65 20 69 6e 20 67 7a 6c ht notice in gzl
0090: 6f 67 2e 68 0a 20 2a 20 76 65 72 73 69 6f 6e 20 og.h. * version
00a0: 32 2e 30 2c 20 32 35 20 41 70 72 20 32 30 30 38 2.0, 25 Apr 2008
00b0: 0a 20 2a 2f 0a 0a 2f 2a 0a 20 20 20 67 7a 6c 6f . */../*. gzlo
00c0: 67 20 70 72 6f 76 69 64 65 73 20 61 20 6d 65 63 g provides a mec
00d0: 68 61 6e 69 73 6d 20 66 6f 72 20 66 72 65 71 75 hanism for frequ
00e0: 65 6e 74 6c 79 20 61 70 70 65 6e 64 69 6e 67 20 ently appending
00f0: 73 68 6f 72 74 20 73 74 72 69 6e 67 73 20 74 6f short strings to
0100: 20 61 20 67 7a 69 70 0a 20 20 20 66 69 6c 65 20 a gzip. file
0110: 74 68 61 74 20 69 73 20 65 66 66 69 63 69 65 6e that is efficien
0120: 74 20 62 6f 74 68 20 69 6e 20 65 78 65 63 75 74 t both in execut
0130: 69 6f 6e 20 74 69 6d 65 20 61 6e 64 20 63 6f 6d ion time and com
0140: 70 72 65 73 73 69 6f 6e 20 72 61 74 69 6f 2e 20 pression ratio.
0150: 20 54 68 65 0a 20 20 20 73 74 72 61 74 65 67 79 The. strategy
0160: 20 69 73 20 74 6f 20 77 72 69 74 65 20 74 68 65 is to write the
0170: 20 73 68 6f 72 74 20 73 74 72 69 6e 67 73 20 69 short strings i
0180: 6e 20 61 6e 20 75 6e 63 6f 6d 70 72 65 73 73 65 n an uncompresse
0190: 64 20 66 6f 72 6d 20 74 6f 20 74 68 65 20 65 6e d form to the en
01a0: 64 20 6f 66 0a 20 20 20 74 68 65 20 67 7a 69 70 d of. the gzip
01b0: 20 66 69 6c 65 2c 20 6f 6e 6c 79 20 63 6f 6d 70 file, only comp
01c0: 72 65 73 73 69 6e 67 20 77 68 65 6e 20 74 68 65 ressing when the
01d0: 20 61 6d 6f 75 6e 74 20 6f 66 20 75 6e 63 6f 6d amount of uncom
01e0: 70 72 65 73 73 65 64 20 64 61 74 61 20 68 61 73 pressed data has
01f0: 0a 20 20 20 72 65 61 63 68 65 64 20 61 20 67 69 . reached a gi
0200: 76 65 6e 20 74 68 72 65 73 68 6f 6c 64 2e 0a 0a ven threshold...
0210: 20 20 20 67 7a 6c 6f 67 20 61 6c 73 6f 20 70 72 gzlog also pr
0220: 6f 76 69 64 65 73 20 70 72 6f 74 65 63 74 69 6f ovides protectio
0230: 6e 20 61 67 61 69 6e 73 74 20 69 6e 74 65 72 72 n against interr
0240: 75 70 74 69 6f 6e 73 20 69 6e 20 74 68 65 20 70 uptions in the p
0250: 72 6f 63 65 73 73 20 64 75 65 20 74 6f 0a 20 20 rocess due to.
0260: 20 73 79 73 74 65 6d 20 63 72 61 73 68 65 73 2e system crashes.
0270: 20 20 54 68 65 20 73 74 61 74 75 73 20 6f 66 20 The status of
0280: 74 68 65 20 6f 70 65 72 61 74 69 6f 6e 20 69 73 the operation is
0290: 20 72 65 63 6f 72 64 65 64 20 69 6e 20 61 6e 20 recorded in an
02a0: 65 78 74 72 61 20 66 69 65 6c 64 0a 20 20 20 69 extra field. i
02b0: 6e 20 74 68 65 20 67 7a 69 70 20 66 69 6c 65 2c n the gzip file,
02c0: 20 61 6e 64 20 69 73 20 6f 6e 6c 79 20 75 70 64 and is only upd
02d0: 61 74 65 64 20 6f 6e 63 65 20 74 68 65 20 67 7a ated once the gz
02e0: 69 70 20 66 69 6c 65 20 69 73 20 62 72 6f 75 67 ip file is broug
02f0: 68 74 20 74 6f 20 61 0a 20 20 20 76 61 6c 69 64 ht to a. valid
0300: 20 73 74 61 74 65 2e 20 20 54 68 65 20 6c 61 73 state. The las
0310: 74 20 64 61 74 61 20 74 6f 20 62 65 20 61 70 70 t data to be app
0320: 65 6e 64 65 64 20 6f 72 20 63 6f 6d 70 72 65 73 ended or compres
0330: 73 65 64 20 69 73 20 73 61 76 65 64 20 69 6e 20 sed is saved in
0340: 61 6e 0a 20 20 20 61 75 78 69 6c 69 61 72 79 20 an. auxiliary
0350: 66 69 6c 65 2c 20 73 6f 20 74 68 61 74 20 69 66 file, so that if
0360: 20 74 68 65 20 6f 70 65 72 61 74 69 6f 6e 20 69 the operation i
0370: 73 20 69 6e 74 65 72 72 75 70 74 65 64 2c 20 69 s interrupted, i
0380: 74 20 63 61 6e 20 62 65 20 63 6f 6d 70 6c 65 74 t can be complet
0390: 65 64 0a 20 20 20 74 68 65 20 6e 65 78 74 20 74 ed. the next t
03a0: 69 6d 65 20 61 6e 20 61 70 70 65 6e 64 20 6f 70 ime an append op
03b0: 65 72 61 74 69 6f 6e 20 69 73 20 61 74 74 65 6d eration is attem
03c0: 70 74 65 64 2e 0a 0a 20 20 20 67 7a 6c 6f 67 20 pted... gzlog
03d0: 6d 61 69 6e 74 61 69 6e 73 20 61 6e 6f 74 68 65 maintains anothe
03e0: 72 20 61 75 78 69 6c 69 61 72 79 20 66 69 6c 65 r auxiliary file
03f0: 20 77 69 74 68 20 74 68 65 20 6c 61 73 74 20 33 with the last 3
0400: 32 4b 20 6f 66 20 64 61 74 61 20 66 72 6f 6d 20 2K of data from
0410: 74 68 65 0a 20 20 20 63 6f 6d 70 72 65 73 73 65 the. compresse
0420: 64 20 70 6f 72 74 69 6f 6e 2c 20 77 68 69 63 68 d portion, which
0430: 20 69 73 20 70 72 65 6c 6f 61 64 65 64 20 66 6f is preloaded fo
0440: 72 20 74 68 65 20 63 6f 6d 70 72 65 73 73 69 6f r the compressio
0450: 6e 20 6f 66 20 74 68 65 20 73 75 62 73 65 71 75 n of the subsequ
0460: 65 6e 74 0a 20 20 20 64 61 74 61 2e 20 20 54 68 ent. data. Th
0470: 69 73 20 6d 69 6e 69 6d 69 7a 65 73 20 74 68 65 is minimizes the
0480: 20 69 6d 70 61 63 74 20 74 6f 20 74 68 65 20 63 impact to the c
0490: 6f 6d 70 72 65 73 73 69 6f 6e 20 72 61 74 69 6f ompression ratio
04a0: 20 6f 66 20 61 70 70 65 6e 64 69 6e 67 2e 0a 20 of appending..
04b0: 2a 2f 0a 0a 2f 2a 0a 20 20 20 4f 70 65 72 61 74 */../*. Operat
04c0: 69 6f 6e 73 20 43 6f 6e 63 65 70 74 3a 0a 0a 20 ions Concept:..
04d0: 20 20 46 69 6c 65 73 20 28 6c 6f 67 20 6e 61 6d Files (log nam
04e0: 65 20 22 66 6f 6f 22 29 3a 0a 20 20 20 66 6f 6f e "foo"):. foo
04f0: 2e 67 7a 20 2d 2d 20 67 7a 69 70 20 66 69 6c 65 .gz -- gzip file
0500: 20 77 69 74 68 20 74 68 65 20 63 6f 6d 70 6c 65 with the comple
0510: 74 65 20 6c 6f 67 0a 20 20 20 66 6f 6f 2e 61 64 te log. foo.ad
0520: 64 20 2d 2d 20 6c 61 73 74 20 6d 65 73 73 61 67 d -- last messag
0530: 65 20 74 6f 20 61 70 70 65 6e 64 20 6f 72 20 6c e to append or l
0540: 61 73 74 20 64 61 74 61 20 74 6f 20 63 6f 6d 70 ast data to comp
0550: 72 65 73 73 0a 20 20 20 66 6f 6f 2e 64 69 63 74 ress. foo.dict
0560: 20 2d 2d 20 64 69 63 74 69 6f 6e 61 72 79 20 6f -- dictionary o
0570: 66 20 74 68 65 20 6c 61 73 74 20 33 32 4b 20 6f f the last 32K o
0580: 66 20 64 61 74 61 20 66 6f 72 20 6e 65 78 74 20 f data for next
0590: 63 6f 6d 70 72 65 73 73 69 6f 6e 0a 20 20 20 66 compression. f
05a0: 6f 6f 2e 74 65 6d 70 20 2d 2d 20 74 65 6d 70 6f oo.temp -- tempo
05b0: 72 61 72 79 20 64 69 63 74 69 6f 6e 61 72 79 20 rary dictionary
05c0: 66 69 6c 65 20 66 6f 72 20 63 6f 6d 70 72 65 73 file for compres
05d0: 73 69 6f 6e 20 61 66 74 65 72 20 74 68 69 73 20 sion after this
05e0: 6f 6e 65 0a 20 20 20 66 6f 6f 2e 6c 6f 63 6b 20 one. foo.lock
05f0: 2d 2d 20 6c 6f 63 6b 20 66 69 6c 65 20 66 6f 72 -- lock file for
0600: 20 72 65 61 64 69 6e 67 20 61 6e 64 20 77 72 69 reading and wri
0610: 74 69 6e 67 20 74 68 65 20 6f 74 68 65 72 20 66 ting the other f
0620: 69 6c 65 73 0a 20 20 20 66 6f 6f 2e 72 65 70 61 iles. foo.repa
0630: 69 72 73 20 2d 2d 20 6c 6f 67 20 66 69 6c 65 20 irs -- log file
0640: 66 6f 72 20 6c 6f 67 20 66 69 6c 65 20 72 65 63 for log file rec
0650: 6f 76 65 72 79 20 6f 70 65 72 61 74 69 6f 6e 73 overy operations
0660: 20 28 6e 6f 74 20 63 6f 6d 70 72 65 73 73 65 64 (not compressed
0670: 29 0a 0a 20 20 20 67 7a 69 70 20 66 69 6c 65 20 ).. gzip file
0680: 73 74 72 75 63 74 75 72 65 3a 0a 20 20 20 2d 20 structure:. -
0690: 66 69 78 65 64 2d 6c 65 6e 67 74 68 20 28 6e 6f fixed-length (no
06a0: 20 66 69 6c 65 20 6e 61 6d 65 29 20 68 65 61 64 file name) head
06b0: 65 72 20 77 69 74 68 20 65 78 74 72 61 20 66 69 er with extra fi
06c0: 65 6c 64 20 28 73 65 65 20 62 65 6c 6f 77 29 0a eld (see below).
06d0: 20 20 20 2d 20 63 6f 6d 70 72 65 73 73 65 64 20 - compressed
06e0: 64 61 74 61 20 65 6e 64 69 6e 67 20 69 6e 69 74 data ending init
06f0: 69 61 6c 6c 79 20 77 69 74 68 20 65 6d 70 74 79 ially with empty
0700: 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 0a 20 20 stored block.
0710: 20 2d 20 75 6e 63 6f 6d 70 72 65 73 73 65 64 20 - uncompressed
0720: 64 61 74 61 20 66 69 6c 6c 69 6e 67 20 6f 75 74 data filling out
0730: 20 6f 72 69 67 69 6e 61 6c 6c 79 20 65 6d 70 74 originally empt
0740: 79 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 61 y stored block a
0750: 6e 64 0a 20 20 20 20 20 73 75 62 73 65 71 75 65 nd. subseque
0760: 6e 74 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 73 nt stored blocks
0770: 20 61 73 20 6e 65 65 64 65 64 20 28 31 36 4b 20 as needed (16K
0780: 6d 61 78 20 65 61 63 68 29 0a 20 20 20 2d 20 67 max each). - g
0790: 7a 69 70 20 74 72 61 69 6c 65 72 0a 20 20 20 2d zip trailer. -
07a0: 20 6e 6f 20 6a 75 6e 6b 20 61 74 20 65 6e 64 20 no junk at end
07b0: 28 6e 6f 20 6f 74 68 65 72 20 67 7a 69 70 20 73 (no other gzip s
07c0: 74 72 65 61 6d 73 29 0a 0a 20 20 20 57 68 65 6e treams).. When
07d0: 20 61 70 70 65 6e 64 69 6e 67 20 64 61 74 61 2c appending data,
07e0: 20 74 68 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e the information
07f0: 20 69 6e 20 74 68 65 20 66 69 72 73 74 20 74 68 in the first th
0800: 72 65 65 20 69 74 65 6d 73 20 61 62 6f 76 65 20 ree items above
0810: 70 6c 75 73 20 74 68 65 0a 20 20 20 66 6f 6f 2e plus the. foo.
0820: 61 64 64 20 66 69 6c 65 20 61 72 65 20 73 75 66 add file are suf
0830: 66 69 63 69 65 6e 74 20 74 6f 20 72 65 63 6f 76 ficient to recov
0840: 65 72 20 61 6e 20 69 6e 74 65 72 72 75 70 74 65 er an interrupte
0850: 64 20 61 70 70 65 6e 64 20 6f 70 65 72 61 74 69 d append operati
0860: 6f 6e 2e 20 20 54 68 65 0a 20 20 20 65 78 74 72 on. The. extr
0870: 61 20 66 69 65 6c 64 20 68 61 73 20 74 68 65 20 a field has the
0880: 6e 65 63 65 73 73 61 72 79 20 69 6e 66 6f 72 6d necessary inform
0890: 61 74 69 6f 6e 20 74 6f 20 72 65 73 74 6f 72 65 ation to restore
08a0: 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 the start of th
08b0: 65 20 6c 61 73 74 0a 20 20 20 73 74 6f 72 65 64 e last. stored
08c0: 20 62 6c 6f 63 6b 20 61 6e 64 20 64 65 74 65 72 block and deter
08d0: 6d 69 6e 65 20 77 68 65 72 65 20 74 6f 20 61 70 mine where to ap
08e0: 70 65 6e 64 20 74 68 65 20 64 61 74 61 20 69 6e pend the data in
08f0: 20 74 68 65 20 66 6f 6f 2e 61 64 64 20 66 69 6c the foo.add fil
0900: 65 2c 20 61 73 0a 20 20 20 77 65 6c 6c 20 61 73 e, as. well as
0910: 20 74 68 65 20 63 72 63 20 61 6e 64 20 6c 65 6e the crc and len
0920: 67 74 68 20 6f 66 20 74 68 65 20 67 7a 69 70 20 gth of the gzip
0930: 64 61 74 61 20 62 65 66 6f 72 65 20 74 68 65 20 data before the
0940: 61 70 70 65 6e 64 20 6f 70 65 72 61 74 69 6f 6e append operation
0950: 2e 0a 0a 20 20 20 54 68 65 20 66 6f 6f 2e 61 64 ... The foo.ad
0960: 64 20 66 69 6c 65 20 69 73 20 63 72 65 61 74 65 d file is create
0970: 64 20 62 65 66 6f 72 65 20 74 68 65 20 67 7a 69 d before the gzi
0980: 70 20 66 69 6c 65 20 69 73 20 6d 61 72 6b 65 64 p file is marked
0990: 20 66 6f 72 20 61 70 70 65 6e 64 2c 20 61 6e 64 for append, and
09a0: 0a 20 20 20 64 65 6c 65 74 65 64 20 61 66 74 65 . deleted afte
09b0: 72 20 74 68 65 20 67 7a 69 70 20 66 69 6c 65 20 r the gzip file
09c0: 69 73 20 6d 61 72 6b 65 64 20 61 73 20 63 6f 6d is marked as com
09d0: 70 6c 65 74 65 2e 20 20 53 6f 20 69 66 20 74 68 plete. So if th
09e0: 65 20 61 70 70 65 6e 64 0a 20 20 20 6f 70 65 72 e append. oper
09f0: 61 74 69 6f 6e 20 69 73 20 69 6e 74 65 72 72 75 ation is interru
0a00: 70 74 65 64 2c 20 74 68 65 20 64 61 74 61 20 74 pted, the data t
0a10: 6f 20 61 64 64 20 77 69 6c 6c 20 73 74 69 6c 6c o add will still
0a20: 20 62 65 20 74 68 65 72 65 2e 20 20 49 66 20 64 be there. If d
0a30: 75 65 20 74 6f 0a 20 20 20 73 6f 6d 65 20 65 78 ue to. some ex
0a40: 74 65 72 6e 61 6c 20 66 6f 72 63 65 2c 20 74 68 ternal force, th
0a50: 65 20 66 6f 6f 2e 61 64 64 20 66 69 6c 65 20 67 e foo.add file g
0a60: 65 74 73 20 64 65 6c 65 74 65 64 20 62 65 74 77 ets deleted betw
0a70: 65 65 6e 20 77 68 65 6e 20 74 68 65 20 61 70 70 een when the app
0a80: 65 6e 64 0a 20 20 20 6f 70 65 72 61 74 69 6f 6e end. operation
0a90: 20 77 61 73 20 69 6e 74 65 72 72 75 70 74 65 64 was interrupted
0aa0: 20 61 6e 64 20 77 68 65 6e 20 72 65 63 6f 76 65 and when recove
0ab0: 72 79 20 69 73 20 61 74 74 65 6d 70 74 65 64 2c ry is attempted,
0ac0: 20 74 68 65 20 67 7a 69 70 20 66 69 6c 65 20 77 the gzip file w
0ad0: 69 6c 6c 0a 20 20 20 73 74 69 6c 6c 20 62 65 20 ill. still be
0ae0: 72 65 73 74 6f 72 65 64 2c 20 62 75 74 20 77 69 restored, but wi
0af0: 74 68 6f 75 74 20 74 68 65 20 61 70 70 65 6e 64 thout the append
0b00: 65 64 20 64 61 74 61 2e 0a 0a 20 20 20 57 68 65 ed data... Whe
0b10: 6e 20 63 6f 6d 70 72 65 73 73 69 6e 67 20 64 61 n compressing da
0b20: 74 61 2c 20 74 68 65 20 69 6e 66 6f 72 6d 61 74 ta, the informat
0b30: 69 6f 6e 20 69 6e 20 74 68 65 20 66 69 72 73 74 ion in the first
0b40: 20 74 77 6f 20 69 74 65 6d 73 20 61 62 6f 76 65 two items above
0b50: 20 70 6c 75 73 20 74 68 65 0a 20 20 20 66 6f 6f plus the. foo
0b60: 2e 61 64 64 20 66 69 6c 65 20 61 72 65 20 73 75 .add file are su
0b70: 66 66 69 63 69 65 6e 74 20 74 6f 20 72 65 63 6f fficient to reco
0b80: 76 65 72 20 61 6e 20 69 6e 74 65 72 72 75 70 74 ver an interrupt
0b90: 65 64 20 63 6f 6d 70 72 65 73 73 20 6f 70 65 72 ed compress oper
0ba0: 61 74 69 6f 6e 2e 0a 20 20 20 54 68 65 20 65 78 ation.. The ex
0bb0: 74 72 61 20 66 69 65 6c 64 20 68 61 73 20 74 68 tra field has th
0bc0: 65 20 6e 65 63 65 73 73 61 72 79 20 69 6e 66 6f e necessary info
0bd0: 72 6d 61 74 69 6f 6e 20 74 6f 20 66 69 6e 64 20 rmation to find
0be0: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 0a 20 the end of the.
0bf0: 20 20 63 6f 6d 70 72 65 73 73 65 64 20 64 61 74 compressed dat
0c00: 61 2c 20 61 6e 64 20 63 6f 6e 74 61 69 6e 73 20 a, and contains
0c10: 62 6f 74 68 20 74 68 65 20 63 72 63 20 61 6e 64 both the crc and
0c20: 20 6c 65 6e 67 74 68 20 6f 66 20 6a 75 73 74 20 length of just
0c30: 74 68 65 20 63 6f 6d 70 72 65 73 73 65 64 0a 20 the compressed.
0c40: 20 20 64 61 74 61 20 61 6e 64 20 6f 66 20 74 68 data and of th
0c50: 65 20 63 6f 6d 70 6c 65 74 65 20 73 65 74 20 6f e complete set o
0c60: 66 20 64 61 74 61 20 69 6e 63 6c 75 64 69 6e 67 f data including
0c70: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 6f 66 the contents of
0c80: 20 74 68 65 20 66 6f 6f 2e 61 64 64 0a 20 20 20 the foo.add.
0c90: 66 69 6c 65 2e 0a 0a 20 20 20 41 67 61 69 6e 2c file... Again,
0ca0: 20 74 68 65 20 66 6f 6f 2e 61 64 64 20 66 69 6c the foo.add fil
0cb0: 65 20 69 73 20 6d 61 69 6e 74 61 69 6e 65 64 20 e is maintained
0cc0: 64 75 72 69 6e 67 20 74 68 65 20 63 6f 6d 70 72 during the compr
0cd0: 65 73 73 20 6f 70 65 72 61 74 69 6f 6e 20 69 6e ess operation in
0ce0: 20 63 61 73 65 0a 20 20 20 6f 66 20 61 6e 20 69 case. of an i
0cf0: 6e 74 65 72 72 75 70 74 69 6f 6e 2e 20 20 49 66 nterruption. If
0d00: 20 69 6e 20 74 68 65 20 75 6e 6c 69 6b 65 6c 79 in the unlikely
0d10: 20 65 76 65 6e 74 20 74 68 65 20 66 6f 6f 2e 61 event the foo.a
0d20: 64 64 20 66 69 6c 65 20 77 69 74 68 20 74 68 65 dd file with the
0d30: 20 64 61 74 61 0a 20 20 20 74 6f 20 62 65 20 63 data. to be c
0d40: 6f 6d 70 72 65 73 73 65 64 20 69 73 20 6d 69 73 ompressed is mis
0d50: 73 69 6e 67 20 64 75 65 20 74 6f 20 73 6f 6d 65 sing due to some
0d60: 20 65 78 74 65 72 6e 61 6c 20 66 6f 72 63 65 2c external force,
0d70: 20 61 20 67 7a 69 70 20 66 69 6c 65 20 77 69 74 a gzip file wit
0d80: 68 0a 20 20 20 6a 75 73 74 20 74 68 65 20 70 72 h. just the pr
0d90: 65 76 69 6f 75 73 20 63 6f 6d 70 72 65 73 73 65 evious compresse
0da0: 64 20 64 61 74 61 20 77 69 6c 6c 20 62 65 20 72 d data will be r
0db0: 65 63 6f 6e 73 74 72 75 63 74 65 64 2e 20 20 49 econstructed. I
0dc0: 6e 20 74 68 69 73 20 63 61 73 65 2c 20 61 6c 6c n this case, all
0dd0: 0a 20 20 20 6f 66 20 74 68 65 20 64 61 74 61 20 . of the data
0de0: 74 68 61 74 20 77 61 73 20 74 6f 20 62 65 20 63 that was to be c
0df0: 6f 6d 70 72 65 73 73 65 64 20 69 73 20 6c 6f 73 ompressed is los
0e00: 74 20 28 61 70 70 72 6f 78 69 6d 61 74 65 6c 79 t (approximately
0e10: 20 6f 6e 65 20 6d 65 67 61 62 79 74 65 29 2e 0a one megabyte)..
0e20: 20 20 20 54 68 69 73 20 77 69 6c 6c 20 6e 6f 74 This will not
0e30: 20 6f 63 63 75 72 20 69 66 20 61 6c 6c 20 74 68 occur if all th
0e40: 61 74 20 68 61 70 70 65 6e 65 64 20 77 61 73 20 at happened was
0e50: 61 6e 20 69 6e 74 65 72 72 75 70 74 69 6f 6e 20 an interruption
0e60: 6f 66 20 74 68 65 20 63 6f 6d 70 72 65 73 73 0a of the compress.
0e70: 20 20 20 6f 70 65 72 61 74 69 6f 6e 2e 0a 0a 20 operation...
0e80: 20 20 54 68 65 20 74 68 69 72 64 20 73 74 61 74 The third stat
0e90: 65 20 74 68 61 74 20 69 73 20 6d 61 72 6b 65 64 e that is marked
0ea0: 20 69 73 20 74 68 65 20 72 65 70 6c 61 63 65 6d is the replacem
0eb0: 65 6e 74 20 6f 66 20 74 68 65 20 6f 6c 64 20 64 ent of the old d
0ec0: 69 63 74 69 6f 6e 61 72 79 20 77 69 74 68 0a 20 ictionary with.
0ed0: 20 20 74 68 65 20 6e 65 77 20 64 69 63 74 69 6f the new dictio
0ee0: 6e 61 72 79 20 61 66 74 65 72 20 61 20 63 6f 6d nary after a com
0ef0: 70 72 65 73 73 20 6f 70 65 72 61 74 69 6f 6e 2e press operation.
0f00: 20 20 4f 6e 63 65 20 63 6f 6d 70 72 65 73 73 69 Once compressi
0f10: 6f 6e 20 69 73 0a 20 20 20 63 6f 6d 70 6c 65 74 on is. complet
0f20: 65 2c 20 74 68 65 20 67 7a 69 70 20 66 69 6c 65 e, the gzip file
0f30: 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 62 65 is marked as be
0f40: 69 6e 67 20 69 6e 20 74 68 65 20 72 65 70 6c 61 ing in the repla
0f50: 63 65 20 73 74 61 74 65 2e 20 20 54 68 69 73 0a ce state. This.
0f60: 20 20 20 63 6f 6d 70 6c 65 74 65 73 20 74 68 65 completes the
0f70: 20 67 7a 69 70 20 66 69 6c 65 2c 20 73 6f 20 61 gzip file, so a
0f80: 6e 20 69 6e 74 65 72 72 75 70 74 20 61 66 74 65 n interrupt afte
0f90: 72 20 62 65 69 6e 67 20 73 6f 20 6d 61 72 6b 65 r being so marke
0fa0: 64 20 64 6f 65 73 20 6e 6f 74 0a 20 20 20 72 65 d does not. re
0fb0: 73 75 6c 74 20 69 6e 20 72 65 63 6f 6d 70 72 65 sult in recompre
0fc0: 73 73 69 6f 6e 2e 20 20 54 68 65 6e 20 74 68 65 ssion. Then the
0fd0: 20 64 69 63 74 69 6f 6e 61 72 79 20 66 69 6c 65 dictionary file
0fe0: 20 69 73 20 72 65 70 6c 61 63 65 64 2c 20 61 6e is replaced, an
0ff0: 64 20 74 68 65 20 67 7a 69 70 0a 20 20 20 66 69 d the gzip. fi
1000: 6c 65 20 69 73 20 6d 61 72 6b 65 64 20 61 73 20 le is marked as
1010: 63 6f 6d 70 6c 65 74 65 64 2e 20 20 54 68 69 73 completed. This
1020: 20 73 74 61 74 65 20 70 72 65 76 65 6e 74 73 20 state prevents
1030: 74 68 65 20 70 6f 73 73 69 62 69 6c 69 74 79 20 the possibility
1040: 6f 66 0a 20 20 20 72 65 73 74 61 72 74 69 6e 67 of. restarting
1050: 20 63 6f 6d 70 72 65 73 73 69 6f 6e 20 77 69 74 compression wit
1060: 68 20 74 68 65 20 77 72 6f 6e 67 20 64 69 63 74 h the wrong dict
1070: 69 6f 6e 61 72 79 20 66 69 6c 65 2e 0a 0a 20 20 ionary file...
1080: 20 41 6c 6c 20 74 68 72 65 65 20 6f 70 65 72 61 All three opera
1090: 74 69 6f 6e 73 20 61 72 65 20 77 72 61 70 70 65 tions are wrappe
10a0: 64 20 62 79 20 61 20 6c 6f 63 6b 2f 75 6e 6c 6f d by a lock/unlo
10b0: 63 6b 20 70 72 6f 63 65 64 75 72 65 2e 20 20 49 ck procedure. I
10c0: 6e 20 6f 72 64 65 72 20 74 6f 0a 20 20 20 67 61 n order to. ga
10d0: 69 6e 20 65 78 63 6c 75 73 69 76 65 20 61 63 63 in exclusive acc
10e0: 65 73 73 20 74 6f 20 74 68 65 20 6c 6f 67 20 66 ess to the log f
10f0: 69 6c 65 73 2c 20 66 69 72 73 74 20 61 20 66 6f iles, first a fo
1100: 6f 2e 6c 6f 63 6b 20 66 69 6c 65 20 6d 75 73 74 o.lock file must
1110: 20 62 65 0a 20 20 20 65 78 63 6c 75 73 69 76 65 be. exclusive
1120: 6c 79 20 63 72 65 61 74 65 64 2e 20 20 57 68 65 ly created. Whe
1130: 6e 20 61 6c 6c 20 6f 70 65 72 61 74 69 6f 6e 73 n all operations
1140: 20 61 72 65 20 63 6f 6d 70 6c 65 74 65 2c 20 74 are complete, t
1150: 68 65 20 6c 6f 63 6b 20 69 73 0a 20 20 20 72 65 he lock is. re
1160: 6c 65 61 73 65 64 20 62 79 20 64 65 6c 65 74 69 leased by deleti
1170: 6e 67 20 74 68 65 20 66 6f 6f 2e 6c 6f 63 6b 20 ng the foo.lock
1180: 66 69 6c 65 2e 20 20 49 66 20 77 68 65 6e 20 61 file. If when a
1190: 74 74 65 6d 70 74 69 6e 67 20 74 6f 20 63 72 65 ttempting to cre
11a0: 61 74 65 20 74 68 65 0a 20 20 20 6c 6f 63 6b 20 ate the. lock
11b0: 66 69 6c 65 2c 20 69 74 20 61 6c 72 65 61 64 79 file, it already
11c0: 20 65 78 69 73 74 73 20 61 6e 64 20 74 68 65 20 exists and the
11d0: 6d 6f 64 69 66 79 20 74 69 6d 65 20 6f 66 20 74 modify time of t
11e0: 68 65 20 6c 6f 63 6b 20 66 69 6c 65 20 69 73 20 he lock file is
11f0: 6d 6f 72 65 0a 20 20 20 74 68 61 6e 20 66 69 76 more. than fiv
1200: 65 20 6d 69 6e 75 74 65 73 20 6f 6c 64 20 28 73 e minutes old (s
1210: 65 74 20 62 79 20 74 68 65 20 50 41 54 49 45 4e et by the PATIEN
1220: 43 45 20 64 65 66 69 6e 65 20 62 65 6c 6f 77 29 CE define below)
1230: 2c 20 74 68 65 6e 20 74 68 65 20 6f 6c 64 0a 20 , then the old.
1240: 20 20 6c 6f 63 6b 20 66 69 6c 65 20 69 73 20 63 lock file is c
1250: 6f 6e 73 69 64 65 72 65 64 20 73 74 61 6c 65 20 onsidered stale
1260: 61 6e 64 20 64 65 6c 65 74 65 64 2c 20 61 6e 64 and deleted, and
1270: 20 74 68 65 20 65 78 63 6c 75 73 69 76 65 20 63 the exclusive c
1280: 72 65 61 74 69 6f 6e 20 6f 66 0a 20 20 20 74 68 reation of. th
1290: 65 20 6c 6f 63 6b 20 66 69 6c 65 20 69 73 20 72 e lock file is r
12a0: 65 74 72 69 65 64 2e 20 20 54 6f 20 61 73 73 75 etried. To assu
12b0: 72 65 20 74 68 61 74 20 74 68 65 72 65 20 61 72 re that there ar
12c0: 65 20 6e 6f 20 66 61 6c 73 65 20 61 73 73 65 73 e no false asses
12d0: 73 6d 65 6e 74 73 0a 20 20 20 6f 66 20 74 68 65 sments. of the
12e0: 20 73 74 61 6c 65 6e 65 73 73 20 6f 66 20 74 68 staleness of th
12f0: 65 20 6c 6f 63 6b 20 66 69 6c 65 2c 20 74 68 65 e lock file, the
1300: 20 6f 70 65 72 61 74 69 6f 6e 73 20 70 65 72 69 operations peri
1310: 6f 64 69 63 61 6c 6c 79 20 74 6f 75 63 68 20 74 odically touch t
1320: 68 65 0a 20 20 20 6c 6f 63 6b 20 66 69 6c 65 20 he. lock file
1330: 74 6f 20 75 70 64 61 74 65 20 74 68 65 20 6d 6f to update the mo
1340: 64 69 66 69 65 64 20 64 61 74 65 2e 0a 0a 20 20 dified date...
1350: 20 46 6f 6c 6c 6f 77 69 6e 67 20 69 73 20 74 68 Following is th
1360: 65 20 64 65 66 69 6e 69 74 69 6f 6e 20 6f 66 20 e definition of
1370: 74 68 65 20 65 78 74 72 61 20 66 69 65 6c 64 20 the extra field
1380: 77 69 74 68 20 61 6c 6c 20 6f 66 20 74 68 65 20 with all of the
1390: 69 6e 66 6f 72 6d 61 74 69 6f 6e 0a 20 20 20 72 information. r
13a0: 65 71 75 69 72 65 64 20 74 6f 20 65 6e 61 62 6c equired to enabl
13b0: 65 20 74 68 65 20 61 62 6f 76 65 20 61 70 70 65 e the above appe
13c0: 6e 64 20 61 6e 64 20 63 6f 6d 70 72 65 73 73 20 nd and compress
13d0: 6f 70 65 72 61 74 69 6f 6e 73 20 61 6e 64 20 74 operations and t
13e0: 68 65 69 72 0a 20 20 20 72 65 63 6f 76 65 72 79 heir. recovery
13f0: 20 69 66 20 69 6e 74 65 72 72 75 70 74 65 64 2e if interrupted.
1400: 20 20 4d 75 6c 74 69 2d 62 79 74 65 20 76 61 6c Multi-byte val
1410: 75 65 73 20 61 72 65 20 73 74 6f 72 65 64 20 6c ues are stored l
1420: 69 74 74 6c 65 20 65 6e 64 69 61 6e 0a 20 20 20 ittle endian.
1430: 28 63 6f 6e 73 69 73 74 65 6e 74 20 77 69 74 68 (consistent with
1440: 20 74 68 65 20 67 7a 69 70 20 66 6f 72 6d 61 74 the gzip format
1450: 29 2e 20 20 46 69 6c 65 20 70 6f 69 6e 74 65 72 ). File pointer
1460: 73 20 61 72 65 20 65 69 67 68 74 20 62 79 74 65 s are eight byte
1470: 73 20 6c 6f 6e 67 2e 0a 20 20 20 54 68 65 20 63 s long.. The c
1480: 72 63 27 73 20 61 6e 64 20 6c 65 6e 67 74 68 73 rc's and lengths
1490: 20 66 6f 72 20 74 68 65 20 67 7a 69 70 20 74 72 for the gzip tr
14a0: 61 69 6c 65 72 20 61 72 65 20 66 6f 75 72 20 62 ailer are four b
14b0: 79 74 65 73 20 6c 6f 6e 67 2e 20 20 28 4e 6f 74 ytes long. (Not
14c0: 65 20 74 68 61 74 0a 20 20 20 74 68 65 20 6c 65 e that. the le
14d0: 6e 67 74 68 20 61 74 20 74 68 65 20 65 6e 64 20 ngth at the end
14e0: 6f 66 20 61 20 67 7a 69 70 20 66 69 6c 65 20 69 of a gzip file i
14f0: 73 20 75 73 65 64 20 66 6f 72 20 65 72 72 6f 72 s used for error
1500: 20 63 68 65 63 6b 69 6e 67 20 6f 6e 6c 79 2c 20 checking only,
1510: 61 6e 64 0a 20 20 20 66 6f 72 20 6c 61 72 67 65 and. for large
1520: 20 66 69 6c 65 73 20 69 73 20 61 63 74 75 61 6c files is actual
1530: 6c 79 20 74 68 65 20 6c 65 6e 67 74 68 20 6d 6f ly the length mo
1540: 64 75 6c 6f 20 32 5e 33 32 2e 29 20 20 54 68 65 dulo 2^32.) The
1550: 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 0a 20 20 stored block.
1560: 20 6c 65 6e 67 74 68 20 69 73 20 74 77 6f 20 62 length is two b
1570: 79 74 65 73 20 6c 6f 6e 67 2e 20 20 54 68 65 20 ytes long. The
1580: 67 7a 69 70 20 65 78 74 72 61 20 66 69 65 6c 64 gzip extra field
1590: 20 74 77 6f 2d 62 79 74 65 20 69 64 65 6e 74 69 two-byte identi
15a0: 66 69 63 61 74 69 6f 6e 20 69 73 0a 20 20 20 22 fication is. "
15b0: 61 70 22 20 66 6f 72 20 61 70 70 65 6e 64 2e 20 ap" for append.
15c0: 20 49 74 20 69 73 20 61 73 73 75 6d 65 64 20 74 It is assumed t
15d0: 68 61 74 20 77 72 69 74 69 6e 67 20 74 68 65 20 hat writing the
15e0: 65 78 74 72 61 20 66 69 65 6c 64 20 74 6f 20 74 extra field to t
15f0: 68 65 20 66 69 6c 65 20 69 73 0a 20 20 20 61 6e he file is. an
1600: 20 22 61 74 6f 6d 69 63 22 20 6f 70 65 72 61 74 "atomic" operat
1610: 69 6f 6e 2e 20 20 54 68 61 74 20 69 73 2c 20 65 ion. That is, e
1620: 69 74 68 65 72 20 61 6c 6c 20 6f 66 20 74 68 65 ither all of the
1630: 20 65 78 74 72 61 20 66 69 65 6c 64 20 69 73 20 extra field is
1640: 77 72 69 74 74 65 6e 0a 20 20 20 74 6f 20 74 68 written. to th
1650: 65 20 66 69 6c 65 2c 20 6f 72 20 6e 6f 6e 65 20 e file, or none
1660: 6f 66 20 69 74 20 69 73 2c 20 69 66 20 74 68 65 of it is, if the
1670: 20 6f 70 65 72 61 74 69 6f 6e 20 69 73 20 69 6e operation is in
1680: 74 65 72 72 75 70 74 65 64 20 72 69 67 68 74 20 terrupted right
1690: 61 74 20 74 68 65 0a 20 20 20 70 6f 69 6e 74 20 at the. point
16a0: 6f 66 20 75 70 64 61 74 69 6e 67 20 74 68 65 20 of updating the
16b0: 65 78 74 72 61 20 66 69 65 6c 64 2e 20 20 54 68 extra field. Th
16c0: 69 73 20 69 73 20 61 20 72 65 61 73 6f 6e 61 62 is is a reasonab
16d0: 6c 65 20 61 73 73 75 6d 70 74 69 6f 6e 2c 20 73 le assumption, s
16e0: 69 6e 63 65 0a 20 20 20 74 68 65 20 65 78 74 72 ince. the extr
16f0: 61 20 66 69 65 6c 64 20 69 73 20 77 69 74 68 69 a field is withi
1700: 6e 20 74 68 65 20 66 69 72 73 74 20 35 32 20 62 n the first 52 b
1710: 79 74 65 73 20 6f 66 20 74 68 65 20 66 69 6c 65 ytes of the file
1720: 2c 20 77 68 69 63 68 20 69 73 20 73 6d 61 6c 6c , which is small
1730: 65 72 0a 20 20 20 74 68 61 6e 20 61 6e 79 20 65 er. than any e
1740: 78 70 65 63 74 65 64 20 62 6c 6f 63 6b 20 73 69 xpected block si
1750: 7a 65 20 66 6f 72 20 61 20 6d 61 73 73 20 73 74 ze for a mass st
1760: 6f 72 61 67 65 20 64 65 76 69 63 65 20 28 75 73 orage device (us
1770: 75 61 6c 6c 79 20 35 31 32 20 62 79 74 65 73 20 ually 512 bytes
1780: 6f 72 0a 20 20 20 6c 61 72 67 65 72 29 2e 0a 0a or. larger)...
1790: 20 20 20 45 78 74 72 61 20 66 69 65 6c 64 20 28 Extra field (
17a0: 33 35 20 62 79 74 65 73 29 3a 0a 20 20 20 2d 20 35 bytes):. -
17b0: 50 6f 69 6e 74 65 72 20 74 6f 20 66 69 72 73 74 Pointer to first
17c0: 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 6c 65 stored block le
17d0: 6e 67 74 68 20 2d 2d 20 74 68 69 73 20 70 6f 69 ngth -- this poi
17e0: 6e 74 73 20 74 6f 20 74 68 65 20 74 77 6f 2d 62 nts to the two-b
17f0: 79 74 65 20 6c 65 6e 67 74 68 0a 20 20 20 20 20 yte length.
1800: 6f 66 20 74 68 65 20 66 69 72 73 74 20 73 74 6f of the first sto
1810: 72 65 64 20 62 6c 6f 63 6b 2c 20 77 68 69 63 68 red block, which
1820: 20 69 73 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 is followed by
1830: 74 68 65 20 74 77 6f 2d 62 79 74 65 2c 20 6f 6e the two-byte, on
1840: 65 27 73 0a 20 20 20 20 20 63 6f 6d 70 6c 65 6d e's. complem
1850: 65 6e 74 20 6f 66 20 74 68 61 74 20 6c 65 6e 67 ent of that leng
1860: 74 68 2e 20 20 54 68 65 20 73 74 6f 72 65 64 20 th. The stored
1870: 62 6c 6f 63 6b 20 6c 65 6e 67 74 68 20 69 73 20 block length is
1880: 70 72 65 63 65 64 65 64 20 62 79 20 74 68 65 0a preceded by the.
1890: 20 20 20 20 20 74 68 72 65 65 2d 62 69 74 20 68 three-bit h
18a0: 65 61 64 65 72 20 6f 66 20 74 68 65 20 73 74 6f eader of the sto
18b0: 72 65 64 20 62 6c 6f 63 6b 2c 20 77 68 69 63 68 red block, which
18c0: 20 69 73 20 74 68 65 20 61 63 74 75 61 6c 20 73 is the actual s
18d0: 74 61 72 74 20 6f 66 20 74 68 65 0a 20 20 20 20 tart of the.
18e0: 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 69 6e stored block in
18f0: 20 74 68 65 20 64 65 66 6c 61 74 65 20 66 6f 72 the deflate for
1900: 6d 61 74 2e 20 20 53 65 65 20 74 68 65 20 62 69 mat. See the bi
1910: 74 20 6f 66 66 73 65 74 20 66 69 65 6c 64 20 62 t offset field b
1920: 65 6c 6f 77 2e 0a 20 20 20 2d 20 50 6f 69 6e 74 elow.. - Point
1930: 65 72 20 74 6f 20 74 68 65 20 6c 61 73 74 20 73 er to the last s
1940: 74 6f 72 65 64 20 62 6c 6f 63 6b 20 6c 65 6e 67 tored block leng
1950: 74 68 2e 20 20 54 68 69 73 20 69 73 20 74 68 65 th. This is the
1960: 20 73 61 6d 65 20 61 73 20 61 62 6f 76 65 2c 20 same as above,
1970: 62 75 74 0a 20 20 20 20 20 66 6f 72 20 74 68 65 but. for the
1980: 20 6c 61 73 74 20 73 74 6f 72 65 64 20 62 6c 6f last stored blo
1990: 63 6b 20 6f 66 20 74 68 65 20 75 6e 63 6f 6d 70 ck of the uncomp
19a0: 72 65 73 73 65 64 20 64 61 74 61 20 69 6e 20 74 ressed data in t
19b0: 68 65 20 67 7a 69 70 20 66 69 6c 65 2e 0a 20 20 he gzip file..
19c0: 20 20 20 49 6e 69 74 69 61 6c 6c 79 20 74 68 69 Initially thi
19d0: 73 20 69 73 20 74 68 65 20 73 61 6d 65 20 61 73 s is the same as
19e0: 20 74 68 65 20 66 69 72 73 74 20 73 74 6f 72 65 the first store
19f0: 64 20 62 6c 6f 63 6b 20 6c 65 6e 67 74 68 20 70 d block length p
1a00: 6f 69 6e 74 65 72 2e 0a 20 20 20 20 20 57 68 65 ointer.. Whe
1a10: 6e 20 74 68 65 20 73 74 6f 72 65 64 20 62 6c 6f n the stored blo
1a20: 63 6b 20 67 65 74 73 20 74 6f 20 31 36 4b 20 28 ck gets to 16K (
1a30: 73 65 65 20 74 68 65 20 4d 41 58 5f 53 54 4f 52 see the MAX_STOR
1a40: 45 20 64 65 66 69 6e 65 29 2c 20 74 68 65 6e 20 E define), then
1a50: 61 20 6e 65 77 0a 20 20 20 20 20 73 74 6f 72 65 a new. store
1a60: 64 20 62 6c 6f 63 6b 20 61 73 20 61 64 64 65 64 d block as added
1a70: 2c 20 61 74 20 77 68 69 63 68 20 70 6f 69 6e 74 , at which point
1a80: 20 74 68 65 20 6c 61 73 74 20 73 74 6f 72 65 64 the last stored
1a90: 20 62 6c 6f 63 6b 20 6c 65 6e 67 74 68 20 70 6f block length po
1aa0: 69 6e 74 65 72 0a 20 20 20 20 20 69 73 20 64 69 inter. is di
1ab0: 66 66 65 72 65 6e 74 20 66 72 6f 6d 20 74 68 65 fferent from the
1ac0: 20 66 69 72 73 74 20 73 74 6f 72 65 64 20 62 6c first stored bl
1ad0: 6f 63 6b 20 6c 65 6e 67 74 68 20 70 6f 69 6e 74 ock length point
1ae0: 65 72 2e 20 20 57 68 65 6e 20 74 68 65 79 20 61 er. When they a
1af0: 72 65 0a 20 20 20 20 20 64 69 66 66 65 72 65 6e re. differen
1b00: 74 2c 20 74 68 65 20 66 69 72 73 74 20 62 69 74 t, the first bit
1b10: 20 6f 66 20 74 68 65 20 6c 61 73 74 20 73 74 6f of the last sto
1b20: 72 65 64 20 62 6c 6f 63 6b 20 68 65 61 64 65 72 red block header
1b30: 20 69 73 20 65 69 67 68 74 20 62 69 74 73 2c 20 is eight bits,
1b40: 6f 72 0a 20 20 20 20 20 6f 6e 65 20 62 79 74 65 or. one byte
1b50: 20 62 61 63 6b 20 66 72 6f 6d 20 74 68 65 20 62 back from the b
1b60: 6c 6f 63 6b 20 6c 65 6e 67 74 68 2e 0a 20 20 20 lock length..
1b70: 2d 20 43 6f 6d 70 72 65 73 73 65 64 20 64 61 74 - Compressed dat
1b80: 61 20 63 72 63 20 61 6e 64 20 6c 65 6e 67 74 68 a crc and length
1b90: 2e 20 20 54 68 69 73 20 69 73 20 74 68 65 20 63 . This is the c
1ba0: 72 63 20 61 6e 64 20 6c 65 6e 67 74 68 20 6f 66 rc and length of
1bb0: 20 74 68 65 20 64 61 74 61 0a 20 20 20 20 20 74 the data. t
1bc0: 68 61 74 20 69 73 20 69 6e 20 74 68 65 20 63 6f hat is in the co
1bd0: 6d 70 72 65 73 73 65 64 20 70 6f 72 74 69 6f 6e mpressed portion
1be0: 20 6f 66 20 74 68 65 20 64 65 66 6c 61 74 65 20 of the deflate
1bf0: 73 74 72 65 61 6d 2e 20 20 54 68 65 73 65 20 61 stream. These a
1c00: 72 65 20 75 73 65 64 0a 20 20 20 20 20 6f 6e 6c re used. onl
1c10: 79 20 69 6e 20 74 68 65 20 65 76 65 6e 74 20 74 y in the event t
1c20: 68 61 74 20 74 68 65 20 66 6f 6f 2e 61 64 64 20 hat the foo.add
1c30: 66 69 6c 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20 file containing
1c40: 74 68 65 20 64 61 74 61 20 74 6f 20 63 6f 6d 70 the data to comp
1c50: 72 65 73 73 20 69 73 0a 20 20 20 20 20 6c 6f 73 ress is. los
1c60: 74 20 61 66 74 65 72 20 61 20 63 6f 6d 70 72 65 t after a compre
1c70: 73 73 20 6f 70 65 72 61 74 69 6f 6e 20 69 73 20 ss operation is
1c80: 69 6e 74 65 72 72 75 70 74 65 64 2e 0a 20 20 20 interrupted..
1c90: 2d 20 54 6f 74 61 6c 20 64 61 74 61 20 63 72 63 - Total data crc
1ca0: 20 61 6e 64 20 6c 65 6e 67 74 68 2e 20 20 54 68 and length. Th
1cb0: 69 73 20 69 73 20 74 68 65 20 63 72 63 20 61 6e is is the crc an
1cc0: 64 20 6c 65 6e 67 74 68 20 6f 66 20 61 6c 6c 20 d length of all
1cd0: 6f 66 20 74 68 65 20 64 61 74 61 0a 20 20 20 20 of the data.
1ce0: 20 73 74 6f 72 65 64 20 69 6e 20 74 68 65 20 67 stored in the g
1cf0: 7a 69 70 20 66 69 6c 65 2c 20 63 6f 6d 70 72 65 zip file, compre
1d00: 73 73 65 64 20 61 6e 64 20 75 6e 63 6f 6d 70 72 ssed and uncompr
1d10: 65 73 73 65 64 2e 20 20 49 74 20 69 73 20 75 73 essed. It is us
1d20: 65 64 20 74 6f 0a 20 20 20 20 20 72 65 63 6f 6e ed to. recon
1d30: 73 74 72 75 63 74 20 74 68 65 20 67 7a 69 70 20 struct the gzip
1d40: 74 72 61 69 6c 65 72 20 77 68 65 6e 20 63 6f 6d trailer when com
1d50: 70 72 65 73 73 69 6e 67 2c 20 61 73 20 77 65 6c pressing, as wel
1d60: 6c 20 61 73 20 77 68 65 6e 20 72 65 63 6f 76 65 l as when recove
1d70: 72 69 6e 67 0a 20 20 20 20 20 69 6e 74 65 72 72 ring. interr
1d80: 75 70 74 65 64 20 6f 70 65 72 61 74 69 6f 6e 73 upted operations
1d90: 2e 0a 20 20 20 2d 20 46 69 6e 61 6c 20 73 74 6f .. - Final sto
1da0: 72 65 64 20 62 6c 6f 63 6b 20 6c 65 6e 67 74 68 red block length
1db0: 2e 20 20 54 68 69 73 20 69 73 20 75 73 65 64 20 . This is used
1dc0: 74 6f 20 71 75 69 63 6b 6c 79 20 66 69 6e 64 20 to quickly find
1dd0: 77 68 65 72 65 20 74 6f 20 61 70 70 65 6e 64 2c where to append,
1de0: 0a 20 20 20 20 20 61 6e 64 20 61 6c 6c 6f 77 73 . and allows
1df0: 20 74 68 65 20 72 65 73 74 6f 72 61 74 69 6f 6e the restoration
1e00: 20 6f 66 20 74 68 65 20 6f 72 69 67 69 6e 61 6c of the original
1e10: 20 66 69 6e 61 6c 20 73 74 6f 72 65 64 20 62 6c final stored bl
1e20: 6f 63 6b 20 73 74 61 74 65 20 77 68 65 6e 0a 20 ock state when.
1e30: 20 20 20 20 61 6e 20 61 70 70 65 6e 64 20 6f 70 an append op
1e40: 65 72 61 74 69 6f 6e 20 69 73 20 69 6e 74 65 72 eration is inter
1e50: 72 75 70 74 65 64 2e 0a 20 20 20 2d 20 46 69 72 rupted.. - Fir
1e60: 73 74 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 st stored block
1e70: 73 74 61 72 74 20 61 73 20 74 68 65 20 6e 75 6d start as the num
1e80: 62 65 72 20 6f 66 20 62 69 74 73 20 62 61 63 6b ber of bits back
1e90: 20 66 72 6f 6d 20 74 68 65 20 66 69 6e 61 6c 20 from the final
1ea0: 73 74 6f 72 65 64 0a 20 20 20 20 20 62 6c 6f 63 stored. bloc
1eb0: 6b 20 66 69 72 73 74 20 6c 65 6e 67 74 68 20 62 k first length b
1ec0: 79 74 65 2e 20 20 54 68 69 73 20 76 61 6c 75 65 yte. This value
1ed0: 20 69 73 20 69 6e 20 74 68 65 20 72 61 6e 67 65 is in the range
1ee0: 20 6f 66 20 33 2e 2e 31 30 2c 20 61 6e 64 20 69 of 3..10, and i
1ef0: 73 0a 20 20 20 20 20 73 74 6f 72 65 64 20 61 73 s. stored as
1f00: 20 74 68 65 20 6c 6f 77 20 74 68 72 65 65 20 62 the low three b
1f10: 69 74 73 20 6f 66 20 74 68 65 20 66 69 6e 61 6c its of the final
1f20: 20 62 79 74 65 20 6f 66 20 74 68 65 20 65 78 74 byte of the ext
1f30: 72 61 20 66 69 65 6c 64 20 61 66 74 65 72 0a 20 ra field after.
1f40: 20 20 20 20 73 75 62 74 72 61 63 74 69 6e 67 20 subtracting
1f50: 74 68 72 65 65 20 28 30 2e 2e 37 29 2e 20 20 54 three (0..7). T
1f60: 68 69 73 20 61 6c 6c 6f 77 73 20 74 68 65 20 6c his allows the l
1f70: 61 73 74 2d 62 6c 6f 63 6b 20 62 69 74 20 6f 66 ast-block bit of
1f80: 20 74 68 65 20 73 74 6f 72 65 64 0a 20 20 20 20 the stored.
1f90: 20 62 6c 6f 63 6b 20 68 65 61 64 65 72 20 74 6f block header to
1fa0: 20 62 65 20 75 70 64 61 74 65 64 20 77 68 65 6e be updated when
1fb0: 20 61 20 6e 65 77 20 73 74 6f 72 65 64 20 62 6c a new stored bl
1fc0: 6f 63 6b 20 69 73 20 61 64 64 65 64 2c 20 66 6f ock is added, fo
1fd0: 72 20 74 68 65 20 63 61 73 65 0a 20 20 20 20 20 r the case.
1fe0: 77 68 65 6e 20 74 68 65 20 66 69 72 73 74 20 73 when the first s
1ff0: 74 6f 72 65 64 20 62 6c 6f 63 6b 20 61 6e 64 20 tored block and
2000: 74 68 65 20 6c 61 73 74 20 73 74 6f 72 65 64 20 the last stored
2010: 62 6c 6f 63 6b 20 61 72 65 20 74 68 65 20 73 61 block are the sa
2020: 6d 65 2e 20 20 28 57 68 65 6e 0a 20 20 20 20 20 me. (When.
2030: 74 68 65 79 20 61 72 65 20 64 69 66 66 65 72 65 they are differe
2040: 6e 74 2c 20 74 68 65 20 6e 75 6d 62 65 72 73 20 nt, the numbers
2050: 6f 66 20 62 69 74 73 20 62 61 63 6b 20 69 73 20 of bits back is
2060: 6b 6e 6f 77 6e 20 74 6f 20 62 65 20 65 69 67 68 known to be eigh
2070: 74 2e 29 20 20 54 68 69 73 0a 20 20 20 20 20 61 t.) This. a
2080: 6c 73 6f 20 61 6c 6c 6f 77 73 20 66 6f 72 20 6e lso allows for n
2090: 65 77 20 63 6f 6d 70 72 65 73 73 65 64 20 64 61 ew compressed da
20a0: 74 61 20 74 6f 20 62 65 20 61 70 70 65 6e 64 65 ta to be appende
20b0: 64 20 74 6f 20 74 68 65 20 6f 6c 64 20 63 6f 6d d to the old com
20c0: 70 72 65 73 73 65 64 0a 20 20 20 20 20 64 61 74 pressed. dat
20d0: 61 20 69 6e 20 74 68 65 20 63 6f 6d 70 72 65 73 a in the compres
20e0: 73 20 6f 70 65 72 61 74 69 6f 6e 2c 20 6f 76 65 s operation, ove
20f0: 72 77 72 69 74 69 6e 67 20 74 68 65 20 70 72 65 rwriting the pre
2100: 76 69 6f 75 73 20 66 69 72 73 74 20 73 74 6f 72 vious first stor
2110: 65 64 0a 20 20 20 20 20 62 6c 6f 63 6b 2c 20 6f ed. block, o
2120: 72 20 66 6f 72 20 74 68 65 20 63 6f 6d 70 72 65 r for the compre
2130: 73 73 65 64 20 64 61 74 61 20 74 6f 20 62 65 20 ssed data to be
2140: 74 65 72 6d 69 6e 61 74 65 64 20 61 6e 64 20 61 terminated and a
2150: 20 76 61 6c 69 64 20 67 7a 69 70 20 66 69 6c 65 valid gzip file
2160: 0a 20 20 20 20 20 72 65 63 6f 6e 73 74 72 75 63 . reconstruc
2170: 74 65 64 20 6f 6e 20 74 68 65 20 6f 66 66 20 63 ted on the off c
2180: 68 61 6e 63 65 20 74 68 61 74 20 61 20 63 6f 6d hance that a com
2190: 70 72 65 73 73 69 6f 6e 20 6f 70 65 72 61 74 69 pression operati
21a0: 6f 6e 20 77 61 73 0a 20 20 20 20 20 69 6e 74 65 on was. inte
21b0: 72 72 75 70 74 65 64 20 61 6e 64 20 74 68 65 20 rrupted and the
21c0: 64 61 74 61 20 74 6f 20 63 6f 6d 70 72 65 73 73 data to compress
21d0: 20 69 6e 20 74 68 65 20 66 6f 6f 2e 61 64 64 20 in the foo.add
21e0: 66 69 6c 65 20 77 61 73 20 64 65 6c 65 74 65 64 file was deleted
21f0: 2e 0a 20 20 20 2d 20 54 68 65 20 6f 70 65 72 61 .. - The opera
2200: 74 69 6f 6e 20 69 6e 20 70 72 6f 63 65 73 73 2e tion in process.
2210: 20 20 54 68 69 73 20 69 73 20 74 68 65 20 6e 65 This is the ne
2220: 78 74 20 74 77 6f 20 62 69 74 73 20 69 6e 20 74 xt two bits in t
2230: 68 65 20 6c 61 73 74 20 62 79 74 65 20 28 74 68 he last byte (th
2240: 65 0a 20 20 20 20 20 62 69 74 73 20 75 6e 64 65 e. bits unde
2250: 72 20 74 68 65 20 6d 61 73 6b 20 30 78 31 38 29 r the mask 0x18)
2260: 2e 20 20 54 68 65 20 61 72 65 20 69 6e 74 65 72 . The are inter
2270: 70 72 65 74 65 64 20 61 73 20 30 3a 20 6e 6f 74 preted as 0: not
2280: 68 69 6e 67 20 69 6e 20 70 72 6f 63 65 73 73 2c hing in process,
2290: 0a 20 20 20 20 20 31 3a 20 61 70 70 65 6e 64 20 . 1: append
22a0: 69 6e 20 70 72 6f 63 65 73 73 2c 20 32 3a 20 63 in process, 2: c
22b0: 6f 6d 70 72 65 73 73 20 69 6e 20 70 72 6f 63 65 ompress in proce
22c0: 73 73 2c 20 33 3a 20 72 65 70 6c 61 63 65 20 69 ss, 3: replace i
22d0: 6e 20 70 72 6f 63 65 73 73 2e 0a 20 20 20 2d 20 n process.. -
22e0: 54 68 65 20 74 6f 70 20 74 68 72 65 65 20 62 69 The top three bi
22f0: 74 73 20 6f 66 20 74 68 65 20 6c 61 73 74 20 62 ts of the last b
2300: 79 74 65 20 69 6e 20 74 68 65 20 65 78 74 72 61 yte in the extra
2310: 20 66 69 65 6c 64 20 61 72 65 20 72 65 73 65 72 field are reser
2320: 76 65 64 20 61 6e 64 0a 20 20 20 20 20 61 72 65 ved and. are
2330: 20 63 75 72 72 65 6e 74 6c 79 20 73 65 74 20 74 currently set t
2340: 6f 20 7a 65 72 6f 2e 0a 0a 20 20 20 4d 61 69 6e o zero... Main
2350: 20 70 72 6f 63 65 64 75 72 65 3a 0a 20 20 20 2d procedure:. -
2360: 20 45 78 63 6c 75 73 69 76 65 6c 79 20 63 72 65 Exclusively cre
2370: 61 74 65 20 74 68 65 20 66 6f 6f 2e 6c 6f 63 6b ate the foo.lock
2380: 20 66 69 6c 65 20 75 73 69 6e 67 20 74 68 65 20 file using the
2390: 4f 5f 43 52 45 41 54 20 61 6e 64 20 4f 5f 45 58 O_CREAT and O_EX
23a0: 43 4c 20 6d 6f 64 65 73 20 6f 66 0a 20 20 20 20 CL modes of.
23b0: 20 74 68 65 20 73 79 73 74 65 6d 20 6f 70 65 6e the system open
23c0: 28 29 20 63 61 6c 6c 2e 20 20 49 66 20 74 68 65 () call. If the
23d0: 20 6d 6f 64 69 66 79 20 74 69 6d 65 20 6f 66 20 modify time of
23e0: 61 6e 20 65 78 69 73 74 69 6e 67 20 6c 6f 63 6b an existing lock
23f0: 20 66 69 6c 65 20 69 73 0a 20 20 20 20 20 6d 6f file is. mo
2400: 72 65 20 74 68 61 6e 20 50 41 54 49 45 4e 43 45 re than PATIENCE
2410: 20 73 65 63 6f 6e 64 73 20 6f 6c 64 2c 20 74 68 seconds old, th
2420: 65 6e 20 74 68 65 20 6c 6f 63 6b 20 66 69 6c 65 en the lock file
2430: 20 69 73 20 64 65 6c 65 74 65 64 20 61 6e 64 20 is deleted and
2440: 74 68 65 0a 20 20 20 20 20 65 78 63 6c 75 73 69 the. exclusi
2450: 76 65 20 63 72 65 61 74 65 20 69 73 20 72 65 74 ve create is ret
2460: 72 69 65 64 2e 0a 20 20 20 2d 20 4c 6f 61 64 20 ried.. - Load
2470: 74 68 65 20 65 78 74 72 61 20 66 69 65 6c 64 20 the extra field
2480: 66 72 6f 6d 20 74 68 65 20 66 6f 6f 2e 67 7a 20 from the foo.gz
2490: 66 69 6c 65 2c 20 61 6e 64 20 73 65 65 20 69 66 file, and see if
24a0: 20 61 6e 20 6f 70 65 72 61 74 69 6f 6e 20 77 61 an operation wa
24b0: 73 20 69 6e 0a 20 20 20 20 20 70 72 6f 67 72 65 s in. progre
24c0: 73 73 20 62 75 74 20 6e 6f 74 20 63 6f 6d 70 6c ss but not compl
24d0: 65 74 65 64 2e 20 20 49 66 20 73 6f 2c 20 61 70 eted. If so, ap
24e0: 70 6c 79 20 74 68 65 20 72 65 63 6f 76 65 72 79 ply the recovery
24f0: 20 70 72 6f 63 65 64 75 72 65 20 62 65 6c 6f 77 procedure below
2500: 2e 0a 20 20 20 2d 20 50 65 72 66 6f 72 6d 20 74 .. - Perform t
2510: 68 65 20 61 70 70 65 6e 64 20 70 72 6f 63 65 64 he append proced
2520: 75 72 65 20 77 69 74 68 20 74 68 65 20 70 72 6f ure with the pro
2530: 76 69 64 65 64 20 64 61 74 61 2e 0a 20 20 20 2d vided data.. -
2540: 20 49 66 20 74 68 65 20 75 6e 63 6f 6d 70 72 65 If the uncompre
2550: 73 73 65 64 20 64 61 74 61 20 69 6e 20 74 68 65 ssed data in the
2560: 20 66 6f 6f 2e 67 7a 20 66 69 6c 65 20 69 73 20 foo.gz file is
2570: 31 4d 42 20 6f 72 20 6d 6f 72 65 2c 20 61 70 70 1MB or more, app
2580: 6c 79 20 74 68 65 0a 20 20 20 20 20 63 6f 6d 70 ly the. comp
2590: 72 65 73 73 20 70 72 6f 63 65 64 75 72 65 2e 0a ress procedure..
25a0: 20 20 20 2d 20 44 65 6c 65 74 65 20 74 68 65 20 - Delete the
25b0: 66 6f 6f 2e 6c 6f 63 6b 20 66 69 6c 65 2e 0a 0a foo.lock file...
25c0: 20 20 20 41 70 70 65 6e 64 20 70 72 6f 63 65 64 Append proced
25d0: 75 72 65 3a 0a 20 20 20 2d 20 50 75 74 20 77 68 ure:. - Put wh
25e0: 61 74 20 74 6f 20 61 70 70 65 6e 64 20 69 6e 20 at to append in
25f0: 74 68 65 20 66 6f 6f 2e 61 64 64 20 66 69 6c 65 the foo.add file
2600: 20 73 6f 20 74 68 61 74 20 74 68 65 20 6f 70 65 so that the ope
2610: 72 61 74 69 6f 6e 20 63 61 6e 20 62 65 0a 20 20 ration can be.
2620: 20 20 20 72 65 73 74 61 72 74 65 64 20 69 66 20 restarted if
2630: 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 69 this procedure i
2640: 73 20 69 6e 74 65 72 72 75 70 74 65 64 2e 0a 20 s interrupted..
2650: 20 20 2d 20 4d 61 72 6b 20 74 68 65 20 66 6f 6f - Mark the foo
2660: 2e 67 7a 20 65 78 74 72 61 20 66 69 65 6c 64 20 .gz extra field
2670: 77 69 74 68 20 74 68 65 20 61 70 70 65 6e 64 20 with the append
2680: 6f 70 65 72 61 74 69 6f 6e 20 69 6e 20 70 72 6f operation in pro
2690: 67 72 65 73 73 2e 0a 20 20 20 2b 20 52 65 73 74 gress.. + Rest
26a0: 6f 72 65 20 74 68 65 20 6f 72 69 67 69 6e 61 6c ore the original
26b0: 20 6c 61 73 74 2d 62 6c 6f 63 6b 20 62 69 74 20 last-block bit
26c0: 61 6e 64 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b and stored block
26d0: 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 6c length of the l
26e0: 61 73 74 0a 20 20 20 20 20 73 74 6f 72 65 64 20 ast. stored
26f0: 62 6c 6f 63 6b 20 66 72 6f 6d 20 74 68 65 20 69 block from the i
2700: 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 6e 20 74 68 nformation in th
2710: 65 20 65 78 74 72 61 20 66 69 65 6c 64 2c 20 69 e extra field, i
2720: 6e 20 63 61 73 65 20 61 20 70 72 65 76 69 6f 75 n case a previou
2730: 73 0a 20 20 20 20 20 61 70 70 65 6e 64 20 6f 70 s. append op
2740: 65 72 61 74 69 6f 6e 20 77 61 73 20 69 6e 74 65 eration was inte
2750: 72 72 75 70 74 65 64 2e 0a 20 20 20 2d 20 41 70 rrupted.. - Ap
2760: 70 65 6e 64 20 74 68 65 20 70 72 6f 76 69 64 65 pend the provide
2770: 64 20 64 61 74 61 20 74 6f 20 74 68 65 20 6c 61 d data to the la
2780: 73 74 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 2c st stored block,
2790: 20 63 72 65 61 74 69 6e 67 20 6e 65 77 20 73 74 creating new st
27a0: 6f 72 65 64 0a 20 20 20 20 20 62 6c 6f 63 6b 73 ored. blocks
27b0: 20 61 73 20 6e 65 65 64 65 64 20 61 6e 64 20 75 as needed and u
27c0: 70 64 61 74 69 6e 67 20 74 68 65 20 73 74 6f 72 pdating the stor
27d0: 65 64 20 62 6c 6f 63 6b 73 20 6c 61 73 74 2d 62 ed blocks last-b
27e0: 6c 6f 63 6b 20 62 69 74 73 20 61 6e 64 0a 20 20 lock bits and.
27f0: 20 20 20 6c 65 6e 67 74 68 73 2e 0a 20 20 20 2d lengths.. -
2800: 20 55 70 64 61 74 65 20 74 68 65 20 63 72 63 20 Update the crc
2810: 61 6e 64 20 6c 65 6e 67 74 68 20 77 69 74 68 20 and length with
2820: 74 68 65 20 6e 65 77 20 64 61 74 61 2c 20 61 6e the new data, an
2830: 64 20 77 72 69 74 65 20 74 68 65 20 67 7a 69 70 d write the gzip
2840: 20 74 72 61 69 6c 65 72 2e 0a 20 20 20 2d 20 57 trailer.. - W
2850: 72 69 74 65 20 6f 76 65 72 20 74 68 65 20 65 78 rite over the ex
2860: 74 72 61 20 66 69 65 6c 64 20 28 77 69 74 68 20 tra field (with
2870: 61 20 73 69 6e 67 6c 65 20 77 72 69 74 65 20 6f a single write o
2880: 70 65 72 61 74 69 6f 6e 29 20 77 69 74 68 20 74 peration) with t
2890: 68 65 20 6e 65 77 0a 20 20 20 20 20 70 6f 69 6e he new. poin
28a0: 74 65 72 73 2c 20 6c 65 6e 67 74 68 73 2c 20 61 ters, lengths, a
28b0: 6e 64 20 63 72 63 27 73 2c 20 61 6e 64 20 6d 61 nd crc's, and ma
28c0: 72 6b 20 74 68 65 20 67 7a 69 70 20 66 69 6c 65 rk the gzip file
28d0: 20 61 73 20 6e 6f 74 20 69 6e 20 70 72 6f 63 65 as not in proce
28e0: 73 73 2e 0a 20 20 20 20 20 54 68 6f 75 67 68 20 ss.. Though
28f0: 74 68 65 72 65 20 69 73 20 73 74 69 6c 6c 20 61 there is still a
2900: 20 66 6f 6f 2e 61 64 64 20 66 69 6c 65 2c 20 69 foo.add file, i
2910: 74 20 77 69 6c 6c 20 62 65 20 69 67 6e 6f 72 65 t will be ignore
2920: 64 20 73 69 6e 63 65 20 6e 6f 74 68 69 6e 67 0a d since nothing.
2930: 20 20 20 20 20 69 73 20 69 6e 20 70 72 6f 63 65 is in proce
2940: 73 73 2e 20 20 49 66 20 61 20 66 6f 6f 2e 61 64 ss. If a foo.ad
2950: 64 20 66 69 6c 65 20 69 73 20 6c 65 66 74 6f 76 d file is leftov
2960: 65 72 20 66 72 6f 6d 20 61 20 70 72 65 76 69 6f er from a previo
2970: 75 73 6c 79 0a 20 20 20 20 20 63 6f 6d 70 6c 65 usly. comple
2980: 74 65 64 20 6f 70 65 72 61 74 69 6f 6e 2c 20 69 ted operation, i
2990: 74 20 69 73 20 74 72 75 6e 63 61 74 65 64 20 77 t is truncated w
29a0: 68 65 6e 20 77 72 69 74 69 6e 67 20 6e 65 77 20 hen writing new
29b0: 64 61 74 61 20 74 6f 20 69 74 2e 0a 20 20 20 2d data to it.. -
29c0: 20 44 65 6c 65 74 65 20 74 68 65 20 66 6f 6f 2e Delete the foo.
29d0: 61 64 64 20 66 69 6c 65 2e 0a 0a 20 20 20 43 6f add file... Co
29e0: 6d 70 72 65 73 73 20 61 6e 64 20 72 65 70 6c 61 mpress and repla
29f0: 63 65 20 70 72 6f 63 65 64 75 72 65 73 3a 0a 20 ce procedures:.
2a00: 20 20 2d 20 52 65 61 64 20 61 6c 6c 20 6f 66 20 - Read all of
2a10: 74 68 65 20 75 6e 63 6f 6d 70 72 65 73 73 65 64 the uncompressed
2a20: 20 64 61 74 61 20 69 6e 20 74 68 65 20 73 74 6f data in the sto
2a30: 72 65 64 20 62 6c 6f 63 6b 73 20 69 6e 20 66 6f red blocks in fo
2a40: 6f 2e 67 7a 20 61 6e 64 20 77 72 69 74 65 0a 20 o.gz and write.
2a50: 20 20 20 20 69 74 20 74 6f 20 66 6f 6f 2e 61 64 it to foo.ad
2a60: 64 2e 20 20 41 6c 73 6f 20 77 72 69 74 65 20 66 d. Also write f
2a70: 6f 6f 2e 74 65 6d 70 20 77 69 74 68 20 74 68 65 oo.temp with the
2a80: 20 6c 61 73 74 20 33 32 4b 20 6f 66 20 74 68 61 last 32K of tha
2a90: 74 20 64 61 74 61 20 74 6f 0a 20 20 20 20 20 70 t data to. p
2aa0: 72 6f 76 69 64 65 20 61 20 64 69 63 74 69 6f 6e rovide a diction
2ab0: 61 72 79 20 66 6f 72 20 74 68 65 20 6e 65 78 74 ary for the next
2ac0: 20 69 6e 76 6f 63 61 74 69 6f 6e 20 6f 66 20 74 invocation of t
2ad0: 68 69 73 20 70 72 6f 63 65 64 75 72 65 2e 0a 20 his procedure..
2ae0: 20 20 2d 20 52 65 77 72 69 74 65 20 74 68 65 20 - Rewrite the
2af0: 65 78 74 72 61 20 66 69 65 6c 64 20 6d 61 72 6b extra field mark
2b00: 69 6e 67 20 66 6f 6f 2e 67 7a 20 77 69 74 68 20 ing foo.gz with
2b10: 61 20 63 6f 6d 70 72 65 73 73 69 6f 6e 20 69 6e a compression in
2b20: 20 70 72 6f 63 65 73 73 2e 0a 20 20 20 2a 20 49 process.. * I
2b30: 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 64 61 f there is no da
2b40: 74 61 20 70 72 6f 76 69 64 65 64 20 74 6f 20 63 ta provided to c
2b50: 6f 6d 70 72 65 73 73 20 28 64 75 65 20 74 6f 20 ompress (due to
2b60: 61 20 6d 69 73 73 69 6e 67 20 66 6f 6f 2e 61 64 a missing foo.ad
2b70: 64 20 66 69 6c 65 0a 20 20 20 20 20 77 68 65 6e d file. when
2b80: 20 72 65 63 6f 76 65 72 69 6e 67 29 2c 20 72 65 recovering), re
2b90: 63 6f 6e 73 74 72 75 63 74 20 61 6e 64 20 74 72 construct and tr
2ba0: 75 6e 63 61 74 65 20 74 68 65 20 66 6f 6f 2e 67 uncate the foo.g
2bb0: 7a 20 66 69 6c 65 20 74 6f 20 63 6f 6e 74 61 69 z file to contai
2bc0: 6e 0a 20 20 20 20 20 6f 6e 6c 79 20 74 68 65 20 n. only the
2bd0: 70 72 65 76 69 6f 75 73 20 63 6f 6d 70 72 65 73 previous compres
2be0: 73 65 64 20 64 61 74 61 20 61 6e 64 20 70 72 6f sed data and pro
2bf0: 63 65 65 64 20 74 6f 20 74 68 65 20 73 74 65 70 ceed to the step
2c00: 20 61 66 74 65 72 20 74 68 65 20 6e 65 78 74 0a after the next.
2c10: 20 20 20 20 20 6f 6e 65 2e 20 20 4f 74 68 65 72 one. Other
2c20: 77 69 73 65 20 2e 2e 2e 0a 20 20 20 2d 20 43 6f wise .... - Co
2c30: 6d 70 72 65 73 73 20 74 68 65 20 64 61 74 61 20 mpress the data
2c40: 77 69 74 68 20 74 68 65 20 64 69 63 74 69 6f 6e with the diction
2c50: 61 72 79 20 69 6e 20 66 6f 6f 2e 64 69 63 74 2c ary in foo.dict,
2c60: 20 61 6e 64 20 77 72 69 74 65 20 74 6f 20 74 68 and write to th
2c70: 65 0a 20 20 20 20 20 66 6f 6f 2e 67 7a 20 66 69 e. foo.gz fi
2c80: 6c 65 20 73 74 61 72 74 69 6e 67 20 61 74 20 74 le starting at t
2c90: 68 65 20 62 69 74 20 69 6d 6d 65 64 69 61 74 65 he bit immediate
2ca0: 6c 79 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 ly following the
2cb0: 20 6c 61 73 74 20 70 72 65 76 69 6f 75 73 6c 79 last previously
2cc0: 0a 20 20 20 20 20 63 6f 6d 70 72 65 73 73 65 64 . compressed
2cd0: 20 62 6c 6f 63 6b 2e 20 20 49 66 20 74 68 65 72 block. If ther
2ce0: 65 20 69 73 20 6e 6f 20 66 6f 6f 2e 64 69 63 74 e is no foo.dict
2cf0: 2c 20 70 72 6f 63 65 65 64 20 61 6e 79 77 61 79 , proceed anyway
2d00: 20 77 69 74 68 20 74 68 65 0a 20 20 20 20 20 63 with the. c
2d10: 6f 6d 70 72 65 73 73 69 6f 6e 20 61 74 20 73 6c ompression at sl
2d20: 69 67 68 74 6c 79 20 72 65 64 75 63 65 64 20 65 ightly reduced e
2d30: 66 66 69 63 69 65 6e 63 79 2e 20 20 28 46 6f 72 fficiency. (For
2d40: 20 74 68 65 20 66 6f 6f 2e 64 69 63 74 20 66 69 the foo.dict fi
2d50: 6c 65 20 74 6f 20 62 65 0a 20 20 20 20 20 6d 69 le to be. mi
2d60: 73 73 69 6e 67 20 72 65 71 75 69 72 65 73 20 73 ssing requires s
2d70: 6f 6d 65 20 65 78 74 65 72 6e 61 6c 20 66 61 69 ome external fai
2d80: 6c 75 72 65 20 62 65 79 6f 6e 64 20 73 69 6d 70 lure beyond simp
2d90: 6c 79 20 74 68 65 20 69 6e 74 65 72 72 75 70 74 ly the interrupt
2da0: 69 6f 6e 20 6f 66 0a 20 20 20 20 20 61 20 63 6f ion of. a co
2db0: 6d 70 72 65 73 73 20 6f 70 65 72 61 74 69 6f 6e mpress operation
2dc0: 2e 29 20 20 44 75 72 69 6e 67 20 74 68 69 73 20 .) During this
2dd0: 70 72 6f 63 65 73 73 2c 20 74 68 65 20 66 6f 6f process, the foo
2de0: 2e 6c 6f 63 6b 20 66 69 6c 65 20 69 73 0a 20 20 .lock file is.
2df0: 20 20 20 70 65 72 69 6f 64 69 63 61 6c 6c 79 20 periodically
2e00: 74 6f 75 63 68 65 64 20 74 6f 20 61 73 73 75 72 touched to assur
2e10: 65 20 74 68 61 74 20 74 68 61 74 20 66 69 6c 65 e that that file
2e20: 20 69 73 20 6e 6f 74 20 63 6f 6e 73 69 64 65 72 is not consider
2e30: 65 64 20 73 74 61 6c 65 20 62 79 0a 20 20 20 20 ed stale by.
2e40: 20 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73 73 another process
2e50: 20 62 65 66 6f 72 65 20 77 65 27 72 65 20 64 6f before we're do
2e60: 6e 65 2e 20 20 54 68 65 20 64 65 66 6c 61 74 69 ne. The deflati
2e70: 6f 6e 20 69 73 20 74 65 72 6d 69 6e 61 74 65 64 on is terminated
2e80: 20 77 69 74 68 20 61 0a 20 20 20 20 20 6e 6f 6e with a. non
2e90: 2d 6c 61 73 74 20 65 6d 70 74 79 20 73 74 61 74 -last empty stat
2ea0: 69 63 20 62 6c 6f 63 6b 20 28 31 30 20 62 69 74 ic block (10 bit
2eb0: 73 20 6c 6f 6e 67 29 2c 20 74 68 61 74 20 69 73 s long), that is
2ec0: 20 74 68 65 6e 20 6c 6f 63 61 74 65 64 20 61 6e then located an
2ed0: 64 0a 20 20 20 20 20 77 72 69 74 74 65 6e 20 6f d. written o
2ee0: 76 65 72 20 62 79 20 61 20 6c 61 73 74 2d 62 69 ver by a last-bi
2ef0: 74 2d 73 65 74 20 65 6d 70 74 79 20 73 74 6f 72 t-set empty stor
2f00: 65 64 20 62 6c 6f 63 6b 2e 0a 20 20 20 2d 20 41 ed block.. - A
2f10: 70 70 65 6e 64 20 74 68 65 20 63 72 63 20 61 6e ppend the crc an
2f20: 64 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 d length of the
2f30: 64 61 74 61 20 69 6e 20 74 68 65 20 67 7a 69 70 data in the gzip
2f40: 20 66 69 6c 65 20 28 70 72 65 76 69 6f 75 73 6c file (previousl
2f50: 79 0a 20 20 20 20 20 63 61 6c 63 75 6c 61 74 65 y. calculate
2f60: 64 20 64 75 72 69 6e 67 20 74 68 65 20 61 70 70 d during the app
2f70: 65 6e 64 20 6f 70 65 72 61 74 69 6f 6e 73 29 2e end operations).
2f80: 0a 20 20 20 2d 20 57 72 69 74 65 20 6f 76 65 72 . - Write over
2f90: 20 74 68 65 20 65 78 74 72 61 20 66 69 65 6c 64 the extra field
2fa0: 20 77 69 74 68 20 74 68 65 20 75 70 64 61 74 65 with the update
2fb0: 64 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 6f d stored block o
2fc0: 66 66 73 65 74 73 2c 20 62 69 74 73 0a 20 20 20 ffsets, bits.
2fd0: 20 20 62 61 63 6b 2c 20 63 72 63 27 73 2c 20 61 back, crc's, a
2fe0: 6e 64 20 6c 65 6e 67 74 68 73 2c 20 61 6e 64 20 nd lengths, and
2ff0: 6d 61 72 6b 20 66 6f 6f 2e 67 7a 20 61 73 20 69 mark foo.gz as i
3000: 6e 20 70 72 6f 63 65 73 73 20 66 6f 72 20 61 20 n process for a
3010: 72 65 70 6c 61 63 65 6d 65 6e 74 0a 20 20 20 20 replacement.
3020: 20 6f 66 20 74 68 65 20 64 69 63 74 69 6f 6e 61 of the dictiona
3030: 72 79 2e 0a 20 20 20 40 20 44 65 6c 65 74 65 20 ry.. @ Delete
3040: 74 68 65 20 66 6f 6f 2e 61 64 64 20 66 69 6c 65 the foo.add file
3050: 2e 0a 20 20 20 2d 20 52 65 70 6c 61 63 65 20 66 .. - Replace f
3060: 6f 6f 2e 64 69 63 74 20 77 69 74 68 20 66 6f 6f oo.dict with foo
3070: 2e 74 65 6d 70 2e 0a 20 20 20 2d 20 57 72 69 74 .temp.. - Writ
3080: 65 20 6f 76 65 72 20 74 68 65 20 65 78 74 72 61 e over the extra
3090: 20 66 69 65 6c 64 2c 20 6d 61 72 6b 69 6e 67 20 field, marking
30a0: 66 6f 6f 2e 67 7a 20 61 73 20 63 6f 6d 70 6c 65 foo.gz as comple
30b0: 74 65 2e 0a 0a 20 20 20 52 65 63 6f 76 65 72 79 te... Recovery
30c0: 20 70 72 6f 63 65 64 75 72 65 3a 0a 20 20 20 2d procedure:. -
30d0: 20 49 66 20 6e 6f 74 20 61 20 72 65 70 6c 61 63 If not a replac
30e0: 65 20 72 65 63 6f 76 65 72 79 2c 20 72 65 61 64 e recovery, read
30f0: 20 69 6e 20 74 68 65 20 66 6f 6f 2e 61 64 64 20 in the foo.add
3100: 66 69 6c 65 2c 20 61 6e 64 20 70 72 6f 76 69 64 file, and provid
3110: 65 20 74 68 61 74 20 64 61 74 61 0a 20 20 20 20 e that data.
3120: 20 74 6f 20 74 68 65 20 61 70 70 72 6f 70 72 69 to the appropri
3130: 61 74 65 20 72 65 63 6f 76 65 72 79 20 62 65 6c ate recovery bel
3140: 6f 77 2e 20 20 49 66 20 74 68 65 72 65 20 69 73 ow. If there is
3150: 20 6e 6f 20 66 6f 6f 2e 61 64 64 20 66 69 6c 65 no foo.add file
3160: 2c 20 70 72 6f 76 69 64 65 0a 20 20 20 20 20 61 , provide. a
3170: 20 7a 65 72 6f 20 64 61 74 61 20 6c 65 6e 67 74 zero data lengt
3180: 68 20 74 6f 20 74 68 65 20 72 65 63 6f 76 65 72 h to the recover
3190: 79 2e 20 20 49 6e 20 74 68 61 74 20 63 61 73 65 y. In that case
31a0: 2c 20 74 68 65 20 61 70 70 65 6e 64 20 72 65 63 , the append rec
31b0: 6f 76 65 72 79 0a 20 20 20 20 20 72 65 73 74 6f overy. resto
31c0: 72 65 73 20 74 68 65 20 66 6f 6f 2e 67 7a 20 74 res the foo.gz t
31d0: 6f 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 63 o the previous c
31e0: 6f 6d 70 72 65 73 73 65 64 20 2b 20 75 6e 63 6f ompressed + unco
31f0: 6d 70 72 65 73 73 65 64 20 64 61 74 61 20 73 74 mpressed data st
3200: 61 74 65 2e 0a 20 20 20 20 20 46 6f 72 20 74 68 ate.. For th
3210: 65 20 74 68 65 20 63 6f 6d 70 72 65 73 73 20 72 e the compress r
3220: 65 63 6f 76 65 72 79 2c 20 61 20 6d 69 73 73 69 ecovery, a missi
3230: 6e 67 20 66 6f 6f 2e 61 64 64 20 66 69 6c 65 20 ng foo.add file
3240: 72 65 73 75 6c 74 73 20 69 6e 20 66 6f 6f 2e 67 results in foo.g
3250: 7a 0a 20 20 20 20 20 62 65 69 6e 67 20 72 65 73 z. being res
3260: 74 6f 72 65 64 20 74 6f 20 74 68 65 20 70 72 65 tored to the pre
3270: 76 69 6f 75 73 20 63 6f 6d 70 72 65 73 73 65 64 vious compressed
3280: 2d 6f 6e 6c 79 20 64 61 74 61 20 73 74 61 74 65 -only data state
3290: 2e 0a 20 20 20 2d 20 41 70 70 65 6e 64 20 72 65 .. - Append re
32a0: 63 6f 76 65 72 79 3a 0a 20 20 20 20 20 2d 20 50 covery:. - P
32b0: 69 63 6b 20 75 70 20 61 70 70 65 6e 64 20 61 74 ick up append at
32c0: 20 2b 20 73 74 65 70 20 61 62 6f 76 65 0a 20 20 + step above.
32d0: 20 2d 20 43 6f 6d 70 72 65 73 73 20 72 65 63 6f - Compress reco
32e0: 76 65 72 79 3a 0a 20 20 20 20 20 2d 20 50 69 63 very:. - Pic
32f0: 6b 20 75 70 20 63 6f 6d 70 72 65 73 73 20 61 74 k up compress at
3300: 20 2a 20 73 74 65 70 20 61 62 6f 76 65 0a 20 20 * step above.
3310: 20 2d 20 52 65 70 6c 61 63 65 20 72 65 63 6f 76 - Replace recov
3320: 65 72 79 3a 0a 20 20 20 20 20 2d 20 50 69 63 6b ery:. - Pick
3330: 20 75 70 20 63 6f 6d 70 72 65 73 73 20 61 74 20 up compress at
3340: 40 20 73 74 65 70 20 61 62 6f 76 65 0a 20 20 20 @ step above.
3350: 2d 20 4c 6f 67 20 74 68 65 20 72 65 70 61 69 72 - Log the repair
3360: 20 77 69 74 68 20 61 20 64 61 74 65 20 73 74 61 with a date sta
3370: 6d 70 20 69 6e 20 66 6f 6f 2e 72 65 70 61 69 72 mp in foo.repair
3380: 73 0a 20 2a 2f 0a 0a 23 69 6e 63 6c 75 64 65 20 s. */..#include
3390: 3c 73 79 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 <sys/types.h>.#i
33a0: 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e nclude <stdio.h>
33b0: 20 20 20 20 20 20 2f 2a 20 72 65 6e 61 6d 65 2c /* rename,
33c0: 20 66 6f 70 65 6e 2c 20 66 70 72 69 6e 74 66 2c fopen, fprintf,
33d0: 20 66 63 6c 6f 73 65 20 2a 2f 0a 23 69 6e 63 6c fclose */.#incl
33e0: 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 20 20 ude <stdlib.h>
33f0: 20 20 20 2f 2a 20 6d 61 6c 6c 6f 63 2c 20 66 72 /* malloc, fr
3400: 65 65 20 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 3c ee */.#include <
3410: 73 74 72 69 6e 67 2e 68 3e 20 20 20 20 20 2f 2a string.h> /*
3420: 20 73 74 72 6c 65 6e 2c 20 73 74 72 72 63 68 72 strlen, strrchr
3430: 2c 20 73 74 72 63 70 79 2c 20 73 74 72 6e 63 70 , strcpy, strncp
3440: 79 2c 20 73 74 72 63 6d 70 20 2a 2f 0a 23 69 6e y, strcmp */.#in
3450: 63 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 20 clude <fcntl.h>
3460: 20 20 20 20 20 2f 2a 20 6f 70 65 6e 20 2a 2f 0a /* open */.
3470: 23 69 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 #include <unistd
3480: 2e 68 3e 20 20 20 20 20 2f 2a 20 6c 73 65 65 6b .h> /* lseek
3490: 2c 20 72 65 61 64 2c 20 77 72 69 74 65 2c 20 63 , read, write, c
34a0: 6c 6f 73 65 2c 20 75 6e 6c 69 6e 6b 2c 20 73 6c lose, unlink, sl
34b0: 65 65 70 2c 20 2a 2f 0a 20 20 20 20 20 20 20 20 eep, */.
34c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
34d0: 2f 2a 20 66 74 72 75 6e 63 61 74 65 2c 20 66 73 /* ftruncate, fs
34e0: 79 6e 63 20 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 ync */.#include
34f0: 3c 65 72 72 6e 6f 2e 68 3e 20 20 20 20 20 20 2f <errno.h> /
3500: 2a 20 65 72 72 6e 6f 20 2a 2f 0a 23 69 6e 63 6c * errno */.#incl
3510: 75 64 65 20 3c 74 69 6d 65 2e 68 3e 20 20 20 20 ude <time.h>
3520: 20 20 20 2f 2a 20 74 69 6d 65 2c 20 63 74 69 6d /* time, ctim
3530: 65 20 2a 2f 0a 23 69 6e 63 6c 75 64 65 20 3c 73 e */.#include <s
3540: 79 73 2f 73 74 61 74 2e 68 3e 20 20 20 2f 2a 20 ys/stat.h> /*
3550: 73 74 61 74 20 2a 2f 0a 23 69 6e 63 6c 75 64 65 stat */.#include
3560: 20 3c 73 79 73 2f 74 69 6d 65 2e 68 3e 20 20 20 <sys/time.h>
3570: 2f 2a 20 75 74 69 6d 65 73 20 2a 2f 0a 23 69 6e /* utimes */.#in
3580: 63 6c 75 64 65 20 22 7a 6c 69 62 2e 68 22 20 20 clude "zlib.h"
3590: 20 20 20 20 20 2f 2a 20 63 72 63 33 32 20 2a 2f /* crc32 */
35a0: 0a 0a 23 69 6e 63 6c 75 64 65 20 22 67 7a 6c 6f ..#include "gzlo
35b0: 67 2e 68 22 20 20 20 20 20 20 2f 2a 20 68 65 61 g.h" /* hea
35c0: 64 65 72 20 66 6f 72 20 65 78 74 65 72 6e 61 6c der for external
35d0: 20 61 63 63 65 73 73 20 2a 2f 0a 0a 23 64 65 66 access */..#def
35e0: 69 6e 65 20 6c 6f 63 61 6c 20 73 74 61 74 69 63 ine local static
35f0: 0a 74 79 70 65 64 65 66 20 75 6e 73 69 67 6e 65 .typedef unsigne
3600: 64 20 69 6e 74 20 75 69 6e 74 3b 0a 74 79 70 65 d int uint;.type
3610: 64 65 66 20 75 6e 73 69 67 6e 65 64 20 6c 6f 6e def unsigned lon
3620: 67 20 75 6c 6f 6e 67 3b 0a 0a 2f 2a 20 4d 61 63 g ulong;../* Mac
3630: 72 6f 20 66 6f 72 20 64 65 62 75 67 67 69 6e 67 ro for debugging
3640: 20 74 6f 20 64 65 74 65 72 6d 69 6e 69 73 74 69 to deterministi
3650: 63 61 6c 6c 79 20 66 6f 72 63 65 20 72 65 63 6f cally force reco
3660: 76 65 72 79 20 6f 70 65 72 61 74 69 6f 6e 73 20 very operations
3670: 2a 2f 0a 23 69 66 64 65 66 20 44 45 42 55 47 0a */.#ifdef DEBUG.
3680: 20 20 20 20 23 69 6e 63 6c 75 64 65 20 3c 73 65 #include <se
3690: 74 6a 6d 70 2e 68 3e 20 20 20 20 20 20 20 20 20 tjmp.h>
36a0: 2f 2a 20 6c 6f 6e 67 6a 6d 70 20 2a 2f 0a 20 20 /* longjmp */.
36b0: 20 20 6a 6d 70 5f 62 75 66 20 67 7a 6c 6f 67 5f jmp_buf gzlog_
36c0: 6a 75 6d 70 3b 20 20 20 20 20 20 20 20 20 2f 2a jump; /*
36d0: 20 77 68 65 72 65 20 74 6f 20 67 6f 20 62 61 63 where to go bac
36e0: 6b 20 74 6f 20 2a 2f 0a 20 20 20 20 69 6e 74 20 k to */. int
36f0: 67 7a 6c 6f 67 5f 62 61 69 6c 20 3d 20 30 3b 20 gzlog_bail = 0;
3700: 20 20 20 20 20 20 20 20 2f 2a 20 77 68 69 63 68 /* which
3710: 20 70 6f 69 6e 74 20 74 6f 20 62 61 69 6c 20 61 point to bail a
3720: 74 20 28 31 2e 2e 38 29 20 2a 2f 0a 20 20 20 20 t (1..8) */.
3730: 69 6e 74 20 67 7a 6c 6f 67 5f 63 6f 75 6e 74 20 int gzlog_count
3740: 3d 20 2d 31 3b 20 20 20 20 20 20 20 2f 2a 20 6e = -1; /* n
3750: 75 6d 62 65 72 20 6f 66 20 74 69 6d 65 73 20 74 umber of times t
3760: 68 72 6f 75 67 68 20 74 6f 20 77 61 69 74 20 2a hrough to wait *
3770: 2f 0a 23 20 20 20 64 65 66 69 6e 65 20 42 41 49 /.# define BAI
3780: 4c 28 6e 29 20 64 6f 20 7b 20 69 66 20 28 6e 20 L(n) do { if (n
3790: 3d 3d 20 67 7a 6c 6f 67 5f 62 61 69 6c 20 26 26 == gzlog_bail &&
37a0: 20 67 7a 6c 6f 67 5f 63 6f 75 6e 74 2d 2d 20 3d gzlog_count-- =
37b0: 3d 20 30 29 20 5c 0a 20 20 20 20 20 20 20 20 20 = 0) \.
37c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
37d0: 20 20 20 6c 6f 6e 67 6a 6d 70 28 67 7a 6c 6f 67 longjmp(gzlog
37e0: 5f 6a 75 6d 70 2c 20 67 7a 6c 6f 67 5f 62 61 69 _jump, gzlog_bai
37f0: 6c 29 3b 20 7d 20 77 68 69 6c 65 20 28 30 29 0a l); } while (0).
3800: 23 65 6c 73 65 0a 23 20 20 20 64 65 66 69 6e 65 #else.# define
3810: 20 42 41 49 4c 28 6e 29 0a 23 65 6e 64 69 66 0a BAIL(n).#endif.
3820: 0a 2f 2a 20 68 6f 77 20 6f 6c 64 20 74 68 65 20 ./* how old the
3830: 6c 6f 63 6b 20 66 69 6c 65 20 63 61 6e 20 62 65 lock file can be
3840: 20 69 6e 20 73 65 63 6f 6e 64 73 20 62 65 66 6f in seconds befo
3850: 72 65 20 63 6f 6e 73 69 64 65 72 69 6e 67 20 69 re considering i
3860: 74 20 73 74 61 6c 65 20 2a 2f 0a 23 64 65 66 69 t stale */.#defi
3870: 6e 65 20 50 41 54 49 45 4e 43 45 20 33 30 30 0a ne PATIENCE 300.
3880: 0a 2f 2a 20 6d 61 78 69 6d 75 6d 20 73 74 6f 72 ./* maximum stor
3890: 65 64 20 62 6c 6f 63 6b 20 73 69 7a 65 20 69 6e ed block size in
38a0: 20 4b 62 79 74 65 73 20 2d 2d 20 6d 75 73 74 20 Kbytes -- must
38b0: 62 65 20 69 6e 20 31 2e 2e 36 33 20 2a 2f 0a 23 be in 1..63 */.#
38c0: 64 65 66 69 6e 65 20 4d 41 58 5f 53 54 4f 52 45 define MAX_STORE
38d0: 20 31 36 0a 0a 2f 2a 20 6e 75 6d 62 65 72 20 6f 16../* number o
38e0: 66 20 73 74 6f 72 65 64 20 4b 62 79 74 65 73 20 f stored Kbytes
38f0: 74 6f 20 74 72 69 67 67 65 72 20 63 6f 6d 70 72 to trigger compr
3900: 65 73 73 69 6f 6e 20 28 6d 75 73 74 20 62 65 20 ession (must be
3910: 3e 3d 20 33 32 20 74 6f 20 61 6c 6c 6f 77 0a 20 >= 32 to allow.
3920: 20 20 64 69 63 74 69 6f 6e 61 72 79 20 63 6f 6e dictionary con
3930: 73 74 72 75 63 74 69 6f 6e 2c 20 61 6e 64 20 3c struction, and <
3940: 3d 20 32 30 34 20 2a 20 4d 41 58 5f 53 54 4f 52 = 204 * MAX_STOR
3950: 45 2c 20 69 6e 20 6f 72 64 65 72 20 66 6f 72 20 E, in order for
3960: 3e 3e 20 31 30 20 74 6f 0a 20 20 20 64 69 73 63 >> 10 to. disc
3970: 61 72 64 20 74 68 65 20 73 74 6f 72 65 64 20 62 ard the stored b
3980: 6c 6f 63 6b 20 68 65 61 64 65 72 73 20 63 6f 6e lock headers con
3990: 74 72 69 62 75 74 69 6f 6e 20 6f 66 20 66 69 76 tribution of fiv
39a0: 65 20 62 79 74 65 73 20 65 61 63 68 29 20 2a 2f e bytes each) */
39b0: 0a 23 64 65 66 69 6e 65 20 54 52 49 47 47 45 52 .#define TRIGGER
39c0: 20 31 30 32 34 0a 0a 2f 2a 20 73 69 7a 65 20 6f 1024../* size o
39d0: 66 20 61 20 64 65 66 6c 61 74 65 20 64 69 63 74 f a deflate dict
39e0: 69 6f 6e 61 72 79 20 28 74 68 69 73 20 63 61 6e ionary (this can
39f0: 6e 6f 74 20 62 65 20 63 68 61 6e 67 65 64 29 20 not be changed)
3a00: 2a 2f 0a 23 64 65 66 69 6e 65 20 44 49 43 54 20 */.#define DICT
3a10: 33 32 37 36 38 55 0a 0a 2f 2a 20 76 61 6c 75 65 32768U../* value
3a20: 73 20 66 6f 72 20 74 68 65 20 6f 70 65 72 61 74 s for the operat
3a30: 69 6f 6e 20 28 32 20 62 69 74 73 29 20 2a 2f 0a ion (2 bits) */.
3a40: 23 64 65 66 69 6e 65 20 4e 4f 5f 4f 50 20 30 0a #define NO_OP 0.
3a50: 23 64 65 66 69 6e 65 20 41 50 50 45 4e 44 5f 4f #define APPEND_O
3a60: 50 20 31 0a 23 64 65 66 69 6e 65 20 43 4f 4d 50 P 1.#define COMP
3a70: 52 45 53 53 5f 4f 50 20 32 0a 23 64 65 66 69 6e RESS_OP 2.#defin
3a80: 65 20 52 45 50 4c 41 43 45 5f 4f 50 20 33 0a 0a e REPLACE_OP 3..
3a90: 2f 2a 20 6d 61 63 72 6f 73 20 74 6f 20 65 78 74 /* macros to ext
3aa0: 72 61 63 74 20 6c 69 74 74 6c 65 2d 65 6e 64 69 ract little-endi
3ab0: 61 6e 20 69 6e 74 65 67 65 72 73 20 66 72 6f 6d an integers from
3ac0: 20 61 6e 20 75 6e 73 69 67 6e 65 64 20 62 79 74 an unsigned byt
3ad0: 65 20 62 75 66 66 65 72 20 2a 2f 0a 23 64 65 66 e buffer */.#def
3ae0: 69 6e 65 20 50 55 4c 4c 32 28 70 29 20 28 28 70 ine PULL2(p) ((p
3af0: 29 5b 30 5d 2b 28 28 75 69 6e 74 29 28 28 70 29 )[0]+((uint)((p)
3b00: 5b 31 5d 29 3c 3c 38 29 29 0a 23 64 65 66 69 6e [1])<<8)).#defin
3b10: 65 20 50 55 4c 4c 34 28 70 29 20 28 50 55 4c 4c e PULL4(p) (PULL
3b20: 32 28 70 29 2b 28 28 75 6c 6f 6e 67 29 50 55 4c 2(p)+((ulong)PUL
3b30: 4c 32 28 70 2b 32 29 3c 3c 31 36 29 29 0a 23 64 L2(p+2)<<16)).#d
3b40: 65 66 69 6e 65 20 50 55 4c 4c 38 28 70 29 20 28 efine PULL8(p) (
3b50: 50 55 4c 4c 34 28 70 29 2b 28 28 6f 66 66 5f 74 PULL4(p)+((off_t
3b60: 29 50 55 4c 4c 34 28 70 2b 34 29 3c 3c 33 32 29 )PULL4(p+4)<<32)
3b70: 29 0a 0a 2f 2a 20 6d 61 63 72 6f 73 20 74 6f 20 )../* macros to
3b80: 73 74 6f 72 65 20 69 6e 74 65 67 65 72 73 20 69 store integers i
3b90: 6e 74 6f 20 61 20 62 79 74 65 20 62 75 66 66 65 nto a byte buffe
3ba0: 72 20 69 6e 20 6c 69 74 74 6c 65 2d 65 6e 64 69 r in little-endi
3bb0: 61 6e 20 6f 72 64 65 72 20 2a 2f 0a 23 64 65 66 an order */.#def
3bc0: 69 6e 65 20 50 55 54 32 28 70 2c 61 29 20 64 6f ine PUT2(p,a) do
3bd0: 20 7b 28 70 29 5b 30 5d 3d 61 3b 28 70 29 5b 31 {(p)[0]=a;(p)[1
3be0: 5d 3d 28 61 29 3e 3e 38 3b 7d 20 77 68 69 6c 65 ]=(a)>>8;} while
3bf0: 28 30 29 0a 23 64 65 66 69 6e 65 20 50 55 54 34 (0).#define PUT4
3c00: 28 70 2c 61 29 20 64 6f 20 7b 50 55 54 32 28 70 (p,a) do {PUT2(p
3c10: 2c 61 29 3b 50 55 54 32 28 70 2b 32 2c 61 3e 3e ,a);PUT2(p+2,a>>
3c20: 31 36 29 3b 7d 20 77 68 69 6c 65 28 30 29 0a 23 16);} while(0).#
3c30: 64 65 66 69 6e 65 20 50 55 54 38 28 70 2c 61 29 define PUT8(p,a)
3c40: 20 64 6f 20 7b 50 55 54 34 28 70 2c 61 29 3b 50 do {PUT4(p,a);P
3c50: 55 54 34 28 70 2b 34 2c 61 3e 3e 33 32 29 3b 7d UT4(p+4,a>>32);}
3c60: 20 77 68 69 6c 65 28 30 29 0a 0a 2f 2a 20 69 6e while(0)../* in
3c70: 74 65 72 6e 61 6c 20 73 74 72 75 63 74 75 72 65 ternal structure
3c80: 20 66 6f 72 20 6c 6f 67 20 69 6e 66 6f 72 6d 61 for log informa
3c90: 74 69 6f 6e 20 2a 2f 0a 23 64 65 66 69 6e 65 20 tion */.#define
3ca0: 4c 4f 47 49 44 20 22 5c 31 30 36 5c 30 33 35 5c LOGID "\106\035\
3cb0: 31 37 32 22 20 20 20 20 2f 2a 20 73 68 6f 75 6c 172" /* shoul
3cc0: 64 20 62 65 20 74 68 72 65 65 20 6e 6f 6e 2d 7a d be three non-z
3cd0: 65 72 6f 20 63 68 61 72 61 63 74 65 72 73 20 2a ero characters *
3ce0: 2f 0a 73 74 72 75 63 74 20 6c 6f 67 20 7b 0a 20 /.struct log {.
3cf0: 20 20 20 63 68 61 72 20 69 64 5b 34 5d 3b 20 20 char id[4];
3d00: 20 20 20 2f 2a 20 63 6f 6e 74 61 69 6e 73 20 4c /* contains L
3d10: 4f 47 49 44 20 74 6f 20 64 65 74 65 63 74 20 69 OGID to detect i
3d20: 6e 61 64 76 65 72 74 65 6e 74 20 6f 76 65 72 77 nadvertent overw
3d30: 72 69 74 65 73 20 2a 2f 0a 20 20 20 20 69 6e 74 rites */. int
3d40: 20 66 64 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 fd; /*
3d50: 66 69 6c 65 20 64 65 73 63 72 69 70 74 6f 72 20 file descriptor
3d60: 66 6f 72 20 2e 67 7a 20 66 69 6c 65 2c 20 6f 70 for .gz file, op
3d70: 65 6e 65 64 20 72 65 61 64 2f 77 72 69 74 65 20 ened read/write
3d80: 2a 2f 0a 20 20 20 20 63 68 61 72 20 2a 70 61 74 */. char *pat
3d90: 68 3b 20 20 20 20 20 2f 2a 20 61 6c 6c 6f 63 61 h; /* alloca
3da0: 74 65 64 20 70 61 74 68 2c 20 65 2e 67 2e 20 22 ted path, e.g. "
3db0: 2f 76 61 72 2f 6c 6f 67 2f 66 6f 6f 22 20 6f 72 /var/log/foo" or
3dc0: 20 22 66 6f 6f 22 20 2a 2f 0a 20 20 20 20 63 68 "foo" */. ch
3dd0: 61 72 20 2a 65 6e 64 3b 20 20 20 20 20 20 2f 2a ar *end; /*
3de0: 20 65 6e 64 20 6f 66 20 70 61 74 68 2c 20 66 6f end of path, fo
3df0: 72 20 61 70 70 65 6e 64 69 6e 67 20 73 75 66 66 r appending suff
3e00: 69 63 65 73 20 73 75 63 68 20 61 73 20 22 2e 67 ices such as ".g
3e10: 7a 22 20 2a 2f 0a 20 20 20 20 6f 66 66 5f 74 20 z" */. off_t
3e20: 66 69 72 73 74 3b 20 20 20 20 2f 2a 20 6f 66 66 first; /* off
3e30: 73 65 74 20 6f 66 20 66 69 72 73 74 20 73 74 6f set of first sto
3e40: 72 65 64 20 62 6c 6f 63 6b 20 66 69 72 73 74 20 red block first
3e50: 6c 65 6e 67 74 68 20 62 79 74 65 20 2a 2f 0a 20 length byte */.
3e60: 20 20 20 69 6e 74 20 62 61 63 6b 3b 20 20 20 20 int back;
3e70: 20 20 20 2f 2a 20 6c 6f 63 61 74 69 6f 6e 20 6f /* location o
3e80: 66 20 66 69 72 73 74 20 62 6c 6f 63 6b 20 69 64 f first block id
3e90: 20 69 6e 20 62 69 74 73 20 62 61 63 6b 20 66 72 in bits back fr
3ea0: 6f 6d 20 66 69 72 73 74 20 2a 2f 0a 20 20 20 20 om first */.
3eb0: 75 69 6e 74 20 73 74 6f 72 65 64 3b 20 20 20 20 uint stored;
3ec0: 2f 2a 20 62 79 74 65 73 20 63 75 72 72 65 6e 74 /* bytes current
3ed0: 6c 79 20 69 6e 20 6c 61 73 74 20 73 74 6f 72 65 ly in last store
3ee0: 64 20 62 6c 6f 63 6b 20 2a 2f 0a 20 20 20 20 6f d block */. o
3ef0: 66 66 5f 74 20 6c 61 73 74 3b 20 20 20 20 20 2f ff_t last; /
3f00: 2a 20 6f 66 66 73 65 74 20 6f 66 20 6c 61 73 74 * offset of last
3f10: 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 66 69 stored block fi
3f20: 72 73 74 20 6c 65 6e 67 74 68 20 62 79 74 65 20 rst length byte
3f30: 2a 2f 0a 20 20 20 20 75 6c 6f 6e 67 20 63 63 72 */. ulong ccr
3f40: 63 3b 20 20 20 20 20 2f 2a 20 63 72 63 20 6f 66 c; /* crc of
3f50: 20 63 6f 6d 70 72 65 73 73 65 64 20 64 61 74 61 compressed data
3f60: 20 2a 2f 0a 20 20 20 20 75 6c 6f 6e 67 20 63 6c */. ulong cl
3f70: 65 6e 3b 20 20 20 20 20 2f 2a 20 6c 65 6e 67 74 en; /* lengt
3f80: 68 20 28 6d 6f 64 75 6c 6f 20 32 5e 33 32 29 20 h (modulo 2^32)
3f90: 6f 66 20 63 6f 6d 70 72 65 73 73 65 64 20 64 61 of compressed da
3fa0: 74 61 20 2a 2f 0a 20 20 20 20 75 6c 6f 6e 67 20 ta */. ulong
3fb0: 74 63 72 63 3b 20 20 20 20 20 2f 2a 20 63 72 63 tcrc; /* crc
3fc0: 20 6f 66 20 74 6f 74 61 6c 20 64 61 74 61 20 2a of total data *
3fd0: 2f 0a 20 20 20 20 75 6c 6f 6e 67 20 74 6c 65 6e /. ulong tlen
3fe0: 3b 20 20 20 20 20 2f 2a 20 6c 65 6e 67 74 68 20 ; /* length
3ff0: 28 6d 6f 64 75 6c 6f 20 32 5e 33 32 29 20 6f 66 (modulo 2^32) of
4000: 20 74 6f 74 61 6c 20 64 61 74 61 20 2a 2f 0a 20 total data */.
4010: 20 20 20 74 69 6d 65 5f 74 20 6c 6f 63 6b 3b 20 time_t lock;
4020: 20 20 20 2f 2a 20 6c 61 73 74 20 6d 6f 64 69 66 /* last modif
4030: 79 20 74 69 6d 65 20 6f 66 20 6f 75 72 20 6c 6f y time of our lo
4040: 63 6b 20 66 69 6c 65 20 2a 2f 0a 7d 3b 0a 0a 2f ck file */.};../
4050: 2a 20 67 7a 69 70 20 68 65 61 64 65 72 20 66 6f * gzip header fo
4060: 72 20 67 7a 6c 6f 67 20 2a 2f 0a 6c 6f 63 61 6c r gzlog */.local
4070: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 6c unsigned char l
4080: 6f 67 5f 67 7a 68 65 61 64 5b 5d 20 3d 20 7b 0a og_gzhead[] = {.
4090: 20 20 20 20 30 78 31 66 2c 20 30 78 38 62 2c 20 0x1f, 0x8b,
40a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
40b0: 2f 2a 20 6d 61 67 69 63 20 67 7a 69 70 20 69 64 /* magic gzip id
40c0: 20 2a 2f 0a 20 20 20 20 38 2c 20 20 20 20 20 20 */. 8,
40d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
40e0: 20 20 20 20 2f 2a 20 63 6f 6d 70 72 65 73 73 69 /* compressi
40f0: 6f 6e 20 6d 65 74 68 6f 64 20 69 73 20 64 65 66 on method is def
4100: 6c 61 74 65 20 2a 2f 0a 20 20 20 20 34 2c 20 20 late */. 4,
4110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4120: 20 20 20 20 20 20 20 20 2f 2a 20 74 68 65 72 65 /* there
4130: 20 69 73 20 61 6e 20 65 78 74 72 61 20 66 69 65 is an extra fie
4140: 6c 64 20 28 6e 6f 20 66 69 6c 65 20 6e 61 6d 65 ld (no file name
4150: 29 20 2a 2f 0a 20 20 20 20 30 2c 20 30 2c 20 30 ) */. 0, 0, 0
4160: 2c 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 , 0,
4170: 20 20 20 20 20 2f 2a 20 6e 6f 20 6d 6f 64 69 66 /* no modif
4180: 69 63 61 74 69 6f 6e 20 74 69 6d 65 20 70 72 6f ication time pro
4190: 76 69 64 65 64 20 2a 2f 0a 20 20 20 20 30 2c 20 vided */. 0,
41a0: 30 78 66 66 2c 20 20 20 20 20 20 20 20 20 20 20 0xff,
41b0: 20 20 20 20 20 20 20 20 20 2f 2a 20 6e 6f 20 65 /* no e
41c0: 78 74 72 61 20 66 6c 61 67 73 2c 20 6e 6f 20 4f xtra flags, no O
41d0: 53 20 73 70 65 63 69 66 69 65 64 20 2a 2f 0a 20 S specified */.
41e0: 20 20 20 33 39 2c 20 30 2c 20 27 61 27 2c 20 27 39, 0, 'a', '
41f0: 70 27 2c 20 33 35 2c 20 30 20 20 20 20 20 20 2f p', 35, 0 /
4200: 2a 20 65 78 74 72 61 20 66 69 65 6c 64 20 77 69 * extra field wi
4210: 74 68 20 22 61 70 22 20 73 75 62 66 69 65 6c 64 th "ap" subfield
4220: 20 2a 2f 0a 20 20 20 20 20 20 20 20 20 20 20 20 */.
4230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4240: 20 20 20 20 2f 2a 20 33 35 20 69 73 20 45 58 54 /* 35 is EXT
4250: 52 41 2c 20 33 39 20 69 73 20 45 58 54 52 41 20 RA, 39 is EXTRA
4260: 2b 20 34 20 2a 2f 0a 7d 3b 0a 0a 23 64 65 66 69 + 4 */.};..#defi
4270: 6e 65 20 48 45 41 44 20 73 69 7a 65 6f 66 28 6c ne HEAD sizeof(l
4280: 6f 67 5f 67 7a 68 65 61 64 29 20 20 20 20 20 2f og_gzhead) /
4290: 2a 20 73 68 6f 75 6c 64 20 62 65 20 31 36 20 2a * should be 16 *
42a0: 2f 0a 0a 2f 2a 20 69 6e 69 74 69 61 6c 20 67 7a /../* initial gz
42b0: 69 70 20 65 78 74 72 61 20 66 69 65 6c 64 20 63 ip extra field c
42c0: 6f 6e 74 65 6e 74 20 28 35 32 20 3d 3d 20 48 45 ontent (52 == HE
42d0: 41 44 20 2b 20 45 58 54 52 41 20 2b 20 31 29 20 AD + EXTRA + 1)
42e0: 2a 2f 0a 6c 6f 63 61 6c 20 75 6e 73 69 67 6e 65 */.local unsigne
42f0: 64 20 63 68 61 72 20 6c 6f 67 5f 67 7a 65 78 74 d char log_gzext
4300: 5b 5d 20 3d 20 7b 0a 20 20 20 20 35 32 2c 20 30 [] = {. 52, 0
4310: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c , 0, 0, 0, 0, 0,
4320: 20 30 2c 20 20 20 20 2f 2a 20 6f 66 66 73 65 74 0, /* offset
4330: 20 6f 66 20 66 69 72 73 74 20 73 74 6f 72 65 64 of first stored
4340: 20 62 6c 6f 63 6b 20 6c 65 6e 67 74 68 20 2a 2f block length */
4350: 0a 20 20 20 20 35 32 2c 20 30 2c 20 30 2c 20 30 . 52, 0, 0, 0
4360: 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 , 0, 0, 0, 0,
4370: 20 2f 2a 20 6f 66 66 73 65 74 20 6f 66 20 6c 61 /* offset of la
4380: 73 74 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 st stored block
4390: 6c 65 6e 67 74 68 20 2a 2f 0a 20 20 20 20 30 2c length */. 0,
43a0: 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 0, 0, 0, 0, 0,
43b0: 30 2c 20 30 2c 20 20 20 20 20 2f 2a 20 63 6f 6d 0, 0, /* com
43c0: 70 72 65 73 73 65 64 20 64 61 74 61 20 63 72 63 pressed data crc
43d0: 20 61 6e 64 20 6c 65 6e 67 74 68 20 2a 2f 0a 20 and length */.
43e0: 20 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c 20 30 0, 0, 0, 0, 0
43f0: 2c 20 30 2c 20 30 2c 20 30 2c 20 20 20 20 20 2f , 0, 0, 0, /
4400: 2a 20 74 6f 74 61 6c 20 64 61 74 61 20 63 72 63 * total data crc
4410: 20 61 6e 64 20 6c 65 6e 67 74 68 20 2a 2f 0a 20 and length */.
4420: 20 20 20 30 2c 20 30 2c 20 20 20 20 20 20 20 20 0, 0,
4430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
4440: 2a 20 66 69 6e 61 6c 20 73 74 6f 72 65 64 20 62 * final stored b
4450: 6c 6f 63 6b 20 64 61 74 61 20 6c 65 6e 67 74 68 lock data length
4460: 20 2a 2f 0a 20 20 20 20 35 20 20 20 20 20 20 20 */. 5
4470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4480: 20 20 20 20 2f 2a 20 6f 70 20 69 73 20 4e 4f 5f /* op is NO_
4490: 4f 50 2c 20 6c 61 73 74 20 62 69 74 20 38 20 62 OP, last bit 8 b
44a0: 69 74 73 20 62 61 63 6b 20 2a 2f 0a 7d 3b 0a 0a its back */.};..
44b0: 23 64 65 66 69 6e 65 20 45 58 54 52 41 20 73 69 #define EXTRA si
44c0: 7a 65 6f 66 28 6c 6f 67 5f 67 7a 65 78 74 29 20 zeof(log_gzext)
44d0: 20 20 20 20 2f 2a 20 73 68 6f 75 6c 64 20 62 65 /* should be
44e0: 20 33 35 20 2a 2f 0a 0a 2f 2a 20 69 6e 69 74 69 35 */../* initi
44f0: 61 6c 20 67 7a 69 70 20 64 61 74 61 20 61 6e 64 al gzip data and
4500: 20 74 72 61 69 6c 65 72 20 2a 2f 0a 6c 6f 63 61 trailer */.loca
4510: 6c 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 l unsigned char
4520: 6c 6f 67 5f 67 7a 62 6f 64 79 5b 5d 20 3d 20 7b log_gzbody[] = {
4530: 0a 20 20 20 20 31 2c 20 30 2c 20 30 2c 20 30 78 . 1, 0, 0, 0x
4540: 66 66 2c 20 30 78 66 66 2c 20 20 20 20 20 20 20 ff, 0xff,
4550: 20 2f 2a 20 65 6d 70 74 79 20 73 74 6f 72 65 64 /* empty stored
4560: 20 62 6c 6f 63 6b 20 28 6c 61 73 74 29 20 2a 2f block (last) */
4570: 0a 20 20 20 20 30 2c 20 30 2c 20 30 2c 20 30 2c . 0, 0, 0, 0,
4580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4590: 20 2f 2a 20 63 72 63 20 2a 2f 0a 20 20 20 20 30 /* crc */. 0
45a0: 2c 20 30 2c 20 30 2c 20 30 20 20 20 20 20 20 20 , 0, 0, 0
45b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 75 6e /* un
45c0: 63 6f 6d 70 72 65 73 73 65 64 20 6c 65 6e 67 74 compressed lengt
45d0: 68 20 2a 2f 0a 7d 3b 0a 0a 23 64 65 66 69 6e 65 h */.};..#define
45e0: 20 42 4f 44 59 20 73 69 7a 65 6f 66 28 6c 6f 67 BODY sizeof(log
45f0: 5f 67 7a 62 6f 64 79 29 0a 0a 2f 2a 20 45 78 63 _gzbody)../* Exc
4600: 6c 75 73 69 76 65 6c 79 20 63 72 65 61 74 65 20 lusively create
4610: 66 6f 6f 2e 6c 6f 63 6b 20 69 6e 20 6f 72 64 65 foo.lock in orde
4620: 72 20 74 6f 20 6e 65 67 6f 74 69 61 74 65 20 65 r to negotiate e
4630: 78 63 6c 75 73 69 76 65 20 61 63 63 65 73 73 20 xclusive access
4640: 74 6f 20 74 68 65 0a 20 20 20 66 6f 6f 2e 2a 20 to the. foo.*
4650: 66 69 6c 65 73 2e 20 20 49 66 20 74 68 65 20 6d files. If the m
4660: 6f 64 69 66 79 20 74 69 6d 65 20 6f 66 20 61 6e odify time of an
4670: 20 65 78 69 73 74 69 6e 67 20 6c 6f 63 6b 20 66 existing lock f
4680: 69 6c 65 20 69 73 20 67 72 65 61 74 65 72 20 74 ile is greater t
4690: 68 61 6e 0a 20 20 20 50 41 54 49 45 4e 43 45 20 han. PATIENCE
46a0: 73 65 63 6f 6e 64 73 20 69 6e 20 74 68 65 20 70 seconds in the p
46b0: 61 73 74 2c 20 74 68 65 6e 20 63 6f 6e 73 69 64 ast, then consid
46c0: 65 72 20 74 68 65 20 6c 6f 63 6b 20 66 69 6c 65 er the lock file
46d0: 20 74 6f 20 68 61 76 65 20 62 65 65 6e 0a 20 20 to have been.
46e0: 20 61 62 61 6e 64 6f 6e 65 64 2c 20 64 65 6c 65 abandoned, dele
46f0: 74 65 20 69 74 2c 20 61 6e 64 20 74 72 79 20 74 te it, and try t
4700: 68 65 20 65 78 63 6c 75 73 69 76 65 20 63 72 65 he exclusive cre
4710: 61 74 65 20 61 67 61 69 6e 2e 20 20 53 61 76 65 ate again. Save
4720: 20 74 68 65 20 6c 6f 63 6b 0a 20 20 20 66 69 6c the lock. fil
4730: 65 20 6d 6f 64 69 66 79 20 74 69 6d 65 20 66 6f e modify time fo
4740: 72 20 76 65 72 69 66 69 63 61 74 69 6f 6e 20 6f r verification o
4750: 66 20 6f 77 6e 65 72 73 68 69 70 2e 20 20 52 65 f ownership. Re
4760: 74 75 72 6e 20 30 20 6f 6e 20 73 75 63 63 65 73 turn 0 on succes
4770: 73 2c 20 6f 72 20 2d 31 0a 20 20 20 6f 6e 20 66 s, or -1. on f
4780: 61 69 6c 75 72 65 2c 20 75 73 75 61 6c 6c 79 20 ailure, usually
4790: 64 75 65 20 74 6f 20 61 6e 20 61 63 63 65 73 73 due to an access
47a0: 20 72 65 73 74 72 69 63 74 69 6f 6e 20 6f 72 20 restriction or
47b0: 69 6e 76 61 6c 69 64 20 70 61 74 68 2e 20 20 4e invalid path. N
47c0: 6f 74 65 20 74 68 61 74 0a 20 20 20 69 66 20 73 ote that. if s
47d0: 74 61 74 28 29 20 6f 72 20 75 6e 6c 69 6e 6b 28 tat() or unlink(
47e0: 29 20 66 61 69 6c 73 2c 20 69 74 20 6d 61 79 20 ) fails, it may
47f0: 62 65 20 64 75 65 20 74 6f 20 61 6e 6f 74 68 65 be due to anothe
4800: 72 20 70 72 6f 63 65 73 73 20 6e 6f 74 69 63 69 r process notici
4810: 6e 67 20 74 68 65 0a 20 20 20 61 62 61 6e 64 6f ng the. abando
4820: 6e 65 64 20 6c 6f 63 6b 20 66 69 6c 65 20 61 20 ned lock file a
4830: 73 6d 69 64 67 65 20 73 6f 6f 6e 65 72 20 61 6e smidge sooner an
4840: 64 20 64 65 6c 65 74 69 6e 67 20 69 74 2c 20 73 d deleting it, s
4850: 6f 20 74 68 6f 73 65 20 61 72 65 20 6e 6f 74 0a o those are not.
4860: 20 20 20 66 6c 61 67 67 65 64 20 61 73 20 61 6e flagged as an
4870: 20 65 72 72 6f 72 2e 20 2a 2f 0a 6c 6f 63 61 6c error. */.local
4880: 20 69 6e 74 20 6c 6f 67 5f 6c 6f 63 6b 28 73 74 int log_lock(st
4890: 72 75 63 74 20 6c 6f 67 20 2a 6c 6f 67 29 0a 7b ruct log *log).{
48a0: 0a 20 20 20 20 69 6e 74 20 66 64 3b 0a 20 20 20 . int fd;.
48b0: 20 73 74 72 75 63 74 20 73 74 61 74 20 73 74 3b struct stat st;
48c0: 0a 0a 20 20 20 20 73 74 72 63 70 79 28 6c 6f 67 .. strcpy(log
48d0: 2d 3e 65 6e 64 2c 20 22 2e 6c 6f 63 6b 22 29 3b ->end, ".lock");
48e0: 0a 20 20 20 20 77 68 69 6c 65 20 28 28 66 64 20 . while ((fd
48f0: 3d 20 6f 70 65 6e 28 6c 6f 67 2d 3e 70 61 74 68 = open(log->path
4900: 2c 20 4f 5f 43 52 45 41 54 20 7c 20 4f 5f 45 58 , O_CREAT | O_EX
4910: 43 4c 2c 20 30 36 34 34 29 29 20 3c 20 30 29 20 CL, 0644)) < 0)
4920: 7b 0a 20 20 20 20 20 20 20 20 69 66 20 28 65 72 {. if (er
4930: 72 6e 6f 20 21 3d 20 45 45 58 49 53 54 29 0a 20 rno != EEXIST).
4940: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 retur
4950: 6e 20 2d 31 3b 0a 20 20 20 20 20 20 20 20 69 66 n -1;. if
4960: 20 28 73 74 61 74 28 6c 6f 67 2d 3e 70 61 74 68 (stat(log->path
4970: 2c 20 26 73 74 29 20 3d 3d 20 30 20 26 26 20 74 , &st) == 0 && t
4980: 69 6d 65 28 4e 55 4c 4c 29 20 2d 20 73 74 2e 73 ime(NULL) - st.s
4990: 74 5f 6d 74 69 6d 65 20 3e 20 50 41 54 49 45 4e t_mtime > PATIEN
49a0: 43 45 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 CE) {.
49b0: 20 20 75 6e 6c 69 6e 6b 28 6c 6f 67 2d 3e 70 61 unlink(log->pa
49c0: 74 68 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 th);.
49d0: 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 continue;.
49e0: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 73 6c 65 }. sle
49f0: 65 70 28 32 29 3b 20 20 20 20 20 20 20 2f 2a 20 ep(2); /*
4a00: 72 65 6c 69 6e 71 75 69 73 68 20 74 68 65 20 43 relinquish the C
4a10: 50 55 20 66 6f 72 20 74 77 6f 20 73 65 63 6f 6e PU for two secon
4a20: 64 73 20 77 68 69 6c 65 20 77 61 69 74 69 6e 67 ds while waiting
4a30: 20 2a 2f 0a 20 20 20 20 7d 0a 20 20 20 20 63 6c */. }. cl
4a40: 6f 73 65 28 66 64 29 3b 0a 20 20 20 20 69 66 20 ose(fd);. if
4a50: 28 73 74 61 74 28 6c 6f 67 2d 3e 70 61 74 68 2c (stat(log->path,
4a60: 20 26 73 74 29 20 3d 3d 20 30 29 0a 20 20 20 20 &st) == 0).
4a70: 20 20 20 20 6c 6f 67 2d 3e 6c 6f 63 6b 20 3d 20 log->lock =
4a80: 73 74 2e 73 74 5f 6d 74 69 6d 65 3b 0a 20 20 20 st.st_mtime;.
4a90: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a return 0;.}../*
4aa0: 20 55 70 64 61 74 65 20 74 68 65 20 6d 6f 64 69 Update the modi
4ab0: 66 79 20 74 69 6d 65 20 6f 66 20 74 68 65 20 6c fy time of the l
4ac0: 6f 63 6b 20 66 69 6c 65 20 74 6f 20 6e 6f 77 2c ock file to now,
4ad0: 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 70 72 65 in order to pre
4ae0: 76 65 6e 74 20 61 6e 6f 74 68 65 72 0a 20 20 20 vent another.
4af0: 74 61 73 6b 20 66 72 6f 6d 20 74 68 69 6e 6b 69 task from thinki
4b00: 6e 67 20 74 68 61 74 20 74 68 65 20 6c 6f 63 6b ng that the lock
4b10: 20 69 73 20 73 74 61 6c 65 2e 20 20 53 61 76 65 is stale. Save
4b20: 20 74 68 65 20 6c 6f 63 6b 20 66 69 6c 65 20 6d the lock file m
4b30: 6f 64 69 66 79 20 74 69 6d 65 0a 20 20 20 66 6f odify time. fo
4b40: 72 20 76 65 72 69 66 69 63 61 74 69 6f 6e 20 6f r verification o
4b50: 66 20 6f 77 6e 65 72 73 68 69 70 2e 20 2a 2f 0a f ownership. */.
4b60: 6c 6f 63 61 6c 20 76 6f 69 64 20 6c 6f 67 5f 74 local void log_t
4b70: 6f 75 63 68 28 73 74 72 75 63 74 20 6c 6f 67 20 ouch(struct log
4b80: 2a 6c 6f 67 29 0a 7b 0a 20 20 20 20 73 74 72 75 *log).{. stru
4b90: 63 74 20 73 74 61 74 20 73 74 3b 0a 0a 20 20 20 ct stat st;..
4ba0: 20 73 74 72 63 70 79 28 6c 6f 67 2d 3e 65 6e 64 strcpy(log->end
4bb0: 2c 20 22 2e 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 , ".lock");.
4bc0: 75 74 69 6d 65 73 28 6c 6f 67 2d 3e 70 61 74 68 utimes(log->path
4bd0: 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 69 66 20 , NULL);. if
4be0: 28 73 74 61 74 28 6c 6f 67 2d 3e 70 61 74 68 2c (stat(log->path,
4bf0: 20 26 73 74 29 20 3d 3d 20 30 29 0a 20 20 20 20 &st) == 0).
4c00: 20 20 20 20 6c 6f 67 2d 3e 6c 6f 63 6b 20 3d 20 log->lock =
4c10: 73 74 2e 73 74 5f 6d 74 69 6d 65 3b 0a 7d 0a 0a st.st_mtime;.}..
4c20: 2f 2a 20 43 68 65 63 6b 20 74 68 65 20 6c 6f 67 /* Check the log
4c30: 20 66 69 6c 65 20 6d 6f 64 69 66 79 20 74 69 6d file modify tim
4c40: 65 20 61 67 61 69 6e 73 74 20 77 68 61 74 20 69 e against what i
4c50: 73 20 65 78 70 65 63 74 65 64 2e 20 20 52 65 74 s expected. Ret
4c60: 75 72 6e 20 74 72 75 65 20 69 66 0a 20 20 20 74 urn true if. t
4c70: 68 69 73 20 69 73 20 6e 6f 74 20 6f 75 72 20 6c his is not our l
4c80: 6f 63 6b 2e 20 20 49 66 20 69 74 20 69 73 20 6f ock. If it is o
4c90: 75 72 20 6c 6f 63 6b 2c 20 74 6f 75 63 68 20 69 ur lock, touch i
4ca0: 74 20 74 6f 20 6b 65 65 70 20 69 74 2e 20 2a 2f t to keep it. */
4cb0: 0a 6c 6f 63 61 6c 20 69 6e 74 20 6c 6f 67 5f 63 .local int log_c
4cc0: 68 65 63 6b 28 73 74 72 75 63 74 20 6c 6f 67 20 heck(struct log
4cd0: 2a 6c 6f 67 29 0a 7b 0a 20 20 20 20 73 74 72 75 *log).{. stru
4ce0: 63 74 20 73 74 61 74 20 73 74 3b 0a 0a 20 20 20 ct stat st;..
4cf0: 20 73 74 72 63 70 79 28 6c 6f 67 2d 3e 65 6e 64 strcpy(log->end
4d00: 2c 20 22 2e 6c 6f 63 6b 22 29 3b 0a 20 20 20 20 , ".lock");.
4d10: 69 66 20 28 73 74 61 74 28 6c 6f 67 2d 3e 70 61 if (stat(log->pa
4d20: 74 68 2c 20 26 73 74 29 20 7c 7c 20 73 74 2e 73 th, &st) || st.s
4d30: 74 5f 6d 74 69 6d 65 20 21 3d 20 6c 6f 67 2d 3e t_mtime != log->
4d40: 6c 6f 63 6b 29 0a 20 20 20 20 20 20 20 20 72 65 lock). re
4d50: 74 75 72 6e 20 31 3b 0a 20 20 20 20 6c 6f 67 5f turn 1;. log_
4d60: 74 6f 75 63 68 28 6c 6f 67 29 3b 0a 20 20 20 20 touch(log);.
4d70: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 return 0;.}../*
4d80: 55 6e 6c 6f 63 6b 20 61 20 70 72 65 76 69 6f 75 Unlock a previou
4d90: 73 6c 79 20 61 63 71 75 69 72 65 64 20 6c 6f 63 sly acquired loc
4da0: 6b 2c 20 62 75 74 20 6f 6e 6c 79 20 69 66 20 69 k, but only if i
4db0: 74 27 73 20 6f 75 72 73 2e 20 2a 2f 0a 6c 6f 63 t's ours. */.loc
4dc0: 61 6c 20 76 6f 69 64 20 6c 6f 67 5f 75 6e 6c 6f al void log_unlo
4dd0: 63 6b 28 73 74 72 75 63 74 20 6c 6f 67 20 2a 6c ck(struct log *l
4de0: 6f 67 29 0a 7b 0a 20 20 20 20 69 66 20 28 6c 6f og).{. if (lo
4df0: 67 5f 63 68 65 63 6b 28 6c 6f 67 29 29 0a 20 20 g_check(log)).
4e00: 20 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 return;.
4e10: 20 20 73 74 72 63 70 79 28 6c 6f 67 2d 3e 65 6e strcpy(log->en
4e20: 64 2c 20 22 2e 6c 6f 63 6b 22 29 3b 0a 20 20 20 d, ".lock");.
4e30: 20 75 6e 6c 69 6e 6b 28 6c 6f 67 2d 3e 70 61 74 unlink(log->pat
4e40: 68 29 3b 0a 20 20 20 20 6c 6f 67 2d 3e 6c 6f 63 h);. log->loc
4e50: 6b 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 20 43 68 65 k = 0;.}../* Che
4e60: 63 6b 20 74 68 65 20 67 7a 69 70 20 68 65 61 64 ck the gzip head
4e70: 65 72 20 61 6e 64 20 72 65 61 64 20 69 6e 20 74 er and read in t
4e80: 68 65 20 65 78 74 72 61 20 66 69 65 6c 64 2c 20 he extra field,
4e90: 66 69 6c 6c 69 6e 67 20 69 6e 20 74 68 65 20 76 filling in the v
4ea0: 61 6c 75 65 73 20 69 6e 0a 20 20 20 74 68 65 20 alues in. the
4eb0: 6c 6f 67 20 73 74 72 75 63 74 75 72 65 2e 20 20 log structure.
4ec0: 52 65 74 75 72 6e 20 6f 70 20 6f 6e 20 73 75 63 Return op on suc
4ed0: 63 65 73 73 20 6f 72 20 2d 31 20 69 66 20 74 68 cess or -1 if th
4ee0: 65 20 67 7a 69 70 20 68 65 61 64 65 72 20 77 61 e gzip header wa
4ef0: 73 20 6e 6f 74 20 61 73 0a 20 20 20 65 78 70 65 s not as. expe
4f00: 63 74 65 64 2e 20 20 6f 70 20 69 73 20 74 68 65 cted. op is the
4f10: 20 63 75 72 72 65 6e 74 20 6f 70 65 72 61 74 69 current operati
4f20: 6f 6e 20 69 6e 20 70 72 6f 67 72 65 73 73 20 6c on in progress l
4f30: 61 73 74 20 77 72 69 74 74 65 6e 20 74 6f 20 74 ast written to t
4f40: 68 65 20 65 78 74 72 61 0a 20 20 20 66 69 65 6c he extra. fiel
4f50: 64 2e 20 20 54 68 69 73 20 61 73 73 75 6d 65 73 d. This assumes
4f60: 20 74 68 61 74 20 74 68 65 20 67 7a 69 70 20 66 that the gzip f
4f70: 69 6c 65 20 68 61 73 20 61 6c 72 65 61 64 79 20 ile has already
4f80: 62 65 65 6e 20 6f 70 65 6e 65 64 2c 20 77 69 74 been opened, wit
4f90: 68 20 74 68 65 0a 20 20 20 66 69 6c 65 20 64 65 h the. file de
4fa0: 73 63 72 69 70 74 6f 72 20 6c 6f 67 2d 3e 66 64 scriptor log->fd
4fb0: 2e 20 2a 2f 0a 6c 6f 63 61 6c 20 69 6e 74 20 6c . */.local int l
4fc0: 6f 67 5f 68 65 61 64 28 73 74 72 75 63 74 20 6c og_head(struct l
4fd0: 6f 67 20 2a 6c 6f 67 29 0a 7b 0a 20 20 20 20 69 og *log).{. i
4fe0: 6e 74 20 6f 70 3b 0a 20 20 20 20 75 6e 73 69 67 nt op;. unsig
4ff0: 6e 65 64 20 63 68 61 72 20 62 75 66 5b 48 45 41 ned char buf[HEA
5000: 44 20 2b 20 45 58 54 52 41 5d 3b 0a 0a 20 20 20 D + EXTRA];..
5010: 20 69 66 20 28 6c 73 65 65 6b 28 6c 6f 67 2d 3e if (lseek(log->
5020: 66 64 2c 20 30 2c 20 53 45 45 4b 5f 53 45 54 29 fd, 0, SEEK_SET)
5030: 20 3c 20 30 20 7c 7c 0a 20 20 20 20 20 20 20 20 < 0 ||.
5040: 72 65 61 64 28 6c 6f 67 2d 3e 66 64 2c 20 62 75 read(log->fd, bu
5050: 66 2c 20 48 45 41 44 20 2b 20 45 58 54 52 41 29 f, HEAD + EXTRA)
5060: 20 21 3d 20 48 45 41 44 20 2b 20 45 58 54 52 41 != HEAD + EXTRA
5070: 20 7c 7c 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 ||. memc
5080: 6d 70 28 62 75 66 2c 20 6c 6f 67 5f 67 7a 68 65 mp(buf, log_gzhe
5090: 61 64 2c 20 48 45 41 44 29 29 20 7b 0a 20 20 20 ad, HEAD)) {.
50a0: 20 20 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a return -1;.
50b0: 20 20 20 20 7d 0a 20 20 20 20 6c 6f 67 2d 3e 66 }. log->f
50c0: 69 72 73 74 20 3d 20 50 55 4c 4c 38 28 62 75 66 irst = PULL8(buf
50d0: 20 2b 20 48 45 41 44 29 3b 0a 20 20 20 20 6c 6f + HEAD);. lo
50e0: 67 2d 3e 6c 61 73 74 20 3d 20 50 55 4c 4c 38 28 g->last = PULL8(
50f0: 62 75 66 20 2b 20 48 45 41 44 20 2b 20 38 29 3b buf + HEAD + 8);
5100: 0a 20 20 20 20 6c 6f 67 2d 3e 63 63 72 63 20 3d . log->ccrc =
5110: 20 50 55 4c 4c 34 28 62 75 66 20 2b 20 48 45 41 PULL4(buf + HEA
5120: 44 20 2b 20 31 36 29 3b 0a 20 20 20 20 6c 6f 67 D + 16);. log
5130: 2d 3e 63 6c 65 6e 20 3d 20 50 55 4c 4c 34 28 62 ->clen = PULL4(b
5140: 75 66 20 2b 20 48 45 41 44 20 2b 20 32 30 29 3b uf + HEAD + 20);
5150: 0a 20 20 20 20 6c 6f 67 2d 3e 74 63 72 63 20 3d . log->tcrc =
5160: 20 50 55 4c 4c 34 28 62 75 66 20 2b 20 48 45 41 PULL4(buf + HEA
5170: 44 20 2b 20 32 34 29 3b 0a 20 20 20 20 6c 6f 67 D + 24);. log
5180: 2d 3e 74 6c 65 6e 20 3d 20 50 55 4c 4c 34 28 62 ->tlen = PULL4(b
5190: 75 66 20 2b 20 48 45 41 44 20 2b 20 32 38 29 3b uf + HEAD + 28);
51a0: 0a 20 20 20 20 6c 6f 67 2d 3e 73 74 6f 72 65 64 . log->stored
51b0: 20 3d 20 50 55 4c 4c 32 28 62 75 66 20 2b 20 48 = PULL2(buf + H
51c0: 45 41 44 20 2b 20 33 32 29 3b 0a 20 20 20 20 6c EAD + 32);. l
51d0: 6f 67 2d 3e 62 61 63 6b 20 3d 20 33 20 2b 20 28 og->back = 3 + (
51e0: 62 75 66 5b 48 45 41 44 20 2b 20 33 34 5d 20 26 buf[HEAD + 34] &
51f0: 20 37 29 3b 0a 20 20 20 20 6f 70 20 3d 20 28 62 7);. op = (b
5200: 75 66 5b 48 45 41 44 20 2b 20 33 34 5d 20 3e 3e uf[HEAD + 34] >>
5210: 20 33 29 20 26 20 33 3b 0a 20 20 20 20 72 65 74 3) & 3;. ret
5220: 75 72 6e 20 6f 70 3b 0a 7d 0a 0a 2f 2a 20 57 72 urn op;.}../* Wr
5230: 69 74 65 20 6f 76 65 72 20 74 68 65 20 65 78 74 ite over the ext
5240: 72 61 20 66 69 65 6c 64 20 63 6f 6e 74 65 6e 74 ra field content
5250: 73 2c 20 6d 61 72 6b 69 6e 67 20 74 68 65 20 6f s, marking the o
5260: 70 65 72 61 74 69 6f 6e 20 61 73 20 6f 70 2e 20 peration as op.
5270: 20 55 73 65 20 66 73 79 6e 63 0a 20 20 20 74 6f Use fsync. to
5280: 20 61 73 73 75 72 65 20 74 68 61 74 20 74 68 65 assure that the
5290: 20 64 65 76 69 63 65 20 69 73 20 77 72 69 74 74 device is writt
52a0: 65 6e 20 74 6f 2c 20 61 6e 64 20 69 6e 20 74 68 en to, and in th
52b0: 65 20 72 65 71 75 65 73 74 65 64 20 6f 72 64 65 e requested orde
52c0: 72 2e 20 20 54 68 69 73 0a 20 20 20 6f 70 65 72 r. This. oper
52d0: 61 74 69 6f 6e 2c 20 61 6e 64 20 6f 6e 6c 79 20 ation, and only
52e0: 74 68 69 73 20 6f 70 65 72 61 74 69 6f 6e 2c 20 this operation,
52f0: 69 73 20 61 73 73 75 6d 65 64 20 74 6f 20 62 65 is assumed to be
5300: 20 61 74 6f 6d 69 63 20 69 6e 20 6f 72 64 65 72 atomic in order
5310: 20 74 6f 0a 20 20 20 61 73 73 75 72 65 20 74 68 to. assure th
5320: 61 74 20 74 68 65 20 6c 6f 67 20 69 73 20 72 65 at the log is re
5330: 63 6f 76 65 72 61 62 6c 65 20 69 6e 20 74 68 65 coverable in the
5340: 20 65 76 65 6e 74 20 6f 66 20 61 6e 20 69 6e 74 event of an int
5350: 65 72 72 75 70 74 69 6f 6e 20 61 74 20 61 6e 79 erruption at any
5360: 0a 20 20 20 70 6f 69 6e 74 20 69 6e 20 74 68 65 . point in the
5370: 20 70 72 6f 63 65 73 73 2e 20 20 52 65 74 75 72 process. Retur
5380: 6e 20 2d 31 20 69 66 20 74 68 65 20 77 72 69 74 n -1 if the writ
5390: 65 20 74 6f 20 66 6f 6f 2e 67 7a 20 66 61 69 6c e to foo.gz fail
53a0: 65 64 2e 20 2a 2f 0a 6c 6f 63 61 6c 20 69 6e 74 ed. */.local int
53b0: 20 6c 6f 67 5f 6d 61 72 6b 28 73 74 72 75 63 74 log_mark(struct
53c0: 20 6c 6f 67 20 2a 6c 6f 67 2c 20 69 6e 74 20 6f log *log, int o
53d0: 70 29 0a 7b 0a 20 20 20 20 69 6e 74 20 72 65 74 p).{. int ret
53e0: 3b 0a 20 20 20 20 75 6e 73 69 67 6e 65 64 20 63 ;. unsigned c
53f0: 68 61 72 20 65 78 74 5b 45 58 54 52 41 5d 3b 0a har ext[EXTRA];.
5400: 0a 20 20 20 20 50 55 54 38 28 65 78 74 2c 20 6c . PUT8(ext, l
5410: 6f 67 2d 3e 66 69 72 73 74 29 3b 0a 20 20 20 20 og->first);.
5420: 50 55 54 38 28 65 78 74 20 2b 20 38 2c 20 6c 6f PUT8(ext + 8, lo
5430: 67 2d 3e 6c 61 73 74 29 3b 0a 20 20 20 20 50 55 g->last);. PU
5440: 54 34 28 65 78 74 20 2b 20 31 36 2c 20 6c 6f 67 T4(ext + 16, log
5450: 2d 3e 63 63 72 63 29 3b 0a 20 20 20 20 50 55 54 ->ccrc);. PUT
5460: 34 28 65 78 74 20 2b 20 32 30 2c 20 6c 6f 67 2d 4(ext + 20, log-
5470: 3e 63 6c 65 6e 29 3b 0a 20 20 20 20 50 55 54 34 >clen);. PUT4
5480: 28 65 78 74 20 2b 20 32 34 2c 20 6c 6f 67 2d 3e (ext + 24, log->
5490: 74 63 72 63 29 3b 0a 20 20 20 20 50 55 54 34 28 tcrc);. PUT4(
54a0: 65 78 74 20 2b 20 32 38 2c 20 6c 6f 67 2d 3e 74 ext + 28, log->t
54b0: 6c 65 6e 29 3b 0a 20 20 20 20 50 55 54 32 28 65 len);. PUT2(e
54c0: 78 74 20 2b 20 33 32 2c 20 6c 6f 67 2d 3e 73 74 xt + 32, log->st
54d0: 6f 72 65 64 29 3b 0a 20 20 20 20 65 78 74 5b 33 ored);. ext[3
54e0: 34 5d 20 3d 20 6c 6f 67 2d 3e 62 61 63 6b 20 2d 4] = log->back -
54f0: 20 33 20 2b 20 28 6f 70 20 3c 3c 20 33 29 3b 0a 3 + (op << 3);.
5500: 20 20 20 20 66 73 79 6e 63 28 6c 6f 67 2d 3e 66 fsync(log->f
5510: 64 29 3b 0a 20 20 20 20 72 65 74 20 3d 20 6c 73 d);. ret = ls
5520: 65 65 6b 28 6c 6f 67 2d 3e 66 64 2c 20 48 45 41 eek(log->fd, HEA
5530: 44 2c 20 53 45 45 4b 5f 53 45 54 29 20 3c 20 30 D, SEEK_SET) < 0
5540: 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 77 72 ||. wr
5550: 69 74 65 28 6c 6f 67 2d 3e 66 64 2c 20 65 78 74 ite(log->fd, ext
5560: 2c 20 45 58 54 52 41 29 20 21 3d 20 45 58 54 52 , EXTRA) != EXTR
5570: 41 20 3f 20 2d 31 20 3a 20 30 3b 0a 20 20 20 20 A ? -1 : 0;.
5580: 66 73 79 6e 63 28 6c 6f 67 2d 3e 66 64 29 3b 0a fsync(log->fd);.
5590: 20 20 20 20 72 65 74 75 72 6e 20 72 65 74 3b 0a return ret;.
55a0: 7d 0a 0a 2f 2a 20 52 65 77 72 69 74 65 20 74 68 }../* Rewrite th
55b0: 65 20 6c 61 73 74 20 62 6c 6f 63 6b 20 68 65 61 e last block hea
55c0: 64 65 72 20 62 69 74 73 20 61 6e 64 20 73 75 62 der bits and sub
55d0: 73 65 71 75 65 6e 74 20 7a 65 72 6f 20 62 69 74 sequent zero bit
55e0: 73 20 74 6f 20 67 65 74 20 74 6f 20 61 20 62 79 s to get to a by
55f0: 74 65 0a 20 20 20 62 6f 75 6e 64 61 72 79 2c 20 te. boundary,
5600: 73 65 74 74 69 6e 67 20 74 68 65 20 6c 61 73 74 setting the last
5610: 20 62 6c 6f 63 6b 20 62 69 74 20 69 66 20 6c 61 block bit if la
5620: 73 74 20 69 73 20 74 72 75 65 2c 20 61 6e 64 20 st is true, and
5630: 74 68 65 6e 20 77 72 69 74 65 20 74 68 65 0a 20 then write the.
5640: 20 20 72 65 6d 61 69 6e 64 65 72 20 6f 66 20 74 remainder of t
5650: 68 65 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 he stored block
5660: 68 65 61 64 65 72 20 28 6c 65 6e 67 74 68 20 61 header (length a
5670: 6e 64 20 6f 6e 65 27 73 20 63 6f 6d 70 6c 65 6d nd one's complem
5680: 65 6e 74 29 2e 20 20 4c 65 61 76 65 0a 20 20 20 ent). Leave.
5690: 74 68 65 20 66 69 6c 65 20 70 6f 69 6e 74 65 72 the file pointer
56a0: 20 61 66 74 65 72 20 74 68 65 20 65 6e 64 20 6f after the end o
56b0: 66 20 74 68 65 20 6c 61 73 74 20 73 74 6f 72 65 f the last store
56c0: 64 20 62 6c 6f 63 6b 20 64 61 74 61 2e 20 20 52 d block data. R
56d0: 65 74 75 72 6e 20 2d 31 20 69 66 0a 20 20 20 74 eturn -1 if. t
56e0: 68 65 72 65 20 69 73 20 61 20 72 65 61 64 20 6f here is a read o
56f0: 72 20 77 72 69 74 65 20 66 61 69 6c 75 72 65 20 r write failure
5700: 6f 6e 20 74 68 65 20 66 6f 6f 2e 67 7a 20 66 69 on the foo.gz fi
5710: 6c 65 20 2a 2f 0a 6c 6f 63 61 6c 20 69 6e 74 20 le */.local int
5720: 6c 6f 67 5f 6c 61 73 74 28 73 74 72 75 63 74 20 log_last(struct
5730: 6c 6f 67 20 2a 6c 6f 67 2c 20 69 6e 74 20 6c 61 log *log, int la
5740: 73 74 29 0a 7b 0a 20 20 20 20 69 6e 74 20 62 61 st).{. int ba
5750: 63 6b 2c 20 6c 65 6e 2c 20 6d 61 73 6b 3b 0a 20 ck, len, mask;.
5760: 20 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 unsigned char
5770: 20 62 75 66 5b 36 5d 3b 0a 0a 20 20 20 20 2f 2a buf[6];.. /*
5780: 20 64 65 74 65 72 6d 69 6e 65 20 74 68 65 20 6c determine the l
5790: 6f 63 61 74 69 6f 6e 73 20 6f 66 20 74 68 65 20 ocations of the
57a0: 62 79 74 65 73 20 61 6e 64 20 62 69 74 73 20 74 bytes and bits t
57b0: 6f 20 6d 6f 64 69 66 79 20 2a 2f 0a 20 20 20 20 o modify */.
57c0: 62 61 63 6b 20 3d 20 6c 6f 67 2d 3e 6c 61 73 74 back = log->last
57d0: 20 3d 3d 20 6c 6f 67 2d 3e 66 69 72 73 74 20 3f == log->first ?
57e0: 20 6c 6f 67 2d 3e 62 61 63 6b 20 3a 20 38 3b 0a log->back : 8;.
57f0: 20 20 20 20 6c 65 6e 20 3d 20 62 61 63 6b 20 3e len = back >
5800: 20 38 20 3f 20 32 20 3a 20 31 3b 20 20 20 20 20 8 ? 2 : 1;
5810: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 62 /* b
5820: 79 74 65 73 20 62 61 63 6b 20 66 72 6f 6d 20 6c ytes back from l
5830: 6f 67 2d 3e 6c 61 73 74 20 2a 2f 0a 20 20 20 20 og->last */.
5840: 6d 61 73 6b 20 3d 20 30 78 38 30 20 3e 3e 20 28 mask = 0x80 >> (
5850: 28 62 61 63 6b 20 2d 20 31 29 20 26 20 37 29 3b (back - 1) & 7);
5860: 20 20 20 20 20 20 20 20 2f 2a 20 6d 61 73 6b 20 /* mask
5870: 66 6f 72 20 62 6c 6f 63 6b 20 6c 61 73 74 2d 62 for block last-b
5880: 69 74 20 2a 2f 0a 0a 20 20 20 20 2f 2a 20 67 65 it */.. /* ge
5890: 74 20 74 68 65 20 62 79 74 65 20 74 6f 20 6d 6f t the byte to mo
58a0: 64 69 66 79 20 28 6f 6e 65 20 6f 72 20 74 77 6f dify (one or two
58b0: 20 62 61 63 6b 29 20 69 6e 74 6f 20 62 75 66 5b back) into buf[
58c0: 30 5d 20 2d 2d 20 64 6f 6e 27 74 20 6e 65 65 64 0] -- don't need
58d0: 20 74 6f 0a 20 20 20 20 20 20 20 72 65 61 64 20 to. read
58e0: 74 68 65 20 62 79 74 65 20 69 66 20 74 68 65 20 the byte if the
58f0: 6c 61 73 74 2d 62 69 74 20 69 73 20 65 69 67 68 last-bit is eigh
5900: 74 20 62 69 74 73 20 62 61 63 6b 2c 20 73 69 6e t bits back, sin
5910: 63 65 20 69 6e 20 74 68 61 74 20 63 61 73 65 0a ce in that case.
5920: 20 20 20 20 20 20 20 74 68 65 20 65 6e 74 69 72 the entir
5930: 65 20 62 79 74 65 20 77 69 6c 6c 20 62 65 20 6d e byte will be m
5940: 6f 64 69 66 69 65 64 20 2a 2f 0a 20 20 20 20 62 odified */. b
5950: 75 66 5b 30 5d 20 3d 20 30 3b 0a 20 20 20 20 69 uf[0] = 0;. i
5960: 66 20 28 62 61 63 6b 20 21 3d 20 38 20 26 26 20 f (back != 8 &&
5970: 28 6c 73 65 65 6b 28 6c 6f 67 2d 3e 66 64 2c 20 (lseek(log->fd,
5980: 6c 6f 67 2d 3e 6c 61 73 74 20 2d 20 6c 65 6e 2c log->last - len,
5990: 20 53 45 45 4b 5f 53 45 54 29 20 3c 20 30 20 7c SEEK_SET) < 0 |
59a0: 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 |.
59b0: 20 20 20 20 20 20 20 20 72 65 61 64 28 6c 6f 67 read(log
59c0: 2d 3e 66 64 2c 20 62 75 66 2c 20 31 29 20 21 3d ->fd, buf, 1) !=
59d0: 20 31 29 29 0a 20 20 20 20 20 20 20 20 72 65 74 1)). ret
59e0: 75 72 6e 20 2d 31 3b 0a 0a 20 20 20 20 2f 2a 20 urn -1;.. /*
59f0: 63 68 61 6e 67 65 20 74 68 65 20 6c 61 73 74 2d change the last-
5a00: 62 69 74 20 6f 66 20 74 68 65 20 6c 61 73 74 20 bit of the last
5a10: 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 61 73 20 stored block as
5a20: 72 65 71 75 65 73 74 65 64 20 2d 2d 20 6e 6f 74 requested -- not
5a30: 65 0a 20 20 20 20 20 20 20 74 68 61 74 20 61 6c e. that al
5a40: 6c 20 62 69 74 73 20 61 62 6f 76 65 20 74 68 65 l bits above the
5a50: 20 6c 61 73 74 2d 62 69 74 20 61 72 65 20 73 65 last-bit are se
5a60: 74 20 74 6f 20 7a 65 72 6f 2c 20 70 65 72 20 74 t to zero, per t
5a70: 68 65 20 74 79 70 65 20 62 69 74 73 0a 20 20 20 he type bits.
5a80: 20 20 20 20 6f 66 20 61 20 73 74 6f 72 65 64 20 of a stored
5a90: 62 6c 6f 63 6b 20 62 65 69 6e 67 20 30 30 20 61 block being 00 a
5aa0: 6e 64 20 70 65 72 20 74 68 65 20 63 6f 6e 76 65 nd per the conve
5ab0: 6e 74 69 6f 6e 20 74 68 61 74 20 74 68 65 20 62 ntion that the b
5ac0: 69 74 73 20 74 6f 0a 20 20 20 20 20 20 20 62 72 its to. br
5ad0: 69 6e 67 20 74 68 65 20 73 74 72 65 61 6d 20 74 ing the stream t
5ae0: 6f 20 61 20 62 79 74 65 20 62 6f 75 6e 64 61 72 o a byte boundar
5af0: 79 20 61 72 65 20 61 6c 73 6f 20 7a 65 72 6f 73 y are also zeros
5b00: 20 2a 2f 0a 20 20 20 20 62 75 66 5b 31 5d 20 3d */. buf[1] =
5b10: 20 30 3b 0a 20 20 20 20 62 75 66 5b 32 20 2d 20 0;. buf[2 -
5b20: 6c 65 6e 5d 20 3d 20 28 2a 62 75 66 20 26 20 28 len] = (*buf & (
5b30: 6d 61 73 6b 20 2d 20 31 29 29 20 2b 20 28 6c 61 mask - 1)) + (la
5b40: 73 74 20 3f 20 6d 61 73 6b 20 3a 20 30 29 3b 0a st ? mask : 0);.
5b50: 0a 20 20 20 20 2f 2a 20 77 72 69 74 65 20 74 68 . /* write th
5b60: 65 20 6d 6f 64 69 66 69 65 64 20 73 74 6f 72 65 e modified store
5b70: 64 20 62 6c 6f 63 6b 20 68 65 61 64 65 72 20 61 d block header a
5b80: 6e 64 20 6c 65 6e 67 74 68 73 2c 20 6d 6f 76 65 nd lengths, move
5b90: 20 74 68 65 20 66 69 6c 65 0a 20 20 20 20 20 20 the file.
5ba0: 20 70 6f 69 6e 74 65 72 20 74 6f 20 61 66 74 65 pointer to afte
5bb0: 72 20 74 68 65 20 6c 61 73 74 20 73 74 6f 72 65 r the last store
5bc0: 64 20 62 6c 6f 63 6b 20 64 61 74 61 20 2a 2f 0a d block data */.
5bd0: 20 20 20 20 50 55 54 32 28 62 75 66 20 2b 20 32 PUT2(buf + 2
5be0: 2c 20 6c 6f 67 2d 3e 73 74 6f 72 65 64 29 3b 0a , log->stored);.
5bf0: 20 20 20 20 50 55 54 32 28 62 75 66 20 2b 20 34 PUT2(buf + 4
5c00: 2c 20 6c 6f 67 2d 3e 73 74 6f 72 65 64 20 5e 20 , log->stored ^
5c10: 30 78 66 66 66 66 29 3b 0a 20 20 20 20 72 65 74 0xffff);. ret
5c20: 75 72 6e 20 6c 73 65 65 6b 28 6c 6f 67 2d 3e 66 urn lseek(log->f
5c30: 64 2c 20 6c 6f 67 2d 3e 6c 61 73 74 20 2d 20 6c d, log->last - l
5c40: 65 6e 2c 20 53 45 45 4b 5f 53 45 54 29 20 3c 20 en, SEEK_SET) <
5c50: 30 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 0 ||.
5c60: 77 72 69 74 65 28 6c 6f 67 2d 3e 66 64 2c 20 62 write(log->fd, b
5c70: 75 66 20 2b 20 32 20 2d 20 6c 65 6e 2c 20 6c 65 uf + 2 - len, le
5c80: 6e 20 2b 20 34 29 20 21 3d 20 6c 65 6e 20 2b 20 n + 4) != len +
5c90: 34 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 4 ||.
5ca0: 6c 73 65 65 6b 28 6c 6f 67 2d 3e 66 64 2c 20 6c lseek(log->fd, l
5cb0: 6f 67 2d 3e 73 74 6f 72 65 64 2c 20 53 45 45 4b og->stored, SEEK
5cc0: 5f 43 55 52 29 20 3c 20 30 20 3f 20 2d 31 20 3a _CUR) < 0 ? -1 :
5cd0: 20 30 3b 0a 7d 0a 0a 2f 2a 20 41 70 70 65 6e 64 0;.}../* Append
5ce0: 20 6c 65 6e 20 62 79 74 65 73 20 66 72 6f 6d 20 len bytes from
5cf0: 64 61 74 61 20 74 6f 20 74 68 65 20 6c 6f 63 6b data to the lock
5d00: 65 64 20 61 6e 64 20 6f 70 65 6e 20 6c 6f 67 20 ed and open log
5d10: 66 69 6c 65 2e 20 20 6c 65 6e 20 6d 61 79 20 62 file. len may b
5d20: 65 20 7a 65 72 6f 0a 20 20 20 69 66 20 72 65 63 e zero. if rec
5d30: 6f 76 65 72 69 6e 67 20 61 6e 64 20 6e 6f 20 2e overing and no .
5d40: 61 64 64 20 66 69 6c 65 20 77 61 73 20 66 6f 75 add file was fou
5d50: 6e 64 2e 20 20 49 6e 20 74 68 61 74 20 63 61 73 nd. In that cas
5d60: 65 2c 20 74 68 65 20 70 72 65 76 69 6f 75 73 20 e, the previous
5d70: 73 74 61 74 65 0a 20 20 20 6f 66 20 74 68 65 20 state. of the
5d80: 66 6f 6f 2e 67 7a 20 66 69 6c 65 20 69 73 20 72 foo.gz file is r
5d90: 65 73 74 6f 72 65 64 2e 20 20 54 68 65 20 64 61 estored. The da
5da0: 74 61 20 69 73 20 61 70 70 65 6e 64 65 64 20 75 ta is appended u
5db0: 6e 63 6f 6d 70 72 65 73 73 65 64 20 69 6e 0a 20 ncompressed in.
5dc0: 20 20 64 65 66 6c 61 74 65 20 73 74 6f 72 65 64 deflate stored
5dd0: 20 62 6c 6f 63 6b 73 2e 20 20 52 65 74 75 72 6e blocks. Return
5de0: 20 2d 31 20 69 66 20 74 68 65 72 65 20 77 61 73 -1 if there was
5df0: 20 61 6e 20 65 72 72 6f 72 20 72 65 61 64 69 6e an error readin
5e00: 67 20 6f 72 20 77 72 69 74 69 6e 67 0a 20 20 20 g or writing.
5e10: 74 68 65 20 66 6f 6f 2e 67 7a 20 66 69 6c 65 2e the foo.gz file.
5e20: 20 2a 2f 0a 6c 6f 63 61 6c 20 69 6e 74 20 6c 6f */.local int lo
5e30: 67 5f 61 70 70 65 6e 64 28 73 74 72 75 63 74 20 g_append(struct
5e40: 6c 6f 67 20 2a 6c 6f 67 2c 20 75 6e 73 69 67 6e log *log, unsign
5e50: 65 64 20 63 68 61 72 20 2a 64 61 74 61 2c 20 73 ed char *data, s
5e60: 69 7a 65 5f 74 20 6c 65 6e 29 0a 7b 0a 20 20 20 ize_t len).{.
5e70: 20 75 69 6e 74 20 70 75 74 3b 0a 20 20 20 20 6f uint put;. o
5e80: 66 66 5f 74 20 65 6e 64 3b 0a 20 20 20 20 75 6e ff_t end;. un
5e90: 73 69 67 6e 65 64 20 63 68 61 72 20 62 75 66 5b signed char buf[
5ea0: 38 5d 3b 0a 0a 20 20 20 20 2f 2a 20 73 65 74 20 8];.. /* set
5eb0: 74 68 65 20 6c 61 73 74 20 62 6c 6f 63 6b 20 6c the last block l
5ec0: 61 73 74 2d 62 69 74 20 61 6e 64 20 6c 65 6e 67 ast-bit and leng
5ed0: 74 68 2c 20 69 6e 20 63 61 73 65 20 72 65 63 6f th, in case reco
5ee0: 76 65 72 69 6e 67 20 61 6e 0a 20 20 20 20 20 20 vering an.
5ef0: 20 69 6e 74 65 72 72 75 70 74 65 64 20 61 70 70 interrupted app
5f00: 65 6e 64 2c 20 74 68 65 6e 20 70 6f 73 69 74 69 end, then positi
5f10: 6f 6e 20 74 68 65 20 66 69 6c 65 20 70 6f 69 6e on the file poin
5f20: 74 65 72 20 74 6f 20 61 70 70 65 6e 64 20 74 6f ter to append to
5f30: 20 74 68 65 0a 20 20 20 20 20 20 20 62 6c 6f 63 the. bloc
5f40: 6b 20 2a 2f 0a 20 20 20 20 69 66 20 28 6c 6f 67 k */. if (log
5f50: 5f 6c 61 73 74 28 6c 6f 67 2c 20 31 29 29 0a 20 _last(log, 1)).
5f60: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 2d 31 return -1
5f70: 3b 0a 0a 20 20 20 20 2f 2a 20 61 70 70 65 6e 64 ;.. /* append
5f80: 2c 20 61 64 64 69 6e 67 20 73 74 6f 72 65 64 20 , adding stored
5f90: 62 6c 6f 63 6b 73 20 61 6e 64 20 75 70 64 61 74 blocks and updat
5fa0: 69 6e 67 20 74 68 65 20 6f 66 66 73 65 74 20 6f ing the offset o
5fb0: 66 20 74 68 65 20 6c 61 73 74 20 73 74 6f 72 65 f the last store
5fc0: 64 0a 20 20 20 20 20 20 20 62 6c 6f 63 6b 20 61 d. block a
5fd0: 73 20 6e 65 65 64 65 64 2c 20 61 6e 64 20 75 70 s needed, and up
5fe0: 64 61 74 65 20 74 68 65 20 74 6f 74 61 6c 20 63 date the total c
5ff0: 72 63 20 61 6e 64 20 6c 65 6e 67 74 68 20 2a 2f rc and length */
6000: 0a 20 20 20 20 77 68 69 6c 65 20 28 6c 65 6e 29 . while (len)
6010: 20 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 61 70 {. /* ap
6020: 70 65 6e 64 20 61 73 20 6d 75 63 68 20 61 73 20 pend as much as
6030: 77 65 20 63 61 6e 20 74 6f 20 74 68 65 20 6c 61 we can to the la
6040: 73 74 20 62 6c 6f 63 6b 20 2a 2f 0a 20 20 20 20 st block */.
6050: 20 20 20 20 70 75 74 20 3d 20 28 4d 41 58 5f 53 put = (MAX_S
6060: 54 4f 52 45 20 3c 3c 20 31 30 29 20 2d 20 6c 6f TORE << 10) - lo
6070: 67 2d 3e 73 74 6f 72 65 64 3b 0a 20 20 20 20 20 g->stored;.
6080: 20 20 20 69 66 20 28 70 75 74 20 3e 20 6c 65 6e if (put > len
6090: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 70 75 ). pu
60a0: 74 20 3d 20 28 75 69 6e 74 29 6c 65 6e 3b 0a 20 t = (uint)len;.
60b0: 20 20 20 20 20 20 20 69 66 20 28 70 75 74 29 20 if (put)
60c0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 {. if
60d0: 20 28 77 72 69 74 65 28 6c 6f 67 2d 3e 66 64 2c (write(log->fd,
60e0: 20 64 61 74 61 2c 20 70 75 74 29 20 21 3d 20 70 data, put) != p
60f0: 75 74 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 ut).
6100: 20 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 return -1;.
6110: 20 20 20 20 20 20 20 20 20 20 20 42 41 49 4c 28 BAIL(
6120: 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 1);.
6130: 6c 6f 67 2d 3e 74 63 72 63 20 3d 20 63 72 63 33 log->tcrc = crc3
6140: 32 28 6c 6f 67 2d 3e 74 63 72 63 2c 20 64 61 74 2(log->tcrc, dat
6150: 61 2c 20 70 75 74 29 3b 0a 20 20 20 20 20 20 20 a, put);.
6160: 20 20 20 20 20 6c 6f 67 2d 3e 74 6c 65 6e 20 2b log->tlen +
6170: 3d 20 70 75 74 3b 0a 20 20 20 20 20 20 20 20 20 = put;.
6180: 20 20 20 6c 6f 67 2d 3e 73 74 6f 72 65 64 20 2b log->stored +
6190: 3d 20 70 75 74 3b 0a 20 20 20 20 20 20 20 20 20 = put;.
61a0: 20 20 20 64 61 74 61 20 2b 3d 20 70 75 74 3b 0a data += put;.
61b0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 65 6e 20 len
61c0: 2d 3d 20 70 75 74 3b 0a 20 20 20 20 20 20 20 20 -= put;.
61d0: 7d 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20 69 66 }.. /* if
61e0: 20 77 65 20 6e 65 65 64 20 74 6f 2c 20 61 64 64 we need to, add
61f0: 20 61 20 6e 65 77 20 65 6d 70 74 79 20 73 74 6f a new empty sto
6200: 72 65 64 20 62 6c 6f 63 6b 20 2a 2f 0a 20 20 20 red block */.
6210: 20 20 20 20 20 69 66 20 28 6c 65 6e 29 20 7b 0a if (len) {.
6220: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 6d /* m
6230: 61 72 6b 20 63 75 72 72 65 6e 74 20 62 6c 6f 63 ark current bloc
6240: 6b 20 61 73 20 6e 6f 74 20 6c 61 73 74 20 2a 2f k as not last */
6250: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 . if
6260: 28 6c 6f 67 5f 6c 61 73 74 28 6c 6f 67 2c 20 30 (log_last(log, 0
6270: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 )).
6280: 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 0a 20 return -1;..
6290: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 6f /* po
62a0: 69 6e 74 20 74 6f 20 6e 65 77 2c 20 65 6d 70 74 int to new, empt
62b0: 79 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b 20 2a y stored block *
62c0: 2f 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f /. lo
62d0: 67 2d 3e 6c 61 73 74 20 2b 3d 20 34 20 2b 20 6c g->last += 4 + l
62e0: 6f 67 2d 3e 73 74 6f 72 65 64 20 2b 20 31 3b 0a og->stored + 1;.
62f0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67 2d log-
6300: 3e 73 74 6f 72 65 64 20 3d 20 30 3b 0a 20 20 20 >stored = 0;.
6310: 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 }..
6320: 2f 2a 20 6d 61 72 6b 20 6c 61 73 74 20 62 6c 6f /* mark last blo
6330: 63 6b 20 61 73 20 6c 61 73 74 2c 20 75 70 64 61 ck as last, upda
6340: 74 65 20 69 74 73 20 6c 65 6e 67 74 68 20 2a 2f te its length */
6350: 0a 20 20 20 20 20 20 20 20 69 66 20 28 6c 6f 67 . if (log
6360: 5f 6c 61 73 74 28 6c 6f 67 2c 20 31 29 29 0a 20 _last(log, 1)).
6370: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 retur
6380: 6e 20 2d 31 3b 0a 20 20 20 20 20 20 20 20 42 41 n -1;. BA
6390: 49 4c 28 32 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 IL(2);. }..
63a0: 20 20 2f 2a 20 77 72 69 74 65 20 74 68 65 20 6e /* write the n
63b0: 65 77 20 63 72 63 20 61 6e 64 20 6c 65 6e 67 74 ew crc and lengt
63c0: 68 20 74 72 61 69 6c 65 72 2c 20 61 6e 64 20 74 h trailer, and t
63d0: 72 75 6e 63 61 74 65 20 6a 75 73 74 20 69 6e 20 runcate just in
63e0: 63 61 73 65 20 28 63 6f 75 6c 64 0a 20 20 20 20 case (could.
63f0: 20 20 20 62 65 20 72 65 63 6f 76 65 72 69 6e 67 be recovering
6400: 20 66 72 6f 6d 20 70 61 72 74 69 61 6c 20 61 70 from partial ap
6410: 70 65 6e 64 20 77 69 74 68 20 61 20 6d 69 73 73 pend with a miss
6420: 69 6e 67 20 66 6f 6f 2e 61 64 64 20 66 69 6c 65 ing foo.add file
6430: 29 20 2a 2f 0a 20 20 20 20 50 55 54 34 28 62 75 ) */. PUT4(bu
6440: 66 2c 20 6c 6f 67 2d 3e 74 63 72 63 29 3b 0a 20 f, log->tcrc);.
6450: 20 20 20 50 55 54 34 28 62 75 66 20 2b 20 34 2c PUT4(buf + 4,
6460: 20 6c 6f 67 2d 3e 74 6c 65 6e 29 3b 0a 20 20 20 log->tlen);.
6470: 20 69 66 20 28 77 72 69 74 65 28 6c 6f 67 2d 3e if (write(log->
6480: 66 64 2c 20 62 75 66 2c 20 38 29 20 21 3d 20 38 fd, buf, 8) != 8
6490: 20 7c 7c 0a 20 20 20 20 20 20 20 20 28 65 6e 64 ||. (end
64a0: 20 3d 20 6c 73 65 65 6b 28 6c 6f 67 2d 3e 66 64 = lseek(log->fd
64b0: 2c 20 30 2c 20 53 45 45 4b 5f 43 55 52 29 29 20 , 0, SEEK_CUR))
64c0: 3c 20 30 20 7c 7c 20 66 74 72 75 6e 63 61 74 65 < 0 || ftruncate
64d0: 28 6c 6f 67 2d 3e 66 64 2c 20 65 6e 64 29 29 0a (log->fd, end)).
64e0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 2d return -
64f0: 31 3b 0a 0a 20 20 20 20 2f 2a 20 77 72 69 74 65 1;.. /* write
6500: 20 74 68 65 20 65 78 74 72 61 20 66 69 65 6c 64 the extra field
6510: 2c 20 6d 61 72 6b 69 6e 67 20 74 68 65 20 6c 6f , marking the lo
6520: 67 20 66 69 6c 65 20 61 73 20 64 6f 6e 65 2c 20 g file as done,
6530: 64 65 6c 65 74 65 20 2e 61 64 64 20 66 69 6c 65 delete .add file
6540: 20 2a 2f 0a 20 20 20 20 69 66 20 28 6c 6f 67 5f */. if (log_
6550: 6d 61 72 6b 28 6c 6f 67 2c 20 4e 4f 5f 4f 50 29 mark(log, NO_OP)
6560: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e ). return
6570: 20 2d 31 3b 0a 20 20 20 20 73 74 72 63 70 79 28 -1;. strcpy(
6580: 6c 6f 67 2d 3e 65 6e 64 2c 20 22 2e 61 64 64 22 log->end, ".add"
6590: 29 3b 0a 20 20 20 20 75 6e 6c 69 6e 6b 28 6c 6f );. unlink(lo
65a0: 67 2d 3e 70 61 74 68 29 3b 20 20 20 20 20 20 20 g->path);
65b0: 20 20 20 2f 2a 20 69 67 6e 6f 72 65 20 65 72 72 /* ignore err
65c0: 6f 72 2c 20 73 69 6e 63 65 20 6d 61 79 20 6e 6f or, since may no
65d0: 74 20 65 78 69 73 74 20 2a 2f 0a 20 20 20 20 72 t exist */. r
65e0: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 52 eturn 0;.}../* R
65f0: 65 70 6c 61 63 65 20 74 68 65 20 66 6f 6f 2e 64 eplace the foo.d
6600: 69 63 74 20 66 69 6c 65 20 77 69 74 68 20 74 68 ict file with th
6610: 65 20 66 6f 6f 2e 74 65 6d 70 20 66 69 6c 65 2e e foo.temp file.
6620: 20 20 41 6c 73 6f 20 64 65 6c 65 74 65 20 74 68 Also delete th
6630: 65 20 66 6f 6f 2e 61 64 64 0a 20 20 20 66 69 6c e foo.add. fil
6640: 65 2c 20 73 69 6e 63 65 20 74 68 65 20 63 6f 6d e, since the com
6650: 70 72 65 73 73 20 6f 70 65 72 61 74 69 6f 6e 20 press operation
6660: 6d 61 79 20 68 61 76 65 20 62 65 65 6e 20 69 6e may have been in
6670: 74 65 72 72 75 70 74 65 64 20 62 65 66 6f 72 65 terrupted before
6680: 20 74 68 61 74 20 77 61 73 0a 20 20 20 64 6f 6e that was. don
6690: 65 2e 20 20 52 65 74 75 72 6e 73 20 31 20 69 66 e. Returns 1 if
66a0: 20 6d 65 6d 6f 72 79 20 63 6f 75 6c 64 20 6e 6f memory could no
66b0: 74 20 62 65 20 61 6c 6c 6f 63 61 74 65 64 2c 20 t be allocated,
66c0: 6f 72 20 2d 31 20 69 66 20 72 65 61 64 69 6e 67 or -1 if reading
66d0: 20 6f 72 0a 20 20 20 77 72 69 74 69 6e 67 20 66 or. writing f
66e0: 6f 6f 2e 67 7a 20 66 61 69 6c 73 2c 20 6f 72 20 oo.gz fails, or
66f0: 69 66 20 74 68 65 20 72 65 6e 61 6d 65 20 66 61 if the rename fa
6700: 69 6c 73 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 ils for some rea
6710: 73 6f 6e 20 6f 74 68 65 72 20 74 68 61 6e 0a 20 son other than.
6720: 20 20 66 6f 6f 2e 74 65 6d 70 20 6e 6f 74 20 65 foo.temp not e
6730: 78 69 73 74 69 6e 67 2e 20 20 66 6f 6f 2e 74 65 xisting. foo.te
6740: 6d 70 20 6e 6f 74 20 65 78 69 73 74 69 6e 67 20 mp not existing
6750: 69 73 20 61 20 70 65 72 6d 69 74 74 65 64 20 65 is a permitted e
6760: 72 72 6f 72 2c 20 73 69 6e 63 65 0a 20 20 20 74 rror, since. t
6770: 68 65 20 72 65 70 6c 61 63 65 20 6f 70 65 72 61 he replace opera
6780: 74 69 6f 6e 20 6d 61 79 20 68 61 76 65 20 62 65 tion may have be
6790: 65 6e 20 69 6e 74 65 72 72 75 70 74 65 64 20 61 en interrupted a
67a0: 66 74 65 72 20 74 68 65 20 72 65 6e 61 6d 65 20 fter the rename
67b0: 69 73 20 64 6f 6e 65 2c 0a 20 20 20 62 75 74 20 is done,. but
67c0: 62 65 66 6f 72 65 20 66 6f 6f 2e 67 7a 20 69 73 before foo.gz is
67d0: 20 6d 61 72 6b 65 64 20 61 73 20 63 6f 6d 70 6c marked as compl
67e0: 65 74 65 2e 20 2a 2f 0a 6c 6f 63 61 6c 20 69 6e ete. */.local in
67f0: 74 20 6c 6f 67 5f 72 65 70 6c 61 63 65 28 73 74 t log_replace(st
6800: 72 75 63 74 20 6c 6f 67 20 2a 6c 6f 67 29 0a 7b ruct log *log).{
6810: 0a 20 20 20 20 69 6e 74 20 72 65 74 3b 0a 20 20 . int ret;.
6820: 20 20 63 68 61 72 20 2a 64 65 73 74 3b 0a 0a 20 char *dest;..
6830: 20 20 20 2f 2a 20 64 65 6c 65 74 65 20 66 6f 6f /* delete foo
6840: 2e 61 64 64 20 66 69 6c 65 20 2a 2f 0a 20 20 20 .add file */.
6850: 20 73 74 72 63 70 79 28 6c 6f 67 2d 3e 65 6e 64 strcpy(log->end
6860: 2c 20 22 2e 61 64 64 22 29 3b 0a 20 20 20 20 75 , ".add");. u
6870: 6e 6c 69 6e 6b 28 6c 6f 67 2d 3e 70 61 74 68 29 nlink(log->path)
6880: 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 69 67 6e ; /* ign
6890: 6f 72 65 20 65 72 72 6f 72 2c 20 73 69 6e 63 65 ore error, since
68a0: 20 6d 61 79 20 6e 6f 74 20 65 78 69 73 74 20 2a may not exist *
68b0: 2f 0a 20 20 20 20 42 41 49 4c 28 33 29 3b 0a 0a /. BAIL(3);..
68c0: 20 20 20 20 2f 2a 20 72 65 6e 61 6d 65 20 66 6f /* rename fo
68d0: 6f 2e 6e 61 6d 65 20 74 6f 20 66 6f 6f 2e 64 69 o.name to foo.di
68e0: 63 74 2c 20 72 65 70 6c 61 63 69 6e 67 20 66 6f ct, replacing fo
68f0: 6f 2e 64 69 63 74 20 69 66 20 69 74 20 65 78 69 o.dict if it exi
6900: 73 74 73 20 2a 2f 0a 20 20 20 20 73 74 72 63 70 sts */. strcp
6910: 79 28 6c 6f 67 2d 3e 65 6e 64 2c 20 22 2e 64 69 y(log->end, ".di
6920: 63 74 22 29 3b 0a 20 20 20 20 64 65 73 74 20 3d ct");. dest =
6930: 20 6d 61 6c 6c 6f 63 28 73 74 72 6c 65 6e 28 6c malloc(strlen(l
6940: 6f 67 2d 3e 70 61 74 68 29 20 2b 20 31 29 3b 0a og->path) + 1);.
6950: 20 20 20 20 69 66 20 28 64 65 73 74 20 3d 3d 20 if (dest ==
6960: 4e 55 4c 4c 29 0a 20 20 20 20 20 20 20 20 72 65 NULL). re
6970: 74 75 72 6e 20 2d 32 3b 0a 20 20 20 20 73 74 72 turn -2;. str
6980: 63 70 79 28 64 65 73 74 2c 20 6c 6f 67 2d 3e 70 cpy(dest, log->p
6990: 61 74 68 29 3b 0a 20 20 20 20 73 74 72 63 70 79 ath);. strcpy
69a0: 28 6c 6f 67 2d 3e 65 6e 64 2c 20 22 2e 74 65 6d (log->end, ".tem
69b0: 70 22 29 3b 0a 20 20 20 20 72 65 74 20 3d 20 72 p");. ret = r
69c0: 65 6e 61 6d 65 28 6c 6f 67 2d 3e 70 61 74 68 2c ename(log->path,
69d0: 20 64 65 73 74 29 3b 0a 20 20 20 20 66 72 65 65 dest);. free
69e0: 28 64 65 73 74 29 3b 0a 20 20 20 20 69 66 20 28 (dest);. if (
69f0: 72 65 74 20 26 26 20 65 72 72 6e 6f 20 21 3d 20 ret && errno !=
6a00: 45 4e 4f 45 4e 54 29 0a 20 20 20 20 20 20 20 20 ENOENT).
6a10: 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 20 20 42 return -1;. B
6a20: 41 49 4c 28 34 29 3b 0a 0a 20 20 20 20 2f 2a 20 AIL(4);.. /*
6a30: 6d 61 72 6b 20 74 68 65 20 66 6f 6f 2e 67 7a 20 mark the foo.gz
6a40: 66 69 6c 65 20 61 73 20 64 6f 6e 65 20 2a 2f 0a file as done */.
6a50: 20 20 20 20 72 65 74 75 72 6e 20 6c 6f 67 5f 6d return log_m
6a60: 61 72 6b 28 6c 6f 67 2c 20 4e 4f 5f 4f 50 29 3b ark(log, NO_OP);
6a70: 0a 7d 0a 0a 2f 2a 20 43 6f 6d 70 72 65 73 73 20 .}../* Compress
6a80: 74 68 65 20 6c 65 6e 20 62 79 74 65 73 20 61 74 the len bytes at
6a90: 20 64 61 74 61 20 61 6e 64 20 61 70 70 65 6e 64 data and append
6aa0: 20 74 68 65 20 63 6f 6d 70 72 65 73 73 65 64 20 the compressed
6ab0: 64 61 74 61 20 74 6f 20 74 68 65 0a 20 20 20 66 data to the. f
6ac0: 6f 6f 2e 67 7a 20 64 65 66 6c 61 74 65 20 64 61 oo.gz deflate da
6ad0: 74 61 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 61 ta immediately a
6ae0: 66 74 65 72 20 74 68 65 20 70 72 65 76 69 6f 75 fter the previou
6af0: 73 20 63 6f 6d 70 72 65 73 73 65 64 20 64 61 74 s compressed dat
6b00: 61 2e 20 20 54 68 69 73 0a 20 20 20 6f 76 65 72 a. This. over
6b10: 77 72 69 74 65 73 20 74 68 65 20 70 72 65 76 69 writes the previ
6b20: 6f 75 73 20 75 6e 63 6f 6d 70 72 65 73 73 65 64 ous uncompressed
6b30: 20 64 61 74 61 2c 20 77 68 69 63 68 20 77 61 73 data, which was
6b40: 20 73 74 6f 72 65 64 20 69 6e 20 66 6f 6f 2e 61 stored in foo.a
6b50: 64 64 0a 20 20 20 61 6e 64 20 69 73 20 74 68 65 dd. and is the
6b60: 20 64 61 74 61 20 70 72 6f 76 69 64 65 64 20 69 data provided i
6b70: 6e 20 64 61 74 61 5b 30 2e 2e 6c 65 6e 2d 31 5d n data[0..len-1]
6b80: 2e 20 20 49 66 20 74 68 69 73 20 6f 70 65 72 61 . If this opera
6b90: 74 69 6f 6e 20 69 73 0a 20 20 20 69 6e 74 65 72 tion is. inter
6ba0: 72 75 70 74 65 64 2c 20 69 74 20 70 69 63 6b 73 rupted, it picks
6bb0: 20 75 70 20 61 74 20 74 68 65 20 73 74 61 72 74 up at the start
6bc0: 20 6f 66 20 74 68 69 73 20 72 6f 75 74 69 6e 65 of this routine
6bd0: 2c 20 77 69 74 68 20 74 68 65 20 66 6f 6f 2e 61 , with the foo.a
6be0: 64 64 0a 20 20 20 66 69 6c 65 20 72 65 61 64 20 dd. file read
6bf0: 69 6e 20 61 67 61 69 6e 2e 20 20 49 66 20 74 68 in again. If th
6c00: 65 72 65 20 69 73 20 6e 6f 20 64 61 74 61 20 74 ere is no data t
6c10: 6f 20 63 6f 6d 70 72 65 73 73 20 28 6c 65 6e 20 o compress (len
6c20: 3d 3d 20 30 29 2c 20 74 68 65 6e 20 77 65 0a 20 == 0), then we.
6c30: 20 20 73 69 6d 70 6c 79 20 74 65 72 6d 69 6e 61 simply termina
6c40: 74 65 20 74 68 65 20 66 6f 6f 2e 67 7a 20 66 69 te the foo.gz fi
6c50: 6c 65 20 61 66 74 65 72 20 74 68 65 20 70 72 65 le after the pre
6c60: 76 69 6f 75 73 6c 79 20 63 6f 6d 70 72 65 73 73 viously compress
6c70: 65 64 20 64 61 74 61 2c 0a 20 20 20 61 70 70 65 ed data,. appe
6c80: 6e 64 69 6e 67 20 61 20 66 69 6e 61 6c 20 65 6d nding a final em
6c90: 70 74 79 20 73 74 6f 72 65 64 20 62 6c 6f 63 6b pty stored block
6ca0: 20 61 6e 64 20 74 68 65 20 67 7a 69 70 20 74 72 and the gzip tr
6cb0: 61 69 6c 65 72 2e 20 20 52 65 74 75 72 6e 20 2d ailer. Return -
6cc0: 31 20 69 66 0a 20 20 20 72 65 61 64 69 6e 67 20 1 if. reading
6cd0: 6f 72 20 77 72 69 74 69 6e 67 20 74 68 65 20 6c or writing the l
6ce0: 6f 67 2e 67 7a 20 66 69 6c 65 20 66 61 69 6c 65 og.gz file faile
6cf0: 64 2c 20 6f 72 20 2d 32 20 69 66 20 74 68 65 72 d, or -2 if ther
6d00: 65 20 77 61 73 20 61 20 6d 65 6d 6f 72 79 0a 20 e was a memory.
6d10: 20 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 61 69 allocation fai
6d20: 6c 75 72 65 2e 20 2a 2f 0a 6c 6f 63 61 6c 20 69 lure. */.local i
6d30: 6e 74 20 6c 6f 67 5f 63 6f 6d 70 72 65 73 73 28 nt log_compress(
6d40: 73 74 72 75 63 74 20 6c 6f 67 20 2a 6c 6f 67 2c struct log *log,
6d50: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a unsigned char *
6d60: 64 61 74 61 2c 20 73 69 7a 65 5f 74 20 6c 65 6e data, size_t len
6d70: 29 0a 7b 0a 20 20 20 20 69 6e 74 20 66 64 3b 0a ).{. int fd;.
6d80: 20 20 20 20 75 69 6e 74 20 67 6f 74 2c 20 6d 61 uint got, ma
6d90: 78 3b 0a 20 20 20 20 73 73 69 7a 65 5f 74 20 64 x;. ssize_t d
6da0: 69 63 74 3b 0a 20 20 20 20 6f 66 66 5f 74 20 65 ict;. off_t e
6db0: 6e 64 3b 0a 20 20 20 20 7a 5f 73 74 72 65 61 6d nd;. z_stream
6dc0: 20 73 74 72 6d 3b 0a 20 20 20 20 75 6e 73 69 67 strm;. unsig
6dd0: 6e 65 64 20 63 68 61 72 20 62 75 66 5b 44 49 43 ned char buf[DIC
6de0: 54 5d 3b 0a 0a 20 20 20 20 2f 2a 20 63 6f 6d 70 T];.. /* comp
6df0: 72 65 73 73 20 61 6e 64 20 61 70 70 65 6e 64 20 ress and append
6e00: 63 6f 6d 70 72 65 73 73 65 64 20 64 61 74 61 20 compressed data
6e10: 2a 2f 0a 20 20 20 20 69 66 20 28 6c 65 6e 29 20 */. if (len)
6e20: 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20 73 65 74 {. /* set
6e30: 20 75 70 20 66 6f 72 20 64 65 66 6c 61 74 65 2c up for deflate,
6e40: 20 61 6c 6c 6f 63 61 74 69 6e 67 20 6d 65 6d 6f allocating memo
6e50: 72 79 20 2a 2f 0a 20 20 20 20 20 20 20 20 73 74 ry */. st
6e60: 72 6d 2e 7a 61 6c 6c 6f 63 20 3d 20 5a 5f 4e 55 rm.zalloc = Z_NU
6e70: 4c 4c 3b 0a 20 20 20 20 20 20 20 20 73 74 72 6d LL;. strm
6e80: 2e 7a 66 72 65 65 20 3d 20 5a 5f 4e 55 4c 4c 3b .zfree = Z_NULL;
6e90: 0a 20 20 20 20 20 20 20 20 73 74 72 6d 2e 6f 70 . strm.op
6ea0: 61 71 75 65 20 3d 20 5a 5f 4e 55 4c 4c 3b 0a 20 aque = Z_NULL;.
6eb0: 20 20 20 20 20 20 20 69 66 20 28 64 65 66 6c 61 if (defla
6ec0: 74 65 49 6e 69 74 32 28 26 73 74 72 6d 2c 20 5a teInit2(&strm, Z
6ed0: 5f 44 45 46 41 55 4c 54 5f 43 4f 4d 50 52 45 53 _DEFAULT_COMPRES
6ee0: 53 49 4f 4e 2c 20 5a 5f 44 45 46 4c 41 54 45 44 SION, Z_DEFLATED
6ef0: 2c 20 2d 31 35 2c 20 38 2c 0a 20 20 20 20 20 20 , -15, 8,.
6f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
6f10: 20 20 20 5a 5f 44 45 46 41 55 4c 54 5f 53 54 52 Z_DEFAULT_STR
6f20: 41 54 45 47 59 29 20 21 3d 20 5a 5f 4f 4b 29 0a ATEGY) != Z_OK).
6f30: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 retu
6f40: 72 6e 20 2d 32 3b 0a 0a 20 20 20 20 20 20 20 20 rn -2;..
6f50: 2f 2a 20 72 65 61 64 20 69 6e 20 64 69 63 74 69 /* read in dicti
6f60: 6f 6e 61 72 79 20 28 6c 61 73 74 20 33 32 4b 20 onary (last 32K
6f70: 6f 66 20 64 61 74 61 20 74 68 61 74 20 77 61 73 of data that was
6f80: 20 63 6f 6d 70 72 65 73 73 65 64 29 20 2a 2f 0a compressed) */.
6f90: 20 20 20 20 20 20 20 20 73 74 72 63 70 79 28 6c strcpy(l
6fa0: 6f 67 2d 3e 65 6e 64 2c 20 22 2e 64 69 63 74 22 og->end, ".dict"
6fb0: 29 3b 0a 20 20 20 20 20 20 20 20 66 64 20 3d 20 );. fd =
6fc0: 6f 70 65 6e 28 6c 6f 67 2d 3e 70 61 74 68 2c 20 open(log->path,
6fd0: 4f 5f 52 44 4f 4e 4c 59 2c 20 30 29 3b 0a 20 20 O_RDONLY, 0);.
6fe0: 20 20 20 20 20 20 69 66 20 28 66 64 20 3e 3d 20 if (fd >=
6ff0: 30 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 0) {.
7000: 20 64 69 63 74 20 3d 20 72 65 61 64 28 66 64 2c dict = read(fd,
7010: 20 62 75 66 2c 20 44 49 43 54 29 3b 0a 20 20 20 buf, DICT);.
7020: 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 66 close(f
7030: 64 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 d);.
7040: 69 66 20 28 64 69 63 74 20 3c 20 30 29 20 7b 0a if (dict < 0) {.
7050: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
7060: 64 65 66 6c 61 74 65 45 6e 64 28 26 73 74 72 6d deflateEnd(&strm
7070: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 );.
7080: 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 return -1;.
7090: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 }.
70a0: 20 20 20 20 20 20 20 20 69 66 20 28 64 69 63 74 if (dict
70b0: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ).
70c0: 20 20 64 65 66 6c 61 74 65 53 65 74 44 69 63 74 deflateSetDict
70d0: 69 6f 6e 61 72 79 28 26 73 74 72 6d 2c 20 62 75 ionary(&strm, bu
70e0: 66 2c 20 28 75 69 6e 74 29 64 69 63 74 29 3b 0a f, (uint)dict);.
70f0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 }.
7100: 20 20 6c 6f 67 5f 74 6f 75 63 68 28 6c 6f 67 29 log_touch(log)
7110: 3b 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20 70 72 ;.. /* pr
7120: 69 6d 65 20 64 65 66 6c 61 74 65 20 77 69 74 68 ime deflate with
7130: 20 6c 61 73 74 20 62 69 74 73 20 6f 66 20 70 72 last bits of pr
7140: 65 76 69 6f 75 73 20 62 6c 6f 63 6b 2c 20 70 6f evious block, po
7150: 73 69 74 69 6f 6e 20 77 72 69 74 65 0a 20 20 20 sition write.
7160: 20 20 20 20 20 20 20 20 70 6f 69 6e 74 65 72 20 pointer
7170: 74 6f 20 77 72 69 74 65 20 74 68 6f 73 65 20 62 to write those b
7180: 69 74 73 20 61 6e 64 20 6f 76 65 72 77 72 69 74 its and overwrit
7190: 65 20 77 68 61 74 20 66 6f 6c 6c 6f 77 73 20 2a e what follows *
71a0: 2f 0a 20 20 20 20 20 20 20 20 69 66 20 28 6c 73 /. if (ls
71b0: 65 65 6b 28 6c 6f 67 2d 3e 66 64 2c 20 6c 6f 67 eek(log->fd, log
71c0: 2d 3e 66 69 72 73 74 20 2d 20 28 6c 6f 67 2d 3e ->first - (log->
71d0: 62 61 63 6b 20 3e 20 38 20 3f 20 32 20 3a 20 31 back > 8 ? 2 : 1
71e0: 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 ),.
71f0: 20 20 20 53 45 45 4b 5f 53 45 54 29 20 3c 20 30 SEEK_SET) < 0
7200: 20 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 ||.
7210: 72 65 61 64 28 6c 6f 67 2d 3e 66 64 2c 20 62 75 read(log->fd, bu
7220: 66 2c 20 31 29 20 21 3d 20 31 20 7c 7c 20 6c 73 f, 1) != 1 || ls
7230: 65 65 6b 28 6c 6f 67 2d 3e 66 64 2c 20 2d 31 2c eek(log->fd, -1,
7240: 20 53 45 45 4b 5f 43 55 52 29 20 3c 20 30 29 20 SEEK_CUR) < 0)
7250: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 65 {. de
7260: 66 6c 61 74 65 45 6e 64 28 26 73 74 72 6d 29 3b flateEnd(&strm);
7270: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 . ret
7280: 75 72 6e 20 2d 31 3b 0a 20 20 20 20 20 20 20 20 urn -1;.
7290: 7d 0a 20 20 20 20 20 20 20 20 64 65 66 6c 61 74 }. deflat
72a0: 65 50 72 69 6d 65 28 26 73 74 72 6d 2c 20 28 38 ePrime(&strm, (8
72b0: 20 2d 20 6c 6f 67 2d 3e 62 61 63 6b 29 20 26 20 - log->back) &
72c0: 37 2c 20 2a 62 75 66 29 3b 0a 0a 20 20 20 20 20 7, *buf);..
72d0: 20 20 20 2f 2a 20 63 6f 6d 70 72 65 73 73 2c 20 /* compress,
72e0: 66 69 6e 69 73 68 69 6e 67 20 77 69 74 68 20 61 finishing with a
72f0: 20 70 61 72 74 69 61 6c 20 6e 6f 6e 2d 6c 61 73 partial non-las
7300: 74 20 65 6d 70 74 79 20 73 74 61 74 69 63 20 62 t empty static b
7310: 6c 6f 63 6b 20 2a 2f 0a 20 20 20 20 20 20 20 20 lock */.
7320: 73 74 72 6d 2e 6e 65 78 74 5f 69 6e 20 3d 20 64 strm.next_in = d
7330: 61 74 61 3b 0a 20 20 20 20 20 20 20 20 6d 61 78 ata;. max
7340: 20 3d 20 28 28 28 75 69 6e 74 29 30 20 2d 20 31 = (((uint)0 - 1
7350: 29 20 3e 3e 20 31 29 20 2b 20 31 3b 20 2f 2a 20 ) >> 1) + 1; /*
7360: 69 6e 20 63 61 73 65 20 69 6e 74 20 73 6d 61 6c in case int smal
7370: 6c 65 72 20 74 68 61 6e 20 73 69 7a 65 5f 74 20 ler than size_t
7380: 2a 2f 0a 20 20 20 20 20 20 20 20 64 6f 20 7b 0a */. do {.
7390: 20 20 20 20 20 20 20 20 20 20 20 20 73 74 72 6d strm
73a0: 2e 61 76 61 69 6c 5f 69 6e 20 3d 20 6c 65 6e 20 .avail_in = len
73b0: 3e 20 6d 61 78 20 3f 20 6d 61 78 20 3a 20 28 75 > max ? max : (u
73c0: 69 6e 74 29 6c 65 6e 3b 0a 20 20 20 20 20 20 20 int)len;.
73d0: 20 20 20 20 20 6c 65 6e 20 2d 3d 20 73 74 72 6d len -= strm
73e0: 2e 61 76 61 69 6c 5f 69 6e 3b 0a 20 20 20 20 20 .avail_in;.
73f0: 20 20 20 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 do {.
7400: 20 20 20 20 20 20 20 20 20 20 20 20 73 74 72 6d strm
7410: 2e 61 76 61 69 6c 5f 6f 75 74 20 3d 20 44 49 43 .avail_out = DIC
7420: 54 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 T;.
7430: 20 20 20 73 74 72 6d 2e 6e 65 78 74 5f 6f 75 74 strm.next_out
7440: 20 3d 20 62 75 66 3b 0a 20 20 20 20 20 20 20 20 = buf;.
7450: 20 20 20 20 20 20 20 20 64 65 66 6c 61 74 65 28 deflate(
7460: 26 73 74 72 6d 2c 20 6c 65 6e 20 3f 20 5a 5f 4e &strm, len ? Z_N
7470: 4f 5f 46 4c 55 53 48 20 3a 20 5a 5f 50 41 52 54 O_FLUSH : Z_PART
7480: 49 41 4c 5f 46 4c 55 53 48 29 3b 0a 20 20 20 20 IAL_FLUSH);.
7490: 20 20 20 20 20 20 20 20 20 20 20 20 67 6f 74 20 got
74a0: 3d 20 44 49 43 54 20 2d 20 73 74 72 6d 2e 61 76 = DICT - strm.av
74b0: 61 69 6c 5f 6f 75 74 3b 0a 20 20 20 20 20 20 20 ail_out;.
74c0: 20 20 20 20 20 20 20 20 20 69 66 20 28 67 6f 74 if (got
74d0: 20 26 26 20 77 72 69 74 65 28 6c 6f 67 2d 3e 66 && write(log->f
74e0: 64 2c 20 62 75 66 2c 20 67 6f 74 29 20 21 3d 20 d, buf, got) !=
74f0: 67 6f 74 29 20 7b 0a 20 20 20 20 20 20 20 20 20 got) {.
7500: 20 20 20 20 20 20 20 20 20 20 20 64 65 66 6c 61 defla
7510: 74 65 45 6e 64 28 26 73 74 72 6d 29 3b 0a 20 20 teEnd(&strm);.
7520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
7530: 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 20 return -1;.
7540: 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 }.
7550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c l
7560: 6f 67 5f 74 6f 75 63 68 28 6c 6f 67 29 3b 0a 20 og_touch(log);.
7570: 20 20 20 20 20 20 20 20 20 20 20 7d 20 77 68 69 } whi
7580: 6c 65 20 28 73 74 72 6d 2e 61 76 61 69 6c 5f 6f le (strm.avail_o
7590: 75 74 20 3d 3d 20 30 29 3b 0a 20 20 20 20 20 20 ut == 0);.
75a0: 20 20 7d 20 77 68 69 6c 65 20 28 6c 65 6e 29 3b } while (len);
75b0: 0a 20 20 20 20 20 20 20 20 64 65 66 6c 61 74 65 . deflate
75c0: 45 6e 64 28 26 73 74 72 6d 29 3b 0a 20 20 20 20 End(&strm);.
75d0: 20 20 20 20 42 41 49 4c 28 35 29 3b 0a 0a 20 20 BAIL(5);..
75e0: 20 20 20 20 20 20 2f 2a 20 66 69 6e 64 20 73 74 /* find st
75f0: 61 72 74 20 6f 66 20 65 6d 70 74 79 20 73 74 61 art of empty sta
7600: 74 69 63 20 62 6c 6f 63 6b 20 2d 2d 20 73 63 61 tic block -- sca
7610: 6e 6e 69 6e 67 20 62 61 63 6b 77 61 72 64 73 20 nning backwards
7620: 74 68 65 20 66 69 72 73 74 20 6f 6e 65 0a 20 20 the first one.
7630: 20 20 20 20 20 20 20 20 20 62 69 74 20 69 73 20 bit is
7640: 74 68 65 20 73 65 63 6f 6e 64 20 62 69 74 20 6f the second bit o
7650: 66 20 74 68 65 20 62 6c 6f 63 6b 2c 20 69 66 20 f the block, if
7660: 74 68 65 20 6c 61 73 74 20 62 79 74 65 20 69 73 the last byte is
7670: 20 7a 65 72 6f 2c 20 74 68 65 6e 0a 20 20 20 20 zero, then.
7680: 20 20 20 20 20 20 20 77 65 20 6b 6e 6f 77 20 74 we know t
7690: 68 65 20 62 79 74 65 20 62 65 66 6f 72 65 20 74 he byte before t
76a0: 68 61 74 20 68 61 73 20 61 20 6f 6e 65 20 69 6e hat has a one in
76b0: 20 74 68 65 20 74 6f 70 20 62 69 74 2c 20 73 69 the top bit, si
76c0: 6e 63 65 20 61 6e 0a 20 20 20 20 20 20 20 20 20 nce an.
76d0: 20 20 65 6d 70 74 79 20 73 74 61 74 69 63 20 62 empty static b
76e0: 6c 6f 63 6b 20 69 73 20 74 65 6e 20 62 69 74 73 lock is ten bits
76f0: 20 6c 6f 6e 67 20 2a 2f 0a 20 20 20 20 20 20 20 long */.
7700: 20 69 66 20 28 28 6c 6f 67 2d 3e 66 69 72 73 74 if ((log->first
7710: 20 3d 20 6c 73 65 65 6b 28 6c 6f 67 2d 3e 66 64 = lseek(log->fd
7720: 2c 20 2d 31 2c 20 53 45 45 4b 5f 43 55 52 29 29 , -1, SEEK_CUR))
7730: 20 3c 20 30 20 7c 7c 0a 20 20 20 20 20 20 20 20 < 0 ||.
7740: 20 20 20 20 72 65 61 64 28 6c 6f 67 2d 3e 66 64 read(log->fd
7750: 2c 20 62 75 66 2c 20 31 29 20 21 3d 20 31 29 0a , buf, 1) != 1).
7760: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 retu
7770: 72 6e 20 2d 31 3b 0a 20 20 20 20 20 20 20 20 6c rn -1;. l
7780: 6f 67 2d 3e 66 69 72 73 74 2b 2b 3b 0a 20 20 20 og->first++;.
7790: 20 20 20 20 20 69 66 20 28 2a 62 75 66 29 20 7b if (*buf) {
77a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67 . log
77b0: 2d 3e 62 61 63 6b 20 3d 20 31 3b 0a 20 20 20 20 ->back = 1;.
77c0: 20 20 20 20 20 20 20 20 77 68 69 6c 65 20 28 28 while ((
77d0: 2a 62 75 66 20 26 20 28 28 75 69 6e 74 29 31 20 *buf & ((uint)1
77e0: 3c 3c 20 28 38 20 2d 20 6c 6f 67 2d 3e 62 61 63 << (8 - log->bac
77f0: 6b 2b 2b 29 29 29 20 3d 3d 20 30 29 0a 20 20 20 k++))) == 0).
7800: 20 20 20 20 20 20 20 20 20 20 20 20 20 3b 20 20 ;
7810: 20 20 20 20 20 2f 2a 20 67 75 61 72 61 6e 74 65 /* guarante
7820: 65 64 20 74 6f 20 74 65 72 6d 69 6e 61 74 65 2c ed to terminate,
7830: 20 73 69 6e 63 65 20 2a 62 75 66 20 21 3d 20 30 since *buf != 0
7840: 20 2a 2f 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 */. }.
7850: 20 20 20 20 20 20 65 6c 73 65 0a 20 20 20 20 20 else.
7860: 20 20 20 20 20 20 20 6c 6f 67 2d 3e 62 61 63 6b log->back
7870: 20 3d 20 31 30 3b 0a 0a 20 20 20 20 20 20 20 20 = 10;..
7880: 2f 2a 20 75 70 64 61 74 65 20 63 6f 6d 70 72 65 /* update compre
7890: 73 73 65 64 20 63 72 63 20 61 6e 64 20 6c 65 6e ssed crc and len
78a0: 67 74 68 20 2a 2f 0a 20 20 20 20 20 20 20 20 6c gth */. l
78b0: 6f 67 2d 3e 63 63 72 63 20 3d 20 6c 6f 67 2d 3e og->ccrc = log->
78c0: 74 63 72 63 3b 0a 20 20 20 20 20 20 20 20 6c 6f tcrc;. lo
78d0: 67 2d 3e 63 6c 65 6e 20 3d 20 6c 6f 67 2d 3e 74 g->clen = log->t
78e0: 6c 65 6e 3b 0a 20 20 20 20 7d 0a 20 20 20 20 65 len;. }. e
78f0: 6c 73 65 20 7b 0a 20 20 20 20 20 20 20 20 2f 2a lse {. /*
7900: 20 6e 6f 20 64 61 74 61 20 74 6f 20 63 6f 6d 70 no data to comp
7910: 72 65 73 73 20 2d 2d 20 66 69 78 20 75 70 20 65 ress -- fix up e
7920: 78 69 73 74 69 6e 67 20 67 7a 69 70 20 73 74 72 xisting gzip str
7930: 65 61 6d 20 2a 2f 0a 20 20 20 20 20 20 20 20 6c eam */. l
7940: 6f 67 2d 3e 74 63 72 63 20 3d 20 6c 6f 67 2d 3e og->tcrc = log->
7950: 63 63 72 63 3b 0a 20 20 20 20 20 20 20 20 6c 6f ccrc;. lo
7960: 67 2d 3e 74 6c 65 6e 20 3d 20 6c 6f 67 2d 3e 63 g->tlen = log->c
7970: 6c 65 6e 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 len;. }..
7980: 2f 2a 20 63 6f 6d 70 6c 65 74 65 20 61 6e 64 20 /* complete and
7990: 74 72 75 6e 63 61 74 65 20 67 7a 69 70 20 73 74 truncate gzip st
79a0: 72 65 61 6d 20 2a 2f 0a 20 20 20 20 6c 6f 67 2d ream */. log-
79b0: 3e 6c 61 73 74 20 3d 20 6c 6f 67 2d 3e 66 69 72 >last = log->fir
79c0: 73 74 3b 0a 20 20 20 20 6c 6f 67 2d 3e 73 74 6f st;. log->sto
79d0: 72 65 64 20 3d 20 30 3b 0a 20 20 20 20 50 55 54 red = 0;. PUT
79e0: 34 28 62 75 66 2c 20 6c 6f 67 2d 3e 74 63 72 63 4(buf, log->tcrc
79f0: 29 3b 0a 20 20 20 20 50 55 54 34 28 62 75 66 20 );. PUT4(buf
7a00: 2b 20 34 2c 20 6c 6f 67 2d 3e 74 6c 65 6e 29 3b + 4, log->tlen);
7a10: 0a 20 20 20 20 69 66 20 28 6c 6f 67 5f 6c 61 73 . if (log_las
7a20: 74 28 6c 6f 67 2c 20 31 29 20 7c 7c 20 77 72 69 t(log, 1) || wri
7a30: 74 65 28 6c 6f 67 2d 3e 66 64 2c 20 62 75 66 2c te(log->fd, buf,
7a40: 20 38 29 20 21 3d 20 38 20 7c 7c 0a 20 20 20 20 8) != 8 ||.
7a50: 20 20 20 20 28 65 6e 64 20 3d 20 6c 73 65 65 6b (end = lseek
7a60: 28 6c 6f 67 2d 3e 66 64 2c 20 30 2c 20 53 45 45 (log->fd, 0, SEE
7a70: 4b 5f 43 55 52 29 29 20 3c 20 30 20 7c 7c 20 66 K_CUR)) < 0 || f
7a80: 74 72 75 6e 63 61 74 65 28 6c 6f 67 2d 3e 66 64 truncate(log->fd
7a90: 2c 20 65 6e 64 29 29 0a 20 20 20 20 20 20 20 20 , end)).
7aa0: 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 20 20 42 return -1;. B
7ab0: 41 49 4c 28 36 29 3b 0a 0a 20 20 20 20 2f 2a 20 AIL(6);.. /*
7ac0: 6d 61 72 6b 20 61 73 20 62 65 69 6e 67 20 69 6e mark as being in
7ad0: 20 74 68 65 20 72 65 70 6c 61 63 65 20 6f 70 65 the replace ope
7ae0: 72 61 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 69 66 ration */. if
7af0: 20 28 6c 6f 67 5f 6d 61 72 6b 28 6c 6f 67 2c 20 (log_mark(log,
7b00: 52 45 50 4c 41 43 45 5f 4f 50 29 29 0a 20 20 20 REPLACE_OP)).
7b10: 20 20 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a return -1;.
7b20: 0a 20 20 20 20 2f 2a 20 65 78 65 63 75 74 65 20 . /* execute
7b30: 74 68 65 20 72 65 70 6c 61 63 65 20 6f 70 65 72 the replace oper
7b40: 61 74 69 6f 6e 20 61 6e 64 20 6d 61 72 6b 20 74 ation and mark t
7b50: 68 65 20 66 69 6c 65 20 61 73 20 64 6f 6e 65 20 he file as done
7b60: 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 6c 6f */. return lo
7b70: 67 5f 72 65 70 6c 61 63 65 28 6c 6f 67 29 3b 0a g_replace(log);.
7b80: 7d 0a 0a 2f 2a 20 6c 6f 67 20 61 20 72 65 70 61 }../* log a repa
7b90: 69 72 20 72 65 63 6f 72 64 20 74 6f 20 74 68 65 ir record to the
7ba0: 20 2e 72 65 70 61 69 72 73 20 66 69 6c 65 20 2a .repairs file *
7bb0: 2f 0a 6c 6f 63 61 6c 20 76 6f 69 64 20 6c 6f 67 /.local void log
7bc0: 5f 6c 6f 67 28 73 74 72 75 63 74 20 6c 6f 67 20 _log(struct log
7bd0: 2a 6c 6f 67 2c 20 69 6e 74 20 6f 70 2c 20 63 68 *log, int op, ch
7be0: 61 72 20 2a 72 65 63 6f 72 64 29 0a 7b 0a 20 20 ar *record).{.
7bf0: 20 20 74 69 6d 65 5f 74 20 6e 6f 77 3b 0a 20 20 time_t now;.
7c00: 20 20 46 49 4c 45 20 2a 72 65 63 3b 0a 0a 20 20 FILE *rec;..
7c10: 20 20 6e 6f 77 20 3d 20 74 69 6d 65 28 4e 55 4c now = time(NUL
7c20: 4c 29 3b 0a 20 20 20 20 73 74 72 63 70 79 28 6c L);. strcpy(l
7c30: 6f 67 2d 3e 65 6e 64 2c 20 22 2e 72 65 70 61 69 og->end, ".repai
7c40: 72 73 22 29 3b 0a 20 20 20 20 72 65 63 20 3d 20 rs");. rec =
7c50: 66 6f 70 65 6e 28 6c 6f 67 2d 3e 70 61 74 68 2c fopen(log->path,
7c60: 20 22 61 22 29 3b 0a 20 20 20 20 69 66 20 28 72 "a");. if (r
7c70: 65 63 20 3d 3d 20 4e 55 4c 4c 29 0a 20 20 20 20 ec == NULL).
7c80: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 return;.
7c90: 66 70 72 69 6e 74 66 28 72 65 63 2c 20 22 25 2e fprintf(rec, "%.
7ca0: 32 34 73 20 25 73 20 72 65 63 6f 76 65 72 79 3a 24s %s recovery:
7cb0: 20 25 73 5c 6e 22 2c 20 63 74 69 6d 65 28 26 6e %s\n", ctime(&n
7cc0: 6f 77 29 2c 20 6f 70 20 3d 3d 20 41 50 50 45 4e ow), op == APPEN
7cd0: 44 5f 4f 50 20 3f 0a 20 20 20 20 20 20 20 20 20 D_OP ?.
7ce0: 20 20 20 22 61 70 70 65 6e 64 22 20 3a 20 28 6f "append" : (o
7cf0: 70 20 3d 3d 20 43 4f 4d 50 52 45 53 53 5f 4f 50 p == COMPRESS_OP
7d00: 20 3f 20 22 63 6f 6d 70 72 65 73 73 22 20 3a 20 ? "compress" :
7d10: 22 72 65 70 6c 61 63 65 22 29 2c 20 72 65 63 6f "replace"), reco
7d20: 72 64 29 3b 0a 20 20 20 20 66 63 6c 6f 73 65 28 rd);. fclose(
7d30: 72 65 63 29 3b 0a 20 20 20 20 72 65 74 75 72 6e rec);. return
7d40: 3b 0a 7d 0a 0a 2f 2a 20 52 65 63 6f 76 65 72 20 ;.}../* Recover
7d50: 74 68 65 20 69 6e 74 65 72 72 75 70 74 65 64 20 the interrupted
7d60: 6f 70 65 72 61 74 69 6f 6e 20 6f 70 2e 20 20 46 operation op. F
7d70: 69 72 73 74 20 72 65 61 64 20 66 6f 6f 2e 61 64 irst read foo.ad
7d80: 64 20 66 6f 72 20 72 65 63 6f 76 65 72 69 6e 67 d for recovering
7d90: 20 61 6e 0a 20 20 20 61 70 70 65 6e 64 20 6f 72 an. append or
7da0: 20 63 6f 6d 70 72 65 73 73 20 6f 70 65 72 61 74 compress operat
7db0: 69 6f 6e 2e 20 20 52 65 74 75 72 6e 20 2d 31 20 ion. Return -1
7dc0: 69 66 20 74 68 65 72 65 20 77 61 73 20 61 6e 20 if there was an
7dd0: 65 72 72 6f 72 20 72 65 61 64 69 6e 67 20 6f 72 error reading or
7de0: 0a 20 20 20 77 72 69 74 69 6e 67 20 66 6f 6f 2e . writing foo.
7df0: 67 7a 20 6f 72 20 72 65 61 64 69 6e 67 20 61 6e gz or reading an
7e00: 20 65 78 69 73 74 69 6e 67 20 66 6f 6f 2e 61 64 existing foo.ad
7e10: 64 2c 20 6f 72 20 2d 32 20 69 66 20 74 68 65 72 d, or -2 if ther
7e20: 65 20 77 61 73 20 61 20 6d 65 6d 6f 72 79 0a 20 e was a memory.
7e30: 20 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 61 69 allocation fai
7e40: 6c 75 72 65 2e 20 2a 2f 0a 6c 6f 63 61 6c 20 69 lure. */.local i
7e50: 6e 74 20 6c 6f 67 5f 72 65 63 6f 76 65 72 28 73 nt log_recover(s
7e60: 74 72 75 63 74 20 6c 6f 67 20 2a 6c 6f 67 2c 20 truct log *log,
7e70: 69 6e 74 20 6f 70 29 0a 7b 0a 20 20 20 20 69 6e int op).{. in
7e80: 74 20 66 64 2c 20 72 65 74 20 3d 20 30 3b 0a 20 t fd, ret = 0;.
7e90: 20 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 unsigned char
7ea0: 20 2a 64 61 74 61 20 3d 20 4e 55 4c 4c 3b 0a 20 *data = NULL;.
7eb0: 20 20 20 73 69 7a 65 5f 74 20 6c 65 6e 20 3d 20 size_t len =
7ec0: 30 3b 0a 20 20 20 20 73 74 72 75 63 74 20 73 74 0;. struct st
7ed0: 61 74 20 73 74 3b 0a 0a 20 20 20 20 2f 2a 20 6c at st;.. /* l
7ee0: 6f 67 20 72 65 63 6f 76 65 72 79 20 2a 2f 0a 20 og recovery */.
7ef0: 20 20 20 6c 6f 67 5f 6c 6f 67 28 6c 6f 67 2c 20 log_log(log,
7f00: 6f 70 2c 20 22 73 74 61 72 74 22 29 3b 0a 0a 20 op, "start");..
7f10: 20 20 20 2f 2a 20 6c 6f 61 64 20 66 6f 6f 2e 61 /* load foo.a
7f20: 64 64 20 66 69 6c 65 20 69 66 20 65 78 70 65 63 dd file if expec
7f30: 74 65 64 20 61 6e 64 20 70 72 65 73 65 6e 74 20 ted and present
7f40: 2a 2f 0a 20 20 20 20 69 66 20 28 6f 70 20 3d 3d */. if (op ==
7f50: 20 41 50 50 45 4e 44 5f 4f 50 20 7c 7c 20 6f 70 APPEND_OP || op
7f60: 20 3d 3d 20 43 4f 4d 50 52 45 53 53 5f 4f 50 29 == COMPRESS_OP)
7f70: 20 7b 0a 20 20 20 20 20 20 20 20 73 74 72 63 70 {. strcp
7f80: 79 28 6c 6f 67 2d 3e 65 6e 64 2c 20 22 2e 61 64 y(log->end, ".ad
7f90: 64 22 29 3b 0a 20 20 20 20 20 20 20 20 69 66 20 d");. if
7fa0: 28 73 74 61 74 28 6c 6f 67 2d 3e 70 61 74 68 2c (stat(log->path,
7fb0: 20 26 73 74 29 20 3d 3d 20 30 20 26 26 20 73 74 &st) == 0 && st
7fc0: 2e 73 74 5f 73 69 7a 65 29 20 7b 0a 20 20 20 20 .st_size) {.
7fd0: 20 20 20 20 20 20 20 20 6c 65 6e 20 3d 20 28 73 len = (s
7fe0: 69 7a 65 5f 74 29 28 73 74 2e 73 74 5f 73 69 7a ize_t)(st.st_siz
7ff0: 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 e);.
8000: 69 66 20 28 6c 65 6e 20 21 3d 20 73 74 2e 73 74 if (len != st.st
8010: 5f 73 69 7a 65 20 7c 7c 20 28 64 61 74 61 20 3d _size || (data =
8020: 20 6d 61 6c 6c 6f 63 28 73 74 2e 73 74 5f 73 69 malloc(st.st_si
8030: 7a 65 29 29 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a ze)) == NULL) {.
8040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8050: 6c 6f 67 5f 6c 6f 67 28 6c 6f 67 2c 20 6f 70 2c log_log(log, op,
8060: 20 22 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 61 69 "allocation fai
8070: 6c 75 72 65 22 29 3b 0a 20 20 20 20 20 20 20 20 lure");.
8080: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 2d return -
8090: 32 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 2;. }
80a0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 . if
80b0: 28 28 66 64 20 3d 20 6f 70 65 6e 28 6c 6f 67 2d ((fd = open(log-
80c0: 3e 70 61 74 68 2c 20 4f 5f 52 44 4f 4e 4c 59 2c >path, O_RDONLY,
80d0: 20 30 29 29 20 3c 20 30 29 20 7b 0a 20 20 20 20 0)) < 0) {.
80e0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67 5f log_
80f0: 6c 6f 67 28 6c 6f 67 2c 20 6f 70 2c 20 22 2e 61 log(log, op, ".a
8100: 64 64 20 66 69 6c 65 20 72 65 61 64 20 66 61 69 dd file read fai
8110: 6c 75 72 65 22 29 3b 0a 20 20 20 20 20 20 20 20 lure");.
8120: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 2d return -
8130: 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 1;. }
8140: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 . ret
8150: 20 3d 20 72 65 61 64 28 66 64 2c 20 64 61 74 61 = read(fd, data
8160: 2c 20 6c 65 6e 29 20 21 3d 20 6c 65 6e 3b 0a 20 , len) != len;.
8170: 20 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 close
8180: 28 66 64 29 3b 0a 20 20 20 20 20 20 20 20 20 20 (fd);.
8190: 20 20 69 66 20 28 72 65 74 29 20 7b 0a 20 20 20 if (ret) {.
81a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f 67 log
81b0: 5f 6c 6f 67 28 6c 6f 67 2c 20 6f 70 2c 20 22 2e _log(log, op, ".
81c0: 61 64 64 20 66 69 6c 65 20 72 65 61 64 20 66 61 add file read fa
81d0: 69 6c 75 72 65 22 29 3b 0a 20 20 20 20 20 20 20 ilure");.
81e0: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 return
81f0: 2d 31 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 -1;.
8200: 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 6c 6f }. lo
8210: 67 5f 6c 6f 67 28 6c 6f 67 2c 20 6f 70 2c 20 22 g_log(log, op, "
8220: 6c 6f 61 64 65 64 20 2e 61 64 64 20 66 69 6c 65 loaded .add file
8230: 22 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 ");. }.
8240: 20 20 20 20 20 20 65 6c 73 65 0a 20 20 20 20 20 else.
8250: 20 20 20 20 20 20 20 6c 6f 67 5f 6c 6f 67 28 6c log_log(l
8260: 6f 67 2c 20 6f 70 2c 20 22 6d 69 73 73 69 6e 67 og, op, "missing
8270: 20 2e 61 64 64 20 66 69 6c 65 21 22 29 3b 0a 20 .add file!");.
8280: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 72 65 63 }.. /* rec
8290: 6f 76 65 72 20 74 68 65 20 69 6e 74 65 72 72 75 over the interru
82a0: 70 74 65 64 20 6f 70 65 72 61 74 69 6f 6e 20 2a pted operation *
82b0: 2f 0a 20 20 20 20 73 77 69 74 63 68 20 28 6f 70 /. switch (op
82c0: 29 20 7b 0a 20 20 20 20 63 61 73 65 20 41 50 50 ) {. case APP
82d0: 45 4e 44 5f 4f 50 3a 0a 20 20 20 20 20 20 20 20 END_OP:.
82e0: 72 65 74 20 3d 20 6c 6f 67 5f 61 70 70 65 6e 64 ret = log_append
82f0: 28 6c 6f 67 2c 20 64 61 74 61 2c 20 6c 65 6e 29 (log, data, len)
8300: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b ;. break;
8310: 0a 20 20 20 20 63 61 73 65 20 43 4f 4d 50 52 45 . case COMPRE
8320: 53 53 5f 4f 50 3a 0a 20 20 20 20 20 20 20 20 72 SS_OP:. r
8330: 65 74 20 3d 20 6c 6f 67 5f 63 6f 6d 70 72 65 73 et = log_compres
8340: 73 28 6c 6f 67 2c 20 64 61 74 61 2c 20 6c 65 6e s(log, data, len
8350: 29 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b );. break
8360: 3b 0a 20 20 20 20 63 61 73 65 20 52 45 50 4c 41 ;. case REPLA
8370: 43 45 5f 4f 50 3a 0a 20 20 20 20 20 20 20 20 72 CE_OP:. r
8380: 65 74 20 3d 20 6c 6f 67 5f 72 65 70 6c 61 63 65 et = log_replace
8390: 28 6c 6f 67 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 (log);. }..
83a0: 20 20 2f 2a 20 6c 6f 67 20 73 74 61 74 75 73 20 /* log status
83b0: 2a 2f 0a 20 20 20 20 6c 6f 67 5f 6c 6f 67 28 6c */. log_log(l
83c0: 6f 67 2c 20 6f 70 2c 20 72 65 74 20 3f 20 22 66 og, op, ret ? "f
83d0: 61 69 6c 75 72 65 22 20 3a 20 22 63 6f 6d 70 6c ailure" : "compl
83e0: 65 74 65 22 29 3b 0a 0a 20 20 20 20 2f 2a 20 63 ete");.. /* c
83f0: 6c 65 61 6e 20 75 70 20 2a 2f 0a 20 20 20 20 69 lean up */. i
8400: 66 20 28 64 61 74 61 20 21 3d 20 4e 55 4c 4c 29 f (data != NULL)
8410: 0a 20 20 20 20 20 20 20 20 66 72 65 65 28 64 61 . free(da
8420: 74 61 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 ta);. return
8430: 72 65 74 3b 0a 7d 0a 0a 2f 2a 20 43 6c 6f 73 65 ret;.}../* Close
8440: 20 74 68 65 20 66 6f 6f 2e 67 7a 20 66 69 6c 65 the foo.gz file
8450: 20 28 69 66 20 6f 70 65 6e 29 20 61 6e 64 20 72 (if open) and r
8460: 65 6c 65 61 73 65 20 74 68 65 20 6c 6f 63 6b 2e elease the lock.
8470: 20 2a 2f 0a 6c 6f 63 61 6c 20 76 6f 69 64 20 6c */.local void l
8480: 6f 67 5f 63 6c 6f 73 65 28 73 74 72 75 63 74 20 og_close(struct
8490: 6c 6f 67 20 2a 6c 6f 67 29 0a 7b 0a 20 20 20 20 log *log).{.
84a0: 69 66 20 28 6c 6f 67 2d 3e 66 64 20 3e 3d 20 30 if (log->fd >= 0
84b0: 29 0a 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 ). close(
84c0: 6c 6f 67 2d 3e 66 64 29 3b 0a 20 20 20 20 6c 6f log->fd);. lo
84d0: 67 2d 3e 66 64 20 3d 20 2d 31 3b 0a 20 20 20 20 g->fd = -1;.
84e0: 6c 6f 67 5f 75 6e 6c 6f 63 6b 28 6c 6f 67 29 3b log_unlock(log);
84f0: 0a 7d 0a 0a 2f 2a 20 4f 70 65 6e 20 66 6f 6f 2e .}../* Open foo.
8500: 67 7a 2c 20 76 65 72 69 66 79 20 74 68 65 20 68 gz, verify the h
8510: 65 61 64 65 72 2c 20 61 6e 64 20 6c 6f 61 64 20 eader, and load
8520: 74 68 65 20 65 78 74 72 61 20 66 69 65 6c 64 20 the extra field
8530: 63 6f 6e 74 65 6e 74 73 2c 20 61 66 74 65 72 0a contents, after.
8540: 20 20 20 66 69 72 73 74 20 63 72 65 61 74 69 6e first creatin
8550: 67 20 74 68 65 20 66 6f 6f 2e 6c 6f 63 6b 20 66 g the foo.lock f
8560: 69 6c 65 20 74 6f 20 67 61 69 6e 20 65 78 63 6c ile to gain excl
8570: 75 73 69 76 65 20 61 63 63 65 73 73 20 74 6f 20 usive access to
8580: 74 68 65 20 66 6f 6f 2e 2a 0a 20 20 20 66 69 6c the foo.*. fil
8590: 65 73 2e 20 20 49 66 20 66 6f 6f 2e 67 7a 20 64 es. If foo.gz d
85a0: 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 6f 72 oes not exist or
85b0: 20 69 73 20 65 6d 70 74 79 2c 20 74 68 65 6e 20 is empty, then
85c0: 77 72 69 74 65 20 74 68 65 20 69 6e 69 74 69 61 write the initia
85d0: 6c 20 68 65 61 64 65 72 2c 0a 20 20 20 65 78 74 l header,. ext
85e0: 72 61 2c 20 61 6e 64 20 62 6f 64 79 20 63 6f 6e ra, and body con
85f0: 74 65 6e 74 20 6f 66 20 61 6e 20 65 6d 70 74 79 tent of an empty
8600: 20 66 6f 6f 2e 67 7a 20 6c 6f 67 20 66 69 6c 65 foo.gz log file
8610: 2e 20 20 49 66 20 74 68 65 72 65 20 69 73 20 61 . If there is a
8620: 6e 20 65 72 72 6f 72 0a 20 20 20 63 72 65 61 74 n error. creat
8630: 69 6e 67 20 74 68 65 20 6c 6f 63 6b 20 66 69 6c ing the lock fil
8640: 65 20 64 75 65 20 74 6f 20 61 63 63 65 73 73 20 e due to access
8650: 72 65 73 74 72 69 63 74 69 6f 6e 73 2c 20 6f 72 restrictions, or
8660: 20 61 6e 20 65 72 72 6f 72 20 72 65 61 64 69 6e an error readin
8670: 67 20 6f 72 0a 20 20 20 77 72 69 74 69 6e 67 20 g or. writing
8680: 74 68 65 20 66 6f 6f 2e 67 7a 20 66 69 6c 65 2c the foo.gz file,
8690: 20 6f 72 20 69 66 20 74 68 65 20 66 6f 6f 2e 67 or if the foo.g
86a0: 7a 20 66 69 6c 65 20 69 73 20 6e 6f 74 20 61 20 z file is not a
86b0: 70 72 6f 70 65 72 20 6c 6f 67 20 66 69 6c 65 20 proper log file
86c0: 66 6f 72 0a 20 20 20 74 68 69 73 20 6f 62 6a 65 for. this obje
86d0: 63 74 20 28 65 2e 67 2e 20 6e 6f 74 20 61 20 67 ct (e.g. not a g
86e0: 7a 69 70 20 66 69 6c 65 20 6f 72 20 64 6f 65 73 zip file or does
86f0: 20 6e 6f 74 20 63 6f 6e 74 61 69 6e 20 74 68 65 not contain the
8700: 20 65 78 70 65 63 74 65 64 20 65 78 74 72 61 0a expected extra.
8710: 20 20 20 66 69 65 6c 64 29 2c 20 74 68 65 6e 20 field), then
8720: 72 65 74 75 72 6e 20 74 72 75 65 2e 20 20 49 66 return true. If
8730: 20 74 68 65 72 65 20 69 73 20 61 6e 20 65 72 72 there is an err
8740: 6f 72 2c 20 74 68 65 20 6c 6f 63 6b 20 69 73 20 or, the lock is
8750: 72 65 6c 65 61 73 65 64 2e 0a 20 20 20 4f 74 68 released.. Oth
8760: 65 72 77 69 73 65 2c 20 74 68 65 20 6c 6f 63 6b erwise, the lock
8770: 20 69 73 20 6c 65 66 74 20 69 6e 20 70 6c 61 63 is left in plac
8780: 65 2e 20 2a 2f 0a 6c 6f 63 61 6c 20 69 6e 74 20 e. */.local int
8790: 6c 6f 67 5f 6f 70 65 6e 28 73 74 72 75 63 74 20 log_open(struct
87a0: 6c 6f 67 20 2a 6c 6f 67 29 0a 7b 0a 20 20 20 20 log *log).{.
87b0: 69 6e 74 20 6f 70 3b 0a 0a 20 20 20 20 2f 2a 20 int op;.. /*
87c0: 72 65 6c 65 61 73 65 20 6f 70 65 6e 20 66 69 6c release open fil
87d0: 65 20 72 65 73 6f 75 72 63 65 20 69 66 20 6c 65 e resource if le
87e0: 66 74 20 6f 76 65 72 20 2d 2d 20 63 61 6e 20 6f ft over -- can o
87f0: 63 63 75 72 20 69 66 20 6c 6f 63 6b 20 6c 6f 73 ccur if lock los
8800: 74 0a 20 20 20 20 20 20 20 62 65 74 77 65 65 6e t. between
8810: 20 67 7a 6c 6f 67 5f 6f 70 65 6e 28 29 20 61 6e gzlog_open() an
8820: 64 20 67 7a 6c 6f 67 5f 77 72 69 74 65 28 29 20 d gzlog_write()
8830: 2a 2f 0a 20 20 20 20 69 66 20 28 6c 6f 67 2d 3e */. if (log->
8840: 66 64 20 3e 3d 20 30 29 0a 20 20 20 20 20 20 20 fd >= 0).
8850: 20 63 6c 6f 73 65 28 6c 6f 67 2d 3e 66 64 29 3b close(log->fd);
8860: 0a 20 20 20 20 6c 6f 67 2d 3e 66 64 20 3d 20 2d . log->fd = -
8870: 31 3b 0a 0a 20 20 20 20 2f 2a 20 6e 65 67 6f 74 1;.. /* negot
8880: 69 61 74 65 20 65 78 63 6c 75 73 69 76 65 20 61 iate exclusive a
8890: 63 63 65 73 73 20 2a 2f 0a 20 20 20 20 69 66 20 ccess */. if
88a0: 28 6c 6f 67 5f 6c 6f 63 6b 28 6c 6f 67 29 20 3c (log_lock(log) <
88b0: 20 30 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 0). retu
88c0: 72 6e 20 2d 31 3b 0a 0a 20 20 20 20 2f 2a 20 6f rn -1;.. /* o
88d0: 70 65 6e 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 pen the log file
88e0: 2c 20 66 6f 6f 2e 67 7a 20 2a 2f 0a 20 20 20 20 , foo.gz */.
88f0: 73 74 72 63 70 79 28 6c 6f 67 2d 3e 65 6e 64 2c strcpy(log->end,
8900: 20 22 2e 67 7a 22 29 3b 0a 20 20 20 20 6c 6f 67 ".gz");. log
8910: 2d 3e 66 64 20 3d 20 6f 70 65 6e 28 6c 6f 67 2d ->fd = open(log-
8920: 3e 70 61 74 68 2c 20 4f 5f 52 44 57 52 20 7c 20 >path, O_RDWR |
8930: 4f 5f 43 52 45 41 54 2c 20 30 36 34 34 29 3b 0a O_CREAT, 0644);.
8940: 20 20 20 20 69 66 20 28 6c 6f 67 2d 3e 66 64 20 if (log->fd
8950: 3c 20 30 29 20 7b 0a 20 20 20 20 20 20 20 20 6c < 0) {. l
8960: 6f 67 5f 63 6c 6f 73 65 28 6c 6f 67 29 3b 0a 20 og_close(log);.
8970: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 2d 31 return -1
8980: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 ;. }.. /*
8990: 69 66 20 6e 65 77 2c 20 69 6e 69 74 69 61 6c 69 if new, initiali
89a0: 7a 65 20 66 6f 6f 2e 67 7a 20 77 69 74 68 20 61 ze foo.gz with a
89b0: 6e 20 65 6d 70 74 79 20 6c 6f 67 2c 20 64 65 6c n empty log, del
89c0: 65 74 65 20 6f 6c 64 20 64 69 63 74 69 6f 6e 61 ete old dictiona
89d0: 72 79 20 2a 2f 0a 20 20 20 20 69 66 20 28 6c 73 ry */. if (ls
89e0: 65 65 6b 28 6c 6f 67 2d 3e 66 64 2c 20 30 2c 20 eek(log->fd, 0,
89f0: 53 45 45 4b 5f 45 4e 44 29 20 3d 3d 20 30 29 20 SEEK_END) == 0)
8a00: 7b 0a 20 20 20 20 20 20 20 20 69 66 20 28 77 72 {. if (wr
8a10: 69 74 65 28 6c 6f 67 2d 3e 66 64 2c 20 6c 6f 67 ite(log->fd, log
8a20: 5f 67 7a 68 65 61 64 2c 20 48 45 41 44 29 20 21 _gzhead, HEAD) !
8a30: 3d 20 48 45 41 44 20 7c 7c 0a 20 20 20 20 20 20 = HEAD ||.
8a40: 20 20 20 20 20 20 77 72 69 74 65 28 6c 6f 67 2d write(log-
8a50: 3e 66 64 2c 20 6c 6f 67 5f 67 7a 65 78 74 2c 20 >fd, log_gzext,
8a60: 45 58 54 52 41 29 20 21 3d 20 45 58 54 52 41 20 EXTRA) != EXTRA
8a70: 7c 7c 0a 20 20 20 20 20 20 20 20 20 20 20 20 77 ||. w
8a80: 72 69 74 65 28 6c 6f 67 2d 3e 66 64 2c 20 6c 6f rite(log->fd, lo
8a90: 67 5f 67 7a 62 6f 64 79 2c 20 42 4f 44 59 29 20 g_gzbody, BODY)
8aa0: 21 3d 20 42 4f 44 59 29 20 7b 0a 20 20 20 20 20 != BODY) {.
8ab0: 20 20 20 20 20 20 20 6c 6f 67 5f 63 6c 6f 73 65 log_close
8ac0: 28 6c 6f 67 29 3b 0a 20 20 20 20 20 20 20 20 20 (log);.
8ad0: 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 return -1;.
8ae0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 }.
8af0: 73 74 72 63 70 79 28 6c 6f 67 2d 3e 65 6e 64 2c strcpy(log->end,
8b00: 20 22 2e 64 69 63 74 22 29 3b 0a 20 20 20 20 20 ".dict");.
8b10: 20 20 20 75 6e 6c 69 6e 6b 28 6c 6f 67 2d 3e 70 unlink(log->p
8b20: 61 74 68 29 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 ath);. }..
8b30: 20 2f 2a 20 76 65 72 69 66 79 20 6c 6f 67 20 66 /* verify log f
8b40: 69 6c 65 20 61 6e 64 20 6c 6f 61 64 20 65 78 74 ile and load ext
8b50: 72 61 20 66 69 65 6c 64 20 69 6e 66 6f 72 6d 61 ra field informa
8b60: 74 69 6f 6e 20 2a 2f 0a 20 20 20 20 69 66 20 28 tion */. if (
8b70: 28 6f 70 20 3d 20 6c 6f 67 5f 68 65 61 64 28 6c (op = log_head(l
8b80: 6f 67 29 29 20 3c 20 30 29 20 7b 0a 20 20 20 20 og)) < 0) {.
8b90: 20 20 20 20 6c 6f 67 5f 63 6c 6f 73 65 28 6c 6f log_close(lo
8ba0: 67 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 g);. retu
8bb0: 72 6e 20 2d 31 3b 0a 20 20 20 20 7d 0a 0a 20 20 rn -1;. }..
8bc0: 20 20 2f 2a 20 63 68 65 63 6b 20 66 6f 72 20 69 /* check for i
8bd0: 6e 74 65 72 72 75 70 74 65 64 20 70 72 6f 63 65 nterrupted proce
8be0: 73 73 20 61 6e 64 20 69 66 20 73 6f 2c 20 72 65 ss and if so, re
8bf0: 63 6f 76 65 72 20 2a 2f 0a 20 20 20 20 69 66 20 cover */. if
8c00: 28 6f 70 20 21 3d 20 4e 4f 5f 4f 50 20 26 26 20 (op != NO_OP &&
8c10: 6c 6f 67 5f 72 65 63 6f 76 65 72 28 6c 6f 67 2c log_recover(log,
8c20: 20 6f 70 29 29 20 7b 0a 20 20 20 20 20 20 20 20 op)) {.
8c30: 6c 6f 67 5f 63 6c 6f 73 65 28 6c 6f 67 29 3b 0a log_close(log);.
8c40: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 2d return -
8c50: 31 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 1;. }.. /*
8c60: 20 74 6f 75 63 68 20 74 68 65 20 6c 6f 63 6b 20 touch the lock
8c70: 66 69 6c 65 20 74 6f 20 70 72 65 76 65 6e 74 20 file to prevent
8c80: 61 6e 6f 74 68 65 72 20 70 72 6f 63 65 73 73 20 another process
8c90: 66 72 6f 6d 20 67 72 61 62 62 69 6e 67 20 69 74 from grabbing it
8ca0: 20 2a 2f 0a 20 20 20 20 6c 6f 67 5f 74 6f 75 63 */. log_touc
8cb0: 68 28 6c 6f 67 29 3b 0a 20 20 20 20 72 65 74 75 h(log);. retu
8cc0: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 20 53 65 65 20 rn 0;.}../* See
8cd0: 67 7a 6c 6f 67 2e 68 20 66 6f 72 20 74 68 65 20 gzlog.h for the
8ce0: 64 65 73 63 72 69 70 74 69 6f 6e 20 6f 66 20 74 description of t
8cf0: 68 65 20 65 78 74 65 72 6e 61 6c 20 6d 65 74 68 he external meth
8d00: 6f 64 73 20 62 65 6c 6f 77 20 2a 2f 0a 67 7a 6c ods below */.gzl
8d10: 6f 67 20 2a 67 7a 6c 6f 67 5f 6f 70 65 6e 28 63 og *gzlog_open(c
8d20: 68 61 72 20 2a 70 61 74 68 29 0a 7b 0a 20 20 20 har *path).{.
8d30: 20 73 69 7a 65 5f 74 20 6e 3b 0a 20 20 20 20 73 size_t n;. s
8d40: 74 72 75 63 74 20 6c 6f 67 20 2a 6c 6f 67 3b 0a truct log *log;.
8d50: 0a 20 20 20 20 2f 2a 20 63 68 65 63 6b 20 61 72 . /* check ar
8d60: 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 20 20 69 guments */. i
8d70: 66 20 28 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 20 f (path == NULL
8d80: 7c 7c 20 2a 70 61 74 68 20 3d 3d 20 30 29 0a 20 || *path == 0).
8d90: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e 55 return NU
8da0: 4c 4c 3b 0a 0a 20 20 20 20 2f 2a 20 61 6c 6c 6f LL;.. /* allo
8db0: 63 61 74 65 20 61 6e 64 20 69 6e 69 74 69 61 6c cate and initial
8dc0: 69 7a 65 20 6c 6f 67 20 73 74 72 75 63 74 75 72 ize log structur
8dd0: 65 20 2a 2f 0a 20 20 20 20 6c 6f 67 20 3d 20 6d e */. log = m
8de0: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 73 74 72 alloc(sizeof(str
8df0: 75 63 74 20 6c 6f 67 29 29 3b 0a 20 20 20 20 69 uct log));. i
8e00: 66 20 28 6c 6f 67 20 3d 3d 20 4e 55 4c 4c 29 0a f (log == NULL).
8e10: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e return N
8e20: 55 4c 4c 3b 0a 20 20 20 20 73 74 72 63 70 79 28 ULL;. strcpy(
8e30: 6c 6f 67 2d 3e 69 64 2c 20 4c 4f 47 49 44 29 3b log->id, LOGID);
8e40: 0a 20 20 20 20 6c 6f 67 2d 3e 66 64 20 3d 20 2d . log->fd = -
8e50: 31 3b 0a 0a 20 20 20 20 2f 2a 20 73 61 76 65 20 1;.. /* save
8e60: 70 61 74 68 20 61 6e 64 20 65 6e 64 20 6f 66 20 path and end of
8e70: 70 61 74 68 20 66 6f 72 20 6e 61 6d 65 20 63 6f path for name co
8e80: 6e 73 74 72 75 63 74 69 6f 6e 20 2a 2f 0a 20 20 nstruction */.
8e90: 20 20 6e 20 3d 20 73 74 72 6c 65 6e 28 70 61 74 n = strlen(pat
8ea0: 68 29 3b 0a 20 20 20 20 6c 6f 67 2d 3e 70 61 74 h);. log->pat
8eb0: 68 20 3d 20 6d 61 6c 6c 6f 63 28 6e 20 2b 20 39 h = malloc(n + 9
8ec0: 29 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 );
8ed0: 2f 2a 20 61 6c 6c 6f 77 20 66 6f 72 20 22 2e 72 /* allow for ".r
8ee0: 65 70 61 69 72 73 22 20 2a 2f 0a 20 20 20 20 69 epairs" */. i
8ef0: 66 20 28 6c 6f 67 2d 3e 70 61 74 68 20 3d 3d 20 f (log->path ==
8f00: 4e 55 4c 4c 29 20 7b 0a 20 20 20 20 20 20 20 20 NULL) {.
8f10: 66 72 65 65 28 6c 6f 67 29 3b 0a 20 20 20 20 20 free(log);.
8f20: 20 20 20 72 65 74 75 72 6e 20 4e 55 4c 4c 3b 0a return NULL;.
8f30: 20 20 20 20 7d 0a 20 20 20 20 73 74 72 63 70 79 }. strcpy
8f40: 28 6c 6f 67 2d 3e 70 61 74 68 2c 20 70 61 74 68 (log->path, path
8f50: 29 3b 0a 20 20 20 20 6c 6f 67 2d 3e 65 6e 64 20 );. log->end
8f60: 3d 20 6c 6f 67 2d 3e 70 61 74 68 20 2b 20 6e 3b = log->path + n;
8f70: 0a 0a 20 20 20 20 2f 2a 20 67 61 69 6e 20 65 78 .. /* gain ex
8f80: 63 6c 75 73 69 76 65 20 61 63 63 65 73 73 20 61 clusive access a
8f90: 6e 64 20 76 65 72 69 66 79 20 6c 6f 67 20 66 69 nd verify log fi
8fa0: 6c 65 20 2d 2d 20 6d 61 79 20 70 65 72 66 6f 72 le -- may perfor
8fb0: 6d 20 61 0a 20 20 20 20 20 20 20 72 65 63 6f 76 m a. recov
8fc0: 65 72 79 20 6f 70 65 72 61 74 69 6f 6e 20 69 66 ery operation if
8fd0: 20 6e 65 65 64 65 64 20 2a 2f 0a 20 20 20 20 69 needed */. i
8fe0: 66 20 28 6c 6f 67 5f 6f 70 65 6e 28 6c 6f 67 29 f (log_open(log)
8ff0: 29 20 7b 0a 20 20 20 20 20 20 20 20 66 72 65 65 ) {. free
9000: 28 6c 6f 67 2d 3e 70 61 74 68 29 3b 0a 20 20 20 (log->path);.
9010: 20 20 20 20 20 66 72 65 65 28 6c 6f 67 29 3b 0a free(log);.
9020: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 4e return N
9030: 55 4c 4c 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 ULL;. }..
9040: 2f 2a 20 72 65 74 75 72 6e 20 70 6f 69 6e 74 65 /* return pointe
9050: 72 20 74 6f 20 6c 6f 67 20 73 74 72 75 63 74 75 r to log structu
9060: 72 65 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e re */. return
9070: 20 6c 6f 67 3b 0a 7d 0a 0a 2f 2a 20 67 7a 6c 6f log;.}../* gzlo
9080: 67 5f 63 6f 6d 70 72 65 73 73 28 29 20 72 65 74 g_compress() ret
9090: 75 72 6e 20 76 61 6c 75 65 73 3a 0a 20 20 20 20 urn values:.
90a0: 30 3a 20 61 6c 6c 20 67 6f 6f 64 0a 20 20 20 2d 0: all good. -
90b0: 31 3a 20 66 69 6c 65 20 69 2f 6f 20 65 72 72 6f 1: file i/o erro
90c0: 72 20 28 75 73 75 61 6c 6c 79 20 61 63 63 65 73 r (usually acces
90d0: 73 20 69 73 73 75 65 29 0a 20 20 20 2d 32 3a 20 s issue). -2:
90e0: 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61 74 69 6f memory allocatio
90f0: 6e 20 66 61 69 6c 75 72 65 0a 20 20 20 2d 33 3a n failure. -3:
9100: 20 69 6e 76 61 6c 69 64 20 6c 6f 67 20 70 6f 69 invalid log poi
9110: 6e 74 65 72 20 61 72 67 75 6d 65 6e 74 20 2a 2f nter argument */
9120: 0a 69 6e 74 20 67 7a 6c 6f 67 5f 63 6f 6d 70 72 .int gzlog_compr
9130: 65 73 73 28 67 7a 6c 6f 67 20 2a 6c 6f 67 64 29 ess(gzlog *logd)
9140: 0a 7b 0a 20 20 20 20 69 6e 74 20 66 64 2c 20 72 .{. int fd, r
9150: 65 74 3b 0a 20 20 20 20 75 69 6e 74 20 62 6c 6f et;. uint blo
9160: 63 6b 3b 0a 20 20 20 20 73 69 7a 65 5f 74 20 6c ck;. size_t l
9170: 65 6e 2c 20 6e 65 78 74 3b 0a 20 20 20 20 75 6e en, next;. un
9180: 73 69 67 6e 65 64 20 63 68 61 72 20 2a 64 61 74 signed char *dat
9190: 61 2c 20 62 75 66 5b 35 5d 3b 0a 20 20 20 20 73 a, buf[5];. s
91a0: 74 72 75 63 74 20 6c 6f 67 20 2a 6c 6f 67 20 3d truct log *log =
91b0: 20 6c 6f 67 64 3b 0a 0a 20 20 20 20 2f 2a 20 63 logd;.. /* c
91c0: 68 65 63 6b 20 61 72 67 75 6d 65 6e 74 73 20 2a heck arguments *
91d0: 2f 0a 20 20 20 20 69 66 20 28 6c 6f 67 20 3d 3d /. if (log ==
91e0: 20 4e 55 4c 4c 20 7c 7c 20 73 74 72 63 6d 70 28 NULL || strcmp(
91f0: 6c 6f 67 2d 3e 69 64 2c 20 4c 4f 47 49 44 29 20 log->id, LOGID)
9200: 7c 7c 20 6c 65 6e 20 3c 20 30 29 0a 20 20 20 20 || len < 0).
9210: 20 20 20 20 72 65 74 75 72 6e 20 2d 33 3b 0a 0a return -3;..
9220: 20 20 20 20 2f 2a 20 73 65 65 20 69 66 20 77 65 /* see if we
9230: 20 6c 6f 73 74 20 74 68 65 20 6c 6f 63 6b 20 2d lost the lock -
9240: 2d 20 69 66 20 73 6f 20 67 65 74 20 69 74 20 61 - if so get it a
9250: 67 61 69 6e 20 61 6e 64 20 72 65 6c 6f 61 64 20 gain and reload
9260: 74 68 65 20 65 78 74 72 61 0a 20 20 20 20 20 20 the extra.
9270: 20 66 69 65 6c 64 20 69 6e 66 6f 72 6d 61 74 69 field informati
9280: 6f 6e 20 28 69 74 20 70 72 6f 62 61 62 6c 79 20 on (it probably
9290: 63 68 61 6e 67 65 64 29 2c 20 72 65 63 6f 76 65 changed), recove
92a0: 72 20 6c 61 73 74 20 6f 70 65 72 61 74 69 6f 6e r last operation
92b0: 20 69 66 0a 20 20 20 20 20 20 20 6e 65 63 65 73 if. neces
92c0: 73 61 72 79 20 2a 2f 0a 20 20 20 20 69 66 20 28 sary */. if (
92d0: 6c 6f 67 5f 63 68 65 63 6b 28 6c 6f 67 29 20 26 log_check(log) &
92e0: 26 20 6c 6f 67 5f 6f 70 65 6e 28 6c 6f 67 29 29 & log_open(log))
92f0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 . return
9300: 2d 31 3b 0a 0a 20 20 20 20 2f 2a 20 63 72 65 61 -1;.. /* crea
9310: 74 65 20 73 70 61 63 65 20 66 6f 72 20 75 6e 63 te space for unc
9320: 6f 6d 70 72 65 73 73 65 64 20 64 61 74 61 20 2a ompressed data *
9330: 2f 0a 20 20 20 20 6c 65 6e 20 3d 20 28 28 73 69 /. len = ((si
9340: 7a 65 5f 74 29 28 6c 6f 67 2d 3e 6c 61 73 74 20 ze_t)(log->last
9350: 2d 20 6c 6f 67 2d 3e 66 69 72 73 74 29 20 26 20 - log->first) &
9360: 7e 28 28 28 73 69 7a 65 5f 74 29 31 20 3c 3c 20 ~(((size_t)1 <<
9370: 31 30 29 20 2d 20 31 29 29 20 2b 0a 20 20 20 20 10) - 1)) +.
9380: 20 20 20 20 20 20 6c 6f 67 2d 3e 73 74 6f 72 65 log->store
9390: 64 3b 0a 20 20 20 20 69 66 20 28 28 64 61 74 61 d;. if ((data
93a0: 20 3d 20 6d 61 6c 6c 6f 63 28 6c 65 6e 29 29 20 = malloc(len))
93b0: 3d 3d 20 4e 55 4c 4c 29 0a 20 20 20 20 20 20 20 == NULL).
93c0: 20 72 65 74 75 72 6e 20 2d 32 3b 0a 0a 20 20 20 return -2;..
93d0: 20 2f 2a 20 64 6f 20 73 74 61 74 65 6d 65 6e 74 /* do statement
93e0: 20 68 65 72 65 20 69 73 20 6a 75 73 74 20 61 20 here is just a
93f0: 63 68 65 61 70 20 74 72 69 63 6b 20 66 6f 72 20 cheap trick for
9400: 65 72 72 6f 72 20 68 61 6e 64 6c 69 6e 67 20 2a error handling *
9410: 2f 0a 20 20 20 20 64 6f 20 7b 0a 20 20 20 20 20 /. do {.
9420: 20 20 20 2f 2a 20 72 65 61 64 20 69 6e 20 74 68 /* read in th
9430: 65 20 75 6e 63 6f 6d 70 72 65 73 73 65 64 20 64 e uncompressed d
9440: 61 74 61 20 2a 2f 0a 20 20 20 20 20 20 20 20 69 ata */. i
9450: 66 20 28 6c 73 65 65 6b 28 6c 6f 67 2d 3e 66 64 f (lseek(log->fd
9460: 2c 20 6c 6f 67 2d 3e 66 69 72 73 74 20 2d 20 31 , log->first - 1
9470: 2c 20 53 45 45 4b 5f 53 45 54 29 20 3c 20 30 29 , SEEK_SET) < 0)
9480: 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72 65 . bre
9490: 61 6b 3b 0a 20 20 20 20 20 20 20 20 6e 65 78 74 ak;. next
94a0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 77 68 = 0;. wh
94b0: 69 6c 65 20 28 6e 65 78 74 20 3c 20 6c 65 6e 29 ile (next < len)
94c0: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 69 {. i
94d0: 66 20 28 72 65 61 64 28 6c 6f 67 2d 3e 66 64 2c f (read(log->fd,
94e0: 20 62 75 66 2c 20 35 29 20 21 3d 20 35 29 0a 20 buf, 5) != 5).
94f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 62 b
9500: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 reak;.
9510: 20 20 62 6c 6f 63 6b 20 3d 20 50 55 4c 4c 32 28 block = PULL2(
9520: 62 75 66 20 2b 20 31 29 3b 0a 20 20 20 20 20 20 buf + 1);.
9530: 20 20 20 20 20 20 69 66 20 28 6e 65 78 74 20 2b if (next +
9540: 20 62 6c 6f 63 6b 20 3e 20 6c 65 6e 20 7c 7c 0a block > len ||.
9550: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
9560: 72 65 61 64 28 6c 6f 67 2d 3e 66 64 2c 20 28 63 read(log->fd, (c
9570: 68 61 72 20 2a 29 64 61 74 61 20 2b 20 6e 65 78 har *)data + nex
9580: 74 2c 20 62 6c 6f 63 6b 29 20 21 3d 20 62 6c 6f t, block) != blo
9590: 63 6b 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 ck).
95a0: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 break;.
95b0: 20 20 20 20 20 20 20 6e 65 78 74 20 2b 3d 20 62 next += b
95c0: 6c 6f 63 6b 3b 0a 20 20 20 20 20 20 20 20 7d 0a lock;. }.
95d0: 20 20 20 20 20 20 20 20 69 66 20 28 6c 73 65 65 if (lsee
95e0: 6b 28 6c 6f 67 2d 3e 66 64 2c 20 30 2c 20 53 45 k(log->fd, 0, SE
95f0: 45 4b 5f 43 55 52 29 20 21 3d 20 6c 6f 67 2d 3e EK_CUR) != log->
9600: 6c 61 73 74 20 2b 20 34 20 2b 20 6c 6f 67 2d 3e last + 4 + log->
9610: 73 74 6f 72 65 64 29 0a 20 20 20 20 20 20 20 20 stored).
9620: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 break;.
9630: 20 20 20 6c 6f 67 5f 74 6f 75 63 68 28 6c 6f 67 log_touch(log
9640: 29 3b 0a 0a 20 20 20 20 20 20 20 20 2f 2a 20 77 );.. /* w
9650: 72 69 74 65 20 74 68 65 20 75 6e 63 6f 6d 70 72 rite the uncompr
9660: 65 73 73 65 64 20 64 61 74 61 20 74 6f 20 74 68 essed data to th
9670: 65 20 2e 61 64 64 20 66 69 6c 65 20 2a 2f 0a 20 e .add file */.
9680: 20 20 20 20 20 20 20 73 74 72 63 70 79 28 6c 6f strcpy(lo
9690: 67 2d 3e 65 6e 64 2c 20 22 2e 61 64 64 22 29 3b g->end, ".add");
96a0: 0a 20 20 20 20 20 20 20 20 66 64 20 3d 20 6f 70 . fd = op
96b0: 65 6e 28 6c 6f 67 2d 3e 70 61 74 68 2c 20 4f 5f en(log->path, O_
96c0: 57 52 4f 4e 4c 59 20 7c 20 4f 5f 43 52 45 41 54 WRONLY | O_CREAT
96d0: 20 7c 20 4f 5f 54 52 55 4e 43 2c 20 30 36 34 34 | O_TRUNC, 0644
96e0: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 20 28 66 );. if (f
96f0: 64 20 3c 20 30 29 0a 20 20 20 20 20 20 20 20 20 d < 0).
9700: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 break;.
9710: 20 20 72 65 74 20 3d 20 77 72 69 74 65 28 66 64 ret = write(fd
9720: 2c 20 64 61 74 61 2c 20 6c 65 6e 29 20 21 3d 20 , data, len) !=
9730: 6c 65 6e 3b 0a 20 20 20 20 20 20 20 20 69 66 20 len;. if
9740: 28 72 65 74 20 7c 20 63 6c 6f 73 65 28 66 64 29 (ret | close(fd)
9750: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72 ). br
9760: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 6c 6f 67 eak;. log
9770: 5f 74 6f 75 63 68 28 6c 6f 67 29 3b 0a 0a 20 20 _touch(log);..
9780: 20 20 20 20 20 20 2f 2a 20 77 72 69 74 65 20 74 /* write t
9790: 68 65 20 64 69 63 74 69 6f 6e 61 72 79 20 66 6f he dictionary fo
97a0: 72 20 74 68 65 20 6e 65 78 74 20 63 6f 6d 70 72 r the next compr
97b0: 65 73 73 20 74 6f 20 74 68 65 20 2e 74 65 6d 70 ess to the .temp
97c0: 20 66 69 6c 65 20 2a 2f 0a 20 20 20 20 20 20 20 file */.
97d0: 20 73 74 72 63 70 79 28 6c 6f 67 2d 3e 65 6e 64 strcpy(log->end
97e0: 2c 20 22 2e 74 65 6d 70 22 29 3b 0a 20 20 20 20 , ".temp");.
97f0: 20 20 20 20 66 64 20 3d 20 6f 70 65 6e 28 6c 6f fd = open(lo
9800: 67 2d 3e 70 61 74 68 2c 20 4f 5f 57 52 4f 4e 4c g->path, O_WRONL
9810: 59 20 7c 20 4f 5f 43 52 45 41 54 20 7c 20 4f 5f Y | O_CREAT | O_
9820: 54 52 55 4e 43 2c 20 30 36 34 34 29 3b 0a 20 20 TRUNC, 0644);.
9830: 20 20 20 20 20 20 69 66 20 28 66 64 20 3c 20 30 if (fd < 0
9840: 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 72 ). br
9850: 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 6e 65 78 eak;. nex
9860: 74 20 3d 20 44 49 43 54 20 3e 20 6c 65 6e 20 3f t = DICT > len ?
9870: 20 6c 65 6e 20 3a 20 44 49 43 54 3b 0a 20 20 20 len : DICT;.
9880: 20 20 20 20 20 72 65 74 20 3d 20 77 72 69 74 65 ret = write
9890: 28 66 64 2c 20 28 63 68 61 72 20 2a 29 64 61 74 (fd, (char *)dat
98a0: 61 20 2b 20 6c 65 6e 20 2d 20 6e 65 78 74 2c 20 a + len - next,
98b0: 6e 65 78 74 29 20 21 3d 20 6e 65 78 74 3b 0a 20 next) != next;.
98c0: 20 20 20 20 20 20 20 69 66 20 28 72 65 74 20 7c if (ret |
98d0: 20 63 6c 6f 73 65 28 66 64 29 29 0a 20 20 20 20 close(fd)).
98e0: 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 break;.
98f0: 20 20 20 20 20 20 20 6c 6f 67 5f 74 6f 75 63 68 log_touch
9900: 28 6c 6f 67 29 3b 0a 0a 20 20 20 20 20 20 20 20 (log);..
9910: 2f 2a 20 72 6f 6c 6c 20 62 61 63 6b 20 74 6f 20 /* roll back to
9920: 63 6f 6d 70 72 65 73 73 65 64 20 64 61 74 61 2c compressed data,
9930: 20 6d 61 72 6b 20 74 68 65 20 63 6f 6d 70 72 65 mark the compre
9940: 73 73 20 69 6e 20 70 72 6f 67 72 65 73 73 20 2a ss in progress *
9950: 2f 0a 20 20 20 20 20 20 20 20 6c 6f 67 2d 3e 6c /. log->l
9960: 61 73 74 20 3d 20 6c 6f 67 2d 3e 66 69 72 73 74 ast = log->first
9970: 3b 0a 20 20 20 20 20 20 20 20 6c 6f 67 2d 3e 73 ;. log->s
9980: 74 6f 72 65 64 20 3d 20 30 3b 0a 20 20 20 20 20 tored = 0;.
9990: 20 20 20 69 66 20 28 6c 6f 67 5f 6d 61 72 6b 28 if (log_mark(
99a0: 6c 6f 67 2c 20 43 4f 4d 50 52 45 53 53 5f 4f 50 log, COMPRESS_OP
99b0: 29 29 0a 20 20 20 20 20 20 20 20 20 20 20 20 62 )). b
99c0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 42 41 reak;. BA
99d0: 49 4c 28 37 29 3b 0a 0a 20 20 20 20 20 20 20 20 IL(7);..
99e0: 2f 2a 20 63 6f 6d 70 72 65 73 73 20 61 6e 64 20 /* compress and
99f0: 61 70 70 65 6e 64 20 74 68 65 20 64 61 74 61 20 append the data
9a00: 28 63 6c 65 61 72 73 20 6d 61 72 6b 29 20 2a 2f (clears mark) */
9a10: 0a 20 20 20 20 20 20 20 20 72 65 74 20 3d 20 6c . ret = l
9a20: 6f 67 5f 63 6f 6d 70 72 65 73 73 28 6c 6f 67 2c og_compress(log,
9a30: 20 64 61 74 61 2c 20 6c 65 6e 29 3b 0a 20 20 20 data, len);.
9a40: 20 20 20 20 20 66 72 65 65 28 64 61 74 61 29 3b free(data);
9a50: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 . return
9a60: 72 65 74 3b 0a 20 20 20 20 7d 20 77 68 69 6c 65 ret;. } while
9a70: 20 28 30 29 3b 0a 0a 20 20 20 20 2f 2a 20 62 72 (0);.. /* br
9a80: 6f 6b 65 20 6f 75 74 20 6f 66 20 64 6f 20 61 62 oke out of do ab
9a90: 6f 76 65 20 6f 6e 20 69 2f 6f 20 65 72 72 6f 72 ove on i/o error
9aa0: 20 2a 2f 0a 20 20 20 20 66 72 65 65 28 64 61 74 */. free(dat
9ab0: 61 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 2d a);. return -
9ac0: 31 3b 0a 7d 0a 0a 2f 2a 20 67 7a 6c 6f 67 5f 77 1;.}../* gzlog_w
9ad0: 72 69 74 65 28 29 20 72 65 74 75 72 6e 20 76 61 rite() return va
9ae0: 6c 75 65 73 3a 0a 20 20 20 20 30 3a 20 61 6c 6c lues:. 0: all
9af0: 20 67 6f 6f 64 0a 20 20 20 2d 31 3a 20 66 69 6c good. -1: fil
9b00: 65 20 69 2f 6f 20 65 72 72 6f 72 20 28 75 73 75 e i/o error (usu
9b10: 61 6c 6c 79 20 61 63 63 65 73 73 20 69 73 73 75 ally access issu
9b20: 65 29 0a 20 20 20 2d 32 3a 20 6d 65 6d 6f 72 79 e). -2: memory
9b30: 20 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 61 69 6c allocation fail
9b40: 75 72 65 0a 20 20 20 2d 33 3a 20 69 6e 76 61 6c ure. -3: inval
9b50: 69 64 20 6c 6f 67 20 70 6f 69 6e 74 65 72 20 61 id log pointer a
9b60: 72 67 75 6d 65 6e 74 20 2a 2f 0a 69 6e 74 20 67 rgument */.int g
9b70: 7a 6c 6f 67 5f 77 72 69 74 65 28 67 7a 6c 6f 67 zlog_write(gzlog
9b80: 20 2a 6c 6f 67 64 2c 20 76 6f 69 64 20 2a 64 61 *logd, void *da
9b90: 74 61 2c 20 73 69 7a 65 5f 74 20 6c 65 6e 29 0a ta, size_t len).
9ba0: 7b 0a 20 20 20 20 69 6e 74 20 66 64 2c 20 72 65 {. int fd, re
9bb0: 74 3b 0a 20 20 20 20 73 74 72 75 63 74 20 6c 6f t;. struct lo
9bc0: 67 20 2a 6c 6f 67 20 3d 20 6c 6f 67 64 3b 0a 0a g *log = logd;..
9bd0: 20 20 20 20 2f 2a 20 63 68 65 63 6b 20 61 72 67 /* check arg
9be0: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 20 20 69 66 uments */. if
9bf0: 20 28 6c 6f 67 20 3d 3d 20 4e 55 4c 4c 20 7c 7c (log == NULL ||
9c00: 20 73 74 72 63 6d 70 28 6c 6f 67 2d 3e 69 64 2c strcmp(log->id,
9c10: 20 4c 4f 47 49 44 29 20 7c 7c 20 6c 65 6e 20 3c LOGID) || len <
9c20: 20 30 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 0). retu
9c30: 72 6e 20 2d 33 3b 0a 20 20 20 20 69 66 20 28 64 rn -3;. if (d
9c40: 61 74 61 20 3d 3d 20 4e 55 4c 4c 20 7c 7c 20 6c ata == NULL || l
9c50: 65 6e 20 3d 3d 20 30 29 0a 20 20 20 20 20 20 20 en == 0).
9c60: 20 72 65 74 75 72 6e 20 30 3b 0a 0a 20 20 20 20 return 0;..
9c70: 2f 2a 20 73 65 65 20 69 66 20 77 65 20 6c 6f 73 /* see if we los
9c80: 74 20 74 68 65 20 6c 6f 63 6b 20 2d 2d 20 69 66 t the lock -- if
9c90: 20 73 6f 20 67 65 74 20 69 74 20 61 67 61 69 6e so get it again
9ca0: 20 61 6e 64 20 72 65 6c 6f 61 64 20 74 68 65 20 and reload the
9cb0: 65 78 74 72 61 0a 20 20 20 20 20 20 20 66 69 65 extra. fie
9cc0: 6c 64 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 28 ld information (
9cd0: 69 74 20 70 72 6f 62 61 62 6c 79 20 63 68 61 6e it probably chan
9ce0: 67 65 64 29 2c 20 72 65 63 6f 76 65 72 20 6c 61 ged), recover la
9cf0: 73 74 20 6f 70 65 72 61 74 69 6f 6e 20 69 66 0a st operation if.
9d00: 20 20 20 20 20 20 20 6e 65 63 65 73 73 61 72 79 necessary
9d10: 20 2a 2f 0a 20 20 20 20 69 66 20 28 6c 6f 67 5f */. if (log_
9d20: 63 68 65 63 6b 28 6c 6f 67 29 20 26 26 20 6c 6f check(log) && lo
9d30: 67 5f 6f 70 65 6e 28 6c 6f 67 29 29 0a 20 20 20 g_open(log)).
9d40: 20 20 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a return -1;.
9d50: 0a 20 20 20 20 2f 2a 20 63 72 65 61 74 65 20 61 . /* create a
9d60: 6e 64 20 77 72 69 74 65 20 2e 61 64 64 20 66 69 nd write .add fi
9d70: 6c 65 20 2a 2f 0a 20 20 20 20 73 74 72 63 70 79 le */. strcpy
9d80: 28 6c 6f 67 2d 3e 65 6e 64 2c 20 22 2e 61 64 64 (log->end, ".add
9d90: 22 29 3b 0a 20 20 20 20 66 64 20 3d 20 6f 70 65 ");. fd = ope
9da0: 6e 28 6c 6f 67 2d 3e 70 61 74 68 2c 20 4f 5f 57 n(log->path, O_W
9db0: 52 4f 4e 4c 59 20 7c 20 4f 5f 43 52 45 41 54 20 RONLY | O_CREAT
9dc0: 7c 20 4f 5f 54 52 55 4e 43 2c 20 30 36 34 34 29 | O_TRUNC, 0644)
9dd0: 3b 0a 20 20 20 20 69 66 20 28 66 64 20 3c 20 30 ;. if (fd < 0
9de0: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e ). return
9df0: 20 2d 31 3b 0a 20 20 20 20 72 65 74 20 3d 20 77 -1;. ret = w
9e00: 72 69 74 65 28 66 64 2c 20 64 61 74 61 2c 20 6c rite(fd, data, l
9e10: 65 6e 29 20 21 3d 20 6c 65 6e 3b 0a 20 20 20 20 en) != len;.
9e20: 69 66 20 28 72 65 74 20 7c 20 63 6c 6f 73 65 28 if (ret | close(
9e30: 66 64 29 29 0a 20 20 20 20 20 20 20 20 72 65 74 fd)). ret
9e40: 75 72 6e 20 2d 31 3b 0a 20 20 20 20 6c 6f 67 5f urn -1;. log_
9e50: 74 6f 75 63 68 28 6c 6f 67 29 3b 0a 0a 20 20 20 touch(log);..
9e60: 20 2f 2a 20 6d 61 72 6b 20 6c 6f 67 20 66 69 6c /* mark log fil
9e70: 65 20 77 69 74 68 20 61 70 70 65 6e 64 20 69 6e e with append in
9e80: 20 70 72 6f 67 72 65 73 73 20 2a 2f 0a 20 20 20 progress */.
9e90: 20 69 66 20 28 6c 6f 67 5f 6d 61 72 6b 28 6c 6f if (log_mark(lo
9ea0: 67 2c 20 41 50 50 45 4e 44 5f 4f 50 29 29 0a 20 g, APPEND_OP)).
9eb0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 2d 31 return -1
9ec0: 3b 0a 20 20 20 20 42 41 49 4c 28 38 29 3b 0a 0a ;. BAIL(8);..
9ed0: 20 20 20 20 2f 2a 20 61 70 70 65 6e 64 20 64 61 /* append da
9ee0: 74 61 20 28 63 6c 65 61 72 73 20 6d 61 72 6b 29 ta (clears mark)
9ef0: 20 2a 2f 0a 20 20 20 20 69 66 20 28 6c 6f 67 5f */. if (log_
9f00: 61 70 70 65 6e 64 28 6c 6f 67 2c 20 64 61 74 61 append(log, data
9f10: 2c 20 6c 65 6e 29 29 0a 20 20 20 20 20 20 20 20 , len)).
9f20: 72 65 74 75 72 6e 20 2d 31 3b 0a 0a 20 20 20 20 return -1;..
9f30: 2f 2a 20 63 68 65 63 6b 20 74 6f 20 73 65 65 20 /* check to see
9f40: 69 66 20 69 74 27 73 20 74 69 6d 65 20 74 6f 20 if it's time to
9f50: 63 6f 6d 70 72 65 73 73 20 2d 2d 20 69 66 20 6e compress -- if n
9f60: 6f 74 2c 20 74 68 65 6e 20 64 6f 6e 65 20 2a 2f ot, then done */
9f70: 0a 20 20 20 20 69 66 20 28 28 28 6c 6f 67 2d 3e . if (((log->
9f80: 6c 61 73 74 20 2d 20 6c 6f 67 2d 3e 66 69 72 73 last - log->firs
9f90: 74 29 20 3e 3e 20 31 30 29 20 2b 20 28 6c 6f 67 t) >> 10) + (log
9fa0: 2d 3e 73 74 6f 72 65 64 20 3e 3e 20 31 30 29 20 ->stored >> 10)
9fb0: 3c 20 54 52 49 47 47 45 52 29 0a 20 20 20 20 20 < TRIGGER).
9fc0: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 0a 20 20 return 0;..
9fd0: 20 20 2f 2a 20 74 69 6d 65 20 74 6f 20 63 6f 6d /* time to com
9fe0: 70 72 65 73 73 20 2a 2f 0a 20 20 20 20 72 65 74 press */. ret
9ff0: 75 72 6e 20 67 7a 6c 6f 67 5f 63 6f 6d 70 72 65 urn gzlog_compre
a000: 73 73 28 6c 6f 67 29 3b 0a 7d 0a 0a 2f 2a 20 67 ss(log);.}../* g
a010: 7a 6c 6f 67 5f 63 6c 6f 73 65 28 29 20 72 65 74 zlog_close() ret
a020: 75 72 6e 20 76 61 6c 75 65 73 3a 0a 20 20 20 20 urn values:.
a030: 30 3a 20 6f 6b 0a 20 20 20 2d 33 3a 20 69 6e 76 0: ok. -3: inv
a040: 61 6c 69 64 20 6c 6f 67 20 70 6f 69 6e 74 65 72 alid log pointer
a050: 20 61 72 67 75 6d 65 6e 74 20 2a 2f 0a 69 6e 74 argument */.int
a060: 20 67 7a 6c 6f 67 5f 63 6c 6f 73 65 28 67 7a 6c gzlog_close(gzl
a070: 6f 67 20 2a 6c 6f 67 64 29 0a 7b 0a 20 20 20 20 og *logd).{.
a080: 73 74 72 75 63 74 20 6c 6f 67 20 2a 6c 6f 67 20 struct log *log
a090: 3d 20 6c 6f 67 64 3b 0a 0a 20 20 20 20 2f 2a 20 = logd;.. /*
a0a0: 63 68 65 63 6b 20 61 72 67 75 6d 65 6e 74 73 20 check arguments
a0b0: 2a 2f 0a 20 20 20 20 69 66 20 28 6c 6f 67 20 3d */. if (log =
a0c0: 3d 20 4e 55 4c 4c 20 7c 7c 20 73 74 72 63 6d 70 = NULL || strcmp
a0d0: 28 6c 6f 67 2d 3e 69 64 2c 20 4c 4f 47 49 44 29 (log->id, LOGID)
a0e0: 29 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e ). return
a0f0: 20 2d 33 3b 0a 0a 20 20 20 20 2f 2a 20 63 6c 6f -3;.. /* clo
a100: 73 65 20 74 68 65 20 6c 6f 67 20 66 69 6c 65 20 se the log file
a110: 61 6e 64 20 72 65 6c 65 61 73 65 20 74 68 65 20 and release the
a120: 6c 6f 63 6b 20 2a 2f 0a 20 20 20 20 6c 6f 67 5f lock */. log_
a130: 63 6c 6f 73 65 28 6c 6f 67 29 3b 0a 0a 20 20 20 close(log);..
a140: 20 2f 2a 20 66 72 65 65 20 73 74 72 75 63 74 75 /* free structu
a150: 72 65 20 61 6e 64 20 72 65 74 75 72 6e 20 2a 2f re and return */
a160: 0a 20 20 20 20 69 66 20 28 6c 6f 67 2d 3e 70 61 . if (log->pa
a170: 74 68 20 21 3d 20 4e 55 4c 4c 29 0a 20 20 20 20 th != NULL).
a180: 20 20 20 20 66 72 65 65 28 6c 6f 67 2d 3e 70 61 free(log->pa
a190: 74 68 29 3b 0a 20 20 20 20 73 74 72 63 70 79 28 th);. strcpy(
a1a0: 6c 6f 67 2d 3e 69 64 2c 20 22 62 61 64 22 29 3b log->id, "bad");
a1b0: 0a 20 20 20 20 66 72 65 65 28 6c 6f 67 29 3b 0a . free(log);.
a1c0: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a return 0;.}.