1/* vi: set sw=4 ts=4: */ 2/* 3 * Utility routines. 4 * 5 * Copyright (C) tons of folks. Tracking down who wrote what 6 * isn't something I'm going to worry about... If you wrote something 7 * here, please feel free to acknowledge your work. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 * Based in part on code from sash, Copyright (c) 1999 by David I. Bell 24 * Permission has been granted to redistribute this code under the GPL. 25 * 26 */ 27 28#include <stdio.h> 29#include <errno.h> 30#include <fcntl.h> 31#include <string.h> 32#include <unistd.h> 33#include <sys/ioctl.h> 34#include "libbb.h" 35#include "loop.h" /* Pull in loop device support */ 36 37extern int del_loop(const char *device) 38{ 39 int fd; 40 41 if ((fd = open(device, O_RDONLY)) < 0) { 42 perror_msg("%s", device); 43 return (FALSE); 44 } 45 if (ioctl(fd, LOOP_CLR_FD, 0) < 0) { 46 perror_msg("ioctl: LOOP_CLR_FD"); 47 return (FALSE); 48 } 49 close(fd); 50 return (TRUE); 51} 52 53extern int set_loop(const char *device, const char *file, int offset, 54 int *loopro) 55{ 56 struct loop_info loopinfo; 57 int fd, ffd, mode; 58 59 mode = *loopro ? O_RDONLY : O_RDWR; 60 if ((ffd = open(file, mode)) < 0 && !*loopro 61 && (errno != EROFS || (ffd = open(file, mode = O_RDONLY)) < 0)) { 62 perror_msg("%s", file); 63 return 1; 64 } 65 if ((fd = open(device, mode)) < 0) { 66 close(ffd); 67 perror_msg("%s", device); 68 return 1; 69 } 70 *loopro = (mode == O_RDONLY); 71 72 memset(&loopinfo, 0, sizeof(loopinfo)); 73 safe_strncpy(loopinfo.lo_name, file, LO_NAME_SIZE); 74 75 loopinfo.lo_offset = offset; 76 77 loopinfo.lo_encrypt_key_size = 0; 78 if (ioctl(fd, LOOP_SET_FD, ffd) < 0) { 79 perror_msg("ioctl: LOOP_SET_FD"); 80 close(fd); 81 close(ffd); 82 return 1; 83 } 84 if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) { 85 (void) ioctl(fd, LOOP_CLR_FD, 0); 86 perror_msg("ioctl: LOOP_SET_STATUS"); 87 close(fd); 88 close(ffd); 89 return 1; 90 } 91 close(fd); 92 close(ffd); 93 return 0; 94} 95 96extern char *find_unused_loop_device(void) 97{ 98 char dev[20]; 99 int i, fd; 100 struct stat statbuf; 101 struct loop_info loopinfo; 102 103 for (i = 0; i <= 7; i++) { 104 sprintf(dev, "/dev/loop%d", i); 105 if (stat(dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) { 106 if ((fd = open(dev, O_RDONLY)) >= 0) { 107 if (ioctl(fd, LOOP_GET_STATUS, &loopinfo) != 0) { 108 if (errno == ENXIO) { /* probably free */ 109 close(fd); 110 return strdup(dev); 111 } 112 } 113 close(fd); 114 } 115 } 116 } 117 return NULL; 118} 119 120 121/* END CODE */ 122/* 123Local Variables: 124c-file-style: "linux" 125c-basic-offset: 4 126tab-width: 4 127End: 128*/ 129