#include #include #include #include #include #include #include using namespace std; static int noproc = 0; void fs_set_noproc (int _noproc) { noproc = _noproc; } /* Create a uniq ID combining the process number of this instance, a random value and the time in micro-seconds */ string fs_makeid () { string ret; //char tmp[100]; struct timeval t; if (gettimeofday(&t,NULL)!=-1){ static int fd = -1; static bool error_shown = false; if (fd == -1){ fd = open ("/dev/urandom",O_RDONLY,0); } if (fd == -1){ if (!error_shown){ tlmp_error ("Can't open /dev/urandom (%s)\n",strerror(errno)); error_shown = true; } }else{ struct { char buf[8]; unsigned tv_sec; unsigned tv_usec; } data; data.tv_sec = t.tv_sec; data.tv_usec = t.tv_usec; //tlmp_error ("sizeof data=%lu %lu\n",sizeof(data),sizeof(data.tv_sec)); if (read(fd,data.buf,8)!=8){ close (fd); fd = -1; if (!error_shown){ tlmp_error ("Can't read 8 bytes from /dev/urandom (%s)\n",strerror(errno)); error_shown = true; } }else{ #if 0 for (int i=0; i<8; i++) snprintf (tmp+i*2,3,"%02x",buf[i]); int n = snprintf (tmp+16,sizeof(tmp)-16-1,"%08lx%08lx",t.tv_sec,t.tv_usec); snprintf (tmp+16+n,sizeof(tmp)-16-n-1,"-%d",noproc); #elif 0 // Base64 is no good because it puts / in the result ret = base64_encode ((const char *)&data,17); //sizeof(data)); #else static const char *lk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789_="; const unsigned char *pt = (unsigned char*)&data; char out[17*2]; char *ptout = out; // tv_usec is an unsigned, but microseconds goes to 1,000,000. // So the mist significant byte is always 0. // So we processed only the first 15 bytes of the structure // and add noproc at the end. for (unsigned i=0; i<15; i+=3){ // First 6 bits unsigned char byte = *pt++; unsigned byte64 = byte >>2; *ptout++ = lk[byte64]; // Last 2 bits and 4 first bits of the next byte byte64 = (byte&3)<<4; byte = *pt++; byte64 |= byte >> 4; *ptout++ = lk[byte64]; // Last 4 bits and 2 first bits of the next byte byte64 = (byte&15)<<2; byte = *pt++; byte64 |= (byte >> 6); *ptout++ = lk[byte64]; // Last 6 bits of the byte byte64 = byte & 63; *ptout++ = lk[byte64]; } *ptout++ = lk[noproc]; *ptout = '\0'; ret = out; #endif } } } return ret; }