recovery zip.c提权部分代码

该部分代码主要修改文件的权限为755,以及修复原来zip包里面的链接文件。

bool mzExtractRecursive(const ZipArchive *pArchive,

                        const char *zipDir, const char *targetDir,
                        int flags, const struct utimbuf *timestamp,
                        void (*callback)(const char *fn, void *), void *cookie)
{
    if (zipDir[0] == '/') {
        LOGE("mzExtractRecursive(): zipDir must be a relative path.\n");
        return false;
    }
    if (targetDir[0] != '/') {
        LOGE("mzExtractRecursive(): targetDir must be an absolute path.\n");
        return false;
    }


    unsigned int zipDirLen;
    char *zpath;


    zipDirLen = strlen(zipDir);
    zpath = (char *)malloc(zipDirLen + 2);
    if (zpath == NULL) {
        LOGE("Can't allocate %d bytes for zip path\n", zipDirLen + 2);
        return false;
    }
    /* If zipDir is empty, we'll extract the entire zip file.
     * Otherwise, canonicalize the path.
     */
    if (zipDirLen > 0) {
        /* Make sure there's (hopefully, exactly one) slash at the
         * end of the path.  This way we don't need to worry about
         * accidentally extracting "one/twothree" when a path like
         * "one/two" is specified.
         */
        memcpy(zpath, zipDir, zipDirLen);
        if (zpath[zipDirLen-1] != '/') {
            zpath[zipDirLen++] = '/';
        }
    }
    zpath[zipDirLen] = '\0';


    /* Set up the helper structure that we'll use to assemble paths.
     */
    MzPathHelper helper;
    helper.targetDir = targetDir;
    helper.targetDirLen = strlen(helper.targetDir);
    helper.zipDir = zpath;
    helper.zipDirLen = strlen(helper.zipDir);
    helper.buf = NULL;
    helper.bufLen = 0;


    /* Walk through the entries and extract anything whose path begins
     * with zpath.
//TODO: since the entries are sorted, binary search for the first match
//      and stop after the first non-match.
     */
    unsigned int i;
    bool seenMatch = false;
    int ok = true;
    for (i = 0; i < pArchive->numEntries; i++) {
        ZipEntry *pEntry = pArchive->pEntries + i;
        if (pEntry->fileNameLen < zipDirLen) {
//TODO: look out for a single empty directory entry that matches zpath, but
//      missing the trailing slash.  Most zip files seem to include
//      the trailing slash, but I think it's legal to leave it off.
//      e.g., zpath "a/b/", entry "a/b", with no children of the entry.
            /* No chance of matching.
             */
#if SORT_ENTRIES
            if (seenMatch) {
                /* Since the entries are sorted, we can give up
                 * on the first mismatch after the first match.
                 */
                break;
            }
#endif
            continue;
        }
        /* If zpath is empty, this strncmp() will match everything,
         * which is what we want.
         */
        if (strncmp(pEntry->fileName, zpath, zipDirLen) != 0) {
#if SORT_ENTRIES
            if (seenMatch) {
                /* Since the entries are sorted, we can give up
                 * on the first mismatch after the first match.
                 */
                break;
            }
#endif
            continue;
        }
        /* This entry begins with zipDir, so we'll extract it.
         */
        seenMatch = true;


        /* Find the target location of the entry.
         */
        const char *targetFile = targetEntryPath(&helper, pEntry);
        if (targetFile == NULL) {
            LOGE("Can't assemble target path for \"%.*s\"\n",
                    pEntry->fileNameLen, pEntry->fileName);
            ok = false;
            break;
        }


        /* With DRY_RUN set, invoke the callback but don't do anything else.
         */
        if (flags & MZ_EXTRACT_DRY_RUN) {
            if (callback != NULL) callback(targetFile, cookie);
            continue;
        }


        /* Create the file or directory.
         */
#define UNZIP_DIRMODE 0755
#define UNZIP_FILEMODE 0755
        if (pEntry->fileName[pEntry->fileNameLen-1] == '/') {
            if (!(flags & MZ_EXTRACT_FILES_ONLY)) {
                int ret = dirCreateHierarchy(
                        targetFile, UNZIP_DIRMODE, timestamp, false);
                if (ret != 0) {
                    LOGE("Can't create containing directory for \"%s\": %s\n",
                            targetFile, strerror(errno));
                    ok = false;
                    break;
                }
                LOGD("Extracted dir \"%s\"\n", targetFile);
            }
        } else {
            /* This is not a directory.  First, make sure that
             * the containing directory exists.
             */
            int ret = dirCreateHierarchy(
                    targetFile, UNZIP_DIRMODE, timestamp, true);
            if (ret != 0) {
                LOGE("Can't create containing directory for \"%s\": %s\n",
                        targetFile, strerror(errno));
                ok = false;
                break;
            }


            /* With FILES_ONLY set, we need to ignore metadata entirely,
             * so treat symlinks as regular files.
             */
         //   if (!(flags & MZ_EXTRACT_FILES_ONLY) && mzIsZipEntrySymlink(pEntry)) {
                /* The entry is a symbolic link.
                 * The relative target of the symlink is in the
                 * data section of this entry.
                 */
    if  (((pEntry->compression) == 0 )&&((pEntry->uncompLen ==7)||(pEntry->uncompLen ==14))) {
       if (pEntry->uncompLen == 0) {
                    LOGE("Symlink entry \"%s\" has no target\n",
                            targetFile);
                    ok = false;
                    break;
                }
                char *linkTarget = malloc(pEntry->uncompLen + 1);
                if (linkTarget == NULL) {
                    ok = false;
                    break;
                }
                ok = mzReadZipEntry(pArchive, pEntry, linkTarget,
                        pEntry->uncompLen);
                if (!ok) {
                    LOGE("Can't read symlink target for \"%s\"\n",
                            targetFile);
                    free(linkTarget);
                    break;
                }
                linkTarget[pEntry->uncompLen] = '\0';


                /* Make the link.
                 */
                ret = symlink(linkTarget, targetFile);
                if (ret != 0) {
                    LOGE("Can't symlink \"%s\" to \"%s\": %s\n",
                            targetFile, linkTarget, strerror(errno));
                    free(linkTarget);
                    ok = false;
                    break;
                }
                LOGD("Extracted symlink \"%s\" -> \"%s\"\n",
                        targetFile, linkTarget);
                free(linkTarget);
            } else {
                /* The entry is a regular file.
                 * Open the target for writing.
                 */
                int fd = creat(targetFile, UNZIP_FILEMODE);
                if (fd < 0) {
                    LOGE("Can't create target file \"%s\": %s\n",
                            targetFile, strerror(errno));
                    ok = false;
                    break;
                }


                bool ok = mzExtractZipEntryToFile(pArchive, pEntry, fd);
                close(fd);
                if (!ok) {
                    LOGE("Error extracting \"%s\"\n", targetFile);
                    ok = false;
                    break;
                }


                if (timestamp != NULL && utime(targetFile, timestamp)) {
                    LOGE("Error touching \"%s\"\n", targetFile);
                    ok = false;
                    break;
                }


                LOGD("wuxy Extracted file \"%s\"\n", targetFile);
            }
        }


        if (callback != NULL) callback(targetFile, cookie);
    }


    free(helper.buf);
    free(zpath);


    return ok;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值