/* Made my own mount, because aosp api "ensure_path_mounted" relies on recovery.fstab
** and we needed one that can mount based on what the file system really is (from blkid), 
** and not what's in fstab or recovery.fstab
*/
int tw_mount(struct dInfo mMnt)
{
	if (strcmp(mMnt.mnt,"system") == 0 || strcmp(mMnt.mnt,"data") == 0 ||
		strcmp(mMnt.mnt,"cache") == 0 || strcmp(mMnt.mnt,"sd-ext") == 0 || 
		strcmp(mMnt.mnt,"efs") == 0) { // if any of the mount points match these
		FILE *fp;
		char mCommand[255];
		char mOutput[50];
		LOGI("=> Checking if /%s is mounted.\n",mMnt.mnt); // check it mounted
		sprintf(mCommand,"cat /proc/mounts | grep %s | awk '{ print $1 }'",mMnt.blk); // by checking for block in proc mounts
		fp = __popen(mCommand, "r"); // run above command
		if (fscanf(fp,"%s",mOutput) != 1) { // if we get a match
			__pclose(fp);
			LOGI("=> /%s is not mounted. Mounting...\n",mMnt.mnt);
			sprintf(mCommand,"mount -t %s %s /%s",mMnt.fst,mMnt.blk,mMnt.mnt); // mount using filesystem stored in struct mMnt.fst
			fp = __popen(mCommand, "r");
			fgets(mOutput,sizeof(mOutput),fp); // get output
			__pclose(fp);
			if (mOutput[0] == 'm') { // if output starts with m, it's an error
				ui_print("-- Error: %s",mOutput);
				return 1;
			} else {
				LOGI("=> Mounted /%s.\n",mMnt.mnt); // output should be nothing, so it's succesful
			}
		} else {
			__pclose(fp);
			LOGI("=> /%s is already mounted.\n",mMnt.mnt);
		}
	}
	return 0;
}
int tw_unmount(struct dInfo uMnt)
{
	if (strcmp(uMnt.mnt,"system") == 0 || strcmp(uMnt.mnt,"data") == 0 ||
		strcmp(uMnt.mnt,"cache") == 0 || strcmp(uMnt.mnt,"sd-ext") == 0 || 
		strcmp(uMnt.mnt,"efs") == 0) {
		FILE *fp;
		char uCommand[255];
		char uOutput[50];
		char exe[50];
		LOGI("=> Checking if /%s is mounted.\n",uMnt.mnt);
		sprintf(uCommand,"cat /proc/mounts | grep %s | awk '{ print $1 }'",uMnt.blk);
		fp = __popen(uCommand, "r");
		if (fscanf(fp,"%s",uOutput) == 1) {
			__pclose(fp);
			sprintf(exe,"umount /%s",uMnt.mnt);
			fp = __popen(exe, "r");
			fgets(uOutput,sizeof(uOutput),fp);
			__pclose(fp);
			if (uOutput[0] == 'u') {
				ui_print("-- Error: %s",uOutput);
				return 1;
			} else {
				LOGI("=> Unmounted /%s\n",uMnt.mnt);
			}
		} else {
			__pclose(fp);
			LOGI("=> /%s is not mounted.\n\n",uMnt.mnt);
		}
	}
	return 0;
}
Esempio n. 3
0
int twrp_tar_extract_wrapper(const char* popen_command, const char* backup_path, int callback) {
    char tmp[PATH_MAX];

    strcpy(tmp, popen_command);
    set_perf_mode(1);
    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute tar.\n");
        set_perf_mode(0);
        return -1;
    }

    int nand_starts = 1;
    last_size_update = 0;
    while (fgets(tmp, PATH_MAX, fp) != NULL) {
#ifdef PHILZ_TOUCH_RECOVERY
        if (user_cancel_nandroid(&fp, NULL, 0, &nand_starts)) {
            set_perf_mode(0);
            return -1;
        }
#endif
        tmp[PATH_MAX - 1] = '\0';
        if (callback) {
            update_size_progress(backup_path);
            nandroid_callback(tmp);
        }
    }

#ifdef PHILZ_TOUCH_RECOVERY
    ui_print_preset_colors(0, NULL);
#endif
    set_perf_mode(0);
    return __pclose(fp);
}
Esempio n. 4
0
static int dedupe_compress_wrapper(const char* backup_path, const char* backup_file_image, int callback) {
    char tmp[PATH_MAX];
    char blob_dir[PATH_MAX];
    strcpy(blob_dir, backup_file_image);
    char *d = dirname(blob_dir);
    strcpy(blob_dir, d);
    d = dirname(blob_dir);
    strcpy(blob_dir, d);
    d = dirname(blob_dir);
    strcpy(blob_dir, d);
    strcat(blob_dir, "/blobs");
    ensure_directory(blob_dir);

    if (!(nandroid_backup_bitfield & NANDROID_FIELD_DEDUPE_CLEARED_SPACE)) {
        nandroid_backup_bitfield |= NANDROID_FIELD_DEDUPE_CLEARED_SPACE;
        nandroid_dedupe_gc(blob_dir);
    }

    sprintf(tmp, "dedupe c %s %s %s.dup %s", backup_path, blob_dir, backup_file_image, strcmp(backup_path, "/data") == 0 && is_data_media() ? "./media" : "");

    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute dedupe.\n");
        return -1;
    }

    while (fgets(tmp, PATH_MAX, fp) != NULL) {
        tmp[PATH_MAX - 1] = NULL;
        if (callback)
            nandroid_callback(tmp);
    }

    return __pclose(fp);
}
Esempio n. 5
0
static int dedupe_extract_wrapper(const char* backup_file_image, const char* backup_path, int callback) {
    char tmp[PATH_MAX];
    char blob_dir[PATH_MAX];
    strcpy(blob_dir, backup_file_image);
    char *bd = dirname(blob_dir);
    strcpy(blob_dir, bd);
    bd = dirname(blob_dir);
    strcpy(blob_dir, bd);
    bd = dirname(blob_dir);
    sprintf(tmp, "dedupe x %s %s/blobs %s; exit $?", backup_file_image, bd, backup_path);

    char path[PATH_MAX];
    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute dedupe.\n");
        return -1;
    }

    while (fgets(path, PATH_MAX, fp) != NULL) {
        if (callback)
            nandroid_callback(path);
    }

    return __pclose(fp);
}
/* Execute a command */
int TWFunc::Exec_Cmd(const string& cmd, string &result) {
	FILE* exec;
	char buffer[130];
	int ret = 0;
	exec = __popen(cmd.c_str(), "r");
	if (!exec) return -1;
	while(!feof(exec)) {
		if (fgets(buffer, 128, exec) != NULL) {
			result += buffer;
		}
	}
	ret = __pclose(exec);
	return ret;
}
/* Execute a command */
int TWFunc::Exec_Cmd(string cmd, string &result) {
	FILE* exec;
	char buffer[130];
	int ret = 0;
	exec = __popen(cmd.c_str(), "r");
	if (!exec) return -1;
	while(!feof(exec)) {
		memset(&buffer, 0, sizeof(buffer));
		if (fgets(buffer, 128, exec) != NULL) {
			buffer[128] = '\n';
			buffer[129] = NULL;
			result += buffer;
		}
	}
	ret = __pclose(exec);
	return ret;
}
static int do_tar_extract(char* command, int callback) {
    char buf[PATH_MAX];

    FILE *fp = __popen(command, "r");
    if (fp == NULL) {
        ui_print("不能正确执行tar命令.\n");
        return -1;
    }

    while (fgets(buf, PATH_MAX, fp) != NULL) {
        buf[PATH_MAX - 1] = '\0';
        if (callback)
            nandroid_callback(buf);
    }

    return __pclose(fp);
}
static int do_tar_compress(char* command, int callback) {
    char buf[PATH_MAX];

    FILE *fp = __popen(command, "r");
    if (fp == NULL) {
        ui_print("Unable to execute tar command!\n");
        return -1;
    }

    while (fgets(buf, PATH_MAX, fp) != NULL) {
        buf[PATH_MAX - 1] = '\0';
        if (callback)
            nandroid_callback(buf);
    }

    return __pclose(fp);
}
Esempio n. 10
0
unsigned long long getUsedSizeViaDu(const char* path)
{
    char cmd[512];
    sprintf(cmd, "du -sk %s | awk '{ print $1 }'", path);

    FILE *fp;
    fp = __popen(cmd, "r");
    
    char str[512];
    fgets(str, sizeof(str), fp);
    __pclose(fp);

    unsigned long long size = atol(str);
    size *= 1024ULL;

    return size;
}
Esempio n. 11
0
static int unyaffs_wrapper(const char* backup_file_image, const char* backup_path, int callback) {
    char tmp[PATH_MAX];
    sprintf(tmp, "cd %s ; unyaffs %s ; exit $?", backup_path, backup_file_image);
    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute unyaffs.\n");
        return -1;
    }

    while (fgets(tmp, PATH_MAX, fp) != NULL) {
        tmp[PATH_MAX - 1] = NULL;
        if (callback)
            nandroid_callback(tmp);
    }

    return __pclose(fp);
}
Esempio n. 12
0
static int tar_extract_wrapper(const char* backup_file_image, const char* backup_path, int callback) {
    char tmp[PATH_MAX];
    sprintf(tmp, "cd $(dirname %s) ; cat %s* | tar xv ; exit $?", backup_path, backup_file_image);
    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute tar.\n");
        return -1;
    }

    while (fgets(tmp, PATH_MAX, fp) != NULL) {
        tmp[PATH_MAX - 1] = NULL;
        if (callback)
            nandroid_callback(tmp);
    }

    return __pclose(fp);
}
Esempio n. 13
0
static int tar_extract_wrapper(const char* backup_file_image, const char* backup_path, int callback) {
    char tmp[PATH_MAX];
    sprintf(tmp, "cd $(dirname %s) ; tar xvf %s ; exit $?", backup_path, backup_file_image);

    char path[PATH_MAX];
    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute tar.\n");
        return -1;
    }

    while (fgets(path, PATH_MAX, fp) != NULL) {
        if (callback)
            yaffs_callback(path);
    }

    return __pclose(fp);
}
Esempio n. 14
0
static int mkyaffs2image_wrapper(const char* backup_path, const char* backup_file_image, int callback) {
    char tmp[PATH_MAX];
    sprintf(tmp, "cd %s ; mkyaffs2image . %s.img ; exit $?", backup_path, backup_file_image);

    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("运行或者解析mkyaffs2image失败.\n");
        return -1;
    }

    while (fgets(tmp, PATH_MAX, fp) != NULL) {
        tmp[PATH_MAX - 1] = NULL;
        if (callback)
            nandroid_callback(tmp);
    }

    return __pclose(fp);
}
Esempio n. 15
0
static int tar_compress_wrapper(const char* backup_path, const char* backup_file_image, int callback) {
    char tmp[PATH_MAX];
    sprintf(tmp, "cd $(dirname %s) ; touch %s.tar ; (tar cv %s $(basename %s) | split -a 1 -b 1000000000 /proc/self/fd/0 %s.tar.) 2> /proc/self/fd/1 ; exit $?", backup_path, backup_file_image, strcmp(backup_path, "/data") == 0 && is_data_media() ? "--exclude 'media'" : "", backup_path, backup_file_image);

    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute tar.\n");
        return -1;
    }

    while (fgets(tmp, PATH_MAX, fp) != NULL) {
        tmp[PATH_MAX - 1] = NULL;
        if (callback)
            nandroid_callback(tmp);
    }

    return __pclose(fp);
}
Esempio n. 16
0
static int tar_extract_wrapper_legacy(const char* backup_file_image, const char* backup_path, int callback) {
    char tmp[PATH_MAX];
    // All subdirs are included in the tar archive
    sprintf(tmp, "cd / ; tar xvf %s ; exit $?", backup_file_image);

    char path[PATH_MAX];
    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute tar.\n");
        return -1;
    }

    while (fgets(path, PATH_MAX, fp) != NULL) {
        if (callback)
            yaffs_callback(path);
    }

    return __pclose(fp);
}
int TWFunc::Exec_Cmd_Show_Output(const string& cmd) {
	FILE* exec;
	char buffer[130];
	int ret = 0;
	exec = __popen(cmd.c_str(), "r");

	if (!exec)
		return -1;

	while(!feof(exec)) {
		memset(buffer, 0, sizeof(buffer));
		if (fgets(buffer, 128, exec) != NULL) {
			buffer[128] = '\n';
			buffer[129] = NULL;
			gui_print(buffer);
		}
	}
	ret = __pclose(exec);
	return ret;
}
Esempio n. 18
0
static int do_tar_extract(char* command, int callback) {
    char buf[PATH_MAX];

    set_perf_mode(1);
    FILE *fp = __popen(command, "r");
    if (fp == NULL) {
        ui_print("Unable to execute tar command.\n");
        set_perf_mode(0);
        return -1;
    }

    while (fgets(buf, PATH_MAX, fp) != NULL) {
        buf[PATH_MAX - 1] = '\0';
        if (callback)
            nandroid_callback(buf);
    }

    set_perf_mode(0);
    return __pclose(fp);
}
Esempio n. 19
0
eFSType Utility::getDeviceFSType(string device, bool cached /* = true */)
{
    static map<string,string> cachedOutput;

    if (!cached || cachedOutput.size() == 0)
    {
        // This routine uses blkid
        FILE* fp = __popen("blkid", "r");
        if (!fp)                                    return fs_unknown;

        char blkOutput[256];
        while (fgets(blkOutput, sizeof(blkOutput), fp) != NULL)
        {
            char* ptr = blkOutput;
            while (*ptr > 0 && *ptr != ':')     ptr++;
            if (*ptr == 0)  continue;
            *ptr = 0;

            ptr++;
            while (strlen(ptr) > 5)
            {
                if (memcmp(ptr, "TYPE=", 5) == 0)
                {
                    // Skip the open quote too
                    ptr += 6;
                    string type = ptr;
                    type = type.substr(0, type.size() - 2);

                    cachedOutput.insert(make_pair(blkOutput, type));
                    break;
                }
                ptr++;
            }
        }
        __pclose(fp);
    }

    map<string,string>::iterator iter = cachedOutput.find(device);
    if (iter == cachedOutput.end())   return fs_unknown;
    return getFsTypeFromStr(iter->second);
}
Esempio n. 20
0
static int tar_compress_wrapper(const char* backup_path, const char* backup_file_image, int callback) {
    char tmp[PATH_MAX];
    if (strcmp(backup_path, "/data") == 0 && volume_for_path("/sdcard") == NULL)
      sprintf(tmp, "cd $(dirname %s) ; tar cvf %s --exclude 'media' $(basename %s) ; exit $?", backup_path, backup_file_image, backup_path);
    else
      sprintf(tmp, "cd $(dirname %s) ; tar cvf %s $(basename %s) ; exit $?", backup_path, backup_file_image, backup_path);

    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
        ui_print("Unable to execute tar.\n");
        return -1;
    }

    while (fgets(tmp, PATH_MAX, fp) != NULL) {
        tmp[PATH_MAX - 1] = NULL;
        if (callback)
            yaffs_callback(tmp);
    }

    return __pclose(fp);
}
Esempio n. 21
0
static int mkyaffs2image_wrapper(const char* backup_path, const char* backup_file_image, int callback) {
    char tmp[PATH_MAX];
    sprintf(tmp, "cd %s ; mkyaffs2image . %s.img ; exit $?", backup_path, backup_file_image);

    FILE *fp = __popen(tmp, "r");
    if (fp == NULL) {
#ifndef USE_CHINESE_FONT
        ui_print("Unable to execute mkyaffs2image.\n");
#else
        ui_print("无法执行 mkyaffs2image。\n");
#endif
        return -1;
    }

    while (fgets(tmp, PATH_MAX, fp) != NULL) {
        tmp[PATH_MAX - 1] = '\0';
        if (callback)
            nandroid_callback(tmp);
    }

    return __pclose(fp);
}
Esempio n. 22
0
static int do_tar_compress(char* command, int callback) {
    char buf[PATH_MAX];

    set_perf_mode(1);
    FILE *fp = __popen(command, "r");
    if (fp == NULL) {
#ifndef USE_CHINESE_FONT
        ui_print("Unable to execute tar command!\n");
#else
        ui_print("无法执行 tar 命令!\n");
#endif
        set_perf_mode(0);
        return -1;
    }

    while (fgets(buf, PATH_MAX, fp) != NULL) {
        buf[PATH_MAX - 1] = '\0';
        if (callback)
            nandroid_callback(buf);
    }

    set_perf_mode(0);
    return __pclose(fp);
}
int
nandroid_back_exe()
{
	if (ensure_path_mounted(SDCARD_ROOT) != 0) {
		ui_print("-- Could not mount: %s.\n-- Aborting.\n",SDCARD_ROOT);
		return 1;
	}
    struct tm *t;
    char timestamp[15];
	char tw_image_dir[255];
	char exe[255];
	time_t start, stop;
	time_t seconds;
	seconds = time(0);
    t = localtime(&seconds);
    sprintf(timestamp,"%02d%02d%d%02d%02d%02d",t->tm_mon+1,t->tm_mday,t->tm_year+1900,t->tm_hour,t->tm_min,t->tm_sec); // make time stamp
	sprintf(tw_image_dir,"%s/%s/%s/",backup_folder,device_id,timestamp); // for backup folder
	sprintf(exe,"mkdir -p %s",tw_image_dir); // make the folder with timestamp
	if (__system(exe) != 0) {
		ui_print("-- Could not create: %s.\n-- Aborting.",tw_image_dir);
		return 1;
	} else {
		LOGI("=> Created folder: %s\n",tw_image_dir);
	}
	FILE *fp;
	char pOutput[25];
	int sdSpaceFinal;
	LOGI("=> Checking space on %s.\n",SDCARD_ROOT);
	fp = __popen("df -k /sdcard | grep sdcard | awk '{ print $4 \" \" $3 }'", "r"); // how much space left on sdcard?
	fgets(pOutput,25,fp);
	__pclose(fp);
	if(pOutput[2] == '%') { // oh o, crespo devices report diskspace on the 3rd argument.
		if (sscanf(pOutput,"%*s %d",&sdSpaceFinal) != 1) { // is it a number?
			ui_print("-- Could not determine free space on %s.",SDCARD_ROOT); // oh noes! Can't find sdcard's free space.
			return 1;
		}
	} else {
		if (sscanf(pOutput,"%d %*s",&sdSpaceFinal) != 1) { // is it a number?
			ui_print("-- Could not determine free space on %s.",SDCARD_ROOT); // oh noes! Can't find sdcard's free space.
			return 1;
		}
	}
	LOGI("=> %s",pOutput);
	sdSpace = sdSpaceFinal; // set starting and running count of sd space
	LOGI("=> /sdcard has %d MB free.\n",sdSpace/1024);
	time(&start);
	ui_print("\n[BACKUP STARTED]\n\n");
	ui_print("-- Verifying filesystems, please wait...\n");
	verifyFst();
	ui_print("-- Updating fstab.\n");
	createFstab();
	ui_print("-- Done.\n");
	// SYSTEM
	if (DataManager_GetIntValue(TW_NANDROID_SYSTEM_VAR)) { // was system backup enabled?
		if (tw_backup(sys,tw_image_dir) == 1) { // did the backup process return an error ? 0 = no error
			ui_print("-- Error occured, check recovery.log. Aborting.\n"); //oh noes! abort abort!
			return 1;
		}
	}
	// DATA
	if (DataManager_GetIntValue(TW_NANDROID_DATA_VAR)) {
		if (tw_backup(dat,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// BOOT
	if (DataManager_GetIntValue(TW_NANDROID_BOOT_VAR)) {
		if (tw_backup(boo,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// RECOVERY
	if (DataManager_GetIntValue(TW_NANDROID_RECOVERY_VAR)) {
		if (tw_backup(rec,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// CACHE
	if (DataManager_GetIntValue(TW_NANDROID_CACHE_VAR)) {
		if (tw_backup(cac,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// WIMAX
	if (DataManager_GetIntValue(TW_NANDROID_WIMAX_VAR)) {
		if (tw_backup(wim,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// ANDROID-SECURE
	if (DataManager_GetIntValue(TW_NANDROID_ANDSEC_VAR)) {
		if (tw_backup(ase,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	// SD-EXT
	if (DataManager_GetIntValue(TW_NANDROID_SDEXT_VAR)) {
		if (tw_backup(sde,tw_image_dir) == 1) {
			ui_print("-- Error occured, check recovery.log. Aborting.\n");
			return 1;
		}
	}
	LOGI("=> Checking /sdcard space again.\n\n");
	fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $4 \" \" $3 }'", "r");
	fgets(pOutput,25,fp);
	__pclose(fp);
	if(pOutput[2] == '%') {
		if (sscanf(pOutput,"%*s %d",&sdSpace) != 1) { // is it a number?
			ui_print("-- Could not determine free space on %s.\n",SDCARD_ROOT); // oh noes! Can't find sdcard's free space.
			return 1;
		}
	} else {
		if (sscanf(pOutput,"%d %*s",&sdSpace) != 1) { // is it a number?
			ui_print("-- Could not determine free space on %s.\n",SDCARD_ROOT); // oh noes! Can't find sdcard's free space.
			return 1;
		}
	}
	time(&stop);
	ui_print("[%d MB TOTAL BACKED UP TO SDCARD]\n",(int)(sdSpaceFinal - sdSpace) / 1024);
	output_time("BACKUP", "COMPLETED", (int)difftime(stop, start));
	return 0;
}
Esempio n. 24
0
void 
nandroid_back_exe()
{
	ensure_path_mounted(SDCARD_ROOT);
	FILE *fp;
	int isContinue = 1;
	int progTime;
	unsigned long sdSpace;
	unsigned long sdSpaceFinal;
	unsigned long imgSpace;
	char tmpOutput[150];
	char tmpString[15];
	char tmpChar;
	char exe[255];
	char tw_image_base[100];
	char tw_image[255];
    char timestamp[14];
    char tar_arg[5];
	struct stat st;
    struct tm * t;
    time_t seconds;
    time_t nan_ttime;
    time_t nan_ctime;
    seconds = time(0);
    t = localtime(&seconds);
    sprintf(timestamp,"%02d%02d%d%02d%02d",t->tm_mon+1,t->tm_mday,t->tm_year+1900,t->tm_hour,t->tm_min); // get timestamp for nandroid
	if (stat(backup_folder,&st) != 0) {
		if(mkdir(backup_folder,0777) == -1) {
			LOGI("=> Can not create directory: %s\n", backup_folder);
		} else {
			LOGI("=> Created directory: %s\n", backup_folder);
		}
	}
	sprintf(tw_image_base, "%s/%s/", backup_folder, device_id);
	if (stat(tw_image_base,&st) != 0) {
		if(mkdir(tw_image_base,0777) == -1) {
			LOGI("=> Can not create directory: %s\n", tw_image_base);
		} else {
			LOGI("=> Created directory: %s\n", tw_image_base);
		}
	}
	strcat(tw_image_base,timestamp);
	strcat(tw_image_base,"/");
	if(mkdir(tw_image_base,0777) == -1) {
		LOGI("=> Can not create directory: %s\n", tw_image_base);
	} else {
		LOGI("=> Created directory: %s\n", tw_image_base);
	}
	
	fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $4 }'", "r");
	LOGI("=> Checking SDCARD Disk Space.\n");
	while (fgets(tmpString,15,fp) != NULL)
	{
		tmpChar = tmpString[strlen(tmpString)-2];
	}
	__pclose(fp);
	if(tmpChar == '%')
	{
		fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $3 }'", "r");
		LOGI("=> Not the response we were looking for, trying again.\n");
		fgets(tmpString,15,fp);
		__pclose(fp);
	}
	sscanf(tmpString,"%lu",&sdSpace);
	sdSpaceFinal = sdSpace;
	LOGI("=> Space Left on SDCARD: %lu\n\n",sdSpaceFinal);
	
	int div;
	if (is_true(tw_use_compression_val) == 1) {
		strcpy(tar_arg,"czvpf");
		div = 500;
	} else {
		strcpy(tar_arg,"cvpf");
		div = 1000;
	}
	
	ui_print("\nStarting Backup...\n\n");
	nan_ttime = time(0);
	if (is_true(tw_nan_system_val)) {
		ensure_path_mounted("/system");
		fp = __popen("du -sk /system", "r");
		LOGI("=> Checking size of /system.\n");
	    fscanf(fp,"%lu %*s",&imgSpace);
		progTime = imgSpace / div;
		ui_print("[SYSTEM (%d MB)]\n",imgSpace/1024);
		__pclose(fp);
		if (sdSpace > imgSpace)
		{
			nan_ctime = time(0);
			strcpy(tw_image,tw_image_base);
			strcat(tw_image,tw_nan_system);
			sprintf(exe,"cd /%s && tar -%s %s ./*", sys.mnt, tar_arg, tw_image);
			ui_print("...Backing up system partition.\n");
			ui_show_progress(1,progTime);
			fp = __popen(exe, "r");
			while (fscanf(fp,"%s",tmpOutput) != EOF)
			{
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			ui_print_overwrite("....Done.\n");
			__pclose(fp);
			ui_print("...Generating %s md5...\n", sys.mnt);
			makeMD5(tw_image_base,tw_nan_system);
			ui_print("....Done.\n");
			ui_print("...Verifying %s md5...\n", sys.mnt);
			checkMD5(tw_image_base,tw_nan_system);
			ui_print("...Done.\n");
			ui_reset_progress();
			ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
		} else {
			ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
			isContinue = 0;
		}
		ensure_path_unmounted("/system");
		sdSpace -= imgSpace;
	}
	if (isContinue)
	{
		if (is_true(tw_nan_data_val)) {
			ensure_path_mounted("/data");
			fp = __popen("du -sk /data", "r");
			LOGI("=> Checking size of /data.\n");
		    fscanf(fp,"%lu %*s",&imgSpace);
			progTime = imgSpace / div;
			ui_print("[DATA (%d MB)]\n",imgSpace/1024);
			__pclose(fp);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_data);
				sprintf(exe,"cd /%s && tar -%s %s ./*", dat.mnt, tar_arg, tw_image);
				ui_print("...Backing up data partition.\n");
				ui_show_progress(1,progTime);
				fp = __popen(exe, "r");
				while (fscanf(fp,"%s",tmpOutput) != EOF)
				{
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				ui_print_overwrite("....Done.\n");
				__pclose(fp);
				ui_print("...Generating %s md5...\n", dat.mnt);
				makeMD5(tw_image_base,tw_nan_data);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", dat.mnt);
				checkMD5(tw_image_base,tw_nan_data);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			ensure_path_unmounted("/data");
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_boot_val)) {
			imgSpace = boo.sze / 1024;
			ui_print("[BOOT (%i MB)]\n",imgSpace/1024);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_boot);
				if (strcmp(boo.fst,"mtd") == 0)
				{
					sprintf(exe,"dump_image %s %s", boo.mnt, tw_image);
				} else {
					sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, boo.dev, tw_image);
				}
				ui_print("...Backing up boot partition.\n");
				ui_show_progress(1,5);
				__system(exe);
				LOGI("=> %s\n", exe);
				ui_print("....Done.\n");
				ui_print("...Generating %s md5...\n", boo.mnt);
				makeMD5(tw_image_base,tw_nan_boot);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", boo.mnt);
				checkMD5(tw_image_base,tw_nan_boot);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_recovery_val)) {
			imgSpace = rec.sze / 1024;
			ui_print("[RECOVERY (%i MB)]\n",imgSpace/1024);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_recovery);
				if (strcmp(rec.fst,"mtd") == 0)
				{
					sprintf(exe,"dump_image %s %s", rec.mnt, tw_image);
				} else {
					sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, rec.dev, tw_image);
				}
				ui_print("...Backing up recovery partition.\n");
				ui_show_progress(1,5);
				__system(exe);
				LOGI("=> %s\n", exe);
				ui_print("....Done.\n");
				ui_print("...Generating %s md5...\n", rec.mnt);
				makeMD5(tw_image_base,tw_nan_recovery);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", rec.mnt);
				checkMD5(tw_image_base,tw_nan_recovery);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_cache_val)) {
			ensure_path_mounted("/cache");
			fp = __popen("du -sk /cache", "r");
			LOGI("=> Checking size of /cache.\n");
		    fscanf(fp,"%lu %*s",&imgSpace);
			progTime = imgSpace / div;
			ui_print("[CACHE (%d MB)]\n",imgSpace/1024);
			__pclose(fp);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_cache);
				sprintf(exe,"cd /%s && tar -%s %s ./*", cac.mnt, tar_arg, tw_image);
				ui_print("...Backing up cache partition.\n");
				ui_show_progress(1,progTime);
				fp = __popen(exe, "r");
				while (fscanf(fp,"%s",tmpOutput) != EOF)
				{
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				ui_print_overwrite("....Done.\n");
				__pclose(fp);
				ui_print("...Generating %s md5...\n", cac.mnt);
				makeMD5(tw_image_base,tw_nan_cache);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", cac.mnt);
				checkMD5(tw_image_base,tw_nan_cache);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			ensure_path_unmounted("/cache");
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_wimax_val)) {
			if (strcmp(wim.mnt,"wimax") == 0)
			{
				imgSpace = wim.sze / 1024;
				ui_print("[WIMAX (%d MB)]\n",imgSpace/1024);
			} else {
				__system("mount /efs");
				fp = __popen("du -sk /efs", "r");
				LOGI("=> Checking size of /efs.\n");
			    fscanf(fp,"%lu %*s",&imgSpace);
				ui_print("[EFS (%d MB)]\n",imgSpace/1024);
				__pclose(fp);
			}
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_wimax);
				ui_print("...Backing up %s partition.\n", wim.mnt);
				ui_show_progress(1,5);
				if (strcmp(wim.mnt,"efs") == 0)
				{
					sprintf(exe,"cd /%s && tar -%s %s ./*", wim.mnt, tar_arg, tw_image);
				} else {
					if (strcmp(wim.fst,"mtd") == 0)
					{
						sprintf(exe,"dump_image %s %s", wim.mnt, tw_image);
						fp = __popen(exe, "r");
						while (fscanf(fp,"%s",tmpOutput) != EOF)
						{
							if(is_true(tw_show_spam_val))
							{
								ui_print("%s\n",tmpOutput);
							} else {
								ui_print_overwrite("%s",tmpOutput);
							}
						}
						__pclose(fp);
					} else {
						sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, wim.dev, tw_image);
						__system(exe);
						LOGI("=> %s\n", exe);
					}
				}
				ui_print_overwrite("....Done.\n");
				ui_print("...Generating %s md5...\n", wim.mnt);
				makeMD5(tw_image_base,tw_nan_wimax);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", wim.mnt);
				checkMD5(tw_image_base,tw_nan_wimax);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			if (strcmp(wim.mnt,"efs") == 0)
			{
				__system("umount /efs");
			}
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_andsec_val)) {
			ensure_path_mounted(ase.dev);
			fp = __popen("du -sk /sdcard/.android_secure", "r");
			LOGI("=> Checking size of .android_secure.\n");
		    fscanf(fp,"%lu %*s",&imgSpace);
			progTime = imgSpace / div;
			ui_print("[ANDROID_SECURE (%d MB)]\n",imgSpace/1024);
			__pclose(fp);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_andsec);
				sprintf(exe,"cd %s && tar -%s %s ./*", ase.dev, tar_arg, tw_image);
				ui_print("...Backing up .android_secure.\n");
				ui_show_progress(1,progTime);
				fp = __popen(exe, "r");
				while (fscanf(fp,"%s",tmpOutput) != EOF)
				{
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				__pclose(fp);
				ui_print_overwrite("....Done.\n");
				ui_print("...Generating %s md5...\n", ase.mnt);
				makeMD5(tw_image_base,tw_nan_andsec);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", ase.mnt);
				checkMD5(tw_image_base,tw_nan_andsec);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			sdSpace -= imgSpace;
		}
	}
	if (isContinue)
	{
		if (is_true(tw_nan_sdext_val)) {
			__system("mount /sd-ext");
			fp = __popen("du -sk /sd-ext", "r");
			LOGI("=> Checking size of /sd-ext.\n");
		    fscanf(fp,"%lu %*s",&imgSpace);
			progTime = imgSpace / div;
			ui_print("[SD-EXT (%d MB)]\n",imgSpace/1024);
			__pclose(fp);
			if (sdSpace > imgSpace)
			{
				nan_ctime = time(0);
				strcpy(tw_image,tw_image_base);
				strcat(tw_image,tw_nan_sdext);
				sprintf(exe,"cd %s && tar -%s %s ./*", sde.mnt, tar_arg, tw_image);
				ui_print("...Backing up sd-ext partition.\n");
				ui_show_progress(1,progTime);
				fp = __popen(exe, "r");
				while (fscanf(fp,"%s",tmpOutput) != EOF)
				{
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				__pclose(fp);
				ui_print_overwrite("....Done.\n");
				ui_print("...Generating %s md5...\n", sde.mnt);
				makeMD5(tw_image_base,tw_nan_sdext);
				ui_print("....Done.\n");
				ui_print("...Verifying %s md5...\n", sde.mnt);
				checkMD5(tw_image_base,tw_nan_sdext);
				ui_print("...Done.\n");
				ui_reset_progress();
				ui_print("Backed up in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("\nNot enough space left on /sdcard... Aborting.\n\n");
				isContinue = 0;
			}
			__system("umount /sd-ext");
			sdSpace -= imgSpace;
		}
	}
	fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $4 }'", "r");
	while (fgets(tmpString,15,fp) != NULL)
	{
		tmpChar = tmpString[strlen(tmpString)-2];
	}
	__pclose(fp);
	if(tmpChar == '%')
	{
		fp = __popen("df -k /sdcard| grep sdcard | awk '{ print $3 }'", "r");
		LOGI("=> Not the response we were looking for, trying again.\n");
		fgets(tmpString,15,fp);
		__pclose(fp);
	}
	sscanf(tmpString,"%lu",&sdSpace);
    int totalBackedUp = (int)(sdSpaceFinal - sdSpace) / 1024;
	ui_print("[ %d MB TOTAL BACKED UP TO SDCARD ]\n[ BACKUP COMPLETED IN %d SECONDS ]\n\n", totalBackedUp, time(0) - nan_ttime);
}
Esempio n. 25
0
void 
nandroid_rest_exe()
{
	ensure_path_mounted(SDCARD_ROOT);
	FILE *fp;
	char tmpBuffer[1024];
	char *tmpOutput;
	int tmpSize;
	int numErrors = 0;
	char exe[255];
	char* tmp_file = (char*)malloc(255);
    time_t nan_ttime;
    time_t nan_ctime;
	ui_print("\nStarting Restore...\n\n");
	nan_ttime = time(0);
	if (tw_nan_system_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_system);
		ui_show_progress(1,150);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_system))
		{
			ensure_path_mounted("/system");
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_system);
			ui_print("...Wiping %s.\n",sys.mnt);
			sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.* ", sys.mnt, sys.mnt);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd /%s && tar xzvpf %s", sys.mnt, tmp_file);
			ui_print("...Restoring system partition.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			ensure_path_unmounted("/system");
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_data_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_data);
		ui_show_progress(1,150);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_data))
		{
			ensure_path_mounted("/data");
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_data);
			ui_print("...Wiping %s.\n",dat.mnt);
			sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.* ", dat.mnt, dat.mnt);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd /%s && tar xzvpf %s", dat.mnt, tmp_file);
			ui_print("...Restoring data partition.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			ensure_path_unmounted("/data");
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_boot_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_boot);
		ui_show_progress(1,5);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_boot))
		{
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_boot);
			ui_print("...Double checking, by checking file size.\n");
			sprintf(exe,"ls -l %s",tmp_file);
			fp = __popen(exe, "r");
			fscanf(fp,"%*s %*i %*s %*s %i",&tmpSize);
			if (tmpSize == boo.sze)
			{
				ui_print("....File size matched partition size.\n");
				if (strcmp(boo.fst,"mtd") == 0)
				{
					sprintf(exe,"flash_image %s %s", boo.mnt, tmp_file);
				} else {
					sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, tmp_file, boo.dev);
				}
				LOGI("=> %s\n", exe);
				ui_print("...Restoring boot partition.\n");
				__system(exe);
				ui_print("...Done.\n");
				ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("...Failed file size check. Aborted.\n\n");
				numErrors++;
			}
			__pclose(fp);
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_recovery_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_recovery);
		ui_show_progress(1,5);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_recovery))
		{
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_recovery);
			ui_print("...Double checking, by checking file size.\n");
			sprintf(exe,"ls -l %s",tmp_file);
			fp = __popen(exe, "r");
			fscanf(fp,"%*s %*i %*s %*s %i",&tmpSize);
			if (tmpSize == rec.sze)
			{
				ui_print("....File size matched partition size.\n");
				if (strcmp(rec.fst,"mtd") == 0)
				{
					sprintf(exe,"flash_image %s %s", rec.mnt, tmp_file);
				} else {
					sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, tmp_file, rec.dev);
				}
				LOGI("=> %s\n", exe);
				ui_print("...Restoring recovery partition.\n");
				__system(exe);
				ui_print("...Done.\n");
				ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			} else {
				ui_print("...Failed file size check. Aborted.\n\n");
				numErrors++;
			}
			__pclose(fp);
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_cache_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_cache);
		ui_show_progress(1,100);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_cache))
		{
			ensure_path_mounted("/cache");
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_cache);
			ui_print("...Wiping %s.\n",cac.mnt);
			sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.* ", cac.mnt, cac.mnt);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd /%s && tar xzvpf %s", cac.mnt, tmp_file);
			ui_print("...Restoring cache partition.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			ensure_path_unmounted("/cache");
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_wimax_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_wimax);
		ui_show_progress(1,5);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_wimax))
		{
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_wimax);
			if (strcmp(wim.mnt,"efs") == 0)
			{
				__system("mount /efs");
				ui_print("...Wiping %s.\n",wim.mnt);
				sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.*", wim.mnt);
				__system(exe);
				ui_print("....Done.\n");
				sprintf(exe,"cd /%s && tar xzvpf %s", wim.mnt, tmp_file);
				ui_print("...Restoring efs partition.\n");
				fp = __popen(exe, "r");
				while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
				{
					tmpBuffer[strlen(tmpBuffer)-1] = '\0';
					tmpOutput = tmpBuffer;
					if(is_true(tw_show_spam_val))
					{
						ui_print("%s\n",tmpOutput);
					} else {
						ui_print_overwrite("%s",tmpOutput);
					}
				}
				__pclose(fp);
				ui_print_overwrite("....Done.\n");
				ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
				__system("umount /efs");
			} else {
				ui_print("...Double checking, by checking file size.\n");
				sprintf(exe,"ls -l %s",tmp_file);
				fp = __popen(exe, "r");
				fscanf(fp,"%*s %*i %*s %*s %i",&tmpSize);
				if (tmpSize == wim.sze)
				{
					ui_print("....File size matched partition size.\n");
					if (strcmp(rec.fst,"mtd") == 0)
					{
						sprintf(exe,"flash_image %s %s", wim.mnt, tmp_file);
					} else {
						sprintf(exe,"dd bs=%s if=%s of=%s", bs_size, tmp_file, wim.dev);
					}
					LOGI("=> %s\n", exe);
					ui_print("...Restoring wimax partition.\n");
					__system(exe);
					ui_print("...Done.\n");
					ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
				} else {
					ui_print("...Failed file size check. Aborted.\n\n");
					numErrors++;
				}
				__pclose(fp);
			}
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_andsec_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_andsec);
		ui_show_progress(1,25);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_andsec))
		{
			ensure_path_mounted(ase.dev);
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_andsec);
			ui_print("...Wiping %s.\n",ase.dev);
			sprintf(exe,"rm -rf %s/* && rm -rf %s/.* ", ase.dev, ase.dev);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd %s && tar xzvpf %s", ase.dev, tmp_file);
			ui_print("...Restoring .android-secure.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (tw_nan_sdext_x == 1) {
		ui_print("...Verifying md5 hash for %s.\n",tw_nan_sdext);
		ui_show_progress(1,25);
		nan_ctime = time(0);
		if(checkMD5(nan_dir,tw_nan_sdext))
		{
			__system("mount /sd-ext");
			strcpy(tmp_file,nan_dir);
			strcat(tmp_file,tw_nan_sdext);
			ui_print("...Wiping %s.\n",sde.mnt);
			sprintf(exe,"rm -rf /%s/* && rm -rf /%s/.* ", sde.mnt, sde.mnt);
			__system(exe);
			ui_print("....Done.\n");
			sprintf(exe,"cd /%s && tar xzvpf %s", sde.mnt, tmp_file);
			ui_print("...Restoring sd-ext partition.\n");
			fp = __popen(exe, "r");
			while (fgets(tmpBuffer,sizeof(tmpBuffer),fp) != NULL)
			{
				tmpBuffer[strlen(tmpBuffer)-1] = '\0';
				tmpOutput = tmpBuffer;
				if(is_true(tw_show_spam_val))
				{
					ui_print("%s\n",tmpOutput);
				} else {
					ui_print_overwrite("%s",tmpOutput);
				}
			}
			__pclose(fp);
			ui_print_overwrite("....Done.\n");
			ui_print("Restored in %d Seconds\n\n", time(0) - nan_ctime);
			__system("umount /sd-ext");
		} else {
			ui_print("...Failed md5 check. Aborted.\n\n");
			numErrors++;
		}
		ui_reset_progress();
	}
	if (numErrors > 0)
	{
		ui_print("[ %d ERROR(S), PLEASE CHECK LOGS ]\n", numErrors);
	}
	ui_print("[ RESTORE COMPLETED IN %d SECONDS ]\n\n", time(0) - nan_ttime);
	__system("sync");
	free(tmp_file);
}
Esempio n. 26
0
int phx_restore(struct dInfo rMnt, const char *rDir)
{
    int i;
    FILE *reFp;
    char rUppr[20];
    char rMount[30];
    char rFilesystem[10];
    char rFilename[255];
    char rCommand[255];
    char rOutput[255];
    time_t rStart, rStop;
    strcpy(rUppr,rMnt.mnt);
    for (i = 0; i < (int) strlen(rUppr); i++) {
        rUppr[i] = toupper(rUppr[i]);
    }
    ui_print("[%s]\n",rUppr);
    time(&rStart);
    int md5_result;
    if (DataManager_GetIntValue(VAR_SKIP_MD5_CHECK_VAR)) {
        SetDataState("Verifying MD5", rMnt.mnt, 0, 0);
        ui_print("...Verifying md5 hash for %s.\n",rMnt.mnt);
        md5_result = checkMD5(rDir, rMnt.fnm); // verify md5, check if no error; 0 = no error.
    } else {
        md5_result = 0;
        ui_print("Skipping MD5 check based on user setting.\n");
    }
    if(md5_result == 0)
    {
        strcpy(rFilename,rDir);
        if (rFilename[strlen(rFilename)-1] != '/')
        {
            strcat(rFilename, "/");
        }
        strcat(rFilename,rMnt.fnm);
        sprintf(rCommand,"ls -l %s | awk -F'.' '{ print $2 }'",rFilename); // let's get the filesystem type from filename
        reFp = __popen(rCommand, "r");
        LOGI("=> Filename is: %s\n",rMnt.fnm);
        while (fscanf(reFp,"%s",rFilesystem) == 1) { // if we get a match, store filesystem type
            LOGI("=> Filesystem is: %s\n",rFilesystem); // show it off to the world!
        }
        __pclose(reFp);

        if ((DataManager_GetIntValue(VAR_RM_RF_VAR) == 1 && (strcmp(rMnt.mnt,"system") == 0 || strcmp(rMnt.mnt,"data") == 0 || strcmp(rMnt.mnt,"cache") == 0)) || strcmp(rMnt.mnt,".android_secure") == 0) { // we'll use rm -rf instead of formatting for system, data and cache if the option is set, always use rm -rf for android secure
            char rCommand2[255];
            ui_print("...using rm -rf to wipe %s\n", rMnt.mnt);
            if (strcmp(rMnt.mnt,".android_secure") == 0) {
                phx_mount(sdcext); // for android secure we must make sure that the sdcard is mounted
                sprintf(rCommand, "rm -rf %s/*", rMnt.dev);
                sprintf(rCommand2, "rm -rf %s/.*", rMnt.dev);
            } else {
                phx_mount(rMnt); // mount the partition first
                sprintf(rCommand,"rm -rf %s%s/*", "/", rMnt.mnt);
                sprintf(rCommand2,"rm -rf %s%s/.*", "/", rMnt.mnt);
            }
            SetDataState("Wiping", rMnt.mnt, 0, 0);
            __system(rCommand);
            __system(rCommand2);
            ui_print("....done wiping.\n");
        } else {
            ui_print("...Formatting %s\n",rMnt.mnt);
            SetDataState("Formatting", rMnt.mnt, 0, 0);
            if (strcmp(rMnt.fst, "yaffs2") == 0) {
                if (strcmp(rMnt.mnt, "data") == 0) {
                    phx_format(rFilesystem,"userdata"); // on MTD yaffs2, data is actually found under userdata
                } else {
                    phx_format(rFilesystem,rMnt.mnt); // use mount location instead of block for formatting on mtd devices
                }
            } else {
                phx_format(rFilesystem,rMnt.blk); // let's format block, based on filesystem from filename above
            }
            ui_print("....done formatting.\n");
        }

        if (rMnt.backup == files)
        {
            phx_mount(rMnt);
            strcpy(rMount,"/");
            if (strcmp(rMnt.mnt,".android_secure") == 0) { // if it's android_secure, we have add prefix
                strcat(rMount,"sdcard/");
            }
            strcat(rMount,rMnt.mnt);
            sprintf(rCommand,"cd %s && tar -xvf %s",rMount,rFilename); // formulate shell command to restore
        } else if (rMnt.backup == image) {
            if (strcmp(rFilesystem,"mtd") == 0) { // if filesystem is mtd, we use flash image
                sprintf(rCommand,"flash_image %s %s",rMnt.mnt,rFilename);
                strcpy(rMount,rMnt.mnt);
            } else { // if filesystem is emmc, we use dd
                sprintf(rCommand,"dd bs=%s if=%s of=%s",bs_size,rFilename,rMnt.dev);
                strcpy(rMount,rMnt.mnt);
            }
        } else {
            LOGE("Unknown backup method for mount %s\n", rMnt.mnt);
            return 1;
        }

        ui_print("...Restoring %s\n\n",rMount);
        SetDataState("Restoring", rMnt.mnt, 0, 0);
        reFp = __popen(rCommand, "r");
        if(DataManager_GetIntValue(VAR_SHOW_SPAM_VAR) == 2) { // spam
            while (fgets(rOutput,sizeof(rOutput),reFp) != NULL) {
                ui_print_overwrite("%s",rOutput);
            }
        } else {
            while (fscanf(reFp,"%s",rOutput) == 1) {
                if(DataManager_GetIntValue(VAR_SHOW_SPAM_VAR) == 1) ui_print_overwrite("%s",rOutput);
            }
        }
        __pclose(reFp);
        ui_print_overwrite("....done restoring.\n");
        if (strcmp(rMnt.mnt,".android_secure") != 0) { // any partition other than android secure,
            phx_unmount(rMnt); // let's unmount (unmountable partitions won't matter)
        }
    } else {
        ui_print("...Failed md5 check. Aborted.\n\n");
        return 1;
    }
    time(&rStop);
    ui_print("[%s DONE (%d SECONDS)]\n\n",rUppr,(int)difftime(rStop,rStart));
    return 0;
}
void
set_restore_files()
{
	FILE *rfFp;
	char rfCommand[255];
	char rfOutput[20];
	tw_nan_system_x = -1; // set restore files as not there (default)
	tw_nan_data_x = -1;
	tw_nan_cache_x = -1;
	tw_nan_recovery_x = -1;
	tw_nan_wimax_x = -1;
	tw_nan_boot_x = -1;
	tw_nan_andsec_x = -1;
	tw_nan_sdext_x = -1;
	sprintf(rfCommand,"cd %s && ls -l *.win | awk '{ print $9 }'",nan_dir); // form scan for *.win files command
	rfFp = __popen(rfCommand, "r"); // open pipe with scan command
	while (fscanf(rfFp,"%s",rfOutput) == 1) { // while there is output
		if (strcmp(rfOutput,"system.yaffs2.win") == 0 ||
			strcmp(rfOutput,"system.ext2.win") == 0 ||
			strcmp(rfOutput,"system.ext3.win") == 0 ||
			strcmp(rfOutput,"system.ext4.win") == 0) { // if output matches any of these filenames
			strcpy(sys.fnm,rfOutput); // copy the filename and store in struct .fnm
			tw_nan_system_x = 1; // set restore option for system as visible
			tw_total++; // add to restore count
		}
		if (strcmp(rfOutput,"data.yaffs2.win") == 0 ||
			strcmp(rfOutput,"data.ext2.win") == 0 ||
			strcmp(rfOutput,"data.ext3.win") == 0 ||
			strcmp(rfOutput,"data.ext4.win") == 0) {
			strcpy(dat.fnm,rfOutput);
			tw_nan_data_x = 1;
			tw_total++;
		}
		if (strcmp(rfOutput,"cache.yaffs2.win") == 0 ||
			strcmp(rfOutput,"cache.ext2.win") == 0 ||
			strcmp(rfOutput,"cache.ext3.win") == 0 ||
			strcmp(rfOutput,"cache.ext4.win") == 0) {
			strcpy(cac.fnm,rfOutput);
			tw_nan_cache_x = 1;
			tw_total++;
		}
		if (strcmp(rfOutput,"sd-ext.ext2.win") == 0 ||
			strcmp(rfOutput,"sd-ext.ext3.win") == 0 ||
			strcmp(rfOutput,"sd-ext.ext4.win") == 0) {
			strcpy(sde.fnm,rfOutput);
			tw_nan_sdext_x = 1;
			tw_total++;
		}
		if (strcmp(rfOutput,"and-sec.vfat.win") == 0) {
			strcpy(ase.fnm,rfOutput);
			tw_nan_andsec_x = 1;
			tw_total++;
		}
		if (strcmp(rfOutput,"boot.mtd.win") == 0 ||
			strcmp(rfOutput,"boot.emmc.win") == 0) {
			strcpy(boo.fnm,rfOutput);
			tw_nan_boot_x = 1;
			tw_total++;
		}
		if (strcmp(rfOutput,"recovery.mtd.win") == 0 ||
			strcmp(rfOutput,"recovery.emmc.win") == 0) {
			strcpy(rec.fnm,rfOutput);
			tw_nan_recovery_x = 1;
			tw_total++;
		}
		if (strcmp(wim.mnt,"wimax") == 0 || strcmp(wim.mnt,"efs") == 0) {
			if (strcmp(rfOutput,"wimax.mtd.win") == 0 ||
				strcmp(rfOutput,"wimax.emmc.win") == 0) {
				strcpy(wim.fnm,rfOutput);
				tw_nan_wimax_x = 1;
				tw_total++;
			}
			if (strcmp(rfOutput,"efs.yaffs2.win") == 0) {
				strcpy(wim.fnm,rfOutput);
				tw_nan_wimax_x = 1;
				tw_total++;
			}
		}
	}
	__pclose(rfFp);
}
Esempio n. 28
0
int twrp_backup_wrapper(const char* backup_path, const char* backup_file_image, int callback) {
    Volume *v = volume_for_path(backup_path);
    if (v == NULL) {
        ui_print("Unable to find volume.\n");
        return -1;
    }

    if (!is_path_mounted(backup_path)) {
        LOGE("Unable to find mounted volume: '%s'\n", v->mount_point);
        return -1;
    }

    // Always use split format (simpler code) - Build lists of files to backup
    char tmp[PATH_MAX];
    int backup_count;
    ui_print("Breaking backup file into multiple archives...\nGenerating file lists\n");
    backup_count = Make_File_List(backup_path);
    if (backup_count < 1) {
        LOGE("Error generating file list!\n");
        return -1;
    }

    // check we are not backing up an empty volume as it would fail to restore (tar: short read)
    // check first if a filelist was generated. If not, ensure volume is 0 size. Else, it could be an error while 
    if (!file_found("/tmp/list/filelist000")) {
        ui_print("Nothing to backup. Skipping %s\n", BaseName(backup_path));
        return 0;
    }

    unsigned long long total_bsize = 0, file_size = 0;
    int index;
    int nand_starts = 1;
    last_size_update = 0;
    set_perf_mode(1);
    for (index = 0; index < backup_count; index++)
    {
        compute_twrp_backup_stats(index);
        // folder /data/media and google cached music are excluded from tar by Generate_File_Lists(...)
        if (nandroid_get_default_backup_format() == NANDROID_BACKUP_FORMAT_TAR)
            sprintf(tmp, "(tar -cpvf '%s%03i' -T /tmp/list/filelist%03i) 2> /proc/self/fd/1 ; exit $?", backup_file_image, index, index);
        else
            sprintf(tmp, "set -o pipefail ; (tar -cpv -T /tmp/list/filelist%03i | pigz -c -%d >'%s%03i') 2> /proc/self/fd/1 ; exit $?", index, compression_value.value, backup_file_image, index);

        ui_print("  * Backing up archive %i/%i\n", (index + 1), backup_count);
        FILE *fp = __popen(tmp, "r");
        if (fp == NULL) {
            LOGE("Unable to execute tar.\n");
            set_perf_mode(0);
            return -1;
        }

        while (fgets(tmp, PATH_MAX, fp) != NULL) {
#ifdef PHILZ_TOUCH_RECOVERY
            if (user_cancel_nandroid(&fp, backup_file_image, 1, &nand_starts)) {
                set_perf_mode(0);
                return -1;
            }
#endif
            tmp[PATH_MAX - 1] = '\0';
            if (callback) {
                update_size_progress(backup_file_image);
                nandroid_callback(tmp);
            }
        }

#ifdef PHILZ_TOUCH_RECOVERY
        ui_print_preset_colors(0, NULL);
#endif
        if (0 != __pclose(fp)) {
            set_perf_mode(0);
            return -1;
        }

        sprintf(tmp, "%s%03i", backup_file_image, index);
        file_size = Get_File_Size(tmp);
        if (file_size == 0) {
            LOGE("Backup file size for '%s' is 0 bytes!\n", tmp);
            set_perf_mode(0);
            return -1;
        }
        total_bsize += file_size;
    }

    __system("cd /tmp && rm -rf list");
    set_perf_mode(0);
    ui_print("Total backup size:\n  %llu bytes.\n", total_bsize);
    return 0;
}
/* New backup function
** Condensed all partitions into one function
*/
int tw_backup(struct dInfo bMnt, char *bDir)
{
	if (ensure_path_mounted(SDCARD_ROOT) != 0) {
		ui_print("-- Could not mount: %s.\n-- Aborting.\n",SDCARD_ROOT);
		return 1;
	}
	int bDiv;
	char bTarArg[10];
	if (DataManager_GetIntValue(TW_USE_COMPRESSION_VAR)) { // set compression or not
		strcpy(bTarArg,"-czvf");
		bDiv = 512;
	} else {
		strcpy(bTarArg,"-cvf");
		bDiv = 2048;
	}
	FILE *bFp;
	int bPartSize;
	char *bImage = malloc(sizeof(char)*50);
	char *bMount = malloc(sizeof(char)*50);
	char *bCommand = malloc(sizeof(char)*255);
	if (strcmp(bMnt.mnt,"system") == 0 || strcmp(bMnt.mnt,"data") == 0 || 
			strcmp(bMnt.mnt,"cache") == 0 || strcmp(bMnt.mnt,"sd-ext") == 0 || 
			strcmp(bMnt.mnt,"efs") == 0 || strcmp(bMnt.mnt,".android_secure") == 0) { // detect mountable partitions
		if (strcmp(bMnt.mnt,".android_secure") == 0) { // if it's android secure, add sdcard to prefix
			strcpy(bMount,"/sdcard/");
			strcat(bMount,bMnt.mnt);
			sprintf(bImage,"and-sec.%s.win",bMnt.fst); // set image name based on filesystem, should always be vfat for android_secure
		} else {
			strcpy(bMount,"/");
			strcat(bMount,bMnt.mnt);
			sprintf(bImage,"%s.%s.win",bMnt.mnt,bMnt.fst); // anything else that is mountable, will be partition.filesystem.win
			ui_print("\n-- Mounting %s, please wait...\n",bMount);
			if (tw_mount(bMnt)) {
				ui_print("-- Could not mount: %s\n-- Aborting.\n",bMount);
				free(bCommand);
				free(bMount);
				free(bImage);
				return 1;
			}
			ui_print("-- Done.\n\n",bMount);
		}
		sprintf(bCommand,"du -sk %s | awk '{ print $1 }'",bMount); // check for partition/folder size
		bFp = __popen(bCommand, "r");
		fscanf(bFp,"%d",&bPartSize);
		__pclose(bFp);
		sprintf(bCommand,"cd %s && tar %s %s%s ./*",bMount,bTarArg,bDir,bImage); // form backup command
	} else {
		strcpy(bMount,bMnt.mnt);
		bPartSize = bMnt.sze / 1024;
		sprintf(bImage,"%s.%s.win",bMnt.mnt,bMnt.fst); // non-mountable partitions such as boot/wimax/recovery
		if (strcmp(bMnt.fst,"mtd") == 0) {
			sprintf(bCommand,"dump_image %s %s%s",bMnt.mnt,bDir,bImage); // if it's mtd, we use dump image
		} else if (strcmp(bMnt.fst,"emmc") == 0) {
			sprintf(bCommand,"dd bs=%s if=%s of=%s%s",bs_size,bMnt.blk,bDir,bImage); // if it's emmc, use dd
		}
		ui_print("\n");
	}
	LOGI("=> Filename: %s\n",bImage);
	LOGI("=> Size of %s is %d KB.\n\n",bMount,bPartSize);
	int i;
	char bUppr[20];
	strcpy(bUppr,bMnt.mnt);
	for (i = 0; i < strlen(bUppr); i++) { // make uppercase of mount name
		bUppr[i] = toupper(bUppr[i]);
	}
	ui_print("[%s (%d MB)]\n",bUppr,bPartSize/1024); // show size in MB
	int bProgTime;
	time_t bStart, bStop;
	char bOutput[512];
	if (sdSpace > bPartSize) { // Do we have enough space on sdcard?
		time(&bStart); // start timer
		bProgTime = bPartSize / bDiv; // not very accurate but better than nothing progress time for progress bar
		ui_show_progress(1,bProgTime);
		ui_print("...Backing up %s partition.\n",bMount);
		bFp = __popen(bCommand, "r"); // sending backup command formed earlier above
		if(DataManager_GetIntValue(TW_SHOW_SPAM_VAR) == 2) { // if twrp spam is on, show all lines
			while (fgets(bOutput,sizeof(bOutput),bFp) != NULL) {
				ui_print_overwrite("%s",bOutput);
			}
		} else { // else just show single line
			while (fscanf(bFp,"%s",bOutput) == 1) {
				if(DataManager_GetIntValue(TW_SHOW_SPAM_VAR) == 1) ui_print_overwrite("%s",bOutput);
			}
		}
		ui_print_overwrite("....Done.\n");
		__pclose(bFp);
		int pFileSize;
		ui_print("...Double checking backup file size.\n");
		sprintf(bCommand,"ls -l %s%s | awk '{ print $5 }'",bDir,bImage); // double checking to make sure we backed up something
		bFp = __popen(bCommand, "r");
		fscanf(bFp,"%d",&pFileSize);
		__pclose(bFp);
		ui_print("....File size: %d bytes.\n",pFileSize); // file size
		if (pFileSize > 0) { // larger than 0 bytes?
			if (strcmp(bMnt.fst,"mtd") == 0 || strcmp(bMnt.fst,"emmc") == 0) { // if it's an unmountable partition, we can make sure
				LOGI("=> Expected size: %d Got: %d\n",bMnt.sze,pFileSize); // partition size matches file image size (they should match!)
				if (pFileSize != bMnt.sze) {
					ui_print("....File size is incorrect. Aborting...\n\n"); // they dont :(
					free(bCommand);
					free(bMount);
					free(bImage);
					return 1;
				} else {
					ui_print("....File size matches partition size.\n"); // they do, yay!
				}
			}
			ui_print("...Generating %s md5...\n", bMnt.mnt);
			makeMD5(bDir,bImage); // make md5 file
			ui_print("....Done.\n");
			ui_print("...Verifying %s md5...\n", bMnt.mnt);
			checkMD5(bDir,bImage); // test the md5 we just made, just in case
			ui_print("....Done.\n");
			time(&bStop); // stop timer
			ui_reset_progress(); // stop progress bar
			output_time(bUppr, "DONE", (int)difftime(bStop,bStart));
			tw_unmount(bMnt); // unmount partition we just restored to (if it's not a mountable partition, it will just bypass)
			sdSpace -= bPartSize; // minus from sd space number (not accurate but, it's more than the real count so it will suffice)
		} else {
			ui_print("...File size is zero bytes. Aborting...\n\n"); // oh noes! file size is 0, abort! abort!
			tw_unmount(bMnt);
			free(bCommand);
			free(bMount);
			free(bImage);
			return 1;
		}
	} else {
		ui_print("...Not enough space on /sdcard. Aborting.\n"); // oh noes! no space left on sdcard, abort! abort!
		tw_unmount(bMnt);
		free(bCommand);
		free(bMount);
		free(bImage);
		return 1;
	}
	free(bCommand);
	free(bMount);
	free(bImage);
	return 0;
}
int tw_restore(struct dInfo rMnt, char *rDir)
{
	int i;
	FILE *reFp;
	char rUppr[20];
	char rMount[30];
	char rFilesystem[10];
	char rFilename[255];
	char rCommand[255];
	char rOutput[255];
	time_t rStart, rStop;
	strcpy(rUppr,rMnt.mnt);
	for (i = 0; i < strlen(rUppr); i++) {
		rUppr[i] = toupper(rUppr[i]);
	}
	ui_print("[%s]\n",rUppr);
	ui_show_progress(1,150);
	time(&rStart);
	ui_print("...Verifying md5 hash for %s.\n",rMnt.mnt);
	if(checkMD5(rDir,rMnt.fnm) == 0) // verify md5, check if no error; 0 = no error.
	{
		strcpy(rFilename,rDir);
		strcat(rFilename,rMnt.fnm);
		sprintf(rCommand,"ls -l %s | awk -F'.' '{ print $2 }'",rFilename); // let's get the filesystem type from filename
		reFp = __popen(rCommand, "r");
		LOGI("=> Filename is: %s\n",rMnt.fnm);
		while (fscanf(reFp,"%s",rFilesystem) == 1) { // if we get a match, store filesystem type
			LOGI("=> Filesystem is: %s\n",rFilesystem); // show it off to the world!
		}
		__pclose(reFp);
		if (DataManager_GetIntValue(TW_RM_RF_VAR) == 1 && (strcmp(rMnt.mnt,"system") == 0 || strcmp(rMnt.mnt,"data") == 0 || strcmp(rMnt.mnt,"cache") == 0)) { // we'll use rm -rf instead of formatting for system, data and cache if the option is set
			ui_print("...using rm -rf to wipe %s\n", rMnt.mnt);
			tw_mount(rMnt); // mount the partition first
			sprintf(rCommand,"rm -rf %s%s/*", "/", rMnt.mnt);
			LOGI("rm rf commad: %s\n", rCommand);
			reFp = __popen(rCommand, "r");
			while (fscanf(reFp,"%s",rOutput) == 1) {
				ui_print_overwrite("%s",rOutput);
			}
			__pclose(reFp);
		} else {
			ui_print("...Formatting %s\n",rMnt.mnt);
			tw_format(rFilesystem,rMnt.blk); // let's format block, based on filesystem from filename above
		}
		ui_print("....Done.\n");
		if (strcmp(rFilesystem,"mtd") == 0) { // if filesystem is mtd, we use flash image
			sprintf(rCommand,"flash_image %s %s",rMnt.mnt,rFilename);
			strcpy(rMount,rMnt.mnt);
		} else if (strcmp(rFilesystem,"emmc") == 0) { // if filesystem is emmc, we use dd
			sprintf(rCommand,"dd bs=%s if=%s of=%s",bs_size,rFilename,rMnt.dev);
			strcpy(rMount,rMnt.mnt);
		} else {
			tw_mount(rMnt);
			strcpy(rMount,"/");
			if (strcmp(rMnt.mnt,".android_secure") == 0) { // if it's android_secure, we have add prefix
				strcat(rMount,"sdcard/");
			}
			strcat(rMount,rMnt.mnt);
			sprintf(rCommand,"cd %s && tar -xvf %s",rMount,rFilename); // formulate shell command to restore
		}
		ui_print("...Restoring %s\n",rMount);
		reFp = __popen(rCommand, "r");
		if(DataManager_GetIntValue(TW_SHOW_SPAM_VAR) == 2) { // twrp spam
			while (fgets(rOutput,sizeof(rOutput),reFp) != NULL) {
				ui_print_overwrite("%s",rOutput);
			}
		} else {
			while (fscanf(reFp,"%s",rOutput) == 1) {
				if(DataManager_GetIntValue(TW_SHOW_SPAM_VAR) == 1) ui_print_overwrite("%s",rOutput);
			}
		}
		__pclose(reFp);
		ui_print_overwrite("....Done.\n");
		if (strcmp(rMnt.mnt,".android_secure") != 0) { // any partition other than android secure,
			tw_unmount(rMnt); // let's unmount (unmountable partitions won't matter)
		}
	} else {
		ui_print("...Failed md5 check. Aborted.\n\n");
		return 1;
	}
	ui_reset_progress();
	time(&rStop);
	output_time(rUppr, "DONE", (int)difftime(rStop,rStart));
	return 0;
}