/*
 * tools/lib/lvm_create_uuid.c
 *
 * Copyright (C)  1998, 1999  Heinz Mauelshagen, Sistina Software
 *
 * March,July 2000
 *
 *
 * This LVM library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This LVM library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this LVM library; if not, write to the Free
 * Software Foundation, Inc., 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;

   debug_enter ( "lvm_create_uuid -- CALLED\n");

   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;
      }
   }

   debug_leave ( "lvm_create_uuid -- LEAVING with uuidstr: \"%s\"\n",
                 lvm_show_uuid ( uuidstr));
   return uuidstr;
}


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

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

   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:

   debug_leave ( "lvm_check_uuid -- LEAVING with ret: %d\n", ret);
   return ret;
}

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

   if ( strlen ( uuidstr) > NAME_LEN) return NULL;

   memset ( uuid, 0, sizeof ( uuid));

   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;
   }

   strcpy ( &uuid[i], uuidstr);

   return uuid;
}
