-ssize_t write_lseek_blockwise(int fd, const char *buf, size_t count, off_t offset) {
- int bsize = sector_size(fd);
- const char *orig_buf = buf;
- char frontPadBuf[bsize];
- int frontHang = offset % bsize;
- int r;
- int innerCount = count < bsize ? count : bsize;
-
- if (bsize < 0)
- return bsize;
-
- lseek(fd, offset - frontHang, SEEK_SET);
- if(offset % bsize) {
- r = read(fd,frontPadBuf,bsize);
- if(r < 0) return -1;
-
- memcpy(frontPadBuf+frontHang, buf, innerCount);
-
- lseek(fd, offset - frontHang, SEEK_SET);
- r = write(fd,frontPadBuf,bsize);
- if(r < 0) return -1;
-
- buf += innerCount;
- count -= innerCount;
- }
- if(count <= 0) return buf - orig_buf;
-
- return write_blockwise(fd, buf, count) + innerCount;
-}
-
-/* Password reading helpers */
-
-static int untimed_read(int fd, char *pass, size_t maxlen)
-{
- ssize_t i;
-
- i = read(fd, pass, maxlen);
- if (i > 0) {
- pass[i-1] = '\0';
- i = 0;
- } else if (i == 0) { /* EOF */
- *pass = 0;
- i = -1;
- }
- return i;
-}
-
-static int timed_read(int fd, char *pass, size_t maxlen, long timeout)
-{
- struct timeval t;
- fd_set fds;
- int failed = -1;
-
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- t.tv_sec = timeout;
- t.tv_usec = 0;
-
- if (select(fd+1, &fds, NULL, NULL, &t) > 0)
- failed = untimed_read(fd, pass, maxlen);
-
- return failed;
-}
-
-static int interactive_pass(const char *prompt, char *pass, size_t maxlen,
- long timeout)
-{
- struct termios orig, tmp;
- int failed = -1;
- int infd = STDIN_FILENO, outfd;
-
- if (maxlen < 1)
- goto out_err;
-
- /* Read and write to /dev/tty if available */
- if ((infd = outfd = open("/dev/tty", O_RDWR)) == -1) {
- infd = STDIN_FILENO;
- outfd = STDERR_FILENO;
- }
-
- if (tcgetattr(infd, &orig))
- goto out_err;
-
- memcpy(&tmp, &orig, sizeof(tmp));
- tmp.c_lflag &= ~ECHO;
-
- if (write(outfd, prompt, strlen(prompt)) < 0)
- goto out_err;
-
- tcsetattr(infd, TCSAFLUSH, &tmp);
- if (timeout)
- failed = timed_read(infd, pass, maxlen, timeout);
- else
- failed = untimed_read(infd, pass, maxlen);
- tcsetattr(infd, TCSAFLUSH, &orig);
-
-out_err:
- if (!failed && write(outfd, "\n", 1));
-
- if (infd != STDIN_FILENO)
- close(infd);
- return failed;
-}
-
-/*
- * Password reading behaviour matrix of get_key
- *
- * p v n h
- * -----------------+---+---+---+---
- * interactive | Y | Y | Y | Inf
- * from fd | N | N | Y | Inf
- * from binary file | N | N | N | Inf or options->key_size
- *
- * Legend: p..prompt, v..can verify, n..newline-stop, h..read horizon
- *
- * Note: --key-file=- is interpreted as a read from a binary file (stdin)
- */
-
-void get_key(char *prompt, char **key, unsigned int *passLen, int key_size,
- const char *key_file, int timeout, int how2verify,
- struct crypt_device *cd)
-{
- int fd = -1;
- const int verify = how2verify & CRYPT_FLAG_VERIFY;
- const int verify_if_possible = how2verify & CRYPT_FLAG_VERIFY_IF_POSSIBLE;
- char *pass = NULL;
- int newline_stop;
- int read_horizon;
- int regular_file = 0;
- int r;
-
- if(key_file && !strcmp(key_file, "-")) {
- /* Allow binary reading from stdin */
- fd = STDIN_FILENO;
- newline_stop = 0;
- read_horizon = 0;
- } else if (key_file) {
- fd = open(key_file, O_RDONLY);
- if (fd < 0) {
- log_err(cd, _("Failed to open key file %s.\n"), key_file);
- goto out_err;
- }
- newline_stop = 0;
-
- /* This can either be 0 (LUKS) or the actually number
- * of key bytes (default or passed by -s) */
- read_horizon = key_size;
- } else {
- fd = STDIN_FILENO;
- newline_stop = 1;
- read_horizon = 0; /* Infinite, if read from terminal or fd */
- }
-
- /* Interactive case */
- if(isatty(fd)) {
- int i;