-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;
-}
-
-int device_ready(struct crypt_device *cd, const char *device, int mode)
-{
- int devfd, r = 0;
- ssize_t s;
- struct stat st;
- char buf[512];
-
- if(stat(device, &st) < 0) {
- log_err(cd, _("Device %s doesn't exist or access denied.\n"), device);
- return -EINVAL;
- }
-
- if (!S_ISBLK(st.st_mode))
- return -ENOTBLK;
-
- log_dbg("Trying to open and read device %s.", device);
- devfd = open(device, mode | O_DIRECT | O_SYNC);
- if(devfd < 0) {
- log_err(cd, _("Cannot open device %s for %s%s access.\n"), device,
- (mode & O_EXCL) ? _("exclusive ") : "",
- (mode & O_RDWR) ? _("writable") : _("read-only"));
- return -EINVAL;
- }
-
- /* Try to read first sector */
- s = read_blockwise(devfd, buf, sizeof(buf));
- if (s < 0 || s != sizeof(buf)) {
- log_verbose(cd, _("Cannot read device %s.\n"), device);
- r = -EIO;
- }
-
- memset(buf, 0, sizeof(buf));
- close(devfd);
-
- return r;
-}
-
-int get_device_infos(const char *device,
- int open_exclusive,
- int *readonly,
- uint64_t *size)
-{
- struct stat st;
- unsigned long size_small;
- int fd, r = -1;
- int flags = 0;
-
- *readonly = 0;
- *size = 0;
-
- if (stat(device, &st) < 0)
- return -EINVAL;
-
- /* never wipe header on mounted device */
- if (open_exclusive && S_ISBLK(st.st_mode))
- flags |= O_EXCL;
-
- /* Try to open read-write to check whether it is a read-only device */
- fd = open(device, O_RDWR | flags);
- if (fd == -1 && errno == EROFS) {
- *readonly = 1;
- fd = open(device, O_RDONLY | flags);
- }
-
- if (fd == -1 && open_exclusive && errno == EBUSY)
- return -EBUSY;
-
- if (fd == -1)
- return -EINVAL;