/*
 * tools/lib/lvm_create_uuid.c
 *
 * Copyright (C)  1998, 1999  Heinz Mauelshagen, Sistina Software
 *
 * March,July 2000
 *
 * LVM 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, or (at your option)
 * any later version.
 * 
 * LVM 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 GNU CC; see the file COPYING.  If not, write to
 * the Free Software Foundation, 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA. 
 *
 */

/*
 * Changelog
 *
 *    08/07/2000 - implemented lvm_show_uuid()
 *
 */

#include <liblvm.h>

/* if you change this string you will have to alter the lvm_check_uuid
   fn. below */
static unsigned char c[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

unsigned char *lvm_create_uuid ( int len) {
   int random, i;
   static unsigned char uuidstr[NAME_LEN+1];
   char *ret = NULL;

#ifdef DEBUG
   debug_enter ( "lvm_create_uuid -- CALLED\n");
#endif
   if ( len > 0) {
      if ( len > NAME_LEN) len = NAME_LEN;
      memset ( uuidstr, 0, sizeof ( uuidstr));
      if ( ( random = open ( "/dev/urandom", O_RDONLY)) != -1) {
         read ( random, uuidstr, len);
         close ( random);
         for ( i = 0; i < len; i++) {
            uuidstr[i] = c[uuidstr[i] % (sizeof(c)-1)];
         }
         ret = uuidstr;
      }
   }

#ifdef DEBUG
   debug_leave ( "lvm_create_uuid -- LEAVING with uuidstr: \"%s\"\n", uuidstr);
#endif
   return uuidstr;
}


int lvm_check_uuid ( char *uuidstr) {
   int ret = -1;
   char *ptr;

#ifdef DEBUG
   debug_enter ( "lvm_check_uuid -- CALLED with uuidstr: \"%s\"\n", uuidstr);
#endif

   if ( uuidstr == NULL || strlen ( uuidstr) != UUID_LEN)
      goto out;

   for(ptr = uuidstr; *ptr; ptr++)
      if (!((*ptr >= '0' && *ptr <= '9') ||
            (*ptr >= 'a' && *ptr <= 'z') ||
            (*ptr >= 'A' && *ptr <= 'Z')))
         goto out;
   ret = 0;

 out:
#ifdef DEBUG
   debug_leave ( "lvm_check_uuid -- LEAVING with ret: %d\n", ret);
#endif
   return ret;
}

char *lvm_show_uuid ( char *uuidstr) {
   int i, j;
   static char uuid[NAME_LEN] = { 0, };

   memset ( uuid, 0, NAME_LEN);

   i = 6;
   memcpy ( uuid, uuidstr, i);
   uuidstr += i;

   for ( j = 0; j < 6; j++) {
      uuid[i++] = '-';
      memcpy ( &uuid[i], uuidstr, 4);
      uuidstr += 4;
      i += 4;
   }

   memcpy ( &uuid[i], uuidstr, 2 );

   return uuid;
}
