1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Author: Stig Sæther Bakken <ssb@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: uniqid.c 279029 2009-04-20 06:55:11Z pajoye $ */
20 :
21 : #include "php.h"
22 :
23 : #include <stdlib.h>
24 : #if HAVE_UNISTD_H
25 : #include <unistd.h>
26 : #endif
27 :
28 : #include <string.h>
29 : #include <errno.h>
30 : #include <unicode/ustdio.h>
31 :
32 : #include <stdio.h>
33 : #ifdef PHP_WIN32
34 : #include "win32/time.h"
35 : #else
36 : #include <sys/time.h>
37 : #endif
38 :
39 : #include "php_lcg.h"
40 : #include "uniqid.h"
41 :
42 : /* {{{ proto string uniqid([string prefix [, bool more_entropy]]) U
43 : Generates a unique ID */
44 : #ifdef HAVE_GETTIMEOFDAY
45 : PHP_FUNCTION(uniqid)
46 10970 : {
47 10970 : zstr prefix = EMPTY_ZSTR;
48 10970 : int prefix_len = 0;
49 10970 : zend_uchar str_type = IS_UNICODE;
50 : #if defined(__CYGWIN__)
51 : zend_bool more_entropy = 1;
52 : #else
53 10970 : zend_bool more_entropy = 0;
54 : #endif
55 : char *uniqid;
56 : UChar *u_uniqid;
57 : int sec, usec;
58 : struct timeval tv;
59 :
60 10970 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|tb", &prefix,
61 : &prefix_len, &str_type, &more_entropy) == FAILURE) {
62 4 : return;
63 : }
64 :
65 : #if HAVE_USLEEP && !defined(PHP_WIN32)
66 10966 : if (!more_entropy) {
67 : #if defined(__CYGWIN__)
68 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "You must use 'more entropy' under CYGWIN");
69 : RETURN_FALSE;
70 : #else
71 10959 : usleep(1);
72 : #endif
73 : }
74 : #endif
75 10966 : gettimeofday((struct timeval *) &tv, (struct timezone *) NULL);
76 10966 : sec = (int) tv.tv_sec;
77 10966 : usec = (int) (tv.tv_usec % 0x100000);
78 :
79 : /* The max value usec can have is 0xF423F, so we use only five hex
80 : * digits for usecs.
81 : */
82 10966 : if (str_type == IS_UNICODE) {
83 : /* prefix + 8 (sec) + 5 (usec) + 10 (lcg) */
84 10966 : int buf_len = prefix_len + 8 + 5 + 10 + 1;
85 : int written;
86 :
87 10966 : u_uniqid = eumalloc(buf_len + 1);
88 10966 : if (more_entropy) {
89 7 : written = u_sprintf(u_uniqid, "%S%08x%05x%.8f", prefix.u, sec, usec, php_combined_lcg(TSRMLS_C) * 10);
90 : } else {
91 10959 : written = u_sprintf(u_uniqid, "%S%08x%05x", prefix.u, sec, usec);
92 : }
93 10966 : u_uniqid[written] = 0;
94 10966 : RETURN_UNICODEL(u_uniqid, written, 0);
95 : } else {
96 0 : if (more_entropy) {
97 0 : spprintf(&uniqid, 0, "%s%08x%05x%.8f", prefix.s, sec, usec, php_combined_lcg(TSRMLS_C) * 10);
98 : } else {
99 0 : spprintf(&uniqid, 0, "%s%08x%05x", prefix.s, sec, usec);
100 : }
101 :
102 0 : RETURN_STRING(uniqid, 0);
103 : }
104 : }
105 : #endif
106 : /* }}} */
107 :
108 : /*
109 : * Local variables:
110 : * tab-width: 4
111 : * c-basic-offset: 4
112 : * End:
113 : * vim600: sw=4 ts=4 fdm=marker
114 : * vim<600: sw=4 ts=4
115 : */
|