#include #include #include #include #include #include #include #include #include // compile with gcc patches/fs2xml.c -lbz2 struct inode { char name[128]; char src[128]; char link[128]; int mode; int type; int size; int uid; int gid; int parentid; char *data; int compressed; int load; unsigned int mtime; }; struct inode *inodes; int ninodes = 0; char currentpackage[256]; struct __attribute__ ((__packed__)) posix_header { /* byte offset */ char name[100]; /* 0 */ char mode[8]; /* 100 */ char uid[8]; /* 108 */ char gid[8]; /* 116 */ char size[12]; /* 124 */ char mtime[12]; /* 136 */ char chksum[8]; /* 148 */ char typeflag; /* 156 */ char linkname[100]; /* 157 */ char magic[6]; /* 257 */ char version[2]; /* 263 */ char uname[32]; /* 265 */ char gname[32]; /* 297 */ char devmajor[8]; /* 329 */ char devminor[8]; /* 337 */ char prefix[155]; /* 345 */ /* 500 */ }; char* GetFullPath(const char* root, int id) { static char path[1024]; char temp[1024]; path[0] = 0; temp[0] = 0; while(id != -1) { strcpy(temp, path); sprintf(path, "/%s%s", inodes[id].name, temp); id = inodes[id].parentid; } strcpy(temp, path); sprintf(path, "%s%s", root, temp); return path; } char* GetFullPathNotHidden(const char* root, int id, int *hidden) { static char path[1024]; char temp[1024]; path[0] = 0; temp[0] = 0; while(id != -1) { strcpy(temp, path); if (inodes[id].name[0] == '.') { sprintf(path, "/%s%s", &(inodes[id].name[1]), temp); *hidden = 1; } else if ((inodes[id].name[0] == '_') && (inodes[id].name[1] == '_')) { sprintf(path, "/%s%s", &(inodes[id].name[2]), temp); *hidden = 1; } else if (inodes[id].name[0] == '_') { sprintf(path, "/%s%s", &(inodes[id].name[1]), temp); *hidden = 1; } else sprintf(path, "/%s%s", inodes[id].name, temp); id = inodes[id].parentid; } strcpy(temp, path); sprintf(path, "%s%s", root, temp); return path; } int decompress(const char *filename, unsigned char *buf) { BZFILE *BZ2fp_r = NULL; char name[256]; sprintf(name, "%s", filename); BZ2fp_r = BZ2_bzopen(name, "rb"); if (BZ2fp_r == NULL) { fprintf(stderr, "Error: Cannot open bz2 file\n"); exit(1); return 0; } int len = BZ2_bzread(BZ2fp_r, buf, 60*1024*1024); BZ2_bzclose(BZ2fp_r); //printf("decompressed size: %i\n", len); return len; } int Split(char *name, char walk[12][128]) { int n = strlen(name); int p = 0; int pn = 0; int i = 0; if (name[0] == '/') i=1; if (name[0] == '.') i=2; for(; iname, walk); //printf("%i\n", n); int parentid = -1; int i = 0; for(i=0; itypeflag != '5')) { fprintf(stderr, "Warning: File '%s' already exists with id = %i and name '%s'\n", walk[n-1], ret, inodes[ret].name); //exit(1); return; // do not overwrite } if ((ret != -1) && (ph->typeflag == '5')) return; // file exists strncpy(inodes[ninodes].name, walk[n-1], 127); //strncpy(inodes[ninodes].src, currentpackage, 127); inodes[ninodes].src[0] = 0; strncpy(inodes[ninodes].link, ph->linkname, 100); inodes[ninodes].parentid = parentid; inodes[ninodes].size = strtol(ph->size, NULL, 8); inodes[ninodes].uid = strtol(ph->uid, NULL, 8); inodes[ninodes].gid = strtol(ph->gid, NULL, 8); inodes[ninodes].mtime = strtol(ph->mtime, NULL, 8); int mode = strtol(ph->mode, NULL, 8); if ((inodes[ninodes].uid != 0) && (inodes[ninodes].uid != 1000)) { inodes[ninodes].uid = 0; inodes[ninodes].gid = 0; } switch(ph->typeflag) { case '5': mode |= S_IFDIR; break; case '0': mode |= S_IFREG; char *p = (char*)ph; if (inodes[ninodes].size != 0) { inodes[ninodes].data = malloc(inodes[ninodes].size); memcpy(inodes[ninodes].data, p+512, inodes[ninodes].size); } break; case '1': case '2': mode |= S_IFLNK; if (ph->linkname[0] == 0) { fprintf(stderr, "Error: no link given\n"); exit(1); } if (ph->typeflag == '1') { strncpy(inodes[ninodes].link+1, ph->linkname, 100); inodes[ninodes].link[0] = '/'; } //printf("%s\n", ph->linkname); break; default: printf("Error:type %c unknown\n", ph->typeflag); exit(1); break; } inodes[ninodes].mode = mode; ninodes++; } void Untar(unsigned char *buf, int len) { struct posix_header* ph; int p = 0; while(p < len) { ph = (struct posix_header*)&buf[p]; //printf("%s\n", ph->magic); p += 0x200; if (strncmp(ph->magic, "ustar", 5) != 0) { //ph->magic[5] = 0; //printf("magic wrong: %s\n", ph->magic); } if (strncmp(ph->magic, "ustar", 5) != 0) continue; //int size = atoi(ph->size); int size = strtol(ph->size, NULL, 8); printf("%c %s %8i %s\n", ph->typeflag, ph->mode, size, ph->name); MergeFile(ph); if (size != 0) { p = p + size; // round up if (p & 511) {p = p & (~0x1FF); /*p += 0x200;*/} } } } void PrintIdent(FILE *fp, int sub) { int i = 0; for(i=0; i"); if (!(IsEmpty(i))) fprintf(fp, "\n"); WalkXML(fp, i, sub+1); if (!(IsEmpty(i))) PrintIdent(fp, sub); fprintf(fp, "\n"); } else if ((inodes[i].mode & S_IFMT) == S_IFREG){ PrintIdent(fp, sub); fprintf(fp, "\n"); } else if ((inodes[i].mode & S_IFMT) == S_IFLNK) { PrintIdent(fp, sub); fprintf(fp, "\n", inodes[i].name, inodes[i].mode, inodes[i].link); } } } void CreateXML() { FILE *fp = fopen("fs.xml", "w"); if (fp == NULL) { fprintf(stderr, "Error: Cannot create file fs.xml\n"); exit(1); } // fprintf(fp, "\n", ninodes); fprintf(fp, "\n"); WalkXML(fp, -1, 1); fprintf(fp, "\n"); fclose(fp); } void WalkJSON(FILE *fp, int parentid, int sub) { int i=0; int n=0; for(i=0; i lenstr) return 0; return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0; } int ShouldBeCompressed(char *name, char *data, int size) { if (size < 4) return 0; int len = strlen(name); if (EndsWith(name, ".jpg")) return 0; if (EndsWith(name, ".png")) return 0; if (EndsWith(name, ".gz")) return 0; if (EndsWith(name, ".bz2")) return 0; if (EndsWith(name, ".zip")) return 0; if (EndsWith(name, ".png")) return 0; if (EndsWith(name, ".3gp")) return 0; if (EndsWith(name, ".mpg")) return 0; if (size > 10*1024) return 1; if (data[0] == 0x7F) if (data[1] == 'E') if (data[2] == 'L') if (data[3] == 'F') { //printf("found binary\n"); return 1; } return 0; } void RemoveFirstSignofString(char *s) { int n = strlen(s); int i; for(i=0; i=0; i--) { s[i+1] = s[i]; } s[0] = x; } void WalkDir(int parentid) { char *path; int hidden = 0; path = GetFullPathNotHidden("fs", parentid, &hidden); //printf("mkdir %s\n", path); mkdir(path, 0777); int i = 0; for(i=0; i