#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>

#include <linux/loop.h>


/* normally the kernel has only 8 loop devices.
 * newer kernels support the parameter max_loop = ...
 * older kernels require a change from "#define MAX_LOOP 8"
 * to "#define MAX_LOOP 255" in linux/drivers/block/loop.c.
 */

#define LOOP_BASE 16

static const char *imgdir = "/share/cdimages";
static const char *ext = ".iso";
static const char *loopname = "/dev/loop%d";


int main(int argc, char **argv)
{
  char path[4096];
  char devlo[4096];
  int iso_fd;
  int lo_fd;
  int i;
  struct loop_info li;

  if(argc != 2) {
    fprintf(stderr, "cdmount: argc != 2");
    exit(1);
  }
  strcpy(path, imgdir);
  strcat(path, "/");
  strcat(path, argv[1]);
  strcat(path, ext);

  if((iso_fd = open(path, O_RDONLY)) == -1) {
#if DEBUG
    fprintf(stderr, "cdmount: can't open \"%s\" %m", path);
#endif
    exit(1);
  }
  for(i = LOOP_BASE; i < 256; i++) {
    sprintf(devlo, loopname, i);
    if((lo_fd = open(devlo, O_RDWR)) == -1)
      continue;
    /* @@@ be careful set LOOP_BASE high enough */
    ioctl(lo_fd, LOOP_CLR_FD, iso_fd);

    if(ioctl(lo_fd, LOOP_SET_FD, iso_fd)) {
#if DEBUG
      fprintf(stderr, "cdmount: error on \"%s\" for \"%s\":%m", 
	      devlo, path);
#endif
      close(lo_fd);
    } else {
      break;
    }
  }
  if(i == 256) {
#if 1
    fprintf(stderr, "cdmount: no available loop device");
#endif
    exit(1);
  }

  memset(&li, 0, sizeof(struct loop_info));
  li.lo_flags = LO_FLAGS_READ_ONLY;

  if(ioctl(lo_fd, LOOP_SET_STATUS, &li)) {
    fprintf(stderr, "cdmount: error on LO_SET_STATUS %m");
    exit(1);
  }
  /* changed iso9660 to auto because of UFS CDROMs */
  printf(" -fstype=auto,ro :%s\n", devlo);

// fprintf(stderr, "cdmount: trying: \"%s\"", path);
 return 0; 
}

