Exemplo n.º 1
0
int main(int argc, char **argv)
{
	uint32_t capacity, free;
	
	if (get_disk_info(&capacity, &free))
		return -1;

	fprintf(stderr, "Capacity: %08x(%d.%dMiB)\n", capacity, capacity/SIZE_1M, (capacity%SIZE_1M)*10/SIZE_1M);
	fprintf(stderr, "Free:     %08x(%d.%dMiB)\n", free, free/SIZE_1M, (free%SIZE_1M)*10/SIZE_1M);

	if (get_disk_capacity(&capacity))
		return -1;

	if (get_disk_free_space(&free))
		return -1;

	fprintf(stderr, "Capacity: %08x(%d.%dMiB)\n", capacity, capacity/SIZE_1M, (capacity%SIZE_1M)*10/SIZE_1M);
	fprintf(stderr, "Free:     %08x(%d.%dMiB)\n", free, free/SIZE_1M, (free%SIZE_1M)*10/SIZE_1M);

	return 0;
}
Exemplo n.º 2
0
struct tcplay_info *
info_map_common(struct tcplay_opts *opts, char *passphrase_out)
{
	struct tchdr_enc *ehdr, *hehdr = NULL;
	struct tcplay_info *info, *hinfo = NULL;
	char *pass;
	char *h_pass;
	int error, error2 = 0;
	size_t sz;
	size_t blksz;
	disksz_t blocks;
	int is_hidden = 0;
	int try_empty = 0;
	int retries;

	if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) {
		tc_log(1, "could not get disk information\n");
		return NULL;
	}

	if (opts->retries < 1)
		retries = 1;
	else
		retries = opts->retries;

	/*
	 * Add one retry so we can do a first try without asking for
	 * a password if keyfiles are passed in.
	 */
	if (opts->interactive && (opts->nkeyfiles > 0)) {
		try_empty = 1;
		++retries;
	}

	info = NULL;

	ehdr = NULL;
	pass = h_pass = NULL;

	while ((info == NULL) && retries-- > 0)
	{
		pass = h_pass = NULL;
		ehdr = hehdr = NULL;
		info = hinfo = NULL;

		if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
			tc_log(1, "could not allocate safe passphrase memory\n");
			goto out;
		}

		if (try_empty) {
			pass[0] = '\0';
		} else if (opts->interactive) {
		        if ((error = read_passphrase("Passphrase: ", pass,
			    MAX_PASSSZ, PASS_BUFSZ, opts->timeout))) {
				tc_log(1, "could not read passphrase\n");
				/* XXX: handle timeout differently? */
				goto out;
			}
			pass[MAX_PASSSZ] = '\0';
		} else {
			/* In batch mode, use provided passphrase */
			if (opts->passphrase != NULL) {
				strncpy(pass, opts->passphrase, MAX_PASSSZ);
				pass[MAX_PASSSZ] = '\0';
			}
		}

		if (passphrase_out != NULL) {
			strcpy(passphrase_out, pass);
		}

		if (opts->nkeyfiles > 0) {
			/* Apply keyfiles to 'pass' */
			if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
			    opts->keyfiles, opts->nkeyfiles))) {
				tc_log(1, "could not apply keyfiles");
				goto out;
			}
		}

		if (opts->protect_hidden) {
			if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
				tc_log(1, "could not allocate safe passphrase memory\n");
				goto out;
			}

			if (opts->interactive) {
			        if ((error = read_passphrase(
				    "Passphrase for hidden volume: ", h_pass,
				    MAX_PASSSZ, PASS_BUFSZ, opts->timeout))) {
					tc_log(1, "could not read passphrase\n");
					goto out;
				}
				h_pass[MAX_PASSSZ] = '\0';
			} else {
				/* In batch mode, use provided passphrase */
				if (opts->h_passphrase != NULL) {
					strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ);
					h_pass[MAX_PASSSZ] = '\0';
				}
			}

			if (opts->n_hkeyfiles > 0) {
				/* Apply keyfiles to 'pass' */
				if ((error = apply_keyfiles((unsigned char *)h_pass, PASS_BUFSZ,
				    opts->h_keyfiles, opts->n_hkeyfiles))) {
					tc_log(1, "could not apply keyfiles");
					goto out;
				}
			}
		}

		/* Always read blksz-sized chunks */
		sz = blksz;

		if (TC_FLAG_SET(opts->flags, HDR_FROM_FILE)) {
			ehdr = (struct tchdr_enc *)read_to_safe_mem(
			    opts->hdr_file_in, 0, &sz);
			if (ehdr == NULL) {
				tc_log(1, "error read hdr_enc: %s", opts->hdr_file_in);
				goto out;
			}
		} else {
			ehdr = (struct tchdr_enc *)read_to_safe_mem(
			    (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev,
			    (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) ?
			    HDR_OFFSET_SYS :
			    (!TC_FLAG_SET(opts->flags, BACKUP)) ? 0 : -BACKUP_HDR_OFFSET_END,
			    &sz);
			if (ehdr == NULL) {
				tc_log(1, "error read hdr_enc: %s", opts->dev);
				goto out;
			}
		}

		if (!TC_FLAG_SET(opts->flags, SYS)) {
			/* Always read blksz-sized chunks */
			sz = blksz;

			if (TC_FLAG_SET(opts->flags, H_HDR_FROM_FILE)) {
				hehdr = (struct tchdr_enc *)read_to_safe_mem(
				    opts->h_hdr_file_in, 0, &sz);
				if (hehdr == NULL) {
					tc_log(1, "error read hdr_enc: %s", opts->h_hdr_file_in);
					goto out;
				}
			} else {
				hehdr = (struct tchdr_enc *)read_to_safe_mem(opts->dev,
				    (!TC_FLAG_SET(opts->flags, BACKUP)) ? HDR_OFFSET_HIDDEN :
				    -BACKUP_HDR_HIDDEN_OFFSET_END, &sz);
				if (hehdr == NULL) {
					tc_log(1, "error read hdr_enc: %s", opts->dev);
					goto out;
				}
			}
		} else {
			hehdr = NULL;
		}

		error = process_hdr(opts->dev, opts->flags, (unsigned char *)pass,
		    (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
		    ehdr, &info);

		/*
		 * Try to process hidden header if we have to protect the hidden
		 * volume, or the decryption/verification of the main header
		 * failed.
		 */
		if (hehdr && (error || opts->protect_hidden)) {
			if (error) {
				error2 = process_hdr(opts->dev, opts->flags, (unsigned char *)pass,
				    (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass), hehdr,
				    &info);
				is_hidden = !error2;
			} else if (opts->protect_hidden) {
				error2 = process_hdr(opts->dev, opts->flags, (unsigned char *)h_pass,
				    (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), hehdr,
				    &hinfo);
			}
		}

		/* We need both to protect a hidden volume */
		if ((opts->protect_hidden && (error || error2)) ||
		    (error && error2)) {
			if (!try_empty)
				tc_log(1, "Incorrect password or not a TrueCrypt volume\n");

			if (info) {
				free_info(info);
				info = NULL;
			}
			if (hinfo) {
				free_info(hinfo);
				hinfo = NULL;
			}

			/* Try again (or finish) */
			free_safe_mem(pass);
			pass = NULL;

			if (h_pass) {
				free_safe_mem(h_pass);
				h_pass = NULL;
			}
			if (ehdr) {
				free_safe_mem(ehdr);
				ehdr = NULL;
			}
			if (hehdr) {
				free_safe_mem(hehdr);
				hehdr = NULL;
			}

			try_empty = 0;
			continue;
		}

		if (opts->protect_hidden) {
			if (adjust_info(info, hinfo) != 0) {
				tc_log(1, "Could not protect hidden volume\n");
				if (info)
					free_info(info);
				info = NULL;

				if (hinfo)
					free_info(hinfo);
				hinfo = NULL;

				goto out;
			}

			if (hinfo) {
				free_info(hinfo);
				hinfo = NULL;
			}
		}
		try_empty = 0;
        }

out:
	if (hinfo)
		free_info(hinfo);
	if (pass)
		free_safe_mem(pass);
	if (h_pass)
		free_safe_mem(h_pass);
	if (ehdr)
		free_safe_mem(ehdr);
	if (hehdr)
		free_safe_mem(hehdr);

	if (info != NULL)
		info->hidden = is_hidden;

	return info;
}
Exemplo n.º 3
0
int
create_volume(struct tcplay_opts *opts)
{
	char *pass, *pass_again;
	char *h_pass = NULL;
	char buf[1024];
	disksz_t blocks, hidden_blocks = 0;
	size_t blksz;
	struct tchdr_enc *ehdr, *hehdr;
	struct tchdr_enc *ehdr_backup, *hehdr_backup;
	uint64_t tmp;
	int error, r, ret;

	pass = h_pass = pass_again = NULL;
	ehdr = hehdr = NULL;
	ehdr_backup = hehdr_backup = NULL;
	ret = -1; /* Default to returning error */

	if (opts->cipher_chain == NULL)
		opts->cipher_chain = tc_cipher_chains[0];
	if (opts->prf_algo == NULL)
		opts->prf_algo = &pbkdf_prf_algos[0];
	if (opts->h_cipher_chain == NULL)
		opts->h_cipher_chain = opts->cipher_chain;
	if (opts->h_prf_algo == NULL)
		opts->h_prf_algo = opts->prf_algo;

	if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) {
		tc_log(1, "could not get disk info\n");
		return -1;
	}

	if ((blocks*blksz) <= MIN_VOL_BYTES) {
		tc_log(1, "Cannot create volumes on devices with less "
		    "than %d bytes\n", MIN_VOL_BYTES);
		return -1;
	}

	if (opts->interactive) {
		if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
		   ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
			tc_log(1, "could not allocate safe passphrase memory\n");
			goto out;
		}

		if ((error = read_passphrase("Passphrase: ", pass, MAX_PASSSZ,
		    PASS_BUFSZ, 0) ||
		    (read_passphrase("Repeat passphrase: ", pass_again,
		    MAX_PASSSZ, PASS_BUFSZ, 0)))) {
			tc_log(1, "could not read passphrase\n");
			goto out;
		}

		if (strcmp(pass, pass_again) != 0) {
			tc_log(1, "Passphrases don't match\n");
			goto out;
		}

		free_safe_mem(pass_again);
		pass_again = NULL;
	} else {
		/* In batch mode, use provided passphrase */
		if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
			tc_log(1, "could not allocate safe "
			    "passphrase memory");
			goto out;
		}

		if (opts->passphrase != NULL) {
			strncpy(pass, opts->passphrase, MAX_PASSSZ);
			pass[MAX_PASSSZ] = '\0';
		}
	}

	if (opts->nkeyfiles > 0) {
		/* Apply keyfiles to 'pass' */
		if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
		    opts->keyfiles, opts->nkeyfiles))) {
			tc_log(1, "could not apply keyfiles\n");
			goto out;
		}
	}

	if (opts->hidden) {
		if (opts->interactive) {
			if (((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
			   ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
				tc_log(1, "could not allocate safe "
				    "passphrase memory\n");
				goto out;
			}

			if ((error = read_passphrase("Passphrase for hidden volume: ",
			   h_pass, MAX_PASSSZ, PASS_BUFSZ, 0) ||
			   (read_passphrase("Repeat passphrase: ", pass_again,
			   MAX_PASSSZ, PASS_BUFSZ, 0)))) {
				tc_log(1, "could not read passphrase\n");
				goto out;
			}

			if (strcmp(h_pass, pass_again) != 0) {
				tc_log(1, "Passphrases for hidden volume don't "
				    "match\n");
				goto out;
			}

			free_safe_mem(pass_again);
			pass_again = NULL;
		} else {
			/* In batch mode, use provided passphrase */
			if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
				tc_log(1, "could not allocate safe "
				    "passphrase memory");
				goto out;
			}

			if (opts->h_passphrase != NULL) {
				strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ);
				h_pass[MAX_PASSSZ] = '\0';
			}
		}

		if (opts->n_hkeyfiles > 0) {
			/* Apply keyfiles to 'h_pass' */
			if ((error = apply_keyfiles((unsigned char *)h_pass,
			    PASS_BUFSZ, opts->h_keyfiles, opts->n_hkeyfiles))) {
				tc_log(1, "could not apply keyfiles\n");
				goto out;
			}
		}

		if (opts->interactive) {
			hidden_blocks = 0;
		} else {
			hidden_blocks = opts->hidden_size_bytes/blksz;
			if (hidden_blocks == 0) {
				tc_log(1, "hidden_blocks to create volume "
				    "cannot be zero!\n");
				goto out;
			}

			if (opts->hidden_size_bytes >=
			    (blocks*blksz) - MIN_VOL_BYTES) {
				tc_log(1, "Hidden volume needs to be "
				    "smaller than the outer volume\n");
				goto out;
			}
		}

		/* This only happens in interactive mode */
		while (hidden_blocks == 0) {
			if ((r = _humanize_number(buf, sizeof(buf),
			    (uint64_t)(blocks * blksz))) < 0) {
				sprintf(buf, "%"DISKSZ_FMT" bytes", (blocks * blksz));
			}

			printf("The total volume size of %s is %s (bytes)\n", opts->dev, buf);
			memset(buf, 0, sizeof(buf));
			printf("Size of hidden volume (e.g. 127M):  ");
			fflush(stdout);

			if ((fgets(buf, sizeof(buf), stdin)) == NULL) {
				tc_log(1, "Could not read from stdin\n");
				goto out;
			}

			/* get rid of trailing newline */
			buf[strlen(buf)-1] = '\0';
			if ((error = _dehumanize_number(buf,
			    &tmp)) != 0) {
				tc_log(1, "Could not interpret input: %s\n", buf);
				continue;
			}

			if (tmp >= (blocks*blksz) - MIN_VOL_BYTES) {
				tc_log(1, "Hidden volume needs to be "
				    "smaller than the outer volume\n");
				hidden_blocks = 0;
				continue;
			}

			hidden_blocks = (size_t)tmp;
			hidden_blocks /= blksz;
		}
	}

	if (opts->interactive) {
		/* Show summary and ask for confirmation */
		printf("Summary of actions:\n");
		if (opts->secure_erase)
			printf(" - Completely erase *EVERYTHING* on %s\n", opts->dev);
		printf(" - Create %svolume on %s\n", opts->hidden?("outer "):"", opts->dev);
		if (opts->hidden) {
			printf(" - Create hidden volume of %"DISKSZ_FMT" bytes at end of "
			    "outer volume\n",
			    hidden_blocks * blksz);
		}

		printf("\n Are you sure you want to proceed? (y/n) ");
		fflush(stdout);
		if ((fgets(buf, sizeof(buf), stdin)) == NULL) {
			tc_log(1, "Could not read from stdin\n");
			goto out;
		}

		if ((buf[0] != 'y') && (buf[0] != 'Y')) {
			tc_log(1, "User cancelled action(s)\n");
			goto out;
		}
	}

	/* erase volume */
	if (opts->secure_erase) {
		tc_log(0, "Securely erasing the volume...\nThis process may take "
		    "some time depending on the size of the volume\n");

		if (opts->state_change_fn)
			opts->state_change_fn(opts->api_ctx, "secure_erase", 1);

		if ((error = secure_erase(opts->dev, blocks * blksz, blksz)) != 0) {
			tc_log(1, "could not securely erase device %s\n", opts->dev);
			goto out;
		}

		if (opts->state_change_fn)
			opts->state_change_fn(opts->api_ctx, "secure_erase", 0);
	}

	tc_log(0, "Creating volume headers...\nDepending on your system, this "
	    "process may take a few minutes as it uses true random data which "
	    "might take a while to refill\n");

	if (opts->weak_keys_and_salt) {
		tc_log(0, "WARNING: Using a weak random generator to get "
		    "entropy for the key material. Odds are this is NOT "
		    "what you want.\n");
	}

	if (opts->state_change_fn)
		opts->state_change_fn(opts->api_ctx, "create_header", 1);

	/* create encrypted headers */
	ehdr = create_hdr((unsigned char *)pass,
	    (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
	    opts->prf_algo, opts->cipher_chain, blksz, blocks, VOL_RSVD_BYTES_START/blksz,
	    blocks - (MIN_VOL_BYTES/blksz), 0, opts->weak_keys_and_salt, &ehdr_backup);
	if (ehdr == NULL) {
		tc_log(1, "Could not create header\n");
		goto out;
	}

	if (opts->hidden) {
		hehdr = create_hdr((unsigned char *)h_pass,
		    (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), opts->h_prf_algo,
		    opts->h_cipher_chain,
		    blksz, blocks,
		    blocks - (VOL_RSVD_BYTES_END/blksz) - hidden_blocks,
		    hidden_blocks, 1, opts->weak_keys_and_salt, &hehdr_backup);
		if (hehdr == NULL) {
			tc_log(1, "Could not create hidden volume header\n");
			goto out;
		}
	}

	if (opts->state_change_fn)
		opts->state_change_fn(opts->api_ctx, "create_header", 0);

	tc_log(0, "Writing volume headers to disk...\n");

	if ((error = write_to_disk(opts->dev, 0, blksz, ehdr, sizeof(*ehdr))) != 0) {
		tc_log(1, "Could not write volume header to device\n");
		goto out;
	}

	/* Write backup header; it's offset is relative to the end */
	if ((error = write_to_disk(opts->dev, (blocks*blksz - BACKUP_HDR_OFFSET_END),
	    blksz, ehdr_backup, sizeof(*ehdr_backup))) != 0) {
		tc_log(1, "Could not write backup volume header to device\n");
		goto out;
	}

	if (opts->hidden) {
		if ((error = write_to_disk(opts->dev, HDR_OFFSET_HIDDEN, blksz, hehdr,
		    sizeof(*hehdr))) != 0) {
			tc_log(1, "Could not write hidden volume header to "
			    "device\n");
			goto out;
		}

		/* Write backup hidden header; offset is relative to end */
		if ((error = write_to_disk(opts->dev,
		    (blocks*blksz - BACKUP_HDR_HIDDEN_OFFSET_END), blksz,
		    hehdr_backup, sizeof(*hehdr_backup))) != 0) {
			tc_log(1, "Could not write backup hidden volume "
			    "header to device\n");
			goto out;
		}
	}

	/* Everything went ok */
	tc_log(0, "All done!\n");

	ret = 0;

out:
	if (pass)
		free_safe_mem(pass);
	if (h_pass)
		free_safe_mem(h_pass);
	if (pass_again)
		free_safe_mem(pass_again);
	if (ehdr)
		free_safe_mem(ehdr);
	if (hehdr)
		free_safe_mem(hehdr);
	if (ehdr_backup)
		free_safe_mem(ehdr_backup);
	if (hehdr_backup)
		free_safe_mem(hehdr_backup);

	return ret;
}
Exemplo n.º 4
0
int
modify_volume(struct tcplay_opts *opts)
{
	struct tcplay_info *info;
	struct tchdr_enc *ehdr, *ehdr_backup;
	const char *new_passphrase = opts->new_passphrase;
	const char **new_keyfiles = opts->new_keyfiles;
	struct pbkdf_prf_algo *new_prf_algo = opts->new_prf_algo;
	int n_newkeyfiles = opts->n_newkeyfiles;
	char *pass, *pass_again;
	int ret = -1;
	off_t offset, offset_backup = 0;
	const char *dev;
	size_t blksz;
	disksz_t blocks;
	int error;

	ehdr = ehdr_backup = NULL;
	pass = pass_again = NULL;
	info = NULL;

	if (TC_FLAG_SET(opts->flags, ONLY_RESTORE)) {
		if (opts->interactive) {
			if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
				tc_log(1, "could not allocate safe "
				    "passphrase memory");
				goto out;
			}
		} else {
			new_passphrase = opts->passphrase;
		}
		new_keyfiles = opts->keyfiles;
		n_newkeyfiles = opts->nkeyfiles;
		new_prf_algo = NULL;
	}

	info = info_map_common(opts, pass);
	if (info == NULL)
		goto out;

	if (opts->interactive && !TC_FLAG_SET(opts->flags, ONLY_RESTORE)) {
		if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) ||
		   ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) {
			tc_log(1, "could not allocate safe passphrase memory\n");
			goto out;
		}

		if ((error = read_passphrase("New passphrase: ", pass, MAX_PASSSZ,
		    PASS_BUFSZ, 0) ||
		    (read_passphrase("Repeat passphrase: ", pass_again,
		    MAX_PASSSZ, PASS_BUFSZ, 0)))) {
			tc_log(1, "could not read passphrase\n");
			goto out;
		}

		if (strcmp(pass, pass_again) != 0) {
			tc_log(1, "Passphrases don't match\n");
			goto out;
		}

		free_safe_mem(pass_again);
		pass_again = NULL;
	} else if (!opts->interactive) {
		/* In batch mode, use provided passphrase */
		if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) {
			tc_log(1, "could not allocate safe "
			    "passphrase memory");
			goto out;
		}

		if (new_passphrase != NULL) {
			strncpy(pass, new_passphrase, MAX_PASSSZ);
			pass[MAX_PASSSZ] = '\0';
		}
	}

	if (n_newkeyfiles > 0) {
		/* Apply keyfiles to 'pass' */
		if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ,
		    new_keyfiles, n_newkeyfiles))) {
			tc_log(1, "could not apply keyfiles\n");
			goto out;
		}
	}

	ehdr = copy_reencrypt_hdr((unsigned char *)pass,
	    (opts->n_newkeyfiles > 0)?MAX_PASSSZ:strlen(pass),
	    new_prf_algo, opts->weak_keys_and_salt, info, &ehdr_backup);
	if (ehdr == NULL) {
		tc_log(1, "Could not create header\n");
		goto out;
	}

	dev = (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev;
	if (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) {
		/* SYS and FDE don't have backup headers (as far as I understand) */
		if (info->hidden) {
			offset = HDR_OFFSET_HIDDEN;
		} else {
			offset = HDR_OFFSET_SYS;
		}
	} else {
		if (info->hidden) {
			offset = HDR_OFFSET_HIDDEN;
			offset_backup = -BACKUP_HDR_HIDDEN_OFFSET_END;
		} else {
			offset = 0;
			offset_backup = -BACKUP_HDR_OFFSET_END;
		}
	}

	if ((error = get_disk_info(dev, &blocks, &blksz)) != 0) {
		tc_log(1, "could not get disk information\n");
		goto out;
	}

	tc_log(0, "Writing new volume headers to disk/file...\n");

	if (TC_FLAG_SET(opts->flags, SAVE_TO_FILE)) {
		if ((error = write_to_file(opts->hdr_file_out, ehdr, sizeof(*ehdr))) != 0) {
			tc_log(1, "Could not write volume header to file\n");
			goto out;
		}
	} else {
		if ((error = write_to_disk(dev, offset, blksz, ehdr,
		    sizeof(*ehdr))) != 0) {
			tc_log(1, "Could not write volume header to device\n");
			goto out;
		}

		if (!TC_FLAG_SET(opts->flags, SYS) && !TC_FLAG_SET(opts->flags, FDE)) {
			if ((error = write_to_disk(dev, offset_backup, blksz,
			    ehdr_backup, sizeof(*ehdr_backup))) != 0) {
				tc_log(1, "Could not write backup volume header to device\n");
				goto out;
			}
		}
	}

	/* Everything went ok */
	tc_log(0, "All done!\n");

	ret = 0;

out:
	if (pass)
		free_safe_mem(pass);
	if (pass_again)
		free_safe_mem(pass_again);
	if (ehdr)
		free_safe_mem(ehdr);
	if (ehdr_backup)
		free_safe_mem(ehdr_backup);
	if (info)
		free_safe_mem(info);

	return ret;
}
Exemplo n.º 5
0
static void process_filespecs(void)
   {
   char* strptr ;
   unsigned i, j, k ;

   /***********************************************************************/
   /*************************  loop on filespecs  *************************/
   /***********************************************************************/

   //***********************************************************************
   //  when tree listing is selected, it is assumed that each specified
   //  argument is a separate path, and that no wildcards nor specific 
   //  filenames were provided.
   //  If such anomalies are presented, unpredictable results will occur.
   //***********************************************************************
   if (n.tree == 1  ||  n.tree == 4  ||  n.tree == 5) {
      tree_listing() ;
   }
   else if (tcount == 1  &&  !n.exec_only) {
      start = finish = 0 ;

      //  check for validity of long_filename functions
      dname[0] = (char) *target[start] ;

      // if (n.lfn_off == 1) 
      //    lfn_supported = 0 ;
      // else 
      //    IFF (is_lfn_available(dname, (char far *) fsn_bfr) != 0) 
      //    THENN 0  
      //    ELSSE 1 ;
      // lfn_supported = 1 ;
      lfn_supported = 1 - n.lfn_off ;

      //  in lfn format, convert /3 to /4
      if (lfn_supported != 0  &&  columns == 3) 
         columns = 4 ;

      //  Extract base path from first filespec,
      //  and strip off filename
      strcpy(base_path, target[start]) ;
      strptr = strrchr(base_path, '\\') ;
      if (strptr != 0) {
          strptr++ ;  //lint !e613  skip past backslash, to filename
         *strptr = 0 ;  //  strip off filename
      }
      base_len = strlen(base_path) ;

      //**************************************************
      // get_volume_label(base_path[0]) ;
      get_disk_info(base_path) ;

      //**************************************************
      //  initialize file pointer and filecount,
      //  in case of multiple filespecs.
      //**************************************************
      if (ftop != NULL)
         {
         ffdata *ftemp = ftop ;
         ffdata *fkill ;
         while (ftemp != NULL)
            {
            fkill = ftemp ;
            ftemp = ftemp->next ;
            free(fkill) ;
            }
         ftop = NULL ;
         }
      filecount = 0 ;

      //**************************************************
      //  Call directory_tree or file_listing routines,
      //  as specified by flags.
      //**************************************************
      file_listing() ;
      }
   else 
      {
      int temp_columns = columns ;

      start = 0 ;
      while (1)
         {
         //  Extract base path from first filespec,
         //  and strip off filename
         j = start ;

         //  check for validity of long_filename functions
         dname[0] = *target[start] ;
         // if (n.lfn_off == 1) 
         //    lfn_supported = 0 ;
         // else 
         //    lfn_supported =  
         //       IFF (is_lfn_available(dname, (char far *) fsn_bfr) != 0) 
         //       THENN 0  
         //       ELSSE 1 ;
         lfn_supported = 1 ;

         //  in lfn format, convert /3 to /4
         if (lfn_supported != 0  &&  columns == 3) 
            columns = 4 ;

         //  Extract base path from first filespec,
         //  and strip off filename
         strcpy(base_path, target[start]) ;
         //lint -esym(613,strptr) 
         strptr = strrchr(base_path, '\\') ;
         if (strptr != 0) {
            strptr++ ;  // skip past backslash, to filename
            *strptr = 0 ;  //  strip off filename
         }
         base_len = strlen(base_path) ;

         //**************************************************
         get_disk_info(base_path) ;

         //  seek out all other filespecs with same path
         j++ ;
         while (1) {
            if (j >= tcount) {
               finish = j-1 ;
               break;
            }
            else {
               //  strip filename from next argument
               strcpy(tempstr, target[j]) ;
               strptr = strrchr(tempstr, '\\') ;   //lint !e613
               strptr++ ;
               *strptr = 0 ;

               //  now see if they are equal
               if (strcmp(base_path, tempstr) != 0) {
                  finish = j-1 ;
                  break;
               }
               else 
                  j++ ;
            }
         }

         //********************************************************
         //  DELETE DUPLICATE FILESPECS from target array.
         //  Delete record if no differences found.   
         //  Compare file and ext separately.         
         //  This routine uses selection sort, because the list
         //  usually only has a couple of items in it.
         //********************************************************
         for (i=start ; i< finish ; i++)
         for (j=i+1   ; j<=finish ; j++) {
            //  extract filename and extension file target string
            //  to compare for duplicate filespecs.
            strcpy(fi_name, &target[i][base_len]) ;
            strptr = strrchr(fi_name, '.') ; //lint !e613
            if (strptr != 0) {
               *strptr++ = 0 ;   //lint !e613
               strcpy(fi_ext, strptr) ;
            } else {
               fi_ext[0] = 0 ;
            }

            strcpy(fj_name, &target[j][base_len]) ;
            strptr = strrchr(fj_name, '.') ; //lint !e613
            if (strptr != 0) {
               *strptr++ = 0 ;   //lint !e613
               strcpy(fj_ext, strptr) ;
            } else {
               fj_ext[0] = 0 ;
            }

            //  Scan file name and extension for equality.
            //  If both filename and extension are equal, delete one.
            if (strcmpiwc(fi_name, fj_name)  &&  strcmpiwc(fi_ext, fj_ext)) {
               strptr = target[j] ;
               for (k=j+1; k<tcount; k++)
                   target[k] = target[k+1] ;
               tcount-- ;
               finish-- ;
               j-- ;
               free(strptr) ; // release allocated struct.
            }
         }
         // Ndir32.cpp  414  Info 850: for loop index variable 'j' 
         // whose type category is 'integral' 
         // is modified in body of the for loop that began at 'line 375'

         //**************************************************
         //  initialize file pointer and filecount,
         //  in case of multiple filespecs.
         //**************************************************
         if (ftop != NULL) //lint !e850
            {
            ffdata *ftemp = ftop ;
            ffdata *fkill ;
            while (ftemp != NULL)
               {
               fkill = ftemp ;
               ftemp = ftemp->next ;
               free(fkill) ;
               }
            ftop = NULL ;
            }
         filecount = 0 ;

         //**************************************************
         //  Call directory_tree or file_listing routines,
         //  as specified by flags.
         //**************************************************
         if (n.tree == 1)
            tree_listing() ;
         else
            file_listing() ;

         start = finish + 1 ;
         if (start >= tcount) 
            break;
         ncrlf() ;

         columns = temp_columns ;
         }  //  while not done

      }  //  if multiple filespecs are present
   } /*  end  process_filespecs() */