/* * extract an archive entry * returns pointer to the data (must be freed) */ unsigned char *extract(TOC *ptoc) { unsigned char *data; unsigned char *tmp; char msg[400]; sprintf( msg, " extracting %1.20s (%d, %c)\n", ptoc->name, ptoc->cflag, ptoc->typcd); //VS(msg); fseek(f_fp, f_pkgstart + ntohl(ptoc->pos), SEEK_SET); data = (unsigned char *)malloc(ntohl(ptoc->len)); if (data == NULL) { OTHERERROR("Could not allocate read buffer\n"); return NULL; } fread(data, ntohl(ptoc->len), 1, f_fp); if (ptoc->cflag == '\1') { #ifndef NOZLIB tmp = decompress(data, ptoc); free(data); data = tmp; if (data == NULL) { sprintf(msg, "Error decompressing %s\n", ptoc->name); OTHERERROR(msg); return NULL; } #else FATALERROR("No ZLIB support but archive uses compression\n"); return NULL; #endif } return data; }
/* * extract an archive entry * returns pointer to the data (must be freed) */ unsigned char *extract(TOC *ptoc) { unsigned char *data; unsigned char *tmp; fseek(f_fp, f_pkgstart + ntohl(ptoc->pos), SEEK_SET); data = (unsigned char *)malloc(ntohl(ptoc->len)); if (data == NULL) { OTHERERROR("Could not allocate read buffer\n"); return NULL; } fread(data, ntohl(ptoc->len), 1, f_fp); if (ptoc->cflag == '\2') { PyObject *func_new; PyObject *aes_dict; PyObject *aes_obj; PyObject *ddata; long block_size; char *iv; if (!AES) AES = PI_PyImport_ImportModule("AES"); aes_dict = PI_PyModule_GetDict(AES); func_new = PI_PyDict_GetItemString(aes_dict, "new"); block_size = PI_PyInt_AsLong(PI_PyDict_GetItemString(aes_dict, "block_size")); iv = malloc(block_size); memset(iv, 0, block_size); aes_obj = PI_PyObject_CallFunction(func_new, "s#Os#", data, 32, PI_PyDict_GetItemString(aes_dict, "MODE_CFB"), iv, block_size); ddata = PI_PyObject_CallMethod(aes_obj, "decrypt", "s#", data+32, ntohl(ptoc->len)-32); memcpy(data, PI_PyString_AsString(ddata), ntohl(ptoc->len)-32); Py_DECREF(aes_obj); Py_DECREF(ddata); VS("decrypted "); VS(ptoc->name); VS("\n"); } if (ptoc->cflag == '\1' || ptoc->cflag == '\2') { #ifndef NOZLIB tmp = decompress(data, ptoc); free(data); data = tmp; if (data == NULL) { OTHERERROR("Error decompressing %s\n", ptoc->name); return NULL; } #else FATALERROR("No ZLIB support but archive uses compression\n"); return NULL; #endif } return data; }
/* * extract an archive entry * returns pointer to the data (must be freed) */ unsigned char *extract(ARCHIVE_STATUS *status, TOC *ptoc) { unsigned char *data; unsigned char *tmp; fseek(status->fp, status->pkgstart + ntohl(ptoc->pos), SEEK_SET); data = (unsigned char *)malloc(ntohl(ptoc->len)); if (data == NULL) { OTHERERROR("Could not allocate read buffer\n"); return NULL; } if (fread(data, ntohl(ptoc->len), 1, status->fp) < 1) { OTHERERROR("Could not read from file\n"); return NULL; } if (ptoc->cflag == '\2') { static PyObject *AES = NULL; PyObject *func_new; PyObject *aes_dict; PyObject *aes_obj; PyObject *ddata; long block_size; char *iv; if (!AES) AES = PI_PyImport_ImportModule("AES"); aes_dict = PI_PyModule_GetDict(AES); func_new = PI_PyDict_GetItemString(aes_dict, "new"); block_size = PI_PyInt_AsLong(PI_PyDict_GetItemString(aes_dict, "block_size")); iv = malloc(block_size); memset(iv, 0, block_size); aes_obj = PI_PyObject_CallFunction(func_new, "s#Os#", data, 32, PI_PyDict_GetItemString(aes_dict, "MODE_CFB"), iv, block_size); ddata = PI_PyObject_CallMethod(aes_obj, "decrypt", "s#", data+32, ntohl(ptoc->len)-32); memcpy(data, PI_PyString_AsString(ddata), ntohl(ptoc->len)-32); Py_DECREF(aes_obj); Py_DECREF(ddata); VS("decrypted %s\n", ptoc->name); } if (ptoc->cflag == '\1' || ptoc->cflag == '\2') { tmp = decompress(data, ptoc); free(data); data = tmp; if (data == NULL) { OTHERERROR("Error decompressing %s\n", ptoc->name); return NULL; } } return data; }
/* decompress data in buff, described by ptoc * return in malloc'ed buffer (needs to be freed) */ unsigned char *decompress(unsigned char * buff, TOC *ptoc) { const char *ver; unsigned char *out; z_stream zstream; int rc; char msg[400]; ver = (zlibVersion)(); out = (unsigned char *)malloc(ntohl(ptoc->ulen)); if (out == NULL) { OTHERERROR("Error allocating decompression buffer\n"); return NULL; } zstream.zalloc = NULL; zstream.zfree = NULL; zstream.opaque = NULL; zstream.next_in = buff; zstream.avail_in = ntohl(ptoc->len); zstream.next_out = out; zstream.avail_out = ntohl(ptoc->ulen); rc = inflateInit(&zstream); if (rc >= 0) { rc = (inflate)(&zstream, Z_FINISH); if (rc >= 0) { rc = (inflateEnd)(&zstream); } else { sprintf(msg, "Error %d from inflate: %s\n", rc, zstream.msg); OTHERERROR(msg); return NULL; } } else { sprintf(msg, "Error %d from inflateInit: %s\n", rc, zstream.msg); OTHERERROR(msg); return NULL; } return out; }
/* * helper for extract2fs * which may try multiple places */ FILE *openTarget(const char *path, const char* name_) { struct stat sbuf; char fnm[_MAX_PATH+1]; char name[_MAX_PATH+1]; char *dir; strcpy(fnm, path); strcpy(name, name_); fnm[strlen(fnm)-1] = '\0'; dir = strtok(name, "/\\"); while (dir != NULL) { #ifdef WIN32 strcat(fnm, "\\"); #else strcat(fnm, "/"); #endif strcat(fnm, dir); dir = strtok(NULL, "/\\"); if (!dir) break; if (stat(fnm, &sbuf) < 0) { #ifdef WIN32 mkdir(fnm); #else mkdir(fnm, 0700); #endif } } if (stat(fnm, &sbuf) == 0) { OTHERERROR("WARNING: file already exists but should not: %s\n", fnm); } return fopen(fnm, "wb"); }
//TODO find better name for function. FILE *pyi_open_target(const char *path, const char* name_) { struct stat sbuf; char fnm[PATH_MAX]; char name[PATH_MAX]; char *dir; strcpy(fnm, path); strcpy(name, name_); dir = strtok(name, PYI_SEPSTR); while (dir != NULL) { strcat(fnm, PYI_SEPSTR); strcat(fnm, dir); dir = strtok(NULL, PYI_SEPSTR); if (!dir) break; if (stat(fnm, &sbuf) < 0) { #ifdef _WIN32 mkdir(fnm); #else mkdir(fnm, 0700); #endif } } if (stat(fnm, &sbuf) == 0) { OTHERERROR("WARNING: file already exists but should not: %s\n", fnm); } /* * pyi_path_fopen() wraps different fopen names. On Windows it uses * wide-character version of fopen. */ return pyi_path_fopen(fnm, "wb"); }