mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
my_gethwaddr() for linux/freebsd
UUID() function
This commit is contained in:
@ -646,3 +646,4 @@ vio/test-ssl
|
||||
vio/test-sslclient
|
||||
vio/test-sslserver
|
||||
vio/viotest-ssl
|
||||
mysys/test_gethwaddr
|
||||
|
@ -739,6 +739,8 @@ extern ulong crc32(ulong crc, const uchar *buf, uint len);
|
||||
extern uint my_set_max_open_files(uint files);
|
||||
void my_free_open_file_info(void);
|
||||
|
||||
my_bool my_gethwaddr(uchar *to);
|
||||
|
||||
/* character sets */
|
||||
extern uint get_charset_number(const char *cs_name, uint cs_flags);
|
||||
extern uint get_collation_number(const char *name);
|
||||
|
@ -39,7 +39,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c \
|
||||
mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
|
||||
my_symlink.c my_symlink2.c \
|
||||
mf_pack.c mf_unixpath.c mf_strip.c \
|
||||
mf_wcomp.c mf_wfile.c \
|
||||
mf_wcomp.c mf_wfile.c my_gethwaddr.c \
|
||||
mf_qsort.c mf_qsort2.c mf_sort.c \
|
||||
ptr_cmp.c mf_radix.c queues.c \
|
||||
tree.c list.c hash.c array.c string.c typelib.c \
|
||||
@ -110,5 +110,10 @@ charset2html$(EXEEXT): charset2html.c $(LIBRARIES)
|
||||
testhash$(EXEEXT): testhash.c $(LIBRARIES)
|
||||
$(LINK) $(FLAGS) -DMAIN $(srcdir)/testhash.c $(LDADD) $(LIBS)
|
||||
|
||||
test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES)
|
||||
$(CP) $(srcdir)/my_gethwaddr.c ./test_gethwaddr.c
|
||||
$(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS)
|
||||
$(RM) -f ./test_gethwaddr.c
|
||||
|
||||
# Don't update the files from bitkeeper
|
||||
%::SCCS/s.%
|
||||
|
130
mysys/my_gethwaddr.c
Normal file
130
mysys/my_gethwaddr.c
Normal file
@ -0,0 +1,130 @@
|
||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
|
||||
This program 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 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||
|
||||
/* get hardware address for an interface */
|
||||
/* if there are many available, any non-zero one can be used */
|
||||
|
||||
#include "mysys_priv.h"
|
||||
#include <m_string.h>
|
||||
|
||||
#ifndef MAIN
|
||||
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
|
||||
{
|
||||
uint i, res=1;
|
||||
|
||||
for (i=0; i < len; i++)
|
||||
if ((*to++= *from++))
|
||||
res=0;
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#include <net/ethernet.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
|
||||
my_bool my_gethwaddr(uchar *to)
|
||||
{
|
||||
size_t len;
|
||||
uchar *buf, *next, *end, *addr;
|
||||
struct if_msghdr *ifm;
|
||||
struct sockaddr_dl *sdl;
|
||||
int i, res=1, mib[6]={CTL_NET, AF_ROUTE, 0, AF_LINK, NET_RT_IFLIST, 0};
|
||||
|
||||
if (sysctl(mib, 6, NULL, &len, NULL, 0) == -1)
|
||||
goto err;
|
||||
if (!(buf = alloca(len)))
|
||||
goto err;
|
||||
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0)
|
||||
goto err;
|
||||
|
||||
end = buf + len;
|
||||
|
||||
for (next = buf ; res && next < end ; next += ifm->ifm_msglen)
|
||||
{
|
||||
ifm = (struct if_msghdr *)next;
|
||||
if (ifm->ifm_type == RTM_IFINFO)
|
||||
{
|
||||
sdl = (struct sockaddr_dl *)(ifm + 1);
|
||||
addr=LLADDR(sdl);
|
||||
res=memcpy_and_test(to, addr, ETHER_ADDR_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
return res;
|
||||
}
|
||||
|
||||
#elif __linux__
|
||||
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
my_bool my_gethwaddr(uchar *to)
|
||||
{
|
||||
int fd, res=1;
|
||||
struct ifreq ifr;
|
||||
|
||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0)
|
||||
goto err;
|
||||
|
||||
bzero(&ifr, sizeof(ifr));
|
||||
strnmov(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);
|
||||
|
||||
do {
|
||||
if (ioctl(fd, SIOCGIFHWADDR, &ifr) >= 0)
|
||||
res=memcpy_and_test(to, (uchar *)&ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
|
||||
} while (res && (errno == 0 || errno == ENODEV) && ifr.ifr_name[3]++ < '6');
|
||||
|
||||
close(fd);
|
||||
err:
|
||||
return res;
|
||||
}
|
||||
|
||||
#else
|
||||
/* just fail */
|
||||
my_bool my_gethwaddr(uchar *to __attribute__((unused)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else MAIN
|
||||
int main(int argc __attribute__((unused)),char **argv)
|
||||
{
|
||||
uchar mac[6];
|
||||
uint i;
|
||||
MY_INIT(argv[0]);
|
||||
if (my_gethwaddr(mac))
|
||||
{
|
||||
printf("my_gethwaddr failed with errno %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
for (i=0; i < sizeof(mac); i++)
|
||||
{
|
||||
if (i) printf(":");
|
||||
printf("%02x", mac[i]);
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -426,6 +426,11 @@ Item *create_func_ucase(Item* a)
|
||||
return new Item_func_ucase(a);
|
||||
}
|
||||
|
||||
Item *create_func_uuid(void)
|
||||
{
|
||||
return new Item_func_uuid();
|
||||
}
|
||||
|
||||
Item *create_func_version(void)
|
||||
{
|
||||
return new Item_string(NullS,server_version,
|
||||
|
@ -92,6 +92,7 @@ Item *create_func_time_format(Item *a, Item *b);
|
||||
Item *create_func_time_to_sec(Item* a);
|
||||
Item *create_func_to_days(Item* a);
|
||||
Item *create_func_ucase(Item* a);
|
||||
Item *create_func_uuid(void);
|
||||
Item *create_func_version(void);
|
||||
Item *create_func_weekday(Item* a);
|
||||
Item *create_load_file(Item* a);
|
||||
|
@ -2632,3 +2632,112 @@ err:
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
UUID, as in
|
||||
DCE 1.1: Remote Procedure Call,
|
||||
Open Group Technical Standard Document Number C706, August 1997,
|
||||
(supersedes C309 DCE: Remote Procedure Call 8/1994,
|
||||
which was basis for ISO/IEC 11578:1996 specification)
|
||||
*/
|
||||
|
||||
static struct rand_struct uuid_rand;
|
||||
static uint nanoseq;
|
||||
static ulonglong uuid_time=0;
|
||||
static char clock_seq_and_node_str[]="-0000-000000000000";
|
||||
|
||||
/* we cannot use _dig_vec[] as letters should be lowercase */
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
|
||||
/* number of 100-nanosecond intervals between
|
||||
1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00 */
|
||||
#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * 1000 * 10 )
|
||||
|
||||
#define UUID_VERSION 0x1000
|
||||
#define UUID_VARIANT 0x8000
|
||||
|
||||
static ulonglong get_uuid_time()
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv,NULL);
|
||||
return (ulonglong)tv.tv_sec*10000000 +
|
||||
(ulonglong)tv.tv_usec*10 + UUID_TIME_OFFSET + nanoseq;
|
||||
}
|
||||
|
||||
static void tohex(char *to, uint from, uint len)
|
||||
{
|
||||
to+= len;
|
||||
while (len--)
|
||||
{
|
||||
*--to= hex[from & 15];
|
||||
from >>= 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_clock_seq_str()
|
||||
{
|
||||
uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
|
||||
tohex(clock_seq_and_node_str+1, clock_seq, 4);
|
||||
nanoseq= 0;
|
||||
}
|
||||
|
||||
String *Item_func_uuid::val_str(String *str)
|
||||
{
|
||||
char *s;
|
||||
pthread_mutex_lock(&LOCK_uuid_generator);
|
||||
if (! uuid_time) /* first UUID() call. initializing data */
|
||||
{
|
||||
ulong tmp=sql_rnd_with_mutex();
|
||||
uchar mac[6];
|
||||
int i;
|
||||
if (my_gethwaddr(mac))
|
||||
{
|
||||
/*
|
||||
generating random "hardware addr"
|
||||
and because specs explicitly specify that it should NOT correlate
|
||||
with a clock_seq value (initialized random below), we use a separate
|
||||
randominit() here
|
||||
*/
|
||||
randominit(&uuid_rand, tmp + (ulong)current_thd, tmp + query_id);
|
||||
for (i=0; i < sizeof(mac); i++)
|
||||
mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
|
||||
}
|
||||
s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
|
||||
for (i=sizeof(mac)-1 ; i>=0 ; i--)
|
||||
{
|
||||
*--s=hex[mac[i] & 15];
|
||||
*--s=hex[mac[i] >> 4];
|
||||
}
|
||||
randominit(&uuid_rand, tmp + (ulong)start_time, tmp + bytes_sent);
|
||||
set_clock_seq_str();
|
||||
}
|
||||
|
||||
ulonglong tv=get_uuid_time();
|
||||
if (unlikely(tv < uuid_time))
|
||||
set_clock_seq_str();
|
||||
else
|
||||
if (unlikely(tv == uuid_time))
|
||||
{ /* special protection from low-res system clocks */
|
||||
nanoseq++;
|
||||
tv++;
|
||||
}
|
||||
else
|
||||
nanoseq=0;
|
||||
uuid_time=tv;
|
||||
pthread_mutex_unlock(&LOCK_uuid_generator);
|
||||
|
||||
uint32 time_low= tv & 0xFFFFFFFF;
|
||||
uint16 time_mid= (tv >> 32) & 0xFFFF;
|
||||
uint16 time_hi_and_version= (tv >> 48) | UUID_VERSION;
|
||||
|
||||
str->realloc(UUID_LENGTH+1);
|
||||
str->length(UUID_LENGTH);
|
||||
s=(char *) str->ptr();
|
||||
s[8]=s[13]='-';
|
||||
tohex(s, time_low, 8);
|
||||
tohex(s+9, time_mid, 4);
|
||||
tohex(s+14, time_hi_and_version, 4);
|
||||
strmov(s+18, clock_seq_and_node_str);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
@ -691,3 +691,13 @@ public:
|
||||
String *val_str(String *) ZLIB_DEPENDED_FUNCTION
|
||||
};
|
||||
|
||||
#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
|
||||
class Item_func_uuid: public Item_str_func
|
||||
{
|
||||
public:
|
||||
Item_func_uuid(): Item_str_func() {}
|
||||
void fix_length_and_dec() {max_length= UUID_LENGTH; }
|
||||
const char *func_name() const{ return "uuid"; }
|
||||
String *val_str(String *);
|
||||
};
|
||||
|
||||
|
@ -674,6 +674,7 @@ static SYMBOL sql_functions[] = {
|
||||
{ "UNIQUE_USERS", SYM(UNIQUE_USERS)},
|
||||
{ "UNIX_TIMESTAMP", SYM(UNIX_TIMESTAMP)},
|
||||
{ "UPPER", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
|
||||
{ "UUID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_uuid)},
|
||||
{ "VARIANCE", SYM(VARIANCE_SYM)},
|
||||
{ "VERSION", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)},
|
||||
{ "WEEK", SYM(WEEK_SYM)},
|
||||
|
@ -802,7 +802,7 @@ extern char log_error_file[FN_REFLEN];
|
||||
extern double log_10[32];
|
||||
extern ulonglong keybuff_size;
|
||||
extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables;
|
||||
extern ulong created_tmp_tables, created_tmp_disk_tables;
|
||||
extern ulong created_tmp_tables, created_tmp_disk_tables, bytes_sent;
|
||||
extern ulong aborted_threads,aborted_connects;
|
||||
extern ulong delayed_insert_timeout;
|
||||
extern ulong delayed_insert_limit, delayed_queue_size;
|
||||
@ -857,7 +857,7 @@ extern FILE *bootstrap_file;
|
||||
extern pthread_key(MEM_ROOT*,THR_MALLOC);
|
||||
extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
|
||||
LOCK_thread_count,LOCK_mapped_file,LOCK_user_locks, LOCK_status,
|
||||
LOCK_error_log, LOCK_delayed_insert,
|
||||
LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
|
||||
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
|
||||
LOCK_slave_list, LOCK_active_mi, LOCK_manager,
|
||||
LOCK_global_system_variables, LOCK_user_conn;
|
||||
@ -1085,6 +1085,14 @@ inline const char *table_case_name(HA_CREATE_INFO *info, const char *name)
|
||||
return ((lower_case_table_names == 2 && info->alias) ? info->alias : name);
|
||||
}
|
||||
|
||||
inline ulong sql_rnd_with_mutex()
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Comp_creator *comp_eq_creator(bool invert);
|
||||
Comp_creator *comp_ge_creator(bool invert);
|
||||
Comp_creator *comp_gt_creator(bool invert);
|
||||
|
@ -369,7 +369,7 @@ pthread_key(MEM_ROOT*,THR_MALLOC);
|
||||
pthread_key(THD*, THR_THD);
|
||||
pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
|
||||
LOCK_mapped_file, LOCK_status,
|
||||
LOCK_error_log,
|
||||
LOCK_error_log, LOCK_uuid_generator,
|
||||
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
|
||||
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
||||
LOCK_global_system_variables,
|
||||
@ -2206,6 +2206,7 @@ static int init_thread_environment()
|
||||
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
|
||||
(void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
|
||||
(void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
|
||||
(void) my_rwlock_init(&LOCK_grant, NULL);
|
||||
|
@ -179,14 +179,8 @@ THD::THD():user_time(0), current_statement(0), is_fatal_error(0),
|
||||
transaction.trans_log.end_of_file= max_binlog_cache_size;
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
We need good random number initialization for new thread
|
||||
Just coping global one will not work
|
||||
*/
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
ulong tmp=(ulong) (my_rnd(&sql_rand) * 0xffffffff); /* make all bits random */
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
ulong tmp=sql_rnd_with_mutex();
|
||||
randominit(&rand, tmp + (ulong) &rand, tmp + (ulong) ::query_id);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user