⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uuidgen.c

📁 一个简单实用的开源C++消息中间件SAFMQ - [软件开发] - [开源 消息中间件 SAFMQ ] 2006-11-23 在很多网络应用中
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>


#include "uuidgen.h"

struct shmuuid {
	unsigned char	shm_mac[6];
	struct timeval	timestamp;
	unsigned short	clock_seq;
};

static struct sembuf _lockop = { 0, -1, 0};
static struct sembuf _unlockop = { 0, 1, 0};

/* compares two timestamps */
static int tscomp(const struct timeval* lhs, const struct timeval* rhs);
/* retreives the semaphore */
static int getsem(key_t key);
/* releases the semaphore */
static void releasesem(int sem);
/* retreives the shared memory */
static struct shmuuid* getsharedmem(key_t shmkey);
/* releases the shared memory */
static void releaseshm(struct shmuuid* shared);

static void getmac(unsigned char mac[6]);

static key_t getshmkey();

void uuidgen(struct uuid* puuid)
{
	key_t	shmkey;
	int		shmseg;
	int		sem;

	shmkey = getshmkey();
	sem = getsem(shmkey);
	if (sem != -1) {
		struct shmuuid* shared = getsharedmem(shmkey);

		if (shared != (struct shmuuid*)-1) {
			struct timeval	now;
			int				cmp;

			gettimeofday(&now, NULL);
			
			if (tscomp(&(shared->timestamp),&now)) {
				//srand(shared->timestamp.tv_usec);
				srand(shared->clock_seq);
				shared->clock_seq = (unsigned short)rand();
				memcpy(&shared->timestamp,&now,sizeof(now));
			} else
				shared->clock_seq++;

			// takes bottom 12 bits of tv_sec
			puuid->guid.d1 = ((shared->timestamp.tv_sec<<28)&0xF0000000)|((shared->timestamp.tv_usec<<8)&0x0FFFFFFF);
			
			// takes bottom 16 of top 20
			puuid->guid.d2 = (unsigned short)(((shared->timestamp.tv_sec>>4) & 0x00FFFF));
			// takes top 4 of top 16
			puuid->guid.d3 = (unsigned short)(((shared->timestamp.tv_sec>>16) & 0x00FF00) | 0x01);

			memcpy(&(puuid->guid.d4), &(shared->clock_seq), 2);
			puuid->guid.d4[0] = (puuid->guid.d4[0] | 0x80) & 0x9F;
			memcpy((puuid->guid.d4)+2, shared->shm_mac, 6);
			releaseshm(shared);
		} else
			perror("getting shared memory");
		releasesem(sem);
	} else
		perror("getting semaphore");
}

static key_t getshmkey()
{
	static const char path[] = "/tmp/uuid";
	int fd = open(path, O_CREAT, 0666);
	if (fd > 0) {
		close(fd);
		return ftok(path, 0);
	}
	return ftok("/", 999);
}

/*
Gets and locks the semaphore
*/
static int getsem(key_t key)
{
	int sem = semget(key, 1, IPC_CREAT | IPC_EXCL);
	if (sem == -1 && errno == EEXIST) {
		sem = semget(key, 1, 0);
		if (sem == -1)
			return -1;
		semop(sem, &_lockop, 1);
		return sem;
	} else if (sem == -1) {
		return -1;
	}
	semctl(sem, 0, SETVAL, (int)0);
	return sem;
}

static void releasesem(int sem)
{
	semop(sem, &_unlockop, 1);
}

static struct shmuuid* getsharedmem(key_t shmkey)
{
	int	seg;
	struct shmuuid*	pmem;

	seg = shmget(shmkey, sizeof(struct shmuuid), IPC_CREAT|IPC_EXCL|0666);
	if (seg == -1 && errno == EEXIST) {
		seg = shmget(shmkey, sizeof(struct shmuuid), 0666);
		if (seg == -1) 
			return (struct shmuuid*)-1;
		return (struct shmuuid*)shmat(seg, NULL, 0);
	}
	
	pmem = (struct shmuuid*)shmat(seg, NULL, 0);
	if (pmem != (struct shmuuid*)-1) {
		memset(pmem,0,sizeof(struct shmuuid));
		getmac(pmem->shm_mac);
	}
	return pmem;
}

static void releaseshm(struct shmuuid* shared)
{
	shmdt(shared);
}

#ifdef linux
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <linux/if.h>
#endif

#ifdef HPUX
#include <netio.h>
#endif

#ifdef AIX
#include <sys/ndd_var.h>
#include <sys/kinfo.h>
#endif

static long mac_addr_sys ( u_char *addr)
{
/* implementation for Linux */
#ifdef linux
    struct ifreq ifr;
    struct ifreq *IFR;
    struct ifconf ifc;
    char buf[1024];
    int s, i;
    int ok = 0;

    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s==-1) {
        return -1;
    }

    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    ioctl(s, SIOCGIFCONF, &ifc);
 
    IFR = ifc.ifc_req;

    for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++) {
        strcpy(ifr.ifr_name, IFR->ifr_name);
        if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {
            if (! (ifr.ifr_flags & IFF_LOOPBACK)) {
                if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) {
                    ok = 1;
                    break;
                }
            }
        }
    }

    close(s);
    if (ok) {
        bcopy( ifr.ifr_hwaddr.sa_data, addr, 6);
    }
    else {
        return -1;
    }
    return 0;
#endif

/* implementation for HP-UX */
#ifdef HPUX

#define LAN_DEV0 "/dev/lan0"

    int		fd;
    struct fis	iocnt_block;
    int		i;
    char	net_buf[sizeof(LAN_DEV0)+1];
    char	*p;

    (void)sprintf(net_buf, "%s", LAN_DEV0);
    p = net_buf + strlen(net_buf) - 1;

    /* 
     * Get 802.3 address from card by opening the driver and interrogating it.
     */
    for (i = 0; i < 10; i++, (*p)++) {
        if ((fd = open (net_buf, O_RDONLY)) != -1) {
			iocnt_block.reqtype = LOCAL_ADDRESS;
			ioctl (fd, NETSTAT, &iocnt_block);
			close (fd);

            if (iocnt_block.vtype == 6)
                break;
        }
    }

    if (fd == -1 || iocnt_block.vtype != 6) {
        return -1;
    }

	bcopy( &iocnt_block.value.s[0], addr, 6);
	return 0;

#endif /* HPUX */

/* implementation for AIX */
#ifdef AIX

    int size;
    struct kinfo_ndd *nddp;

    size = getkerninfo(KINFO_NDD, 0, 0, 0);
    if (size <= 0) {
        return -1;
    }
    nddp = (struct kinfo_ndd *)malloc(size);
          
    if (!nddp) {
        return -1;
    }
    if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) {
        free(nddp);
        return -1;
    }
    bcopy(nddp->ndd_addr, addr, 6);
    free(nddp);
    return 0;
#endif

/* Not implemented platforms */
	return -1;
}

static void getmac(unsigned char mac[6])
{
	// TODO: Get the mac address
	int iret = mac_addr_sys(mac);
	if (iret)
		memset(mac,1,sizeof(mac));
}

static int tscomp(const struct timeval* lhs, const struct timeval* rhs)
{
	int ret;
	ret = lhs->tv_sec - rhs->tv_sec;
	if (!ret)
		ret = lhs->tv_usec - rhs->tv_usec;
	return ret;
}

static void rmshm(int shmid)
{
	printf("removeing shared memory for shmid:%ld\n", shmid);
	if (shmid != -1) {
		if (shmctl(shmid, IPC_RMID, 0) == -1)
			perror("removing shared memory");
	}
}

#if 0
int main(int argc, char* argv[])
{
	struct uuid Uuid = {0};
	int			x;

	if (argc > 1 && strcmp(argv[1], "clear")==0)
		rmshm(shmget(getshmkey(), sizeof(struct shmuuid), 0));

	while (98751) {
		uuidgen(&Uuid);
		printf("%08lx-%04lx-%04lx-%04lx-%02lx%02lx%02lx%02lx%02lx%02lx\n",
			Uuid.guid.d1,Uuid.guid.d2,Uuid.guid.d3,
			*(unsigned short*)Uuid.guid.d4,Uuid.guid.d4[2],Uuid.guid.d4[3],
			Uuid.guid.d4[4],Uuid.guid.d4[5],Uuid.guid.d4[6],Uuid.guid.d4[7]);
	}

	return 0;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -