110-lzma.patch 65 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226
  1. diff -Nur squashfs4.0/squashfs-tools/compressor.c squashfs4.0-lzma-snapshot/squashfs-tools/compressor.c
  2. --- squashfs4.0/squashfs-tools/compressor.c 1970-01-01 01:00:00.000000000 +0100
  3. +++ squashfs4.0-lzma-snapshot/squashfs-tools/compressor.c 2009-10-20 06:03:37.000000000 +0200
  4. @@ -0,0 +1,78 @@
  5. +/*
  6. + *
  7. + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
  8. + * Phillip Lougher <[email protected]>
  9. + *
  10. + * This program is free software; you can redistribute it and/or
  11. + * modify it under the terms of the GNU General Public License
  12. + * as published by the Free Software Foundation; either version 2,
  13. + * or (at your option) any later version.
  14. + *
  15. + * This program is distributed in the hope that it will be useful,
  16. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. + * GNU General Public License for more details.
  19. + *
  20. + * You should have received a copy of the GNU General Public License
  21. + * along with this program; if not, write to the Free Software
  22. + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. + *
  24. + * compressor.c
  25. + */
  26. +
  27. +#include <stdio.h>
  28. +#include <string.h>
  29. +#include "compressor.h"
  30. +#include "squashfs_fs.h"
  31. +
  32. +extern int gzip_compress(void **, char *, char *, int, int, int *);
  33. +extern int gzip_uncompress(char *, char *, int, int, int *);
  34. +extern int lzma_compress(void **, char *, char *, int, int, int *);
  35. +extern int lzma_uncompress(char *, char *, int, int, int *);
  36. +
  37. +struct compressor compressor[] = {
  38. + { gzip_compress, gzip_uncompress, ZLIB_COMPRESSION, "gzip", 1 },
  39. +#ifdef LZMA_SUPPORT
  40. + { lzma_compress, lzma_uncompress, LZMA_COMPRESSION, "lzma", 1 },
  41. +#else
  42. + { NULL, NULL, LZMA_COMPRESSION, "lzma", 0 },
  43. +#endif
  44. + { NULL, NULL , 0, "unknown", 0}
  45. +};
  46. +
  47. +
  48. +struct compressor *lookup_compressor(char *name)
  49. +{
  50. + int i;
  51. +
  52. + for(i = 0; compressor[i].id; i++)
  53. + if(strcmp(compressor[i].name, name) == 0)
  54. + break;
  55. +
  56. + return &compressor[i];
  57. +}
  58. +
  59. +
  60. +struct compressor *lookup_compressor_id(int id)
  61. +{
  62. + int i;
  63. +
  64. + for(i = 0; compressor[i].id; i++)
  65. + if(id == compressor[i].id)
  66. + break;
  67. +
  68. + return &compressor[i];
  69. +}
  70. +
  71. +
  72. +void display_compressors(char *indent, char *def_comp)
  73. +{
  74. + int i;
  75. +
  76. + for(i = 0; compressor[i].id; i++)
  77. + if(compressor[i].supported)
  78. + fprintf(stderr, "%s\t%s%s\n", indent,
  79. + compressor[i].name,
  80. + strcmp(compressor[i].name, def_comp) == 0 ?
  81. + " (default)" : "");
  82. +}
  83. diff -Nur squashfs4.0/squashfs-tools/compressor.h squashfs4.0-lzma-snapshot/squashfs-tools/compressor.h
  84. --- squashfs4.0/squashfs-tools/compressor.h 1970-01-01 01:00:00.000000000 +0100
  85. +++ squashfs4.0-lzma-snapshot/squashfs-tools/compressor.h 2009-10-20 06:03:37.000000000 +0200
  86. @@ -0,0 +1,33 @@
  87. +/*
  88. + *
  89. + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
  90. + * Phillip Lougher <[email protected]>
  91. + *
  92. + * This program is free software; you can redistribute it and/or
  93. + * modify it under the terms of the GNU General Public License
  94. + * as published by the Free Software Foundation; either version 2,
  95. + * or (at your option) any later version.
  96. + *
  97. + * This program is distributed in the hope that it will be useful,
  98. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  99. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  100. + * GNU General Public License for more details.
  101. + *
  102. + * You should have received a copy of the GNU General Public License
  103. + * along with this program; if not, write to the Free Software
  104. + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  105. + *
  106. + * compressor.h
  107. + */
  108. +
  109. +struct compressor {
  110. + int (*compress)(void **, char *, char *, int, int, int *);
  111. + int (*uncompress)(char *, char *, int, int, int *);
  112. + int id;
  113. + char *name;
  114. + int supported;
  115. +};
  116. +
  117. +extern struct compressor *lookup_compressor(char *);
  118. +extern struct compressor *lookup_compressor_id(int);
  119. +extern void display_compressors(char *, char *);
  120. diff -Nur squashfs4.0/squashfs-tools/gzip_wrapper.c squashfs4.0-lzma-snapshot/squashfs-tools/gzip_wrapper.c
  121. --- squashfs4.0/squashfs-tools/gzip_wrapper.c 1970-01-01 01:00:00.000000000 +0100
  122. +++ squashfs4.0-lzma-snapshot/squashfs-tools/gzip_wrapper.c 2009-10-20 06:03:37.000000000 +0200
  123. @@ -0,0 +1,80 @@
  124. +/*
  125. + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
  126. + * Phillip Lougher <[email protected]>
  127. + *
  128. + * This program is free software; you can redistribute it and/or
  129. + * modify it under the terms of the GNU General Public License
  130. + * as published by the Free Software Foundation; either version 2,
  131. + * or (at your option) any later version.
  132. + *
  133. + * This program is distributed in the hope that it will be useful,
  134. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  135. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  136. + * GNU General Public License for more details.
  137. + *
  138. + * You should have received a copy of the GNU General Public License
  139. + * along with this program; if not, write to the Free Software
  140. + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  141. + *
  142. + * gzip_wrapper.c
  143. + */
  144. +
  145. +#include <stdlib.h>
  146. +#include <zlib.h>
  147. +
  148. +int gzip_compress(void **strm, char *d, char *s, int size, int block_size,
  149. + int *error)
  150. +{
  151. + int res = 0;
  152. + z_stream *stream = *strm;
  153. +
  154. + if(stream == NULL) {
  155. + if((stream = *strm = malloc(sizeof(z_stream))) == NULL)
  156. + goto failed;
  157. +
  158. + stream->zalloc = Z_NULL;
  159. + stream->zfree = Z_NULL;
  160. + stream->opaque = 0;
  161. +
  162. + if((res = deflateInit(stream, 9)) != Z_OK)
  163. + goto failed;
  164. + } else if((res = deflateReset(stream)) != Z_OK)
  165. + goto failed;
  166. +
  167. + stream->next_in = (unsigned char *) s;
  168. + stream->avail_in = size;
  169. + stream->next_out = (unsigned char *) d;
  170. + stream->avail_out = block_size;
  171. +
  172. + res = deflate(stream, Z_FINISH);
  173. + if(res == Z_STREAM_END)
  174. + /*
  175. + * Success, return the compressed size.
  176. + */
  177. + return (int) stream->total_out;
  178. + if(res == Z_OK)
  179. + /*
  180. + * Output buffer overflow. Return out of buffer space
  181. + */
  182. + return 0;
  183. +failed:
  184. + /*
  185. + * All other errors return failure, with the compressor
  186. + * specific error code in *error
  187. + */
  188. + *error = res;
  189. + return -1;
  190. +}
  191. +
  192. +
  193. +int gzip_uncompress(char *d, char *s, int size, int block_size, int *error)
  194. +{
  195. + int res;
  196. + unsigned long bytes = block_size;
  197. +
  198. + res = uncompress((unsigned char *) d, &bytes,
  199. + (const unsigned char *) s, size);
  200. +
  201. + *error = res;
  202. + return res == Z_OK ? (int) bytes : -1;
  203. +}
  204. diff -Nur squashfs4.0/squashfs-tools/lzma_wrapper.c squashfs4.0-lzma-snapshot/squashfs-tools/lzma_wrapper.c
  205. --- squashfs4.0/squashfs-tools/lzma_wrapper.c 1970-01-01 01:00:00.000000000 +0100
  206. +++ squashfs4.0-lzma-snapshot/squashfs-tools/lzma_wrapper.c 2009-10-14 05:32:57.000000000 +0200
  207. @@ -0,0 +1,93 @@
  208. +/*
  209. + * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
  210. + * Phillip Lougher <[email protected]>
  211. + *
  212. + * This program is free software; you can redistribute it and/or
  213. + * modify it under the terms of the GNU General Public License
  214. + * as published by the Free Software Foundation; either version 2,
  215. + * or (at your option) any later version.
  216. + *
  217. + * This program is distributed in the hope that it will be useful,
  218. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  219. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  220. + * GNU General Public License for more details.
  221. + *
  222. + * You should have received a copy of the GNU General Public License
  223. + * along with this program; if not, write to the Free Software
  224. + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  225. + *
  226. + * lzma_wrapper.c
  227. + */
  228. +
  229. +#include <LzmaLib.h>
  230. +
  231. +#define LZMA_HEADER_SIZE (LZMA_PROPS_SIZE + 8)
  232. +
  233. +int lzma_compress(void **strm, char *dest, char *src, int size,int block_size,
  234. + int *error)
  235. +{
  236. + unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src;
  237. + size_t props_size = LZMA_PROPS_SIZE,
  238. + outlen = block_size - LZMA_HEADER_SIZE;
  239. + int res;
  240. +
  241. + res = LzmaCompress(d + LZMA_HEADER_SIZE, &outlen, s, size, d,
  242. + &props_size, 5, block_size, 3, 0, 2, 32, 1);
  243. +
  244. + if(res == SZ_ERROR_OUTPUT_EOF) {
  245. + /*
  246. + * Output buffer overflow. Return out of buffer space error
  247. + */
  248. + return 0;
  249. + }
  250. +
  251. + if(res != SZ_OK) {
  252. + /*
  253. + * All other errors return failure, with the compressor
  254. + * specific error code in *error
  255. + */
  256. + *error = res;
  257. + return -1;
  258. + }
  259. +
  260. + /*
  261. + * Fill in the 8 byte little endian uncompressed size field in the
  262. + * LZMA header. 8 bytes is excessively large for squashfs but
  263. + * this is the standard LZMA header and which is expected by the kernel
  264. + * code
  265. + */
  266. + d[LZMA_PROPS_SIZE] = size & 255;
  267. + d[LZMA_PROPS_SIZE + 1] = (size >> 8) & 255;
  268. + d[LZMA_PROPS_SIZE + 2] = (size >> 16) & 255;
  269. + d[LZMA_PROPS_SIZE + 3] = (size >> 24) & 255;
  270. + d[LZMA_PROPS_SIZE + 4] = 0;
  271. + d[LZMA_PROPS_SIZE + 5] = 0;
  272. + d[LZMA_PROPS_SIZE + 6] = 0;
  273. + d[LZMA_PROPS_SIZE + 7] = 0;
  274. +
  275. + /*
  276. + * Success, return the compressed size. Outlen returned by the LZMA
  277. + * compressor does not include the LZMA header space
  278. + */
  279. + return outlen + LZMA_HEADER_SIZE;
  280. +}
  281. +
  282. +
  283. +int lzma_uncompress(char *dest, char *src, int size, int block_size,
  284. + int *error)
  285. +{
  286. + unsigned char *d = (unsigned char *) dest, *s = (unsigned char *) src;
  287. + size_t outlen, inlen = size - LZMA_HEADER_SIZE;
  288. + int res;
  289. +
  290. + outlen = s[LZMA_PROPS_SIZE] |
  291. + (s[LZMA_PROPS_SIZE + 1] << 8) |
  292. + (s[LZMA_PROPS_SIZE + 2] << 16) |
  293. + (s[LZMA_PROPS_SIZE + 3] << 24);
  294. +
  295. + res = LzmaUncompress(d, &outlen, s + LZMA_HEADER_SIZE, &inlen,
  296. + s, LZMA_PROPS_SIZE);
  297. +
  298. + *error = res;
  299. + return res == SZ_OK ? outlen : -1;
  300. +}
  301. diff -Nur squashfs4.0/squashfs-tools/Makefile squashfs4.0-lzma-snapshot/squashfs-tools/Makefile
  302. --- squashfs4.0/squashfs-tools/Makefile 2009-04-05 04:03:36.000000000 +0200
  303. +++ squashfs4.0-lzma-snapshot/squashfs-tools/Makefile 2009-10-22 06:17:12.000000000 +0200
  304. @@ -1,40 +1,76 @@
  305. +#
  306. +# Building LZMA support
  307. +# Download LZMA sdk (4.65 used in development, other versions may work),
  308. +# set LZMA_DIR to unpacked source, and uncomment next line
  309. +LZMA_SUPPORT = 1
  310. +LZMA_DIR = ../../lzma-4.65
  311. +
  312. +#Compression default.
  313. +COMP_DEFAULT = gzip
  314. +
  315. +INCLUDEDIR = -I.
  316. INSTALL_DIR = /usr/local/bin
  317. -INCLUDEDIR = .
  318. +MKSQUASHFS_OBJS = mksquashfs.o read_fs.o sort.o swap.o pseudo.o compressor.o \
  319. + gzip_wrapper.o
  320. +
  321. +UNSQUASHFS_OBJS = unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o \
  322. + unsquash-4.o swap.o compressor.o gzip_wrapper.o
  323. -CFLAGS := -I$(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_GNU_SOURCE -O2
  324. +CFLAGS = $(INCLUDEDIR) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE \
  325. + -D_GNU_SOURCE -DCOMP_DEFAULT=\"$(COMP_DEFAULT)\" -O2 -Wall
  326. +ifdef LZMA_SUPPORT
  327. +LZMA_OBJS = $(LZMA_DIR)/C/Alloc.o $(LZMA_DIR)/C/LzFind.o \
  328. + $(LZMA_DIR)/C/LzmaDec.o $(LZMA_DIR)/C/LzmaEnc.o $(LZMA_DIR)/C/LzmaLib.o
  329. +INCLUDEDIR += -I$(LZMA_DIR)/C
  330. +CFLAGS += -DLZMA_SUPPORT
  331. +MKSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS)
  332. +UNSQUASHFS_OBJS += lzma_wrapper.o $(LZMA_OBJS)
  333. +endif
  334. +
  335. +.PHONY: all
  336. all: mksquashfs unsquashfs
  337. -mksquashfs: mksquashfs.o read_fs.o sort.o swap.o pseudo.o
  338. - $(CC) mksquashfs.o read_fs.o sort.o swap.o pseudo.o -lz -lpthread -lm -o $@
  339. +mksquashfs: $(MKSQUASHFS_OBJS)
  340. + $(CC) $(MKSQUASHFS_OBJS) -lz -lpthread -lm -o $@
  341. +
  342. +mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h \
  343. + squashfs_swap.h
  344. -mksquashfs.o: mksquashfs.c squashfs_fs.h mksquashfs.h global.h sort.h squashfs_swap.h Makefile
  345. +read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h
  346. -read_fs.o: read_fs.c squashfs_fs.h read_fs.h global.h squashfs_swap.h Makefile
  347. +sort.o: sort.c squashfs_fs.h global.h sort.h
  348. -sort.o: sort.c squashfs_fs.h global.h sort.h Makefile
  349. +swap.o: swap.c
  350. -swap.o: swap.c Makefile
  351. +pseudo.o: pseudo.c pseudo.h
  352. -pseudo.o: pseudo.c pseudo.h Makefile
  353. +compressor.o: compressor.c compressor.h
  354. -unsquashfs: unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o
  355. - $(CC) unsquashfs.o unsquash-1.o unsquash-2.o unsquash-3.o unsquash-4.o swap.o -lz -lpthread -lm -o $@
  356. +unsquashfs: $(UNSQUASHFS_OBJS)
  357. + $(CC) $(UNSQUASHFS_OBJS) -lz -lpthread -lm -o $@
  358. -unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h squashfs_compat.h global.h Makefile
  359. +unsquashfs.o: unsquashfs.h unsquashfs.c squashfs_fs.h squashfs_swap.h \
  360. + squashfs_compat.h global.h
  361. -unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h global.h Makefile
  362. +unsquash-1.o: unsquashfs.h unsquash-1.c squashfs_fs.h squashfs_compat.h \
  363. + global.h
  364. -unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h squashfs_compat.h global.h Makefile
  365. +unsquash-2.o: unsquashfs.h unsquash-2.c unsquashfs.h squashfs_fs.h \
  366. + squashfs_compat.h global.h
  367. -unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h global.h Makefile
  368. +unsquash-3.o: unsquashfs.h unsquash-3.c squashfs_fs.h squashfs_compat.h \
  369. + global.h
  370. -unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h global.h Makefile
  371. +unsquash-4.o: unsquashfs.h unsquash-4.c squashfs_fs.h squashfs_swap.h \
  372. + global.h
  373. +.PHONY: clean
  374. clean:
  375. -rm -f *.o mksquashfs unsquashfs
  376. +.PHONY: install
  377. install: mksquashfs unsquashfs
  378. mkdir -p $(INSTALL_DIR)
  379. cp mksquashfs $(INSTALL_DIR)
  380. diff -Nur squashfs4.0/squashfs-tools/mksquashfs.c squashfs4.0-lzma-snapshot/squashfs-tools/mksquashfs.c
  381. --- squashfs4.0/squashfs-tools/mksquashfs.c 2009-04-05 23:22:48.000000000 +0200
  382. +++ squashfs4.0-lzma-snapshot/squashfs-tools/mksquashfs.c 2009-10-20 06:03:38.000000000 +0200
  383. @@ -36,7 +36,6 @@
  384. #include <errno.h>
  385. #include <dirent.h>
  386. #include <string.h>
  387. -#include <zlib.h>
  388. #include <stdlib.h>
  389. #include <signal.h>
  390. #include <setjmp.h>
  391. @@ -47,6 +46,7 @@
  392. #include <math.h>
  393. #include <regex.h>
  394. #include <fnmatch.h>
  395. +#include <sys/wait.h>
  396. #ifndef linux
  397. #define __BYTE_ORDER BYTE_ORDER
  398. @@ -64,6 +64,7 @@
  399. #include "global.h"
  400. #include "sort.h"
  401. #include "pseudo.h"
  402. +#include "compressor.h"
  403. #ifdef SQUASHFS_TRACE
  404. #define TRACE(s, args...) do { \
  405. @@ -245,10 +246,8 @@
  406. /* list of root directory entries read from original filesystem */
  407. int old_root_entries = 0;
  408. struct old_root_entry_info {
  409. - char name[SQUASHFS_NAME_LEN + 1];
  410. - squashfs_inode inode;
  411. - int type;
  412. - int inode_number;
  413. + char *name;
  414. + struct inode_info inode;
  415. };
  416. struct old_root_entry_info *old_root_entry;
  417. @@ -371,10 +370,15 @@
  418. int reader_buffer_size;
  419. int fragment_buffer_size;
  420. +/* compression operations structure */
  421. +static struct compressor *comp;
  422. +char *comp_name = COMP_DEFAULT;
  423. +
  424. char *read_from_disk(long long start, unsigned int avail_bytes);
  425. void add_old_root_entry(char *name, squashfs_inode inode, int inode_number,
  426. int type);
  427. -extern int read_super(int fd, squashfs_super_block *sBlk, char *source);
  428. +extern struct compressor *read_super(int fd, squashfs_super_block *sBlk,
  429. + char *source);
  430. extern long long read_filesystem(char *root_name, int fd,
  431. squashfs_super_block *sBlk, char **cinode_table, char **data_cache,
  432. char **cdirectory_table, char **directory_data_cache,
  433. @@ -831,83 +835,32 @@
  434. }
  435. -unsigned int mangle2(z_stream **strm, char *d, char *s, int size,
  436. +int mangle2(void **strm, char *d, char *s, int size,
  437. int block_size, int uncompressed, int data_block)
  438. {
  439. - unsigned long c_byte;
  440. - unsigned int res;
  441. - z_stream *stream = *strm;
  442. -
  443. - if(uncompressed)
  444. - goto notcompressed;
  445. -
  446. - if(stream == NULL) {
  447. - if((stream = *strm = malloc(sizeof(z_stream))) == NULL)
  448. - BAD_ERROR("mangle::compress failed, not enough "
  449. - "memory\n");
  450. -
  451. - stream->zalloc = Z_NULL;
  452. - stream->zfree = Z_NULL;
  453. - stream->opaque = 0;
  454. -
  455. - if((res = deflateInit(stream, 9)) != Z_OK) {
  456. - if(res == Z_MEM_ERROR)
  457. - BAD_ERROR("zlib::compress failed, not enough "
  458. - "memory\n");
  459. - else if(res == Z_STREAM_ERROR)
  460. - BAD_ERROR("zlib::compress failed, not a valid "
  461. - "compression level\n");
  462. - else if(res == Z_VERSION_ERROR)
  463. - BAD_ERROR("zlib::compress failed, incorrect "
  464. - "zlib version\n");
  465. - else
  466. - BAD_ERROR("zlib::compress failed, unknown "
  467. - "error %d\n", res);
  468. - }
  469. - } else if((res = deflateReset(stream)) != Z_OK) {
  470. - if(res == Z_STREAM_ERROR)
  471. - BAD_ERROR("zlib::compress failed, stream state "
  472. - "inconsistent\n");
  473. - else
  474. - BAD_ERROR("zlib::compress failed, unknown error %d\n",
  475. - res);
  476. - }
  477. + int error, c_byte = 0;
  478. - stream->next_in = (unsigned char *) s;
  479. - stream->avail_in = size;
  480. - stream->next_out = (unsigned char *) d;
  481. - stream->avail_out = block_size;
  482. -
  483. - res = deflate(stream, Z_FINISH);
  484. - if(res != Z_STREAM_END && res != Z_OK) {
  485. - if(res == Z_STREAM_ERROR)
  486. - BAD_ERROR("zlib::compress failed, stream state "
  487. - "inconsistent\n");
  488. - else if(res == Z_BUF_ERROR)
  489. - BAD_ERROR("zlib::compress failed, no progress possible"
  490. - "\n");
  491. - else
  492. - BAD_ERROR("zlib::compress failed, unknown error %d\n",
  493. - res);
  494. + if(!uncompressed) {
  495. + c_byte = comp->compress(strm, d, s, size, block_size, &error);
  496. + if(c_byte == -1)
  497. + BAD_ERROR("mangle2:: %s compress failed with error "
  498. + "code %d\n", comp->name, error);
  499. }
  500. - c_byte = stream->total_out;
  501. -
  502. - if(res != Z_STREAM_END || c_byte >= size) {
  503. -notcompressed:
  504. + if(c_byte == 0 || c_byte >= size) {
  505. memcpy(d, s, size);
  506. return size | (data_block ? SQUASHFS_COMPRESSED_BIT_BLOCK :
  507. SQUASHFS_COMPRESSED_BIT);
  508. }
  509. - return (unsigned int) c_byte;
  510. + return c_byte;
  511. }
  512. -unsigned int mangle(char *d, char *s, int size, int block_size,
  513. +int mangle(char *d, char *s, int size, int block_size,
  514. int uncompressed, int data_block)
  515. {
  516. - static z_stream *stream = NULL;
  517. + static void *stream = NULL;
  518. return mangle2(&stream, d, s, size, block_size, uncompressed,
  519. data_block);
  520. @@ -1660,8 +1613,7 @@
  521. pthread_mutex_unlock(&fragment_mutex);
  522. if(SQUASHFS_COMPRESSED_BLOCK(disk_fragment->size)) {
  523. - int res;
  524. - unsigned long bytes = block_size;
  525. + int error, res;
  526. char *data;
  527. if(compressed_buffer)
  528. @@ -1669,19 +1621,11 @@
  529. else
  530. data = read_from_disk(start_block, size);
  531. - res = uncompress((unsigned char *) buffer->data, &bytes,
  532. - (const unsigned char *) data, size);
  533. - if(res != Z_OK) {
  534. - if(res == Z_MEM_ERROR)
  535. - BAD_ERROR("zlib::uncompress failed, not enough "
  536. - "memory\n");
  537. - else if(res == Z_BUF_ERROR)
  538. - BAD_ERROR("zlib::uncompress failed, not enough "
  539. - "room in output buffer\n");
  540. - else
  541. - BAD_ERROR("zlib::uncompress failed,"
  542. - " unknown error %d\n", res);
  543. - }
  544. + res = comp->uncompress(buffer->data, data, size, block_size,
  545. + &error);
  546. + if(res == -1)
  547. + BAD_ERROR("%s uncompress failed with error code %d\n",
  548. + comp->name, error);
  549. } else if(compressed_buffer)
  550. memcpy(buffer->data, compressed_buffer->data, size);
  551. else
  552. @@ -1733,9 +1677,7 @@
  553. entry->buffer->block = bytes;
  554. bytes += compressed_size;
  555. fragments_outstanding --;
  556. - pthread_mutex_unlock(&fragment_mutex);
  557. queue_put(to_writer, entry->buffer);
  558. - pthread_mutex_lock(&fragment_mutex);
  559. TRACE("fragment_locked writing fragment %d, compressed size %d"
  560. "\n", entry->fragment, compressed_size);
  561. free(entry);
  562. @@ -1758,6 +1700,8 @@
  563. pthread_mutex_lock(&fragment_mutex);
  564. insert_fragment_list(&frag_locked_list, entry);
  565. pthread_mutex_unlock(&fragment_mutex);
  566. +
  567. + return TRUE;
  568. }
  569. @@ -1824,7 +1768,9 @@
  570. unsigned short c_byte;
  571. char cbuffer[(SQUASHFS_METADATA_SIZE << 2) + 2];
  572. +#ifdef SQUASHFS_TRACE
  573. long long obytes = bytes;
  574. +#endif
  575. for(i = 0; i < meta_blocks; i++) {
  576. int avail_bytes = length > SQUASHFS_METADATA_SIZE ?
  577. @@ -2170,11 +2116,85 @@
  578. }
  579. +static int seq = 0;
  580. +void reader_read_process(struct dir_ent *dir_ent)
  581. +{
  582. + struct file_buffer *prev_buffer = NULL, *file_buffer;
  583. + int status, res, byte, count = 0;
  584. + int file = get_pseudo_file(dir_ent->inode->pseudo_id)->fd;
  585. + int child = get_pseudo_file(dir_ent->inode->pseudo_id)->child;
  586. + long long bytes = 0;
  587. +
  588. + while(1) {
  589. + file_buffer = cache_get(reader_buffer, 0, 0);
  590. + file_buffer->sequence = seq ++;
  591. +
  592. + byte = read_bytes(file, file_buffer->data, block_size);
  593. + if(byte == -1)
  594. + goto read_err;
  595. +
  596. + file_buffer->size = byte;
  597. + file_buffer->file_size = -1;
  598. + file_buffer->block = count ++;
  599. + file_buffer->error = FALSE;
  600. + file_buffer->fragment = FALSE;
  601. + bytes += byte;
  602. +
  603. + if(byte == 0)
  604. + break;
  605. +
  606. + /*
  607. + * Update estimated_uncompressed block count. This is done
  608. + * on every block rather than waiting for all blocks to be
  609. + * read incase write_file_process() is running in parallel
  610. + * with this. Otherwise cur uncompressed block count may
  611. + * get ahead of the total uncompressed block count.
  612. + */
  613. + estimated_uncompressed ++;
  614. +
  615. + if(prev_buffer)
  616. + queue_put(from_reader, prev_buffer);
  617. + prev_buffer = file_buffer;
  618. + }
  619. +
  620. + /*
  621. + * Update inode file size now that the size of the dynamic pseudo file
  622. + * is known. This is needed for the -info option.
  623. + */
  624. + dir_ent->inode->buf.st_size = bytes;
  625. +
  626. + res = waitpid(child, &status, 0);
  627. + if(res == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
  628. + goto read_err;
  629. +
  630. + if(prev_buffer == NULL)
  631. + prev_buffer = file_buffer;
  632. + else {
  633. + cache_block_put(file_buffer);
  634. + seq --;
  635. + }
  636. + prev_buffer->file_size = bytes;
  637. + prev_buffer->fragment = !no_fragments &&
  638. + (count == 2 || always_use_fragments) && (byte < block_size);
  639. + queue_put(from_reader, prev_buffer);
  640. +
  641. + return;
  642. +
  643. +read_err:
  644. + if(prev_buffer) {
  645. + cache_block_put(file_buffer);
  646. + seq --;
  647. + file_buffer = prev_buffer;
  648. + }
  649. + file_buffer->error = TRUE;
  650. + queue_put(from_deflate, file_buffer);
  651. +}
  652. +
  653. +
  654. void reader_read_file(struct dir_ent *dir_ent)
  655. {
  656. struct stat *buf = &dir_ent->inode->buf, buf2;
  657. struct file_buffer *file_buffer;
  658. - static int index = 0;
  659. int blocks, byte, count, expected, file, frag_block;
  660. long long bytes, read_size;
  661. @@ -2202,7 +2222,7 @@
  662. if(file_buffer)
  663. queue_put(from_reader, file_buffer);
  664. file_buffer = cache_get(reader_buffer, 0, 0);
  665. - file_buffer->sequence = index ++;
  666. + file_buffer->sequence = seq ++;
  667. byte = file_buffer->size = read_bytes(file, file_buffer->data,
  668. block_size);
  669. @@ -2238,7 +2258,7 @@
  670. read_err:
  671. file_buffer = cache_get(reader_buffer, 0, 0);
  672. - file_buffer->sequence = index ++;
  673. + file_buffer->sequence = seq ++;
  674. read_err2:
  675. file_buffer->error = TRUE;
  676. queue_put(from_deflate, file_buffer);
  677. @@ -2262,9 +2282,14 @@
  678. for(i = 0; i < dir->count; i++) {
  679. struct dir_ent *dir_ent = dir->list[i];
  680. struct stat *buf = &dir_ent->inode->buf;
  681. - if(dir_ent->data)
  682. + if(dir_ent->inode->root_entry)
  683. continue;
  684. + if(dir_ent->inode->pseudo_file) {
  685. + reader_read_process(dir_ent);
  686. + continue;
  687. + }
  688. +
  689. switch(buf->st_mode & S_IFMT) {
  690. case S_IFREG:
  691. reader_read_file(dir_ent);
  692. @@ -2365,7 +2390,7 @@
  693. void *deflator(void *arg)
  694. {
  695. - z_stream *stream = NULL;
  696. + void *stream = NULL;
  697. int oldstate;
  698. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
  699. @@ -2402,7 +2427,7 @@
  700. void *frag_deflator(void *arg)
  701. {
  702. - z_stream *stream = NULL;
  703. + void *stream = NULL;
  704. int oldstate;
  705. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldstate);
  706. @@ -2426,8 +2451,8 @@
  707. write_buffer->block = bytes;
  708. bytes += compressed_size;
  709. fragments_outstanding --;
  710. - pthread_mutex_unlock(&fragment_mutex);
  711. queue_put(to_writer, write_buffer);
  712. + pthread_mutex_unlock(&fragment_mutex);
  713. TRACE("Writing fragment %lld, uncompressed size %d, "
  714. "compressed size %d\n", file_buffer->block,
  715. file_buffer->size, compressed_size);
  716. @@ -2674,6 +2699,98 @@
  717. }
  718. +int write_file_process(squashfs_inode *inode, struct dir_ent *dir_ent,
  719. + struct file_buffer *read_buffer, int *duplicate_file)
  720. +{
  721. + long long read_size, file_bytes, start;
  722. + struct fragment *fragment;
  723. + unsigned int *block_list = NULL;
  724. + int block = 0, status;
  725. + long long sparse = 0;
  726. + struct file_buffer *fragment_buffer = NULL;
  727. +
  728. + *duplicate_file = FALSE;
  729. +
  730. + lock_fragments();
  731. +
  732. + file_bytes = 0;
  733. + start = bytes;
  734. + while (1) {
  735. + read_size = read_buffer->file_size;
  736. + if(read_buffer->fragment && read_buffer->c_byte)
  737. + fragment_buffer = read_buffer;
  738. + else {
  739. + block_list = realloc(block_list, (block + 1) *
  740. + sizeof(unsigned int));
  741. + if(block_list == NULL)
  742. + BAD_ERROR("Out of memory allocating block_list"
  743. + "\n");
  744. + block_list[block ++] = read_buffer->c_byte;
  745. + if(read_buffer->c_byte) {
  746. + read_buffer->block = bytes;
  747. + bytes += read_buffer->size;
  748. + cache_rehash(read_buffer, read_buffer->block);
  749. + file_bytes += read_buffer->size;
  750. + queue_put(to_writer, read_buffer);
  751. + } else {
  752. + sparse += read_buffer->size;
  753. + cache_block_put(read_buffer);
  754. + }
  755. + }
  756. + inc_progress_bar();
  757. +
  758. + if(read_size != -1)
  759. + break;
  760. +
  761. + read_buffer = get_file_buffer(from_deflate);
  762. + if(read_buffer->error)
  763. + goto read_err;
  764. + }
  765. +
  766. + unlock_fragments();
  767. + fragment = get_and_fill_fragment(fragment_buffer);
  768. + cache_block_put(fragment_buffer);
  769. +
  770. + if(duplicate_checking)
  771. + add_non_dup(read_size, file_bytes, block_list, start, fragment,
  772. + 0, 0, FALSE);
  773. + file_count ++;
  774. + total_bytes += read_size;
  775. +
  776. + if(read_size < (1LL << 32) && start < (1LL << 32) && sparse == 0)
  777. + create_inode(inode, dir_ent, SQUASHFS_FILE_TYPE, read_size,
  778. + start, block, block_list, fragment, NULL, 0);
  779. + else
  780. + create_inode(inode, dir_ent, SQUASHFS_LREG_TYPE, read_size,
  781. + start, block, block_list, fragment, NULL, sparse);
  782. +
  783. + if(duplicate_checking == FALSE)
  784. + free(block_list);
  785. +
  786. + return 0;
  787. +
  788. +read_err:
  789. + cur_uncompressed -= block;
  790. + status = read_buffer->error;
  791. + bytes = start;
  792. + if(!block_device) {
  793. + int res;
  794. +
  795. + queue_put(to_writer, NULL);
  796. + if(queue_get(from_writer) != 0)
  797. + EXIT_MKSQUASHFS();
  798. + res = ftruncate(fd, bytes);
  799. + if(res != 0)
  800. + BAD_ERROR("Failed to truncate dest file because %s\n",
  801. + strerror(errno));
  802. + }
  803. + unlock_fragments();
  804. + free(block_list);
  805. + cache_block_put(read_buffer);
  806. + return status;
  807. +}
  808. +
  809. +
  810. int write_file_blocks(squashfs_inode *inode, struct dir_ent *dir_ent,
  811. long long read_size, struct file_buffer *read_buffer,
  812. int *duplicate_file)
  813. @@ -2941,7 +3058,10 @@
  814. read_size = read_buffer->file_size;
  815. - if(read_size == 0) {
  816. + if(read_size == -1)
  817. + status = write_file_process(inode, dir_ent, read_buffer,
  818. + duplicate_file);
  819. + else if(read_size == 0) {
  820. write_file_empty(inode, dir_ent, duplicate_file);
  821. cache_block_put(read_buffer);
  822. } else if(read_buffer->fragment && read_buffer->c_byte)
  823. @@ -3036,6 +3156,8 @@
  824. memcpy(&inode->buf, buf, sizeof(struct stat));
  825. inode->read = FALSE;
  826. + inode->root_entry = FALSE;
  827. + inode->pseudo_file = FALSE;
  828. inode->inode = SQUASHFS_INVALID_BLK;
  829. inode->nlink = 1;
  830. @@ -3056,7 +3178,7 @@
  831. inline void add_dir_entry(char *name, char *pathname, struct dir_info *sub_dir,
  832. - struct inode_info *inode_info, void *data, struct dir_info *dir)
  833. + struct inode_info *inode_info, struct dir_info *dir)
  834. {
  835. if((dir->count % DIR_ENTRIES) == 0) {
  836. dir->list = realloc(dir->list, (dir->count + DIR_ENTRIES) *
  837. @@ -3075,8 +3197,7 @@
  838. NULL;
  839. dir->list[dir->count]->inode = inode_info;
  840. dir->list[dir->count]->dir = sub_dir;
  841. - dir->list[dir->count]->our_dir = dir;
  842. - dir->list[dir->count++]->data = data;
  843. + dir->list[dir->count++]->our_dir = dir;
  844. dir->byte_count += strlen(name) + sizeof(squashfs_dir_entry);
  845. }
  846. @@ -3128,10 +3249,10 @@
  847. if(dir->count < old_root_entries)
  848. for(i = 0; i < old_root_entries; i++) {
  849. - if(old_root_entry[i].type == SQUASHFS_DIR_TYPE)
  850. + if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE)
  851. dir->directory_count ++;
  852. - add_dir_entry(old_root_entry[i].name, "", NULL, NULL,
  853. - &old_root_entry[i], dir);
  854. + add_dir_entry(old_root_entry[i].name, "", NULL,
  855. + &old_root_entry[i].inode, dir);
  856. }
  857. while(index < source) {
  858. @@ -3167,10 +3288,10 @@
  859. if(dir->count < old_root_entries)
  860. for(i = 0; i < old_root_entries; i++) {
  861. - if(old_root_entry[i].type == SQUASHFS_DIR_TYPE)
  862. + if(old_root_entry[i].inode.type == SQUASHFS_DIR_TYPE)
  863. dir->directory_count ++;
  864. - add_dir_entry(old_root_entry[i].name, "", NULL, NULL,
  865. - &old_root_entry[i], dir);
  866. + add_dir_entry(old_root_entry[i].name, "", NULL,
  867. + &old_root_entry[i].inode, dir);
  868. }
  869. if((d_name = readdir(dir->linuxdir)) != NULL) {
  870. @@ -3215,7 +3336,7 @@
  871. int current_count;
  872. while((current_count = dir_info->current_count++) < dir_info->count)
  873. - if(dir_info->list[current_count]->data)
  874. + if(dir_info->list[current_count]->inode->root_entry)
  875. continue;
  876. else
  877. return dir_info->list[current_count];
  878. @@ -3240,11 +3361,11 @@
  879. int current_count;
  880. while((current_count = dir_info->current_count++) < dir_info->count)
  881. - if(dir_info->list[current_count]->data)
  882. - add_dir(dir_info->list[current_count]->data->inode,
  883. - dir_info->list[current_count]->data->inode_number,
  884. + if(dir_info->list[current_count]->inode->root_entry)
  885. + add_dir(dir_info->list[current_count]->inode->inode,
  886. + dir_info->list[current_count]->inode->inode_number,
  887. dir_info->list[current_count]->name,
  888. - dir_info->list[current_count]->data->type, dir);
  889. + dir_info->list[current_count]->inode->type, dir);
  890. else
  891. return dir_info->list[current_count];
  892. return NULL;
  893. @@ -3313,7 +3434,6 @@
  894. dir_ent->name = dir_ent->pathname = strdup(pathname);
  895. dir_ent->dir = dir_info;
  896. dir_ent->our_dir = NULL;
  897. - dir_ent->data = NULL;
  898. dir_info->dir_ent = dir_ent;
  899. if(sorted)
  900. @@ -3383,7 +3503,7 @@
  901. sub_dir = NULL;
  902. add_dir_entry(dir_name, filename, sub_dir, lookup_inode(&buf),
  903. - NULL, dir);
  904. + dir);
  905. }
  906. scan1_freedir(dir);
  907. @@ -3399,7 +3519,7 @@
  908. struct dir_ent *dir_ent;
  909. struct pseudo_entry *pseudo_ent;
  910. struct stat buf;
  911. - static pseudo_ino = 1;
  912. + static int pseudo_ino = 1;
  913. if(dir == NULL && (dir = scan1_opendir("")) == NULL)
  914. return NULL;
  915. @@ -3415,6 +3535,29 @@
  916. while((pseudo_ent = pseudo_readdir(pseudo)) != NULL) {
  917. dir_ent = scan2_lookup(dir, pseudo_ent->name);
  918. + if(pseudo_ent->dev->type == 's') {
  919. + struct stat *buf;
  920. + if(dir_ent == NULL) {
  921. + ERROR("Pseudo set file \"%s\" does not exist "
  922. + "in source filesystem. Ignoring\n",
  923. + pseudo_ent->pathname);
  924. + continue;
  925. + }
  926. + if(dir_ent->inode->root_entry) {
  927. + ERROR("Pseudo set file \"%s\" is a pre-existing"
  928. + " file in the filesystem being appended"
  929. + " to. It cannot be modified. "
  930. + "Ignoring!\n", pseudo_ent->pathname);
  931. + continue;
  932. + }
  933. + buf = &dir_ent->inode->buf;
  934. + buf->st_mode = (buf->st_mode & S_IFMT) |
  935. + pseudo_ent->dev->mode;
  936. + buf->st_uid = pseudo_ent->dev->uid;
  937. + buf->st_gid = pseudo_ent->dev->gid;
  938. + continue;
  939. + }
  940. +
  941. if(dir_ent) {
  942. ERROR("Pseudo file \"%s\" exists in source filesystem "
  943. "\"%s\"\n", pseudo_ent->pathname,
  944. @@ -3444,8 +3587,29 @@
  945. buf.st_mtime = time(NULL);
  946. buf.st_ino = pseudo_ino ++;
  947. - add_dir_entry(pseudo_ent->name, pseudo_ent->pathname, sub_dir,
  948. - lookup_inode(&buf), NULL, dir);
  949. + if(pseudo_ent->dev->type == 'f') {
  950. +#ifdef USE_TMP_FILE
  951. + struct stat buf2;
  952. + int res = stat(pseudo_ent->dev->filename, &buf2);
  953. + if(res == -1) {
  954. + ERROR("Stat on pseudo file \"%s\" failed, "
  955. + "skipping...", pseudo_ent->pathname);
  956. + continue;
  957. + }
  958. + buf.st_size = buf2.st_size;
  959. + add_dir_entry(pseudo_ent->name,
  960. + pseudo_ent->dev->filename, sub_dir,
  961. + lookup_inode(&buf), dir);
  962. +#else
  963. + struct inode_info *inode = lookup_inode(&buf);
  964. + inode->pseudo_id = pseudo_ent->dev->pseudo_id;
  965. + inode->pseudo_file = TRUE;
  966. + add_dir_entry(pseudo_ent->name, pseudo_ent->pathname,
  967. + sub_dir, inode, dir);
  968. +#endif
  969. + } else
  970. + add_dir_entry(pseudo_ent->name, pseudo_ent->pathname,
  971. + sub_dir, lookup_inode(&buf), dir);
  972. }
  973. scan2_freedir(dir);
  974. @@ -3482,8 +3646,9 @@
  975. &duplicate_file);
  976. INFO("file %s, uncompressed size %lld "
  977. "bytes %s\n", filename,
  978. - buf->st_size, duplicate_file ?
  979. - "DUPLICATE" : "");
  980. + (long long) buf->st_size,
  981. + duplicate_file ? "DUPLICATE" :
  982. + "");
  983. break;
  984. case S_IFDIR:
  985. @@ -3557,6 +3722,7 @@
  986. INFO("file %s, uncompressed "
  987. "size %lld bytes LINK"
  988. "\n", filename,
  989. + (long long)
  990. buf->st_size);
  991. break;
  992. case SQUASHFS_SYMLINK_TYPE:
  993. @@ -3667,10 +3833,11 @@
  994. BAD_ERROR("Out of memory in old root directory entries "
  995. "reallocation\n");
  996. - strcpy(old_root_entry[old_root_entries].name, name);
  997. - old_root_entry[old_root_entries].inode = inode;
  998. - old_root_entry[old_root_entries].inode_number = inode_number;
  999. - old_root_entry[old_root_entries++].type = type;
  1000. + old_root_entry[old_root_entries].name = strdup(name);
  1001. + old_root_entry[old_root_entries].inode.inode = inode;
  1002. + old_root_entry[old_root_entries].inode.inode_number = inode_number;
  1003. + old_root_entry[old_root_entries].inode.type = type;
  1004. + old_root_entry[old_root_entries++].inode.root_entry = TRUE;
  1005. }
  1006. @@ -4137,7 +4304,7 @@
  1007. #define VERSION() \
  1008. - printf("mksquashfs version 4.0 (2009/04/05)\n");\
  1009. + printf("mksquashfs version 4.1-CVS (2009/09/20)\n");\
  1010. printf("copyright (C) 2009 Phillip Lougher <[email protected]>\n\n"); \
  1011. printf("This program is free software; you can redistribute it and/or\n");\
  1012. printf("modify it under the terms of the GNU General Public License\n");\
  1013. @@ -4172,26 +4339,28 @@
  1014. source_path = argv + 1;
  1015. source = i - 2;
  1016. for(; i < argc; i++) {
  1017. - if(strcmp(argv[i], "-pf") == 0) {
  1018. + if(strcmp(argv[i], "-comp") == 0) {
  1019. if(++i == argc) {
  1020. - ERROR("%s: -pf missing filename\n", argv[0]);
  1021. + ERROR("%s: -comp missing compression type\n",
  1022. + argv[0]);
  1023. exit(1);
  1024. }
  1025. - if(read_pseudo_file(&pseudo, argv[i]) == FALSE) {
  1026. - ERROR("Failed to parse pseudo file \"%s\"\n",
  1027. - argv[i]);
  1028. + comp_name = argv[i];
  1029. + } else if(strcmp(argv[i], "-pf") == 0) {
  1030. + if(++i == argc) {
  1031. + ERROR("%s: -pf missing filename\n", argv[0]);
  1032. exit(1);
  1033. }
  1034. + if(read_pseudo_file(&pseudo, argv[i]) == FALSE)
  1035. + exit(1);
  1036. } else if(strcmp(argv[i], "-p") == 0) {
  1037. if(++i == argc) {
  1038. ERROR("%s: -p missing pseudo file definition\n",
  1039. argv[0]);
  1040. exit(1);
  1041. }
  1042. - if(read_pseudo_def(&pseudo, argv[i]) == FALSE) {
  1043. - ERROR("Failed to parse pseudo definition\n");
  1044. + if(read_pseudo_def(&pseudo, argv[i]) == FALSE)
  1045. exit(1);
  1046. - }
  1047. } else if(strcmp(argv[i], "-recover") == 0) {
  1048. if(++i == argc) {
  1049. ERROR("%s: -recover missing recovery file\n",
  1050. @@ -4394,34 +4563,16 @@
  1051. printOptions:
  1052. ERROR("SYNTAX:%s source1 source2 ... dest [options] "
  1053. "[-e list of exclude\ndirs/files]\n", argv[0]);
  1054. - ERROR("\nOptions are\n");
  1055. - ERROR("-version\t\tprint version, licence and "
  1056. - "copyright message\n");
  1057. - ERROR("-recover <name>\t\trecover filesystem data "
  1058. - "using recovery file <name>\n");
  1059. - ERROR("-no-recovery\t\tdon't generate a recovery "
  1060. - "file\n");
  1061. - ERROR("-info\t\t\tprint files written to filesystem\n");
  1062. - ERROR("-no-exports\t\tdon't make the filesystem "
  1063. - "exportable via NFS\n");
  1064. - ERROR("-no-progress\t\tdon't display the progress "
  1065. - "bar\n");
  1066. - ERROR("-no-sparse\t\tdon't detect sparse files\n");
  1067. + ERROR("\nFilesystem build options:\n");
  1068. + ERROR("-comp <comp>\t\tselect <comp> compression\n");
  1069. + ERROR("\t\t\tCompressors available:\n");
  1070. + display_compressors("\t\t\t", COMP_DEFAULT);
  1071. ERROR("-b <block_size>\t\tset data block to "
  1072. "<block_size>. Default %d bytes\n",
  1073. SQUASHFS_FILE_SIZE);
  1074. - ERROR("-processors <number>\tUse <number> processors."
  1075. - " By default will use number of\n");
  1076. - ERROR("\t\t\tprocessors available\n");
  1077. - ERROR("-read-queue <size>\tSet input queue to <size> "
  1078. - "Mbytes. Default %d Mbytes\n",
  1079. - READER_BUFFER_DEFAULT);
  1080. - ERROR("-write-queue <size>\tSet output queue to <size> "
  1081. - "Mbytes. Default %d Mbytes\n",
  1082. - WRITER_BUFFER_DEFAULT);
  1083. - ERROR("-fragment-queue <size>\tSet fagment queue to "
  1084. - "<size> Mbytes. Default %d Mbytes\n",
  1085. - FRAGMENT_BUFFER_DEFAULT);
  1086. + ERROR("-no-exports\t\tdon't make the filesystem "
  1087. + "exportable via NFS\n");
  1088. + ERROR("-no-sparse\t\tdon't detect sparse files\n");
  1089. ERROR("-noI\t\t\tdo not compress inode table\n");
  1090. ERROR("-noD\t\t\tdo not compress data blocks\n");
  1091. ERROR("-noF\t\t\tdo not compress fragment blocks\n");
  1092. @@ -4430,13 +4581,34 @@
  1093. "files larger than block size\n");
  1094. ERROR("-no-duplicates\t\tdo not perform duplicate "
  1095. "checking\n");
  1096. - ERROR("-noappend\t\tdo not append to existing "
  1097. - "filesystem\n");
  1098. + ERROR("-all-root\t\tmake all files owned by root\n");
  1099. + ERROR("-force-uid uid\t\tset all file uids to uid\n");
  1100. + ERROR("-force-gid gid\t\tset all file gids to gid\n");
  1101. + ERROR("-nopad\t\t\tdo not pad filesystem to a multiple "
  1102. + "of 4K\n");
  1103. ERROR("-keep-as-directory\tif one source directory is "
  1104. "specified, create a root\n");
  1105. ERROR("\t\t\tdirectory containing that directory, "
  1106. "rather than the\n");
  1107. ERROR("\t\t\tcontents of the directory\n");
  1108. + ERROR("\nFilesystem filter options:\n");
  1109. + ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n");
  1110. + ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n");
  1111. + ERROR("-sort <sort_file>\tsort files according to "
  1112. + "priorities in <sort_file>. One\n");
  1113. + ERROR("\t\t\tfile or dir with priority per line. "
  1114. + "Priority -32768 to\n");
  1115. + ERROR("\t\t\t32767, default priority 0\n");
  1116. + ERROR("-ef <exclude_file>\tlist of exclude dirs/files."
  1117. + " One per line\n");
  1118. + ERROR("-wildcards\t\tAllow extended shell wildcards "
  1119. + "(globbing) to be used in\n\t\t\texclude "
  1120. + "dirs/files\n");
  1121. + ERROR("-regex\t\t\tAllow POSIX regular expressions to "
  1122. + "be used in exclude\n\t\t\tdirs/files\n");
  1123. + ERROR("\nFilesystem append options:\n");
  1124. + ERROR("-noappend\t\tdo not append to existing "
  1125. + "filesystem\n");
  1126. ERROR("-root-becomes <name>\twhen appending source "
  1127. "files/directories, make the\n");
  1128. ERROR("\t\t\toriginal root become a subdirectory in "
  1129. @@ -4444,11 +4616,29 @@
  1130. ERROR("\t\t\tcalled <name>, rather than adding the new "
  1131. "source items\n");
  1132. ERROR("\t\t\tto the original root\n");
  1133. - ERROR("-all-root\t\tmake all files owned by root\n");
  1134. - ERROR("-force-uid uid\t\tset all file uids to uid\n");
  1135. - ERROR("-force-gid gid\t\tset all file gids to gid\n");
  1136. - ERROR("-nopad\t\t\tdo not pad filesystem to a multiple "
  1137. - "of 4K\n");
  1138. + ERROR("\nMksquashfs runtime options:\n");
  1139. + ERROR("-version\t\tprint version, licence and "
  1140. + "copyright message\n");
  1141. + ERROR("-recover <name>\t\trecover filesystem data "
  1142. + "using recovery file <name>\n");
  1143. + ERROR("-no-recovery\t\tdon't generate a recovery "
  1144. + "file\n");
  1145. + ERROR("-info\t\t\tprint files written to filesystem\n");
  1146. + ERROR("-no-progress\t\tdon't display the progress "
  1147. + "bar\n");
  1148. + ERROR("-processors <number>\tUse <number> processors."
  1149. + " By default will use number of\n");
  1150. + ERROR("\t\t\tprocessors available\n");
  1151. + ERROR("-read-queue <size>\tSet input queue to <size> "
  1152. + "Mbytes. Default %d Mbytes\n",
  1153. + READER_BUFFER_DEFAULT);
  1154. + ERROR("-write-queue <size>\tSet output queue to <size> "
  1155. + "Mbytes. Default %d Mbytes\n",
  1156. + WRITER_BUFFER_DEFAULT);
  1157. + ERROR("-fragment-queue <size>\tSet fagment queue to "
  1158. + "<size> Mbytes. Default %d Mbytes\n",
  1159. + FRAGMENT_BUFFER_DEFAULT);
  1160. + ERROR("\nMiscellaneous options:\n");
  1161. ERROR("-root-owned\t\talternative name for -all-root"
  1162. "\n");
  1163. ERROR("-noInodeCompression\talternative name for -noI"
  1164. @@ -4457,20 +4647,6 @@
  1165. "\n");
  1166. ERROR("-noFragmentCompression\talternative name for "
  1167. "-noF\n");
  1168. - ERROR("-sort <sort_file>\tsort files according to "
  1169. - "priorities in <sort_file>. One\n");
  1170. - ERROR("\t\t\tfile or dir with priority per line. "
  1171. - "Priority -32768 to\n");
  1172. - ERROR("\t\t\t32767, default priority 0\n");
  1173. - ERROR("-ef <exclude_file>\tlist of exclude dirs/files."
  1174. - " One per line\n");
  1175. - ERROR("-wildcards\t\tAllow extended shell wildcards "
  1176. - "(globbing) to be used in\n\t\t\texclude "
  1177. - "dirs/files\n");
  1178. - ERROR("-regex\t\t\tAllow POSIX regular expressions to "
  1179. - "be used in exclude\n\t\t\tdirs/files\n");
  1180. - ERROR("-p <pseudo-definition>\tAdd pseudo file definition\n");
  1181. - ERROR("-pf <pseudo-file>\tAdd list of pseudo file definitions\n");
  1182. exit(1);
  1183. }
  1184. }
  1185. @@ -4548,11 +4724,10 @@
  1186. fclose(fd);
  1187. } else if(strcmp(argv[i], "-e") == 0)
  1188. break;
  1189. - else if(strcmp(argv[i], "-b") == 0 ||
  1190. - strcmp(argv[i], "-root-becomes") == 0 ||
  1191. + else if(strcmp(argv[i], "-root-becomes") == 0 ||
  1192. strcmp(argv[i], "-sort") == 0 ||
  1193. strcmp(argv[i], "-pf") == 0 ||
  1194. - strcmp(argv[i], "-p") == 0)
  1195. + strcmp(argv[i], "-comp") == 0)
  1196. i++;
  1197. if(i != argc) {
  1198. @@ -4574,11 +4749,10 @@
  1199. sorted ++;
  1200. } else if(strcmp(argv[i], "-e") == 0)
  1201. break;
  1202. - else if(strcmp(argv[i], "-b") == 0 ||
  1203. - strcmp(argv[i], "-root-becomes") == 0 ||
  1204. + else if(strcmp(argv[i], "-root-becomes") == 0 ||
  1205. strcmp(argv[i], "-ef") == 0 ||
  1206. strcmp(argv[i], "-pf") == 0 ||
  1207. - strcmp(argv[i], "-p") == 0)
  1208. + strcmp(argv[i], "-comp") == 0)
  1209. i++;
  1210. #ifdef SQUASHFS_TRACE
  1211. @@ -4586,7 +4760,8 @@
  1212. #endif
  1213. if(!delete) {
  1214. - if(read_super(fd, &sBlk, argv[source + 1]) == 0) {
  1215. + comp = read_super(fd, &sBlk, argv[source + 1]);
  1216. + if(comp == NULL) {
  1217. ERROR("Failed to read existing filesystem - will not "
  1218. "overwrite - ABORTING!\n");
  1219. ERROR("To force Mksquashfs to write to this block "
  1220. @@ -4603,6 +4778,15 @@
  1221. always_use_fragments = SQUASHFS_ALWAYS_FRAGMENTS(sBlk.flags);
  1222. duplicate_checking = SQUASHFS_DUPLICATES(sBlk.flags);
  1223. exportable = SQUASHFS_EXPORTABLE(sBlk.flags);
  1224. + } else {
  1225. + comp = lookup_compressor(comp_name);
  1226. + if(!comp->supported) {
  1227. + ERROR("FATAL_ERROR: Compressor \"%s\" is not "
  1228. + "supported!\n", comp_name);
  1229. + ERROR("Compressors available:\n");
  1230. + display_compressors("", COMP_DEFAULT);
  1231. + EXIT_MKSQUASHFS();
  1232. + }
  1233. }
  1234. initialise_threads();
  1235. @@ -4648,8 +4832,8 @@
  1236. "size %d\n", SQUASHFS_MAJOR, s_minor, argv[source + 1],
  1237. block_size);
  1238. printf("All -b, -noI, -noD, -noF, no-duplicates, no-fragments, "
  1239. - "-always-use-fragments and -exportable options ignored"
  1240. - "\n");
  1241. + "-always-use-fragments,\n-exportable and -comp options "
  1242. + "ignored\n");
  1243. printf("\nIf appending is not wanted, please re-run with "
  1244. "-noappend specified!\n\n");
  1245. @@ -4803,8 +4987,7 @@
  1246. sBlk.bytes_used = bytes;
  1247. - /* Only compression supported */
  1248. - sBlk.compression = ZLIB_COMPRESSION;
  1249. + sBlk.compression = comp->id;
  1250. /* Xattrs are not currently supported */
  1251. sBlk.xattr_table_start = SQUASHFS_INVALID_BLK;
  1252. @@ -4820,6 +5003,8 @@
  1253. close(fd);
  1254. + delete_pseudo_files();
  1255. +
  1256. if(recovery_file[0] != '\0')
  1257. unlink(recovery_file);
  1258. @@ -4827,9 +5012,9 @@
  1259. * sizeof(unsigned short) + guid_count * sizeof(unsigned short) +
  1260. sizeof(squashfs_super_block);
  1261. - printf("\n%sSquashfs %d.%d filesystem, data block size %d\n",
  1262. - exportable ? "Exportable " : "", SQUASHFS_MAJOR, SQUASHFS_MINOR,
  1263. - block_size);
  1264. + printf("\n%sSquashfs %d.%d filesystem, %s compressed, data block size"
  1265. + " %d\n", exportable ? "Exportable " : "", SQUASHFS_MAJOR,
  1266. + SQUASHFS_MINOR, comp->name, block_size);
  1267. printf("\t%s data, %s metadata, %s fragments\n",
  1268. noD ? "uncompressed" : "compressed", noI ? "uncompressed" :
  1269. "compressed", no_fragments ? "no" : noF ? "uncompressed" :
  1270. diff -Nur squashfs4.0/squashfs-tools/pseudo.c squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.c
  1271. --- squashfs4.0/squashfs-tools/pseudo.c 2009-04-05 04:01:58.000000000 +0200
  1272. +++ squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.c 2009-10-20 06:03:38.000000000 +0200
  1273. @@ -30,6 +30,7 @@
  1274. #include <string.h>
  1275. #include <stdlib.h>
  1276. #include <sys/types.h>
  1277. +#include <sys/wait.h>
  1278. #include "pseudo.h"
  1279. @@ -55,6 +56,9 @@
  1280. #define TRUE 1
  1281. #define FALSE 0
  1282. +struct pseudo_dev **pseudo_file = NULL;
  1283. +int pseudo_count = 0;
  1284. +
  1285. static void dump_pseudo(struct pseudo *pseudo, char *string)
  1286. {
  1287. int i;
  1288. @@ -99,7 +103,7 @@
  1289. char *target, char *alltarget)
  1290. {
  1291. char targname[1024];
  1292. - int i, error;
  1293. + int i;
  1294. target = get_component(target, targname);
  1295. @@ -128,12 +132,8 @@
  1296. if(target[0] == '\0') {
  1297. /* at leaf pathname component */
  1298. pseudo->name[i].pseudo = NULL;
  1299. - pseudo->name[i].dev = malloc(sizeof(struct pseudo_dev));
  1300. - if(pseudo->name[i].dev == NULL)
  1301. - BAD_ERROR("failed to allocate pseudo file\n");
  1302. pseudo->name[i].pathname = strdup(alltarget);
  1303. - memcpy(pseudo->name[i].dev, pseudo_dev,
  1304. - sizeof(struct pseudo_dev));
  1305. + pseudo->name[i].dev = pseudo_dev;
  1306. } else {
  1307. /* recurse adding child components */
  1308. pseudo->name[i].dev = NULL;
  1309. @@ -169,15 +169,9 @@
  1310. if(target[0] == '\0') {
  1311. if(pseudo->name[i].dev == NULL &&
  1312. pseudo_dev->type == 'd') {
  1313. - pseudo->name[i].dev =
  1314. - malloc(sizeof(struct pseudo_dev));
  1315. - if(pseudo->name[i].dev == NULL)
  1316. - BAD_ERROR("failed to allocate "
  1317. - "pseudo file\n");
  1318. pseudo->name[i].pathname =
  1319. strdup(alltarget);
  1320. - memcpy(pseudo->name[i].dev, pseudo_dev,
  1321. - sizeof(struct pseudo_dev));
  1322. + pseudo->name[i].dev = pseudo_dev;
  1323. } else
  1324. ERROR("%s already exists as a "
  1325. "directory. Ignoring %s!\n",
  1326. @@ -229,16 +223,113 @@
  1327. }
  1328. +int exec_file(char *command, struct pseudo_dev *dev)
  1329. +{
  1330. + int child, res;
  1331. + static pid_t pid = -1;
  1332. + int pipefd[2];
  1333. +#ifdef USE_TMP_FILE
  1334. + char filename[1024];
  1335. + int status;
  1336. + static int number = 0;
  1337. +#endif
  1338. +
  1339. + if(pid == -1)
  1340. + pid = getpid();
  1341. +
  1342. +#ifdef USE_TMP_FILE
  1343. + sprintf(filename, "/tmp/squashfs_pseudo_%d_%d", pid, number ++);
  1344. + pipefd[1] = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
  1345. + if(pipefd[1] == -1) {
  1346. + printf("open failed\n");
  1347. + return -1;
  1348. + }
  1349. +#else
  1350. + res = pipe(pipefd);
  1351. + if(res == -1) {
  1352. + printf("pipe failed\n");
  1353. + return -1;
  1354. + }
  1355. +#endif
  1356. +
  1357. + child = fork();
  1358. + if(child == -1) {
  1359. + printf("fork failed\n");
  1360. + goto failed;
  1361. + }
  1362. +
  1363. + if(child == 0) {
  1364. + close(STDOUT_FILENO);
  1365. + res = dup(pipefd[1]);
  1366. + if(res == -1) {
  1367. + printf("dup failed\n");
  1368. + exit(EXIT_FAILURE);
  1369. + }
  1370. + execl("/bin/sh", "sh", "-c", command, (char *) NULL);
  1371. + printf("execl failed\n");
  1372. + exit(EXIT_FAILURE);
  1373. + }
  1374. +
  1375. +#ifdef USE_TMP_FILE
  1376. + res = waitpid(child, &status, 0);
  1377. + close(pipefd[1]);
  1378. + if(res != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) {
  1379. + dev->filename = strdup(filename);
  1380. + return 0;
  1381. + }
  1382. +failed:
  1383. + unlink(filename);
  1384. + return -1;
  1385. +#else
  1386. + close(pipefd[1]);
  1387. + dev->fd = pipefd[0];
  1388. + dev->child = child;
  1389. + return 0;
  1390. +failed:
  1391. + return -1;
  1392. +#endif
  1393. +}
  1394. +
  1395. +
  1396. +void add_pseudo_file(struct pseudo_dev *dev)
  1397. +{
  1398. + pseudo_file = realloc(pseudo_file, (pseudo_count + 1) *
  1399. + sizeof(struct pseudo_dev *));
  1400. + if(pseudo_file == NULL)
  1401. + BAD_ERROR("Failed to realloc pseudo_file\n");
  1402. +
  1403. + dev->pseudo_id = pseudo_count;
  1404. + pseudo_file[pseudo_count ++] = dev;
  1405. +}
  1406. +
  1407. +
  1408. +void delete_pseudo_files()
  1409. +{
  1410. +#ifdef USE_TMP_FILE
  1411. + int i;
  1412. +
  1413. + for(i = 0; i < pseudo_count; i++)
  1414. + unlink(pseudo_file[i]->filename);
  1415. +#endif
  1416. +}
  1417. +
  1418. +
  1419. +struct pseudo_dev *get_pseudo_file(int pseudo_id)
  1420. +{
  1421. + return pseudo_file[pseudo_id];
  1422. +}
  1423. +
  1424. +
  1425. int read_pseudo_def(struct pseudo **pseudo, char *def)
  1426. {
  1427. - int n;
  1428. + int n, bytes;
  1429. unsigned int major = 0, minor = 0, mode;
  1430. char filename[2048], type, suid[100], sgid[100], *ptr;
  1431. long long uid, gid;
  1432. - struct pseudo_dev dev;
  1433. + struct pseudo_dev *dev;
  1434. - n = sscanf(def, "%s %c %o %s %s %u %u", filename, &type, &mode, suid, sgid,
  1435. - &major, &minor);
  1436. + n = sscanf(def, "%s %c %o %s %s %n", filename, &type, &mode, suid,
  1437. + sgid, &bytes);
  1438. if(n < 5) {
  1439. ERROR("Not enough or invalid arguments in pseudo file "
  1440. @@ -249,7 +340,9 @@
  1441. switch(type) {
  1442. case 'b':
  1443. case 'c':
  1444. - if(n < 7) {
  1445. + n = sscanf(def + bytes, "%u %u", &major, &minor);
  1446. +
  1447. + if(n < 2) {
  1448. ERROR("Not enough or invalid arguments in pseudo file "
  1449. "definition\n");
  1450. goto error;
  1451. @@ -265,47 +358,15 @@
  1452. goto error;
  1453. }
  1454. - /* fall through */
  1455. - case 'd':
  1456. - if(mode > 0777) {
  1457. - ERROR("Mode %o out of range\n", mode);
  1458. + case 'f':
  1459. + if(def[bytes] == '\0') {
  1460. + ERROR("Not enough arguments in pseudo file "
  1461. + "definition\n");
  1462. goto error;
  1463. - }
  1464. -
  1465. - uid = strtoll(suid, &ptr, 10);
  1466. - if(*ptr == '\0') {
  1467. - if(uid < 0 || uid > ((1LL << 32) - 1)) {
  1468. - ERROR("Uid %s out of range\n", suid);
  1469. - goto error;
  1470. - }
  1471. - } else {
  1472. - struct passwd *pwuid = getpwnam(suid);
  1473. - if(pwuid)
  1474. - uid = pwuid->pw_uid;
  1475. - else {
  1476. - ERROR("Uid %s invalid uid or unknown user\n",
  1477. - suid);
  1478. - goto error;
  1479. - }
  1480. - }
  1481. -
  1482. - gid = strtoll(sgid, &ptr, 10);
  1483. - if(*ptr == '\0') {
  1484. - if(gid < 0 || gid > ((1LL << 32) - 1)) {
  1485. - ERROR("Gid %s out of range\n", sgid);
  1486. - goto error;
  1487. - }
  1488. - } else {
  1489. - struct group *grgid = getgrnam(sgid);
  1490. - if(grgid)
  1491. - gid = grgid->gr_gid;
  1492. - else {
  1493. - ERROR("Gid %s invalid uid or unknown user\n",
  1494. - sgid);
  1495. - goto error;
  1496. - }
  1497. - }
  1498. -
  1499. + }
  1500. + break;
  1501. + case 'd':
  1502. + case 'm':
  1503. break;
  1504. default:
  1505. ERROR("Unsupported type %c\n", type);
  1506. @@ -313,6 +374,43 @@
  1507. }
  1508. + if(mode > 0777) {
  1509. + ERROR("Mode %o out of range\n", mode);
  1510. + goto error;
  1511. + }
  1512. +
  1513. + uid = strtoll(suid, &ptr, 10);
  1514. + if(*ptr == '\0') {
  1515. + if(uid < 0 || uid > ((1LL << 32) - 1)) {
  1516. + ERROR("Uid %s out of range\n", suid);
  1517. + goto error;
  1518. + }
  1519. + } else {
  1520. + struct passwd *pwuid = getpwnam(suid);
  1521. + if(pwuid)
  1522. + uid = pwuid->pw_uid;
  1523. + else {
  1524. + ERROR("Uid %s invalid uid or unknown user\n", suid);
  1525. + goto error;
  1526. + }
  1527. + }
  1528. +
  1529. + gid = strtoll(sgid, &ptr, 10);
  1530. + if(*ptr == '\0') {
  1531. + if(gid < 0 || gid > ((1LL << 32) - 1)) {
  1532. + ERROR("Gid %s out of range\n", sgid);
  1533. + goto error;
  1534. + }
  1535. + } else {
  1536. + struct group *grgid = getgrnam(sgid);
  1537. + if(grgid)
  1538. + gid = grgid->gr_gid;
  1539. + else {
  1540. + ERROR("Gid %s invalid uid or unknown user\n", sgid);
  1541. + goto error;
  1542. + }
  1543. + }
  1544. +
  1545. switch(type) {
  1546. case 'b':
  1547. mode |= S_IFBLK;
  1548. @@ -323,16 +421,37 @@
  1549. case 'd':
  1550. mode |= S_IFDIR;
  1551. break;
  1552. + case 'f':
  1553. + mode |= S_IFREG;
  1554. + break;
  1555. }
  1556. - dev.type = type;
  1557. - dev.mode = mode;
  1558. - dev.uid = uid;
  1559. - dev.gid = gid;
  1560. - dev.major = major;
  1561. - dev.minor = minor;
  1562. + dev = malloc(sizeof(struct pseudo_dev));
  1563. + if(dev == NULL)
  1564. + BAD_ERROR("Failed to create pseudo_dev\n");
  1565. +
  1566. + dev->type = type;
  1567. + dev->mode = mode;
  1568. + dev->uid = uid;
  1569. + dev->gid = gid;
  1570. + dev->major = major;
  1571. + dev->minor = minor;
  1572. +
  1573. + if(type == 'f') {
  1574. + int res;
  1575. +
  1576. + printf("Executing dynamic pseudo file\n");
  1577. + printf("\t\"%s\"\n", def);
  1578. + res = exec_file(def + bytes, dev);
  1579. + if(res == -1) {
  1580. + ERROR("Failed to execute dynamic pseudo file definition"
  1581. + " \"%s\"\n", def);
  1582. + return FALSE;
  1583. + }
  1584. + add_pseudo_file(dev);
  1585. + }
  1586. - *pseudo = add_pseudo(*pseudo, &dev, filename, filename);
  1587. + *pseudo = add_pseudo(*pseudo, dev, filename, filename);
  1588. return TRUE;
  1589. diff -Nur squashfs4.0/squashfs-tools/pseudo.h squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.h
  1590. --- squashfs4.0/squashfs-tools/pseudo.h 2009-04-04 03:44:24.000000000 +0200
  1591. +++ squashfs4.0-lzma-snapshot/squashfs-tools/pseudo.h 2009-10-20 06:03:38.000000000 +0200
  1592. @@ -27,6 +27,12 @@
  1593. unsigned int gid;
  1594. unsigned int major;
  1595. unsigned int minor;
  1596. + int pseudo_id;
  1597. + int fd;
  1598. + int child;
  1599. +#ifdef USE_TMP_FILE
  1600. + char *filename;
  1601. +#endif
  1602. };
  1603. struct pseudo_entry {
  1604. @@ -46,3 +52,5 @@
  1605. extern int read_pseudo_file(struct pseudo **, char *);
  1606. extern struct pseudo *pseudo_subdir(char *, struct pseudo *);
  1607. extern struct pseudo_entry *pseudo_readdir(struct pseudo *);
  1608. +extern struct pseudo_dev *get_pseudo_file(int);
  1609. +extern void delete_pseudo_files();
  1610. diff -Nur squashfs4.0/squashfs-tools/read_fs.c squashfs4.0-lzma-snapshot/squashfs-tools/read_fs.c
  1611. --- squashfs4.0/squashfs-tools/read_fs.c 2009-03-31 06:23:14.000000000 +0200
  1612. +++ squashfs4.0-lzma-snapshot/squashfs-tools/read_fs.c 2009-10-20 06:03:38.000000000 +0200
  1613. @@ -36,7 +36,6 @@
  1614. #include <fcntl.h>
  1615. #include <errno.h>
  1616. #include <string.h>
  1617. -#include <zlib.h>
  1618. #include <sys/mman.h>
  1619. #ifndef linux
  1620. @@ -51,6 +50,7 @@
  1621. #include "squashfs_swap.h"
  1622. #include "read_fs.h"
  1623. #include "global.h"
  1624. +#include "compressor.h"
  1625. #include <stdlib.h>
  1626. @@ -66,7 +66,9 @@
  1627. fprintf(stderr, s, ## args); \
  1628. } while(0)
  1629. -int read_block(int fd, long long start, long long *next, unsigned char *block,
  1630. +static struct compressor *comp;
  1631. +
  1632. +int read_block(int fd, long long start, long long *next, void *block,
  1633. squashfs_super_block *sBlk)
  1634. {
  1635. unsigned short c_byte;
  1636. @@ -77,32 +79,24 @@
  1637. if(SQUASHFS_COMPRESSED(c_byte)) {
  1638. char buffer[SQUASHFS_METADATA_SIZE];
  1639. - int res;
  1640. - unsigned long bytes = SQUASHFS_METADATA_SIZE;
  1641. + int error, res;
  1642. c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
  1643. read_destination(fd, start + offset, c_byte, buffer);
  1644. - res = uncompress(block, &bytes, (const unsigned char *) buffer,
  1645. - c_byte);
  1646. - if(res != Z_OK) {
  1647. - if(res == Z_MEM_ERROR)
  1648. - ERROR("zlib::uncompress failed, not enough "
  1649. - "memory\n");
  1650. - else if(res == Z_BUF_ERROR)
  1651. - ERROR("zlib::uncompress failed, not enough "
  1652. - "room in output buffer\n");
  1653. - else
  1654. - ERROR("zlib::uncompress failed, unknown error "
  1655. - "%d\n", res);
  1656. + res = comp->uncompress(block, buffer, c_byte,
  1657. + SQUASHFS_METADATA_SIZE, &error);
  1658. + if(res == -1) {
  1659. + ERROR("%s uncompress failed with error code %d\n",
  1660. + comp->name, error);
  1661. return 0;
  1662. }
  1663. if(next)
  1664. *next = start + offset + c_byte;
  1665. - return bytes;
  1666. + return res;
  1667. } else {
  1668. c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
  1669. - read_destination(fd, start + offset, c_byte, (char *) block);
  1670. + read_destination(fd, start + offset, c_byte, block);
  1671. if(next)
  1672. *next = start + offset + c_byte;
  1673. return c_byte;
  1674. @@ -356,7 +350,7 @@
  1675. }
  1676. -int read_super(int fd, squashfs_super_block *sBlk, char *source)
  1677. +struct compressor *read_super(int fd, squashfs_super_block *sBlk, char *source)
  1678. {
  1679. read_destination(fd, SQUASHFS_START, sizeof(squashfs_super_block),
  1680. (char *) sBlk);
  1681. @@ -388,8 +382,18 @@
  1682. goto failed_mount;
  1683. }
  1684. + /* Check the compression type */
  1685. + comp = lookup_compressor_id(sBlk->compression);
  1686. + if(!comp->supported) {
  1687. + ERROR("Filesystem on %s uses %s compression, this is"
  1688. + "unsupported by this version\n", source, comp->name);
  1689. + display_compressors("", "");
  1690. + goto failed_mount;
  1691. + }
  1692. +
  1693. printf("Found a valid %sSQUASHFS superblock on %s.\n",
  1694. SQUASHFS_EXPORTABLE(sBlk->flags) ? "exportable " : "", source);
  1695. + printf("\tCompression used %s\n", comp->name);
  1696. printf("\tInodes are %scompressed\n",
  1697. SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : "");
  1698. printf("\tData is %scompressed\n",
  1699. @@ -417,10 +421,10 @@
  1700. TRACE("sBlk->lookup_table_start %llx\n", sBlk->lookup_table_start);
  1701. printf("\n");
  1702. - return TRUE;
  1703. + return comp;
  1704. failed_mount:
  1705. - return FALSE;
  1706. + return NULL;
  1707. }
  1708. @@ -514,12 +518,17 @@
  1709. SQUASHFS_INSWAP_ID_BLOCKS(index, indexes);
  1710. for(i = 0; i < indexes; i++) {
  1711. - int length;
  1712. - length = read_block(fd, index[i], NULL,
  1713. + int length = read_block(fd, index[i], NULL,
  1714. ((unsigned char *) id_table) +
  1715. (i * SQUASHFS_METADATA_SIZE), sBlk);
  1716. TRACE("Read id table block %d, from 0x%llx, length %d\n", i,
  1717. index[i], length);
  1718. + if(length == 0) {
  1719. + ERROR("Failed to read id table block %d, from 0x%llx, "
  1720. + "length %d\n", i, index[i], length);
  1721. + free(id_table);
  1722. + return NULL;
  1723. + }
  1724. }
  1725. SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids);
  1726. @@ -563,6 +572,13 @@
  1727. (i * SQUASHFS_METADATA_SIZE), sBlk);
  1728. TRACE("Read fragment table block %d, from 0x%llx, length %d\n",
  1729. i, fragment_table_index[i], length);
  1730. + if(length == 0) {
  1731. + ERROR("Failed to read fragment table block %d, from "
  1732. + "0x%llx, length %d\n", i,
  1733. + fragment_table_index[i], length);
  1734. + free(*fragment_table);
  1735. + return 0;
  1736. + }
  1737. }
  1738. for(i = 0; i < sBlk->fragments; i++)
  1739. @@ -599,6 +615,13 @@
  1740. (i * SQUASHFS_METADATA_SIZE), sBlk);
  1741. TRACE("Read inode lookup table block %d, from 0x%llx, length "
  1742. "%d\n", i, index[i], length);
  1743. + if(length == 0) {
  1744. + ERROR("Failed to read inode lookup table block %d, "
  1745. + "from 0x%llx, length %d\n", i, index[i],
  1746. + length);
  1747. + free(*inode_lookup_table);
  1748. + return 0;
  1749. + }
  1750. }
  1751. SQUASHFS_INSWAP_LONG_LONGS(*inode_lookup_table, sBlk->inodes);
  1752. diff -Nur squashfs4.0/squashfs-tools/sort.c squashfs4.0-lzma-snapshot/squashfs-tools/sort.c
  1753. --- squashfs4.0/squashfs-tools/sort.c 2009-03-31 06:25:53.000000000 +0200
  1754. +++ squashfs4.0-lzma-snapshot/squashfs-tools/sort.c 2009-10-20 06:03:38.000000000 +0200
  1755. @@ -198,7 +198,7 @@
  1756. while(dir->current_count < dir->count) {
  1757. struct dir_ent *dir_ent = dir->list[dir->current_count++];
  1758. struct stat *buf = &dir_ent->inode->buf;
  1759. - if(dir_ent->data)
  1760. + if(dir_ent->inode->root_entry)
  1761. continue;
  1762. switch(buf->st_mode & S_IFMT) {
  1763. @@ -254,6 +254,7 @@
  1764. write_file(&inode, entry->dir, &duplicate_file);
  1765. INFO("file %s, uncompressed size %lld bytes %s"
  1766. "\n", entry->dir->pathname,
  1767. + (long long)
  1768. entry->dir->inode->buf.st_size,
  1769. duplicate_file ? "DUPLICATE" : "");
  1770. entry->dir->inode->inode = inode;
  1771. @@ -261,6 +262,7 @@
  1772. } else
  1773. INFO("file %s, uncompressed size %lld bytes "
  1774. "LINK\n", entry->dir->pathname,
  1775. + (long long)
  1776. entry->dir->inode->buf.st_size);
  1777. }
  1778. }
  1779. diff -Nur squashfs4.0/squashfs-tools/sort.h squashfs4.0-lzma-snapshot/squashfs-tools/sort.h
  1780. --- squashfs4.0/squashfs-tools/sort.h 2009-02-08 13:02:53.000000000 +0100
  1781. +++ squashfs4.0-lzma-snapshot/squashfs-tools/sort.h 2009-10-20 06:03:38.000000000 +0200
  1782. @@ -42,17 +42,19 @@
  1783. struct inode_info *inode;
  1784. struct dir_info *dir;
  1785. struct dir_info *our_dir;
  1786. - struct old_root_entry_info *data;
  1787. };
  1788. struct inode_info {
  1789. - unsigned int nlink;
  1790. struct stat buf;
  1791. + struct inode_info *next;
  1792. squashfs_inode inode;
  1793. - unsigned int type;
  1794. unsigned int inode_number;
  1795. + unsigned int nlink;
  1796. + int pseudo_id;
  1797. + char type;
  1798. char read;
  1799. - struct inode_info *next;
  1800. + char root_entry;
  1801. + char pseudo_file;
  1802. };
  1803. struct priority_entry {
  1804. diff -Nur squashfs4.0/squashfs-tools/squashfs_compat.h squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_compat.h
  1805. --- squashfs4.0/squashfs-tools/squashfs_compat.h 2009-03-16 05:27:27.000000000 +0100
  1806. +++ squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_compat.h 2009-10-20 06:03:38.000000000 +0200
  1807. @@ -777,11 +777,10 @@
  1808. #endif
  1809. #define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
  1810. - int bits;\
  1811. - int b_pos = pos % 8;\
  1812. - unsigned long long val = 0;\
  1813. - unsigned char *s = (unsigned char *)p + (pos / 8);\
  1814. - unsigned char *d = ((unsigned char *) &val) + 7;\
  1815. + b_pos = pos % 8;\
  1816. + val = 0;\
  1817. + s = (unsigned char *)p + (pos / 8);\
  1818. + d = ((unsigned char *) &val) + 7;\
  1819. for(bits = 0; bits < (tbits + b_pos); bits += 8) \
  1820. *d-- = *s++;\
  1821. value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
  1822. diff -Nur squashfs4.0/squashfs-tools/squashfs_fs.h squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_fs.h
  1823. --- squashfs4.0/squashfs-tools/squashfs_fs.h 2009-03-18 03:50:20.000000000 +0100
  1824. +++ squashfs4.0-lzma-snapshot/squashfs-tools/squashfs_fs.h 2009-10-20 06:03:38.000000000 +0200
  1825. @@ -229,6 +229,7 @@
  1826. typedef long long squashfs_inode_t;
  1827. #define ZLIB_COMPRESSION 1
  1828. +#define LZMA_COMPRESSION 2
  1829. struct squashfs_super_block {
  1830. unsigned int s_magic;
  1831. diff -Nur squashfs4.0/squashfs-tools/unsquash-3.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-3.c
  1832. --- squashfs4.0/squashfs-tools/unsquash-3.c 2009-03-31 06:35:10.000000000 +0200
  1833. +++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-3.c 2009-10-20 06:03:38.000000000 +0200
  1834. @@ -36,7 +36,7 @@
  1835. sBlk.fragment_table_start);
  1836. if(sBlk.fragments == 0)
  1837. - return;
  1838. + return TRUE;
  1839. if((fragment_table = malloc(sBlk.fragments *
  1840. sizeof(squashfs_fragment_entry_3))) == NULL)
  1841. diff -Nur squashfs4.0/squashfs-tools/unsquash-4.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-4.c
  1842. --- squashfs4.0/squashfs-tools/unsquash-4.c 2009-03-31 06:38:31.000000000 +0200
  1843. +++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquash-4.c 2009-10-20 06:03:38.000000000 +0200
  1844. @@ -38,7 +38,7 @@
  1845. sBlk.fragment_table_start);
  1846. if(sBlk.fragments == 0)
  1847. - return;
  1848. + return TRUE;
  1849. if((fragment_table = malloc(sBlk.fragments *
  1850. sizeof(squashfs_fragment_entry))) == NULL)
  1851. diff -Nur squashfs4.0/squashfs-tools/unsquashfs.c squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.c
  1852. --- squashfs4.0/squashfs-tools/unsquashfs.c 2009-04-05 23:23:06.000000000 +0200
  1853. +++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.c 2009-10-20 06:03:39.000000000 +0200
  1854. @@ -25,6 +25,7 @@
  1855. #include "squashfs_swap.h"
  1856. #include "squashfs_compat.h"
  1857. #include "read_fs.h"
  1858. +#include "compressor.h"
  1859. struct cache *fragment_cache, *data_cache;
  1860. struct queue *to_reader, *to_deflate, *to_writer, *from_writer;
  1861. @@ -36,6 +39,7 @@
  1862. struct super_block sBlk;
  1863. squashfs_operations s_ops;
  1864. +struct compressor *comp;
  1865. int bytes = 0, swap, file_count = 0, dir_count = 0, sym_count = 0,
  1866. dev_count = 0, fifo_count = 0;
  1867. @@ -590,31 +594,23 @@
  1868. offset = 3;
  1869. if(SQUASHFS_COMPRESSED(c_byte)) {
  1870. char buffer[SQUASHFS_METADATA_SIZE];
  1871. - int res;
  1872. - unsigned long bytes = SQUASHFS_METADATA_SIZE;
  1873. + int error, res;
  1874. c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
  1875. if(read_bytes(start + offset, c_byte, buffer) == FALSE)
  1876. goto failed;
  1877. - res = uncompress((unsigned char *) block, &bytes,
  1878. - (const unsigned char *) buffer, c_byte);
  1879. + res = comp->uncompress(block, buffer, c_byte,
  1880. + SQUASHFS_METADATA_SIZE, &error);
  1881. - if(res != Z_OK) {
  1882. - if(res == Z_MEM_ERROR)
  1883. - ERROR("zlib::uncompress failed, not enough "
  1884. - "memory\n");
  1885. - else if(res == Z_BUF_ERROR)
  1886. - ERROR("zlib::uncompress failed, not enough "
  1887. - "room in output buffer\n");
  1888. - else
  1889. - ERROR("zlib::uncompress failed, unknown error "
  1890. - "%d\n", res);
  1891. + if(res == -1) {
  1892. + ERROR("%s uncompress failed with error code %d\n",
  1893. + comp->name, error);
  1894. goto failed;
  1895. }
  1896. if(next)
  1897. *next = start + offset + c_byte;
  1898. - return bytes;
  1899. + return res;
  1900. } else {
  1901. c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
  1902. if(read_bytes(start + offset, c_byte, block) == FALSE)
  1903. @@ -632,36 +628,26 @@
  1904. int read_data_block(long long start, unsigned int size, char *block)
  1905. {
  1906. - int res;
  1907. - unsigned long bytes = block_size;
  1908. + int error, res;
  1909. int c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(size);
  1910. TRACE("read_data_block: block @0x%llx, %d %s bytes\n", start,
  1911. - SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte),
  1912. - SQUASHFS_COMPRESSED_BLOCK(c_byte) ? "compressed" :
  1913. + c_byte, SQUASHFS_COMPRESSED_BLOCK(size) ? "compressed" :
  1914. "uncompressed");
  1915. if(SQUASHFS_COMPRESSED_BLOCK(size)) {
  1916. if(read_bytes(start, c_byte, data) == FALSE)
  1917. goto failed;
  1918. - res = uncompress((unsigned char *) block, &bytes,
  1919. - (const unsigned char *) data, c_byte);
  1920. + res = comp->uncompress(block, data, c_byte, block_size, &error);
  1921. - if(res != Z_OK) {
  1922. - if(res == Z_MEM_ERROR)
  1923. - ERROR("zlib::uncompress failed, not enough "
  1924. - "memory\n");
  1925. - else if(res == Z_BUF_ERROR)
  1926. - ERROR("zlib::uncompress failed, not enough "
  1927. - "room in output buffer\n");
  1928. - else
  1929. - ERROR("zlib::uncompress failed, unknown error "
  1930. - "%d\n", res);
  1931. + if(res == -1) {
  1932. + ERROR("%s uncompress failed with error code %d\n",
  1933. + comp->name, error);
  1934. goto failed;
  1935. }
  1936. - return bytes;
  1937. + return res;
  1938. } else {
  1939. if(read_bytes(start, c_byte, block) == FALSE)
  1940. goto failed;
  1941. @@ -671,7 +657,7 @@
  1942. failed:
  1943. ERROR("read_data_block: failed to read block @0x%llx, size %d\n", start,
  1944. - size);
  1945. + c_byte);
  1946. return FALSE;
  1947. }
  1948. @@ -1383,6 +1369,11 @@
  1949. #endif
  1950. printf("Creation or last append time %s", mkfs_str ? mkfs_str :
  1951. "failed to get time\n");
  1952. + printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n",
  1953. + sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0));
  1954. + if(sBlk.s_major == 4)
  1955. + printf("Compression %s\n", comp->name);
  1956. + printf("Block size %d\n", sBlk.block_size);
  1957. printf("Filesystem is %sexportable via NFS\n",
  1958. SQUASHFS_EXPORTABLE(sBlk.flags) ? "" : "not ");
  1959. @@ -1409,9 +1400,6 @@
  1960. SQUASHFS_DUPLICATES(sBlk.flags) ? "" : "not ");
  1961. else
  1962. printf("Duplicates are removed\n");
  1963. - printf("Filesystem size %.2f Kbytes (%.2f Mbytes)\n",
  1964. - sBlk.bytes_used / 1024.0, sBlk.bytes_used / (1024.0 * 1024.0));
  1965. - printf("Block size %d\n", sBlk.block_size);
  1966. if(sBlk.s_major > 1)
  1967. printf("Number of fragments %d\n", sBlk.fragments);
  1968. printf("Number of inodes %d\n", sBlk.inodes);
  1969. @@ -1459,6 +1447,18 @@
  1970. s_ops.read_inode = read_inode_4;
  1971. s_ops.read_uids_guids = read_uids_guids_4;
  1972. memcpy(&sBlk, &sBlk_4, sizeof(sBlk_4));
  1973. +
  1974. + /*
  1975. + * Check the compression type
  1976. + */
  1977. + comp = lookup_compressor_id(sBlk.compression);
  1978. + if(!comp->supported) {
  1979. + ERROR("Filesystem uses %s compression, this is "
  1980. + "unsupported by this version\n", comp->name);
  1981. + ERROR("Decompressors available:\n");
  1982. + display_compressors("", "");
  1983. + goto failed_mount;
  1984. + }
  1985. return TRUE;
  1986. }
  1987. @@ -1548,6 +1548,11 @@
  1988. goto failed_mount;
  1989. }
  1990. + /*
  1991. + * 1.x, 2.x and 3.x filesystems use gzip compression. Gzip is always
  1992. + * suppported.
  1993. + */
  1994. + comp = lookup_compressor("gzip");
  1995. return TRUE;
  1996. failed_mount:
  1997. @@ -1707,32 +1712,24 @@
  1998. while(1) {
  1999. struct cache_entry *entry = queue_get(to_deflate);
  2000. - int res;
  2001. - unsigned long bytes = block_size;
  2002. + int error, res;
  2003. - res = uncompress((unsigned char *) tmp, &bytes,
  2004. - (const unsigned char *) entry->data,
  2005. - SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size));
  2006. -
  2007. - if(res != Z_OK) {
  2008. - if(res == Z_MEM_ERROR)
  2009. - ERROR("zlib::uncompress failed, not enough"
  2010. - "memory\n");
  2011. - else if(res == Z_BUF_ERROR)
  2012. - ERROR("zlib::uncompress failed, not enough "
  2013. - "room in output buffer\n");
  2014. - else
  2015. - ERROR("zlib::uncompress failed, unknown error "
  2016. - "%d\n", res);
  2017. - } else
  2018. - memcpy(entry->data, tmp, bytes);
  2019. + res = comp->uncompress(tmp, entry->data,
  2020. + SQUASHFS_COMPRESSED_SIZE_BLOCK(entry->size), block_size,
  2021. + &error);
  2022. +
  2023. + if(res == -1)
  2024. + ERROR("%s uncompress failed with error code %d\n",
  2025. + comp->name, error);
  2026. + else
  2027. + memcpy(entry->data, tmp, res);
  2028. /*
  2029. * block has been either successfully decompressed, or an error
  2030. * occurred, clear pending flag, set error appropriately and
  2031. * wake up any threads waiting on this block
  2032. */
  2033. - cache_block_ready(entry, res != Z_OK);
  2034. + cache_block_ready(entry, res == -1);
  2035. }
  2036. }
  2037. @@ -1913,7 +1910,7 @@
  2038. #define VERSION() \
  2039. - printf("unsquashfs version 4.0 (2009/04/05)\n");\
  2040. + printf("unsquashfs version 4.1-CVS (2009/08/30)\n");\
  2041. printf("copyright (C) 2009 Phillip Lougher <[email protected]>"\
  2042. "\n\n");\
  2043. printf("This program is free software; you can redistribute it and/or\n");\
  2044. @@ -1938,7 +1935,6 @@
  2045. int fragment_buffer_size = FRAGMENT_BUFFER_DEFAULT;
  2046. int data_buffer_size = DATA_BUFFER_DEFAULT;
  2047. char *b;
  2048. - struct winsize winsize;
  2049. pthread_mutex_init(&screen_mutex, NULL);
  2050. root_process = geteuid() == 0;
  2051. @@ -2087,6 +2083,8 @@
  2052. "regular expressions\n");
  2053. ERROR("\t\t\t\trather than use the default shell "
  2054. "wildcard\n\t\t\t\texpansion (globbing)\n");
  2055. + ERROR("\nDecompressors available:\n");
  2056. + display_compressors("", "");
  2057. }
  2058. exit(1);
  2059. }
  2060. diff -Nur squashfs4.0/squashfs-tools/unsquashfs.h squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.h
  2061. --- squashfs4.0/squashfs-tools/unsquashfs.h 2009-03-29 04:29:02.000000000 +0200
  2062. +++ squashfs4.0-lzma-snapshot/squashfs-tools/unsquashfs.h 2009-10-20 06:03:39.000000000 +0200
  2063. @@ -31,7 +31,6 @@
  2064. #include <fcntl.h>
  2065. #include <errno.h>
  2066. #include <string.h>
  2067. -#include <zlib.h>
  2068. #include <sys/mman.h>
  2069. #include <utime.h>
  2070. #include <pwd.h>