1 /* GNU Mailutils -- a suite of utilities for electronic mail 2 Copyright (C) 2017-2021 Free Software Foundation, Inc. 3 4 This library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 3 of the License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General 15 Public License along with this library; If not, see 16 <http://www.gnu.org/licenses/>. */ 17 18 #ifdef HAVE_CONFIG_H 19 #include <config.h> 20 #endif 21 #include <sys/types.h> 22 #include <sys/time.h> 23 #include <unistd.h> 24 #include <time.h> 25 #include <string.h> 26 #include <mailutils/errno.h> 27 #include <mailutils/alloc.h> 28 29 #define SID_ABC "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" 30 #define SID_LEN (sizeof (SID_ABC) - 1) 31 #define SID_LEN_SQR (SID_LEN * SID_LEN) 32 33 /* Generate (almost) unique session ID. The idea borrowed from Sendmail 34 queue ID. 35 */ 36 int mu_sid(char ** res)37mu_sid (char **res) 38 { 39 static int init; 40 static unsigned int seqno = 0; 41 static char abc[] = SID_ABC; 42 43 struct timeval t; 44 struct tm *tm; 45 unsigned int n; 46 char sidbuf[9]; 47 char *p; 48 49 if (!res) 50 return MU_ERR_OUT_PTR_NULL; 51 52 gettimeofday (&t, NULL); 53 54 if (!init) 55 { 56 seqno = getpid () + t.tv_sec + t.tv_usec; 57 init = 1; 58 } 59 60 n = seqno++ % SID_LEN_SQR; 61 tm = gmtime (&t.tv_sec); 62 sidbuf[0] = abc[tm->tm_year % SID_LEN]; 63 sidbuf[1] = abc[tm->tm_mon]; 64 sidbuf[2] = abc[tm->tm_mday]; 65 sidbuf[3] = abc[tm->tm_hour]; 66 sidbuf[4] = abc[tm->tm_min % SID_LEN]; 67 sidbuf[5] = abc[tm->tm_sec % SID_LEN]; 68 sidbuf[6] = abc[n / SID_LEN]; 69 sidbuf[7] = abc[n % SID_LEN]; 70 sidbuf[8] = 0; 71 72 p = strdup (sidbuf); 73 if (!p) 74 return errno; 75 *res = p; 76 return 0; 77 } 78