Пример #1
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);
}
/* 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;
}
Пример #3
0
/* New backup function
** Condensed all partitions into one function
*/
int phx_backup(struct dInfo bMnt, const char *bDir)
{
    // set compression or not
    char bTarArg[32];
    if (DataManager_GetIntValue(VAR_USE_COMPRESSION_VAR)) {
        strcpy(bTarArg,"-czv");
    } else {
        strcpy(bTarArg,"-cv");
    }
    FILE *bFp;

#ifdef RECOVERY_SDCARD_ON_DATA
    strcat(bTarArg, " -X /tmp/excludes.lst");

    bFp = fopen("/tmp/excludes.lst", "wt");
    if (bFp)
    {
        fprintf(bFp, "/data/media\n");
        fprintf(bFp, "./media\n");
        fprintf(bFp, "media\n");
        fclose(bFp);
    }
#endif

    char str[512];
    unsigned long long bPartSize;
    char *bImage = malloc(sizeof(char)*50);
    char *bMount = malloc(sizeof(char)*50);
    char *bCommand = malloc(sizeof(char)*255);

    if (bMnt.backup == files)
    {
        // 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
            SetDataState("Mounting", bMnt.mnt, 0, 0);
            if (phx_mount(bMnt))
            {
                ui_print("-- Could not mount: %s\n-- Aborting.\n",bMount);
                free(bCommand);
                free(bMount);
                free(bImage);
                return 1;
            }
        }
        bPartSize = bMnt.used;
        sprintf(bCommand,"cd %s && tar %s -f %s%s ./*",bMount,bTarArg,bDir,bImage); // form backup command
    } else if (bMnt.backup == image) {
        strcpy(bMount,bMnt.mnt);
        bPartSize = bMnt.sze;
        sprintf(bImage,"%s.%s.win",bMnt.mnt,bMnt.fst); // non-mountable partitions such as boot/sp1/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 {
            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");
    }
    else
    {
        LOGE("Unknown backup method for mount %s\n", bMnt.mnt);
        return 1;
    }

    LOGI("=> Filename: %s\n",bImage);
    LOGI("=> Size of %s is %lu KB.\n\n", bMount, (unsigned long) (bPartSize / 1024));
    int i;
    char bUppr[20];
    strcpy(bUppr,bMnt.mnt);
    for (i = 0; i < (int) strlen(bUppr); i++) { // make uppercase of mount name
        bUppr[i] = toupper(bUppr[i]);
    }
    ui_print("[%s (%lu MB)]\n", bUppr, (unsigned long) (bPartSize / (1024 * 1024))); // show size in MB

    SetDataState("Backup", bMnt.mnt, 0, 0);
    int bProgTime;
    time_t bStart, bStop;
    char bOutput[1024];

    time(&bStart); // start timer
    ui_print("...Backing up %s partition.\n",bMount);
    bFp = __popen(bCommand, "r"); // sending backup command formed earlier above
    if(DataManager_GetIntValue(VAR_SHOW_SPAM_VAR) == 2) { // if 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(VAR_SHOW_SPAM_VAR) == 1) ui_print_overwrite("%s",bOutput);
        }
    }
    ui_print_overwrite(" * Done.\n");
    __pclose(bFp);

    ui_print(" * Verifying backup size.\n");
    SetDataState("Verifying", bMnt.mnt, 0, 0);

    sprintf(bCommand, "%s%s", bDir, bImage);
    struct stat st;
    if (stat(bCommand, &st) != 0 || st.st_size == 0)
    {
        ui_print("E: File size is zero bytes. Aborting...\n\n"); // oh noes! file size is 0, abort! abort!
        phx_unmount(bMnt);
        free(bCommand);
        free(bMount);
        free(bImage);
        return 1;
    }

    ui_print(" * File size: %llu bytes.\n", st.st_size); // file size

    // Only verify image sizes
    if (bMnt.backup == image)
    {
        LOGI(" * Expected size: %llu Got: %lld\n", bMnt.sze, st.st_size);
        if (bMnt.sze != (unsigned long long) st.st_size)
        {
            ui_print("E: File size is incorrect. Aborting.\n\n"); // they dont :(
            free(bCommand);
            free(bMount);
            free(bImage);
            return 1;
        }
    }

    ui_print(" * Generating md5...\n");
    SetDataState("Generating MD5", bMnt.mnt, 0, 0);
    makeMD5(bDir, bImage); // make md5 file
    time(&bStop); // stop timer
    ui_print("[%s DONE (%d SECONDS)]\n\n",bUppr,(int)difftime(bStop,bStart)); // done, finally. How long did it take?
    phx_unmount(bMnt); // unmount partition we just restored to (if it's not a mountable partition, it will just bypass)

    free(bCommand);
    free(bMount);
    free(bImage);
    return 0;
}