/* This file is part of Lcrzo.
*/

int lcrzo_priv_rand_seed(lcrzo_uint32 *pseed)
{

#if defined LCRZODEF_SYSTEM_Unix
  { int fd, retour;
    char pourseed[4];
 
    /*essaie avec "/dev/random"*/  
    fd=open("/dev/random", O_RDONLY);
    if ( fd != -1 )
    { retour=lcrzo_priv_fd_block_set(fd, LCRZO_FALSE);
      if (retour==LCRZO_ERR_OK)
      { retour=read(fd, pourseed, 4);
        if (retour==4)
        { if (pseed!=NULL)
          { *pseed= (pourseed[0]<<24) | (pourseed[1]<<16) |
	            (pourseed[2]<<8)  | pourseed[3] ;
          }
          close(fd);
          errno=0;
	  return(LCRZO_ERR_OK);
        }
      }
      close(fd);
    }

    /*essaie avec "/dev/urandom"*/  
    fd=open("/dev/urandom", O_RDONLY);
    if ( fd != -1 )
    { retour=lcrzo_priv_fd_block_set(fd, LCRZO_FALSE);
      if (retour==LCRZO_ERR_OK)
      { retour=read(fd, pourseed, 4);
        if (retour==4)
        { if (pseed!=NULL)
          { *pseed= (pourseed[0]<<24) | (pourseed[1]<<16) |
	            (pourseed[2]<<8)  | pourseed[3] ;
          }
          close(fd);
	        errno=0; 
  	      return(LCRZO_ERR_OK);
        }
      }
      close(fd);
    }

    /*se sert de l'heure et des pid*/  
    if (pseed!=NULL)
    { *pseed = time(0) ^ ( (getpid()<<16) | getppid() );
    }
  }
#elif defined LCRZODEF_SYSTEM_Windows
  { struct _timeb tstruct;
    /* use localtime */
    _ftime( &tstruct );
    if (pseed!=NULL)
    { *pseed = tstruct.time ^ tstruct.millitm ;
    }
  }
#else
   #error "Unknown value for LCRZODEF_SYSTEM"
#endif

  errno=0;
  return(LCRZO_ERR_OK);
}

