📄 looputils.c
字号:
/* * loopback-device utilities for cryptmount * $Revision: 117 $, $Date: 2006-07-30 10:20:45 +0100 (Sun, 30 Jul 2006) $ * Copyright 2005-2006, RW Penney *//* This file is part of cryptmount cryptmount is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. As a special exemption, permission is granted to link cryptmount with the OpenSSL project's "OpenSSL" library and distribute the linked code without invoking clause 2(b) of the GNU GPL version 2. cryptmount is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with cryptmount; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */#include <config.h>#include <errno.h>#include <fcntl.h>#include <inttypes.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <sys/types.h>#ifndef dev_t# define dev_t dev_t /* FIXME - hack to placate Fedora-4 */#endif#ifdef HAVE_LINUX_LOOP_H# include <linux/loop.h>#else# error loop.h kernel-header is needed to build cryptmount#endif#include <linux/major.h>#include "cryptmount.h"#include "looputils.h"static char *loop_formats[] = { "/dev/loop%u", "/dev/loop/%u", NULL };#if defined(LOOP_GET_STATUS64) && defined(LOOP_SET_STATUS_64)# define HAVE_LOOP_64# define MY_LOOPGETSTATUS LOOP_GET_STATUS64# define MY_LOOPSETSTATUS LOOP_SET_STATUS64# define LOOPFILENAME(x) x.lo_file_name typedef struct loop_info64 my_loopinfo_t;#else# define MY_LOOPGETSTATUS LOOP_GET_STATUS# define MY_LOOPSETSTATUS LOOP_SET_STATUS# define LOOPFILENAME(x) x.lo_name typedef struct loop_info my_loopinfo_t;#endifint loop_findfree(char *buff, int buffsz) /* search for vacant loopback device */{ unsigned idx,min,found=0; int devfd; my_loopinfo_t linfo; char str[256]; struct stat sbuff; str[0] = '\0'; for (min=0; min<256 && !found; ++min) { for (idx=0; loop_formats[idx]!=NULL && !found; ++idx) { sprintf(str, loop_formats[idx], min); if (stat(str, &sbuff) || !S_ISBLK(sbuff.st_mode)) continue; devfd = open(str, O_RDONLY); if (devfd < 0) continue; if (ioctl(devfd, MY_LOOPGETSTATUS, &linfo) && errno == ENXIO) { found = 1;#ifdef DEBUG fprintf(stderr,"loop device \"%s\" is available\n", str);#endif } close(devfd); } } if (found && buff != NULL) strncpy(buff, str, buffsz); return !found;}int loop_setup(const char *dev, const char *file, int flags) /* setup loopback device to point to regular file */{ int devfd=-1,filefd=-1,eflag=ERR_NOERROR; my_loopinfo_t lpinfo; memset((void*)&lpinfo, 0, sizeof(lpinfo)); strncpy((char*)LOOPFILENAME(lpinfo), file, LO_NAME_SIZE); lpinfo.lo_offset = 0; lpinfo.lo_encrypt_key_size = 0; devfd = open(dev, flags); if (devfd < 0) { fprintf(stderr, "cannot open \"%s\" for reading\n", dev); eflag = ERR_BADFILE; goto bail_out; } filefd = open(file, flags); if (filefd < 0) { fprintf(stderr, "cannot open \"%s\" for reading\n", file); eflag = ERR_BADFILE; goto bail_out; } if (ioctl(devfd, LOOP_SET_FD, filefd) || ioctl(devfd, MY_LOOPSETSTATUS, &lpinfo)) { fprintf(stderr,"ioctl() failed on \"%s\"\n", dev); eflag = ERR_BADIOCTL; goto bail_out; } bail_out: if (filefd >= 0) close(filefd); if (devfd >= 0) close(devfd); return eflag;}int loop_destroy(const char *dev) /* detach loopback device from underlying file */{ int devfd; int eflag=ERR_NOERROR; devfd = open(dev, O_RDONLY); if (devfd < 0) { fprintf(stderr, "cannot open \"%s\" for reading\n", dev); eflag = ERR_BADFILE; goto bail_out; } if (ioctl(devfd, LOOP_CLR_FD, 0)) { fprintf(stderr, "ioctl() failed on \"%s\"\n", dev); eflag = ERR_BADIOCTL; goto bail_out; } bail_out: if (devfd >= 0) close(devfd); return eflag;}int loop_ident(unsigned maj, unsigned min, char *buff, size_t buffsz) /* find device node for given minor device number */{ unsigned idx; int found=0; char str[256]; struct stat sbuff; if (maj != LOOP_MAJOR) return !found; for (idx=0; loop_formats[idx]!=NULL && !found; ++idx) { sprintf(str, loop_formats[idx], min); if (stat(str, &sbuff) || !S_ISBLK(sbuff.st_mode)) continue; found = ((unsigned)major(sbuff.st_rdev) == maj && (unsigned)minor(sbuff.st_rdev) == min); } if (found && buff != NULL) strncpy(buff, str, buffsz); return !found;}/* * (C)Copyright 2005-2006, RW Penney */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -