0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef _GNU_SOURCE
0038 #define _GNU_SOURCE
0039 #endif
0040 #include <ndrstandard.h>
0041 #include <time.h>
0042 #include <sys/time.h>
0043 #include <stdlib.h>
0044 #include <string.h>
0045 #include <stdio.h>
0046 #include <sys/stat.h>
0047 #include <ctype.h>
0048 #include <pthread.h>
0049 #include <time.h>
0050 #include <fcntl.h>
0051 #include <sys_unix.h>
0052 #include <nstd_tls.h>
0053 #include <termios.h>
0054 #include <nstdutil.h>
0055 #include <ndebug.h>
0056 #include <userlog.h>
0057 #include <atmi_int.h>
0058 #include <errno.h>
0059 #include <excrypto.h>
0060
0061
0062 #define _MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
0063 #define NDRX_TEMP_ATTEMPTS 1000
0064 #define API_ENTRY {_Nunset_error();}
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 expublic int ndrx_compare4(long a1, long a2, long a3, long a4, long b1, long b2, long b3, long b4)
0075 {
0076
0077 long res1 = a1 - b1;
0078 long res2 = a2 - b2;
0079 long res3 = a3 - b3;
0080 long res4 = a4 - b4;
0081
0082 if (res1!=0)
0083 return (int)res1;
0084
0085 if (res2!=0)
0086 return (int)res2;
0087
0088 if (res3!=0)
0089 return (int)res3;
0090
0091 return (int)res4;
0092 }
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104 expublic int ndrx_compare3(long a1, long a2, long a3, long b1, long b2, long b3)
0105 {
0106
0107 long res1 = a1 - b1;
0108 long res2 = a2 - b2;
0109 long res3 = a3 - b3;
0110
0111
0112 if (res1!=0)
0113 return (int)res1;
0114
0115 if (res2!=0)
0116 return (int)res2;
0117
0118 return (int)res3;
0119
0120 }
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132 expublic int ndrx_utc_cmp(long *t1, long *tusec1, long *t2, long *tusec2)
0133 {
0134 if ((*t1 < *t2) || (*t1 == *t2 && *tusec1 < *tusec2))
0135 {
0136 return -1;
0137 }
0138 else if (*t1 == *t2 && *tusec1 == *tusec2)
0139 {
0140 return 0;
0141 }
0142 else
0143 {
0144 return 1;
0145 }
0146 }
0147
0148
0149
0150
0151
0152
0153 expublic void ndrx_utc_tstamp2(long *t, long *tusec)
0154 {
0155 struct timeval tv;
0156
0157 gettimeofday(&tv, NULL);
0158
0159 *t = tv.tv_sec;
0160 *tusec = tv.tv_usec;
0161 }
0162
0163
0164
0165
0166
0167
0168 expublic char * ndrx_get_strtstamp2(int slot, long t, long tusec)
0169 {
0170 time_t tfmt;
0171 struct tm utc;
0172 NSTD_TLS_ENTRY;
0173
0174 tfmt = t;
0175 gmtime_r(&tfmt, &utc);
0176 strftime(G_nstd_tls->util_buf1[slot],
0177 sizeof(G_nstd_tls->util_buf1[slot]), "%Y-%m-%d %H:%M:%S", &utc);
0178
0179 return G_nstd_tls->util_buf1[slot];
0180 }
0181
0182
0183
0184
0185
0186
0187
0188 expublic unsigned long long ndrx_utc_tstamp(void)
0189 {
0190 struct timeval tv;
0191 unsigned long long ret;
0192
0193 gettimeofday(&tv, NULL);
0194
0195
0196 if (sizeof(unsigned long long)>=8)
0197 {
0198 ret =
0199 (unsigned long long)(tv.tv_sec) * 1000 +
0200 (unsigned long long)(tv.tv_usec) / 1000;
0201 }
0202 else
0203 {
0204 ret = (unsigned long long)(tv.tv_sec);
0205 }
0206
0207 return ret;
0208 }
0209
0210
0211
0212
0213
0214 expublic unsigned long long ndrx_utc_tstamp_micro(void)
0215 {
0216 struct timeval tv;
0217 unsigned long long ret;
0218
0219 gettimeofday(&tv, NULL);
0220
0221 if (sizeof(unsigned long long)>=8)
0222 {
0223 ret =
0224 (unsigned long long)(tv.tv_sec) * 1000000 +
0225 (unsigned long long)(tv.tv_usec);
0226 }
0227 else
0228 {
0229 ret = (unsigned long long)(tv.tv_sec);
0230 }
0231
0232 return ret;
0233 }
0234
0235
0236
0237
0238
0239
0240 expublic char * ndrx_get_strtstamp_from_sec(int slot, long ts)
0241 {
0242 time_t t;
0243 struct tm utc;
0244
0245 NSTD_TLS_ENTRY;
0246
0247 t = ts;
0248 gmtime_r(&t, &utc);
0249 strftime(G_nstd_tls->util_buf2[slot],
0250 sizeof(G_nstd_tls->util_buf2[slot]), "%Y-%m-%d %H:%M:%S", &utc);
0251
0252 return G_nstd_tls->util_buf2[slot];
0253 }
0254
0255
0256
0257
0258
0259 expublic unsigned long long ndrx_get_micro_resolution_for_sec(void)
0260 {
0261 unsigned long long ret;
0262
0263 if (sizeof(unsigned long long)>=8)
0264 {
0265 ret = 1000000;
0266 }
0267 else
0268 {
0269 ret = 1;
0270 }
0271
0272 return ret;
0273 }
0274
0275
0276
0277
0278
0279
0280
0281 expublic void ndrx_get_dt_local(long *p_date, long *p_time, long *p_usec)
0282 {
0283 struct tm stm;
0284 struct timeval timeval;
0285 struct timezone timezone_val;
0286
0287 gettimeofday (&timeval, &timezone_val);
0288
0289 localtime_r(&timeval.tv_sec, &stm);
0290
0291 *p_time = 10000L*stm.tm_hour+100*stm.tm_min+1*stm.tm_sec;
0292 *p_date = 10000L*(1900 + stm.tm_year)+100*(1+stm.tm_mon)+1*(stm.tm_mday);
0293 *p_usec = timeval.tv_usec;
0294
0295 return;
0296 }
0297
0298
0299
0300
0301
0302
0303
0304 expublic long ndrx_timespec_get_delta(struct timespec *stop, struct timespec *start)
0305 {
0306 long ret;
0307
0308
0309 ret = (stop->tv_sec - start->tv_sec)*1000 +
0310 (stop->tv_nsec - start->tv_nsec)/1000000;
0311
0312 return ret;
0313 }
0314
0315
0316
0317
0318
0319
0320
0321 expublic long ndrx_ceil(long x, long y)
0322 {
0323 return (x + y - 1) / y;
0324 }
0325
0326
0327
0328
0329
0330
0331
0332
0333 expublic char *ndrx_str_replace(char *orig, char *rep, char *with) {
0334 char *result;
0335 char *ins;
0336 char *tmp;
0337 int len_rep;
0338 int len_with;
0339 int len_front;
0340 int count;
0341
0342 if (!orig)
0343 return NULL;
0344 if (!rep)
0345 rep = "";
0346 len_rep = strlen(rep);
0347 if (!with)
0348 with = "";
0349 len_with = strlen(with);
0350
0351 ins = orig;
0352 for (count = 0; (tmp = strstr(ins, rep)); ++count)
0353 {
0354 ins = tmp + len_rep;
0355 }
0356
0357
0358
0359
0360
0361
0362
0363 tmp = result = NDRX_FPMALLOC(strlen(orig) + (len_with - len_rep) * count + 1, 0);
0364
0365 if (!result)
0366 return NULL;
0367
0368 while (count--)
0369 {
0370 ins = strstr(orig, rep);
0371 len_front = ins - orig;
0372 NDRX_STRNCPY(tmp, orig, len_front);
0373 tmp = tmp + len_front;
0374 tmp = strcpy(tmp, with) + len_with;
0375 orig += len_front + len_rep;
0376 }
0377 strcpy(tmp, orig);
0378 return result;
0379 }
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390 expublic char * ndrx_str_env_subs_len(char * str, int buf_size)
0391 {
0392 char *p, *p2, *p3;
0393 char *next = str;
0394 char envnm[1024];
0395 char *env;
0396 char *out;
0397 char *empty="";
0398 char *malloced;
0399 char *pval;
0400 char *tempbuf = NULL;
0401 char *close;
0402
0403 #define FUNCTION_SEPERATOR '='
0404
0405 while (NULL!=(p=strstr(next, "${")))
0406 {
0407 p2=strstr(next, "\\${");
0408 p3=strstr(next, "\\\\${");
0409
0410
0411 if (p == p3+2)
0412 {
0413
0414
0415
0416 }
0417 else if (p == (p2+1))
0418 {
0419
0420
0421
0422 memmove(p2, p, strlen(p)+1);
0423 next=p+3;
0424 continue;
0425 }
0426
0427
0428 close =strchr(p, '}');
0429 if (NULL!=close)
0430 {
0431 long bufsz;
0432 int cpylen = close-p-2;
0433 int envlen;
0434
0435 NDRX_STRNCPY(envnm, p+2, cpylen);
0436 envnm[cpylen] = EXEOS;
0437
0438 if (NULL==(pval=strchr(envnm, FUNCTION_SEPERATOR)))
0439 {
0440 env = getenv(envnm);
0441
0442 if (NULL!=env)
0443 out = env;
0444 else
0445 out = empty;
0446 }
0447 else
0448 {
0449 *pval=EXEOS;
0450 pval++;
0451
0452 if (0==(bufsz=strlen(pval)))
0453 {
0454 userlog("Invalid encrypted data (zero len, maybe invalid sep? not =?) "
0455 "for: [%s] - fill empty", envnm);
0456 out = empty;
0457 }
0458 else
0459 {
0460 int err;
0461 tempbuf = NDRX_MALLOC(bufsz);
0462
0463 if (NULL==tempbuf)
0464 {
0465 err = errno;
0466 userlog("Failed to allocate %ld bytes for decryption buffer: %s",
0467 bufsz, strerror(errno));
0468 NDRX_LOG_EARLY(log_error, "Failed to allocate %ld bytes "
0469 "for decryption buffer: %s",
0470 bufsz, strerror(errno));
0471 goto out;
0472 }
0473
0474
0475
0476
0477
0478
0479
0480 if (0==strcmp(envnm, "dec"))
0481 {
0482
0483
0484
0485
0486 if (EXSUCCEED!=ndrx_crypto_dec_string(pval, tempbuf, &bufsz))
0487 {
0488 userlog("Failed to decrypt [%s] string: %s",
0489 pval, Nstrerror(Nerror));
0490 NDRX_LOG_EARLY(log_error, "Failed to decrypt [%s] string: %s",
0491 pval, Nstrerror(Nerror));
0492 out = empty;
0493 }
0494 out = tempbuf;
0495 }
0496 else
0497 {
0498 userlog("Unsupported substitution function: [%s] - skipping",
0499 pval);
0500 NDRX_LOG_EARLY(log_error, "Failed to decrypt [%s] string: %s",
0501 pval, Nstrerror(Nerror));
0502 out = empty;
0503 }
0504
0505 }
0506 }
0507
0508 envlen = strlen(out);
0509
0510
0511 if (cpylen+3==envlen)
0512 {
0513 memcpy(p, out, envlen);
0514 }
0515 else if (cpylen+3 < envlen)
0516 {
0517 int missing;
0518
0519
0520 if (buf_size > 0 &&
0521 strlen(str) - (cpylen+3) + envlen > buf_size-1 )
0522 {
0523 if (NULL!=tempbuf)
0524 {
0525 NDRX_FREE(tempbuf);
0526 }
0527
0528
0529 return str;
0530 }
0531
0532 missing = envlen - (cpylen+2);
0533
0534
0535 memmove(close+missing, close+1, strlen(close+1)+1);
0536 memcpy(p, out, envlen);
0537 }
0538 else if (cpylen+3 > envlen)
0539 {
0540
0541
0542 memcpy(p, out, envlen);
0543
0544 memmove(p+envlen, close+1, strlen(close+1)+1);
0545 }
0546
0547
0548
0549 next = p+envlen;
0550 }
0551 else
0552 {
0553
0554 next+=2;
0555 }
0556
0557 if (NULL!=tempbuf)
0558 {
0559
0560 NDRX_FREE(tempbuf);
0561 tempbuf=NULL;
0562 }
0563 }
0564
0565 out:
0566
0567 if (NULL!=tempbuf)
0568 {
0569
0570 NDRX_FREE(tempbuf);
0571 tempbuf=NULL;
0572 }
0573
0574
0575 if (strstr(str, "\\"))
0576 {
0577 malloced = ndrx_str_replace(str, "\\\\", "\\");
0578 strcpy(str, malloced);
0579 NDRX_FPFREE(malloced);
0580 }
0581
0582 return str;
0583 }
0584
0585
0586
0587
0588
0589
0590
0591
0592 expublic int ndrx_str_subs_context(char * str, int buf_size, char opensymb, char closesymb,
0593 void *data1, void *data2, void *data3, void *data4,
0594 int (*pf_get_data) (void *data1, void *data2, void *data3, void *data4,
0595 char *symbol, char *outbuf, long outbufsz))
0596 {
0597 char *p, *p2, *p3;
0598 char *next = str;
0599 char symbol[1024];
0600 char *malloced;
0601 char *tempbuf = NULL;
0602 char open1[]={'$',opensymb,EXEOS};
0603 char open2[]={'\\', '$', opensymb, EXEOS};
0604 char open3[]={'\\', '\\', '$', opensymb, EXEOS};
0605 char *outbuf = NULL;
0606 int ret = EXSUCCEED;
0607 char *close;
0608
0609 NDRX_MALLOC_OUT(outbuf, buf_size, char);
0610
0611 while (NULL!=(p=strstr(next, open1)))
0612 {
0613 p2=strstr(next, open2);
0614 p3=strstr(next, open3);
0615
0616
0617 if (p == p3+2)
0618 {
0619
0620
0621
0622 }
0623 else if (p == (p2+1))
0624 {
0625
0626
0627
0628 memmove(p2, p, strlen(p)+1);
0629 next=p+3;
0630 continue;
0631 }
0632
0633
0634 close =strchr(p, closesymb);
0635 if (NULL!=close)
0636 {
0637 long bufsz;
0638 int cpylen = close-p-2;
0639 int envlen;
0640
0641 NDRX_STRNCPY(symbol, p+2, cpylen);
0642 symbol[cpylen] = EXEOS;
0643
0644 if (EXSUCCEED!=(ret=pf_get_data(data1, data2, data3, data4,
0645 symbol, outbuf, buf_size)))
0646 {
0647 NDRX_LOG(log_error, "Failed to substitute [%s] error: %d", symbol, ret);
0648 goto out;
0649 }
0650
0651 envlen = strlen(outbuf);
0652
0653
0654 if (cpylen+3==envlen)
0655 {
0656 memcpy(p, outbuf, envlen);
0657 }
0658 else if (cpylen+3 < envlen)
0659 {
0660 int totlen;
0661 int missing;
0662
0663 if (buf_size > 0 &&
0664 (totlen=(strlen(str) - (cpylen+3) + envlen)) > buf_size-1 )
0665 {
0666 if (NULL!=tempbuf)
0667 {
0668 NDRX_FREE(tempbuf);
0669 }
0670
0671 NDRX_LOG(log_error, "buffer overrun in string "
0672 "formatting totlen=%d, bufsz-1=%d", totlen, buf_size-1);
0673 EXFAIL_OUT(ret);
0674 }
0675 missing = envlen - (cpylen+2);
0676
0677
0678 memmove(close+missing, close+1, strlen(close+1)+1);
0679 memcpy(p, outbuf, envlen);
0680
0681 }
0682 else if (cpylen+3 > envlen)
0683 {
0684
0685
0686 memcpy(p, outbuf, envlen);
0687
0688 memmove(p+envlen, close+1, strlen(close+1)+1);
0689
0690 }
0691
0692
0693
0694 next = p+envlen;
0695 }
0696 else
0697 {
0698
0699 next+=2;
0700 }
0701
0702 if (NULL!=tempbuf)
0703 {
0704
0705 tempbuf=NULL;
0706 NDRX_FREE(tempbuf);
0707 }
0708 }
0709
0710 out:
0711
0712 if (strstr(str, "\\"))
0713 {
0714 malloced = ndrx_str_replace(str, "\\\\", "\\");
0715 strcpy(str, malloced);
0716 NDRX_FPFREE(malloced);
0717 }
0718
0719 if (NULL!=outbuf)
0720 {
0721 NDRX_FREE(outbuf);
0722 }
0723
0724 return ret;
0725 }
0726
0727
0728
0729
0730
0731
0732
0733 expublic char * ndrx_str_env_subs(char * str)
0734 {
0735 return ndrx_str_env_subs_len(str, 0);
0736 }
0737
0738
0739
0740
0741
0742
0743
0744 expublic double ndrx_num_dec_parsecfg(char * str)
0745 {
0746 double ret = 0;
0747 double multipler = 1;
0748 int len = strlen(str);
0749 int mapplied = EXFALSE;
0750
0751 if (len>1)
0752 {
0753 switch (str[len-1])
0754 {
0755 case 'k':
0756 case 'K':
0757 multipler = 1000.0f;
0758 mapplied = EXTRUE;
0759 break;
0760 case 'm':
0761 case 'M':
0762 multipler = 1000000.0f;
0763 mapplied = EXTRUE;
0764 break;
0765 case 'g':
0766 case 'G':
0767 multipler = 1000000000.0f;
0768 mapplied = EXTRUE;
0769 break;
0770 }
0771
0772 if (mapplied)
0773 {
0774 str[len-1] = EXEOS;
0775 }
0776 }
0777
0778 ret = atof(str);
0779
0780 ret*=multipler;
0781
0782 return ret;
0783 }
0784
0785
0786
0787
0788
0789
0790 expublic double ndrx_num_time_parsecfg(char * str)
0791 {
0792 double ret = 0;
0793 double multipler = 1;
0794 int len = strlen(str);
0795 int mapplied = EXFALSE;
0796
0797 if (len>1)
0798 {
0799 switch (str[len-1])
0800 {
0801 case 's':
0802
0803 multipler = 1000.0f;
0804 mapplied = EXTRUE;
0805 break;
0806 case 'm':
0807
0808 multipler = 60.0f * 1000.0f;
0809 mapplied = EXTRUE;
0810 break;
0811 case 'h':
0812
0813 multipler = 60.0f * 60.0f * 1000.0f;
0814 mapplied = EXTRUE;
0815 break;
0816 }
0817
0818 if (mapplied)
0819 {
0820 str[len-1] = EXEOS;
0821 }
0822 }
0823
0824 ret = atof(str);
0825
0826 ret*=multipler;
0827
0828 return ret;
0829 }
0830
0831
0832
0833
0834
0835
0836
0837
0838
0839 expublic char *ndrx_decode_str(char *str, char *buf, int buf_sz)
0840 {
0841 int len = strlen(str);
0842
0843 if (len < buf_sz)
0844 {
0845 return str;
0846 }
0847
0848 NDRX_STRCPY_SAFE_DST(buf, str, buf_sz);
0849
0850 buf[buf_sz-2]='+';
0851
0852 return buf;
0853 }
0854
0855
0856
0857
0858
0859
0860
0861 expublic char *ndrx_decode_num(long tt, int slot, int level, int levels)
0862 {
0863 char tmp[128];
0864 long next_t=0;
0865 long t = tt;
0866 #define DEC_K ((long)1000)
0867 #define DEC_M ((long)1000*1000)
0868 #define DEC_B ((long)1000*1000*1000)
0869 #define DEC_T ((long long)1000*1000*1000*1000)
0870
0871 NSTD_TLS_ENTRY;
0872
0873 level++;
0874
0875 if ((double)t/DEC_K < 1.0)
0876 {
0877 snprintf(tmp, sizeof(tmp), "%ld", t);
0878 }
0879 else if ((double)t/DEC_M < 1.0)
0880 {
0881 snprintf(tmp, sizeof(tmp), "%ldK", t/DEC_K);
0882
0883 if (level<levels)
0884 next_t = t%DEC_K;
0885 }
0886 else if ((double)t/DEC_B < 1.0)
0887 {
0888 snprintf(tmp, sizeof(tmp), "%ldM", t/DEC_M);
0889
0890 if (level<levels)
0891 next_t = t%DEC_M;
0892 }
0893 else if ((double)t/DEC_T < 1.0)
0894 {
0895 snprintf(tmp, sizeof(tmp), "%ldB", t/DEC_B);
0896
0897 if (level<levels)
0898 next_t = t%DEC_B;
0899 }
0900
0901 if (level==1)
0902 {
0903 NDRX_STRCPY_SAFE(G_nstd_tls->util_text[slot], tmp);
0904 }
0905 else
0906 {
0907 strcat(G_nstd_tls->util_text[slot], tmp);
0908 }
0909
0910 if (next_t)
0911 ndrx_decode_num(next_t, slot, level, levels);
0912
0913 return G_nstd_tls->util_text[slot];
0914 }
0915
0916
0917
0918
0919
0920
0921
0922 expublic char *ndrx_str_strip(char *haystack, char *needle)
0923 {
0924 char *dest;
0925 char *src;
0926 int len = strlen(needle);
0927 int i;
0928 int have_found;
0929 dest = src = haystack;
0930
0931 for (; EXEOS!=*src; src++)
0932 {
0933 have_found = EXFALSE;
0934 for (i=0; i<len; i++)
0935 {
0936 if (*src == needle[i])
0937 {
0938 have_found = EXTRUE;
0939 continue;
0940 }
0941 }
0942
0943 if (!have_found)
0944 {
0945 *dest = *src;
0946 dest++;
0947 }
0948 }
0949
0950 *dest = EXEOS;
0951
0952 return haystack;
0953 }
0954
0955
0956
0957
0958
0959
0960
0961 expublic char* ndrx_str_rstrip(char* s, char *needle)
0962 {
0963 char* p = s + strlen(s);
0964 while (p > s)
0965 {
0966 p--;
0967
0968 if (strchr(needle, *p))
0969 {
0970 *p = '\0';
0971 }
0972 else
0973 {
0974
0975 break;
0976 }
0977 }
0978 return s;
0979 }
0980
0981
0982
0983
0984
0985
0986
0987 expublic char* ndrx_str_lstrip_ptr(char* s, char *needle)
0988 {
0989 int len = strlen(s);
0990 int i;
0991 char *p =s;
0992
0993 for (i=0; i<len; i++)
0994 {
0995 if (strchr(needle, *p))
0996 {
0997 p++;
0998 }
0999 else
1000 {
1001 break;
1002 }
1003 }
1004
1005 return p;
1006 }
1007
1008
1009
1010
1011
1012
1013 expublic int ndrx_isint(char *str)
1014 {
1015 if (*str == '-')
1016 {
1017 ++str;
1018 }
1019
1020 if (!*str)
1021 {
1022 return EXFALSE;
1023 }
1024
1025 while (*str)
1026 {
1027 if (!isdigit(*str))
1028 {
1029 return EXFALSE;
1030 }
1031 else
1032 {
1033 ++str;
1034 }
1035 }
1036
1037 return EXTRUE;
1038 }
1039
1040
1041
1042
1043
1044
1045 expublic int ndrx_isempty(const char *s)
1046 {
1047
1048 while ( isspace( (unsigned char)*s) )
1049 {
1050 s++;
1051 }
1052
1053 return *s == EXEOS ? EXTRUE : EXFALSE;
1054 }
1055
1056
1057
1058
1059
1060
1061
1062 expublic int ndrx_nr_chars(char *str, char chkchar)
1063 {
1064 char *p = str;
1065 int count = 0;
1066
1067 do
1068 {
1069 if (*p == chkchar)
1070 {
1071 count++;
1072 }
1073 } while (*(p++));
1074
1075 return count;
1076 }
1077
1078
1079
1080
1081
1082
1083
1084
1085 expublic char *ndrx_dolongstrgmap(longstrmap_t *map, long val, long endval)
1086 {
1087 do
1088 {
1089 if (map->from == val)
1090 {
1091 return map->to;
1092 }
1093 map++;
1094 } while (endval!=map->from);
1095
1096 return map->to;
1097 }
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107 expublic char *ndrx_docharstrgmap(longstrmap_t *map, char val, char endval)
1108 {
1109 do
1110 {
1111 if (map->from == val)
1112 {
1113 return map->to;
1114 }
1115 map++;
1116 } while (endval!=map->from);
1117
1118 return map->to;
1119 }
1120
1121
1122
1123
1124
1125
1126 expublic uint64_t ndrx_gettid(void)
1127 {
1128 pthread_t ptid = pthread_self();
1129 uint64_t threadId = 0;
1130 memcpy(&threadId, &ptid, _MIN(sizeof(threadId), sizeof(ptid)));
1131 return threadId;
1132 }
1133
1134
1135
1136
1137
1138
1139 expublic int ndrx_file_exists(char *filename)
1140 {
1141 struct stat st;
1142 int result = stat(filename, &st);
1143 return result == 0;
1144 }
1145
1146
1147
1148
1149
1150
1151 expublic int ndrx_file_touch(char *filename)
1152 {
1153 FILE *f = fopen(filename, "a");
1154
1155 if (NULL==f)
1156 {
1157 return EXFAIL;
1158 }
1159
1160 fclose(f);
1161
1162 return EXSUCCEED;
1163 }
1164
1165
1166
1167
1168
1169
1170 expublic int ndrx_file_regular(char *path)
1171 {
1172 struct stat path_stat;
1173 stat(path, &path_stat);
1174 return S_ISREG(path_stat.st_mode);
1175 }
1176
1177
1178
1179
1180
1181 expublic char * ndrx_fgets_stdin_strip(char *buf, int bufsz)
1182 {
1183 int len;
1184
1185 if (NULL==fgets(buf, bufsz, stdin))
1186 {
1187 userlog("%s: fgets fail: %s", __func__, strerror(errno));
1188 return NULL;
1189 }
1190
1191 len = strlen(buf);
1192
1193 if (len>0)
1194 {
1195 len--;
1196
1197
1198 if (buf[len]=='\n')
1199 {
1200 buf[len] = 0;
1201 len--;
1202 }
1203
1204
1205 if (len>= 0 && buf[len]=='\r')
1206 {
1207 buf[len] = 0;
1208 }
1209 }
1210
1211 return buf;
1212 }
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222 expublic ssize_t ndrx_getline(char **lineptr, size_t *n, FILE *stream)
1223 {
1224 #ifdef HAVE_GETLINE
1225
1226 return getline(lineptr, n, stream);
1227
1228 #else
1229 if (NULL==fgets(*lineptr, *n, stream))
1230 {
1231 return EXFAIL;
1232 }
1233 else
1234 {
1235 return EXTRUE;
1236 }
1237 #endif
1238 }
1239
1240
1241
1242
1243
1244
1245 expublic int ndrx_get_cksum(char *file)
1246 {
1247 unsigned char checksum = 0;
1248 int ret = EXSUCCEED;
1249
1250 FILE *fp = fopen(file,"rb");
1251
1252 if (NULL!=fp)
1253 {
1254
1255 while (!feof(fp) && !ferror(fp)) {
1256 checksum ^= fgetc(fp);
1257 }
1258
1259 fclose(fp);
1260 }
1261 else
1262 {
1263 ret = EXFAIL;
1264 }
1265
1266 if (EXSUCCEED==ret)
1267 {
1268 return checksum;
1269 }
1270 else
1271 {
1272 return EXFAIL;
1273 }
1274 }
1275
1276
1277
1278
1279
1280
1281
1282
1283 expublic char * ndrx_get_executable_path(char * out_path, size_t bufsz, char * in_binary)
1284 {
1285 char * systemPath = NULL;
1286 char * candidateDir = NULL;
1287 int found = EXFALSE;
1288 char *ret;
1289
1290 systemPath = getenv ("PATH");
1291 if (systemPath != NULL)
1292 {
1293 systemPath = strdup (systemPath);
1294 for (candidateDir = strtok (systemPath, ":");
1295 candidateDir != NULL;
1296 candidateDir = strtok (NULL, ":"))
1297 {
1298 snprintf(out_path, bufsz, "%s/%s", candidateDir, in_binary);
1299
1300 if (access(out_path, F_OK) == 0)
1301 {
1302 found = EXTRUE;
1303 goto out;
1304 }
1305 }
1306 }
1307
1308 out:
1309
1310 if (systemPath)
1311 {
1312 free(systemPath);
1313 }
1314
1315 if (found)
1316 {
1317 ret = out_path;
1318 }
1319 else
1320 {
1321 out_path[0] = EXEOS;
1322 ret = NULL;
1323 }
1324
1325 return ret;
1326 }
1327
1328
1329
1330
1331
1332
1333
1334 expublic char * ndrx_memdup(char *org, size_t len)
1335 {
1336 char *ret;
1337
1338 if (NULL!=(ret = NDRX_MALLOC(len)))
1339 {
1340 memcpy(ret, org, len);
1341 return ret;
1342 }
1343
1344 return NULL;
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354 expublic double ndrx_atof(char *str)
1355 {
1356 char test[5];
1357 char buf[128];
1358 char *p;
1359 int len, i;
1360
1361
1362 snprintf(test, sizeof(test), "%.1f", 0.0f);
1363
1364 if (NDRX_LOCALE_STOCK_DECSEP!=test[1])
1365 {
1366 NDRX_STRCPY_SAFE(buf, str);
1367 len = strlen(buf);
1368
1369 for (i=0; i<len; i++)
1370 {
1371 if (NDRX_LOCALE_STOCK_DECSEP==buf[i])
1372 {
1373 buf[i] = test[1];
1374 }
1375 }
1376
1377 p = buf;
1378 }
1379 else
1380 {
1381 p = str;
1382 }
1383
1384 return atof(p);
1385 }
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398 expublic int ndrx_tokens_extract(char *str1, char *fmt, void *tokens,
1399 int tokens_elmsz, int len, int start_tok, int stop_tok)
1400 {
1401 int ret = 0;
1402 char *str = NDRX_STRDUP(str1);
1403 char *ptr;
1404 char *token;
1405 char *str_first = str;
1406 int toks=0;
1407 int is_hex;
1408 char *int_fmt = "%d";
1409
1410 if (0==strcmp(fmt, "%x"))
1411 {
1412 is_hex=EXTRUE;
1413 }
1414 else
1415 {
1416 is_hex=EXFALSE;
1417 }
1418
1419 if (NULL==str)
1420 {
1421 int err = errno;
1422 NDRX_LOG(log_error, "Failed to duplicate [%s]: %s", str1, strerror(err));
1423 userlog("Failed to duplicate [%s]: %s", str1, strerror(err));
1424 goto out;
1425 }
1426
1427 while ((token = strtok_r(str_first, "\t ", &ptr)))
1428 {
1429 if (NULL!=str_first)
1430 {
1431 str_first = NULL;
1432 }
1433
1434 if (toks>=start_tok)
1435 {
1436 if (ret<len)
1437 {
1438
1439 if (is_hex)
1440 {
1441 if (0==strncmp(token, "0x", 2) ||
1442 0==strncmp(token, "0X", 2))
1443 {
1444 token+=2;
1445 sscanf(token, fmt, tokens);
1446 }
1447 else
1448 {
1449
1450 sscanf(token, int_fmt, tokens);
1451 }
1452 }
1453 else
1454 {
1455
1456 sscanf(token, fmt, tokens);
1457 }
1458
1459 tokens+=tokens_elmsz;
1460 }
1461 else
1462 {
1463 break;
1464 }
1465 ret++;
1466 }
1467
1468 if (toks>=stop_tok)
1469 {
1470 break;
1471 }
1472 toks++;
1473 }
1474
1475 out:
1476
1477 if (NULL!=str)
1478 {
1479 NDRX_FREE(str);
1480 }
1481 return ret;
1482 }
1483
1484
1485
1486
1487
1488
1489 expublic void ndrx_chomp(char *str)
1490 {
1491 int len = strlen(str);
1492
1493 while (len>1 && (str[len-1]=='\n' || str[len-1]=='\r'))
1494 {
1495 str[len-1] = EXEOS;
1496 len--;
1497 }
1498 }
1499
1500
1501
1502
1503
1504
1505
1506 expublic uint32_t ndrx_rotl32b (uint32_t x, uint32_t n)
1507 {
1508 if (!n) return x;
1509 return (x<<n) | (x>>(32-n));
1510 }
1511
1512
1513
1514
1515
1516
1517
1518
1519 expublic size_t ndrx_strnlen(char *str, size_t max)
1520 {
1521 char *p;
1522
1523 for(p = str; max && *p; ++p)
1524 {
1525 max--;
1526 }
1527
1528 return(p - str);
1529 }
1530
1531
1532
1533
1534
1535
1536
1537 expublic void ndrx_growlist_init(ndrx_growlist_t *list, int step, size_t size)
1538 {
1539 list->maxindexused = EXFAIL;
1540 list->itemsalloc = 0;
1541 list->step = step;
1542 list->size = size;
1543 list->mem = NULL;
1544 }
1545
1546
1547
1548
1549
1550
1551
1552
1553 expublic int ndrx_growlist_add(ndrx_growlist_t *list, void *item, int index)
1554 {
1555 return ndrx_growlist_add_many(list, item, index, 1);
1556 }
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566 expublic int ndrx_growlist_add_many(ndrx_growlist_t *list, void *item, int index, int count)
1567 {
1568 int ret = EXSUCCEED;
1569 int next_blocks;
1570 size_t new_size;
1571 char *p;
1572
1573 if (NULL==list->mem)
1574 {
1575 new_size = list->step * list->size;
1576 if (NULL==(list->mem = NDRX_FPMALLOC(list->step * list->size, 0)))
1577 {
1578 userlog("Failed to alloc %d bytes: %s", new_size,
1579 strerror(errno));
1580
1581 EXFAIL_OUT(ret);
1582 }
1583
1584 list->itemsalloc+=list->step;
1585 }
1586
1587 while (index+count > list->itemsalloc)
1588 {
1589 list->itemsalloc+=list->step;
1590
1591 next_blocks = list->itemsalloc / list->step;
1592
1593 new_size = next_blocks * list->step * list->size;
1594
1595
1596
1597
1598 if (NULL==(list->mem = NDRX_FPREALLOC(list->mem, new_size)))
1599 {
1600 userlog("Failed to realloc %d bytes (%d blocks): %s", new_size,
1601 next_blocks, strerror(errno));
1602
1603 EXFAIL_OUT(ret);
1604 }
1605 }
1606
1607
1608 p = list->mem;
1609 p+=(index * list->size);
1610
1611
1612
1613
1614
1615
1616
1617 memcpy( p, item, list->size*count);
1618
1619
1620 if ((index+count-1) > list->maxindexused)
1621 {
1622 list->maxindexused = index+count-1;
1623 }
1624
1625 out:
1626
1627 return ret;
1628
1629 }
1630
1631
1632
1633
1634
1635
1636
1637 expublic int ndrx_growlist_append(ndrx_growlist_t *list, void *item)
1638 {
1639 return ndrx_growlist_add(list, item, list->maxindexused+1);
1640 }
1641
1642
1643
1644
1645
1646
1647
1648
1649 expublic int ndrx_growlist_append_many(ndrx_growlist_t *list, void *item, int count)
1650 {
1651 return ndrx_growlist_add_many(list, item, list->maxindexused+1, count);
1652 }
1653
1654
1655
1656
1657
1658
1659 expublic void ndrx_growlist_free(ndrx_growlist_t *list)
1660 {
1661 if (NULL!=list->mem)
1662 {
1663 NDRX_FPFREE(list->mem);
1664
1665 list->mem=NULL;
1666 list->maxindexused=EXFAIL;
1667 list->itemsalloc = 0;
1668 }
1669 }
1670
1671
1672
1673
1674
1675
1676
1677 expublic char *ndrx_strsep(char **s1, char *s2)
1678 {
1679 char *p1 = *s1;
1680
1681 if (p1 != NULL)
1682 {
1683 *s1 = strpbrk(p1, s2);
1684 if (*s1 != NULL)
1685 {
1686 *(*s1) = '\0';
1687
1688
1689 (*s1)++;
1690 }
1691 }
1692
1693 return p1;
1694 }
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706 expublic int ndrx_args_loader_set(ndrx_args_loader_t *args, void *obj,
1707 char *fldnm, char *value,
1708 char *errbuf, size_t errbufsz)
1709 {
1710 int ret = EXSUCCEED;
1711 int *p_bool;
1712 int *p_int;
1713 int tmp_int;
1714
1715 while (EXFAIL!=args->offset)
1716 {
1717 if (0==strcmp(fldnm, args->cname))
1718 {
1719 switch (args->fld_type)
1720 {
1721 case NDRX_ARGS_BOOL:
1722
1723 p_bool = (int *)((char *)obj + args->offset);
1724
1725 if (0==strcmp(value, "y") || 0==strcmp(value, "Y"))
1726 {
1727 *p_bool = EXTRUE;
1728 }
1729 else if (0==strcmp(value, "n") || 0==strcmp(value, "N"))
1730 {
1731 *p_bool = EXFALSE;
1732 }
1733 else
1734 {
1735 snprintf(errbuf, errbufsz, "Unsupported value for [%s] "
1736 "bool field must be [yYnN], got: [%s]",
1737 args->cname, value);
1738
1739 NDRX_LOG(log_error, "%s", errbuf);
1740 EXFAIL_OUT(ret);
1741 }
1742
1743 NDRX_LOG(log_warn, "[%s] set to [%d]", args->cname, *p_bool);
1744
1745 break;
1746 case NDRX_ARGS_INT:
1747
1748
1749 p_int = (int *)((char *)obj + args->offset);
1750 tmp_int = atoi(value);
1751
1752 if (tmp_int < (int)args->min_value)
1753 {
1754 snprintf(errbuf, errbufsz, "Unsupported value for [%s] "
1755 "int field, min [%d], got: [%d]",
1756 args->cname, (int)args->min_value, tmp_int);
1757 NDRX_LOG(log_error, "%s", errbuf);
1758 EXFAIL_OUT(ret);
1759 }
1760 else if (tmp_int > (int)args->max_value)
1761 {
1762 snprintf(errbuf, errbufsz, "Unsupported value for [%s] "
1763 "int field, max [%d], got: [%d]",
1764 args->cname, (int)args->max_value, tmp_int);
1765 NDRX_LOG(log_error, "%s", errbuf);
1766 EXFAIL_OUT(ret);
1767 }
1768 *p_int = tmp_int;
1769
1770 NDRX_LOG(log_warn, "[%s] set to [%d]", args->cname, *p_int);
1771
1772 break;
1773 case NDRX_ARGS_CB:
1774
1775 if (EXSUCCEED!=args->cb_set(args, value, 0, obj, errbuf, errbufsz))
1776 {
1777 EXFAIL_OUT(ret);
1778 }
1779
1780 break;
1781 default:
1782 snprintf(errbuf, errbufsz, "Type not supported: %d",
1783 args->fld_type);
1784 EXFAIL_OUT(ret);
1785 break;
1786 }
1787
1788 break;
1789 }
1790 args++;
1791 }
1792
1793 if (EXFAIL==args->offset)
1794 {
1795 snprintf(errbuf, errbufsz, "Setting not found [%s]", fldnm);
1796 NDRX_LOG(log_error, "%s", errbuf);
1797 EXFAIL_OUT(ret);
1798 }
1799
1800 out:
1801 return ret;
1802 }
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815 expublic int ndrx_args_loader_get(ndrx_args_loader_t *args, void *obj, char *fldnm,
1816 char *value, int valuesz,
1817 char *errbuf, size_t errbufsz)
1818 {
1819 int ret = EXSUCCEED;
1820 int *p_bool;
1821 int *p_int;
1822
1823 while (EXFAIL!=args->offset)
1824 {
1825 if (0==strcmp(fldnm, args->cname))
1826 {
1827 switch (args->fld_type)
1828 {
1829 case NDRX_ARGS_BOOL:
1830
1831 p_bool = (int *)((char *)obj + args->offset);
1832
1833 snprintf(value, valuesz, "%s", (*p_bool)?"Y":"N");
1834
1835 break;
1836 case NDRX_ARGS_INT:
1837
1838 p_int = (int *)((char *)obj + args->offset);
1839
1840 snprintf(value, valuesz, "%d", *p_int);
1841
1842 break;
1843 case NDRX_ARGS_CB:
1844
1845 if (EXSUCCEED!=args->cb_get(args, value, valuesz, obj, errbuf, errbufsz))
1846 {
1847 EXFAIL_OUT(ret);
1848 }
1849
1850 break;
1851 default:
1852 snprintf(errbuf, errbufsz, "Type not supported: %d",
1853 args->fld_type);
1854 NDRX_LOG(log_error, "%s", errbuf);
1855 EXFAIL_OUT(ret);
1856 break;
1857 }
1858
1859
1860 break;
1861 }
1862 args++;
1863 }
1864
1865 if (EXFAIL==args->offset)
1866 {
1867 snprintf(errbuf, errbufsz, "Setting not found [%s]", fldnm);
1868 NDRX_LOG(log_error, "%s", errbuf);
1869 EXFAIL_OUT(ret);
1870 }
1871
1872 out:
1873 return ret;
1874 }
1875
1876
1877
1878
1879
1880
1881
1882 expublic int ndrx_args_confirm(char *arg)
1883 {
1884 int ret = EXFAIL;
1885
1886 if (strlen(arg) !=1 )
1887 {
1888 ret = EXFAIL;
1889 }
1890 else if (NULL!=strstr(NDRX_ARGS_YES, arg))
1891 {
1892 ret=EXTRUE;
1893 }
1894 else if (NULL!=strstr(NDRX_ARGS_NO, arg))
1895 {
1896 ret=EXFALSE;
1897 }
1898
1899 return ret;
1900 }
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912 expublic int ndrx_storage_decode(char *bytesenc, long *outnrbytes)
1913 {
1914 int ret = EXSUCCEED;
1915 int len = strlen(bytesenc);
1916 char tmp[256];
1917 char suffix;
1918 long vout;
1919
1920 if (len < 2)
1921 {
1922 EXFAIL_OUT(ret);
1923 }
1924
1925 NDRX_STRCPY_SAFE(tmp, bytesenc);
1926
1927 suffix = bytesenc[len-1];
1928 tmp[len-1] = EXEOS;
1929
1930 vout = atol(tmp);
1931
1932 if (suffix>='0' && suffix <= '9')
1933 {
1934
1935 goto out;
1936 }
1937
1938 switch (suffix)
1939 {
1940 case 'T':
1941 case 't':
1942 vout *=NDRX_STOR_KBYTE;
1943 case 'G':
1944 case 'g':
1945 vout *=NDRX_STOR_KBYTE;
1946 case 'M':
1947 case 'm':
1948 vout *=NDRX_STOR_KBYTE;
1949 case 'K':
1950 case 'k':
1951 vout *=NDRX_STOR_KBYTE;
1952 break;
1953 default:
1954 NDRX_LOG(log_error, "Invalid suffix for [%s] %c", bytesenc, suffix);
1955 EXFAIL_OUT(ret);
1956 break;
1957 }
1958
1959 out:
1960 if (EXSUCCEED==ret)
1961 {
1962 *outnrbytes = vout;
1963 }
1964
1965 return ret;
1966 }
1967
1968
1969
1970
1971
1972
1973
1974 expublic void ndrx_storage_encode(long bytes, char *outbuf, int outbufsz)
1975 {
1976 int ret = EXSUCCEED;
1977 int loops=0;
1978 double left_over = bytes;
1979 char suffix=EXEOS;
1980
1981 while (1)
1982 {
1983
1984 if ( left_over < (double)NDRX_STOR_KBYTE)
1985 {
1986 break;
1987 }
1988
1989 left_over= left_over / (double)NDRX_STOR_KBYTE;
1990
1991 loops++;
1992 }
1993
1994 switch (loops)
1995 {
1996 case 4:
1997 suffix = 'T';
1998 break;
1999 case 3:
2000 suffix = 'G';
2001 break;
2002 case 2:
2003 suffix = 'M';
2004 break;
2005 case 1:
2006 suffix = 'K';
2007 break;
2008 case 0:
2009 suffix = 'B';
2010 break;
2011 default:
2012 suffix = '?';
2013 break;
2014 }
2015
2016 snprintf(outbuf, outbufsz, "%.3lf%c", left_over, suffix);
2017
2018 }
2019
2020
2021
2022
2023
2024
2025
2026
2027 expublic char *ndrx_strchr_repl (char *str, char from_char, char to_char)
2028 {
2029
2030 char *p = str;
2031
2032 while ((p = strchr (p, from_char)) != NULL)
2033 {
2034 *p = to_char;
2035 p++;
2036 }
2037
2038 return str;
2039 }
2040
2041
2042
2043
2044
2045
2046
2047 expublic ndrx_intmap_t *ndrx_intmap_find (ndrx_intmap_t ** hash, int key)
2048 {
2049 ndrx_intmap_t *ret = NULL;
2050 EXHASH_FIND_INT( (*hash), &key, ret);
2051 return ret;
2052 }
2053
2054
2055
2056
2057
2058
2059
2060
2061 expublic ndrx_intmap_t * ndrx_intmap_add (ndrx_intmap_t ** hash, int key, int value)
2062 {
2063 ndrx_intmap_t * el;
2064 el = NDRX_CALLOC(1, sizeof(ndrx_intmap_t));
2065
2066 if (NULL==el)
2067 {
2068 userlog("intmap: Failed to alloc %d bytes: %s", sizeof(ndrx_intmap_t),
2069 strerror(errno));
2070 }
2071 else
2072 {
2073 el->key = key;
2074 el->value = value;
2075 EXHASH_ADD_INT((*hash), key, el);
2076 }
2077
2078 return el;
2079 }
2080
2081
2082
2083
2084
2085 expublic void ndrx_intmap_remove (ndrx_intmap_t ** hash)
2086 {
2087 ndrx_intmap_t *e=NULL, *et=NULL;
2088
2089 EXHASH_ITER(hh, (*hash), e, et)
2090 {
2091 EXHASH_DEL((*hash), e);
2092 NDRX_FREE(e);
2093 }
2094
2095 }
2096
2097 #define TEMP_MAKS_LEN 6
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110 expublic FILE* ndrx_mkstemps(char *filetempl, int suffixlen, long flags)
2111 {
2112 FILE *ret = NULL;
2113 int i, j, len, fd, err;
2114 char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
2115 int chk_size = sizeof(letters) -1;
2116
2117
2118
2119
2120
2121 len = strlen(filetempl);
2122
2123 if (len < TEMP_MAKS_LEN + suffixlen)
2124 {
2125 errno = EINVAL;
2126 goto out;
2127 }
2128
2129 for (i=0; i<NDRX_TEMP_ATTEMPTS; i++)
2130 {
2131 if (!(flags & NDRX_STDF_TEST))
2132 {
2133 for (j=len-suffixlen-TEMP_MAKS_LEN; j<len-suffixlen; j++)
2134 {
2135 filetempl[j] = letters[ndrx_rand() % chk_size];
2136 }
2137 }
2138
2139 fd = open(filetempl, O_EXCL | O_CREAT | O_WRONLY, 0600);
2140
2141 if (EXFAIL==fd)
2142 {
2143 if (EEXIST!=errno)
2144 {
2145 err = errno;
2146
2147 NDRX_LOG(log_error, "Failed to create temp name [%s]: %s",
2148 filetempl, strerror(err));
2149
2150 errno = err;
2151 goto out;
2152 }
2153 }
2154 else
2155 {
2156
2157 ret = fdopen(fd, "w");
2158 if (NULL==ret)
2159 {
2160 err = errno;
2161
2162 NDRX_LOG(log_error, "Failed to fdopen: %s", strerror(err));
2163 close(fd);
2164 errno = err;
2165 goto out;
2166 }
2167 break;
2168 }
2169 }
2170
2171 if (NULL==ret)
2172 {
2173 NDRX_LOG(log_error, "%d attempts exceeded, no free file found: [%s] (last templ)",
2174 NDRX_TEMP_ATTEMPTS, filetempl);
2175 errno = EEXIST;
2176 }
2177
2178 out:
2179 return ret;
2180 }
2181
2182
2183
2184
2185
2186
2187 expublic int ndrx_is_numberic(char *str)
2188 {
2189 while(*str != EXEOS)
2190 {
2191 if(*str < '0' || *str > '9')
2192 {
2193 return EXFALSE;
2194 }
2195
2196 str++;
2197 }
2198
2199 return EXTRUE;
2200 }
2201
2202
2203
2204
2205
2206
2207 expublic void ndrx_read_silent(char *buf, size_t bufsz)
2208 {
2209 static struct termios old_terminal;
2210 static struct termios new_terminal;
2211
2212
2213 tcgetattr(STDIN_FILENO, &old_terminal);
2214
2215
2216 new_terminal = old_terminal;
2217 new_terminal.c_lflag &= ~(ECHO);
2218
2219
2220 tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal);
2221
2222 ndrx_fgets_stdin_strip(buf, bufsz);
2223
2224
2225 tcsetattr(STDIN_FILENO, TCSANOW, &old_terminal);
2226 }
2227
2228
2229
2230
2231
2232
2233
2234
2235 expublic int ndrx_get_password(char *msg, char *buf, size_t bufsz)
2236 {
2237 char *tmp_buf = NDRX_MALLOC(bufsz);
2238 int ret = EXSUCCEED;
2239
2240 if (NULL==tmp_buf)
2241 {
2242 fprintf(stderr, "System error.\n");
2243 NDRX_LOG(log_error, "Failed to malloc: %s", strerror(errno));
2244 EXFAIL_OUT(ret);
2245 }
2246
2247 fprintf(stderr, "Enter %s: ", msg);
2248 ndrx_read_silent(tmp_buf, bufsz);
2249 fprintf(stderr, "\n");
2250
2251 fprintf(stderr, "Retype %s: ", msg);
2252 ndrx_read_silent(buf, bufsz);
2253 fprintf(stderr, "\n");
2254
2255 if (0!=strcmp(buf, tmp_buf))
2256 {
2257 fprintf(stderr, "Sorry, input do not match\n");
2258 EXFAIL_OUT(ret);
2259 }
2260
2261 out:
2262
2263 if (NULL!=tmp_buf)
2264 {
2265 NDRX_FREE(tmp_buf);
2266 }
2267
2268 return ret;
2269 }
2270
2271
2272
2273
2274
2275
2276 expublic void ndrx_timespec_plus(struct timespec *due, long ms)
2277 {
2278 due->tv_sec += (ms / 1000);
2279 due->tv_nsec += ((ms % 1000) * 1000000);
2280
2281 if (due->tv_nsec >= 1000000000)
2282 {
2283 due->tv_nsec -= 1000000000;
2284 due->tv_sec++;
2285 }
2286 else if (due->tv_nsec < 0)
2287 {
2288 due->tv_nsec += 1000000000;
2289 due->tv_sec--;
2290 }
2291 }
2292
2293
2294
2295
2296
2297
2298
2299
2300 expublic void ndrx_strcpy_safe_dst(char *dest, const char *src, size_t dst_size)
2301 {
2302 NDRX_STRCPY_SAFE_DST(dest, src, dst_size);
2303 }
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313 expublic void ndrx_strncpy_eos(char *dest, const char *src, size_t n, size_t dst_size)
2314 {
2315 NDRX_STRNCPY_EOS(dest, src, n, dst_size);
2316 }
2317
2318
2319
2320
2321
2322
2323
2324 expublic void ndrx_strcat_s(char *dest, size_t dst_size, const char *src)
2325 {
2326 NDRX_STRCAT_S(dest, dst_size, src);
2327
2328 }
2329
2330
2331
2332
2333
2334
2335
2336 expublic int ndrx_str_valid_cid(char *str, int max_len)
2337 {
2338 int i;
2339 int len = strlen(str);
2340
2341 if (len < 1 || len > max_len)
2342 {
2343 return EXFALSE;
2344 }
2345
2346 if (!((str[0] >= 'a' && str[0] <= 'z')
2347 || (str[0] >= 'A' && str[1] <= 'Z')
2348 || str[0] == '_'))
2349 {
2350 return EXFALSE;
2351 }
2352
2353 for (i = 1; i < len; i++)
2354 {
2355 if (!((str[i] >= 'a' && str[i] <= 'z')
2356 || (str[i] >= 'A' && str[i] <= 'Z')
2357 || (str[i] >= '0' && str[i] <= '9')
2358 || str[i] == '_'))
2359 return EXFALSE;
2360 }
2361
2362 return EXTRUE;
2363 }
2364
2365
2366
2367
2368
2369
2370
2371 expublic int ndrx_str_valid_alphanumeric_(char *str, int max_len)
2372 {
2373 int i;
2374 int len = strlen(str);
2375
2376 if (len < 1 || len > max_len)
2377 {
2378 return EXFALSE;
2379 }
2380
2381 for (i = 0; i < len; i++)
2382 {
2383 if (!((str[i] >= 'a' && str[i] <= 'z')
2384 || (str[i] >= 'A' && str[i] <= 'Z')
2385 || (str[i] >= '0' && str[i] <= '9')
2386 || str[i] == '_'))
2387 return EXFALSE;
2388 }
2389
2390 return EXTRUE;
2391 }
2392
2393
2394
2395
2396
2397
2398
2399
2400 expublic int ndrx_str_ends_with(char *str, char *needle)
2401 {
2402 int len_str = strlen(str);
2403 int len_needle = strlen(needle);
2404
2405 return (len_str >= len_needle) && (0 == strcmp(str + (len_str-len_needle), needle));
2406 }
2407
2408
2409
2410
2411
2412
2413 expublic long ndrx_file_age(char *fname)
2414 {
2415 struct stat buf;
2416 struct timespec tm;
2417 struct timespec tm2;
2418 long diff=EXFAIL;
2419
2420
2421 if (EXSUCCEED!=stat(fname, &buf))
2422 {
2423 NDRX_LOG(log_error, "Failed to stat [%s]: %s", fname, strerror(errno));
2424 goto out;
2425 }
2426
2427 clock_gettime(CLOCK_REALTIME, &tm);
2428
2429 #ifdef EX_OS_DARWIN
2430 diff = ndrx_timespec_get_delta(&tm, &buf.st_ctimespec) / 1000;
2431 #elif EX_OS_AIX
2432 tm2.tv_sec = buf.st_ctime;
2433 tm2.tv_nsec = buf.st_ctime_n;
2434 diff = ndrx_timespec_get_delta(&tm, &tm2) / 1000;
2435 #else
2436 diff = ndrx_timespec_get_delta(&tm, &buf.st_ctim) / 1000;
2437 #endif
2438
2439 out:
2440 return diff;
2441 }
2442
2443
2444
2445
2446
2447
2448
2449 expublic char *ndrx_file_read(char *fname, size_t *bytes_loaded)
2450 {
2451 FILE *f = NULL;
2452 char *buf=NULL;
2453 size_t cur_len =0;
2454 size_t nrread=0;
2455 size_t allocd=0;
2456 #define LOAD_STEP 1024
2457
2458 if (NULL==(f=NDRX_FOPEN(fname, "rb")))
2459 {
2460 _Nset_error_fmt(NENOENT, "Failed to open [%s] file: %s",
2461 fname, strerror(errno));
2462 goto out;
2463 }
2464
2465 do
2466 {
2467 cur_len+=nrread;
2468 if (allocd - cur_len < LOAD_STEP)
2469 {
2470 allocd+=LOAD_STEP;
2471 buf = NDRX_REALLOC(buf, allocd);
2472
2473 if (NULL==buf)
2474 {
2475 _Nset_error_fmt(NENOENT, "Failed to malloc %d bytes", (int)allocd);
2476 goto out;
2477 }
2478 }
2479 } while ((nrread = fread(&buf[cur_len], 1, LOAD_STEP, f)) >= 1);
2480
2481
2482 if (ferror(f))
2483 {
2484 _Nset_error_fmt(NESYSTEM, "Failed to read [%s] file: %s", fname, strerror(errno));
2485
2486 NDRX_FREE(buf);
2487 buf=NULL;
2488 goto out;
2489 }
2490
2491 *bytes_loaded=cur_len;
2492
2493 out:
2494
2495 if (NULL!=f)
2496 {
2497 NDRX_FCLOSE(f);
2498 }
2499
2500 return buf;
2501 }
2502
2503
2504
2505
2506
2507
2508
2509
2510 expublic int ndrx_chk_confirm(char *message, short is_confirmed)
2511 {
2512 int ret=EXFALSE;
2513 char buffer[128];
2514 int ans_ok = EXFALSE;
2515
2516 if (!is_confirmed)
2517 {
2518 if (isatty(0))
2519 {
2520 do
2521 {
2522
2523 fprintf(stderr, "%s [Y/N]: ", message);
2524 while (NULL==fgets(buffer, sizeof(buffer), stdin))
2525 {
2526
2527 }
2528
2529 if (toupper(buffer[0])=='Y' && '\n'==buffer[1] && EXEOS==buffer[2])
2530 {
2531 ret=EXTRUE;
2532 ans_ok=EXTRUE;
2533 }
2534 else if (toupper(buffer[0])=='N' && '\n'==buffer[1] && EXEOS==buffer[2])
2535 {
2536 ret=EXFALSE;
2537 ans_ok=EXTRUE;
2538 }
2539
2540 } while (!ans_ok);
2541 }
2542 else
2543 {
2544 NDRX_LOG(log_warn, "Not tty, assuming no for: %s", message);
2545 }
2546 }
2547 else
2548 {
2549 ret=EXTRUE;
2550 }
2551
2552 return ret;
2553 }
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564 expublic char *ndrx_str_fmtesc(char *dst, size_t dstsz, char *src)
2565 {
2566 int i, j=0, len = strlen(src);
2567
2568 for (i=0; i<=len; i++)
2569 {
2570 if (src[i]!='%' && j<dstsz-1)
2571 {
2572 dst[j]=src[i];
2573 j++;
2574 }
2575 else if (src[i]=='%' && j<dstsz-2)
2576 {
2577 dst[j]='%';
2578 j++;
2579 dst[j]='%';
2580 j++;
2581 }
2582 else
2583 {
2584
2585 dst[j]=EXEOS;
2586 break;
2587 }
2588 }
2589
2590 return dst;
2591 }
2592
2593
2594
2595
2596
2597 expublic int ndrx_rand(void)
2598 {
2599 NSTD_TLS_ENTRY;
2600
2601 if (!G_nstd_tls->rand_init)
2602 {
2603 ndrx_rand_seedset(&G_nstd_tls->rand_seed);
2604 G_nstd_tls->rand_init=EXTRUE;
2605 }
2606
2607 return rand_r(&G_nstd_tls->rand_seed);
2608 }
2609
2610
2611
2612
2613 expublic int ndrx_realtime_get(struct timespec *tp)
2614 {
2615 int ret = EXSUCCEED;
2616 #if 0
2617 clockid_t clk_id=CLOCK_REALTIME;
2618
2619 #ifdef EX_OS_LINUX
2620 clk_id=CLOCK_BOOTTIME;
2621 #endif
2622
2623 if (EXSUCCEED!=clock_gettime(clk_id, tp))
2624 #endif
2625 if (EXSUCCEED!=clock_gettime(CLOCK_MONOTONIC, tp))
2626 {
2627 ret = EXFAIL;
2628 }
2629
2630 return ret;
2631 }
2632
2633
2634
2635
2636
2637
2638 expublic char * ndrx_basename(char *path)
2639 {
2640 char *p = strrchr(path, '/');
2641
2642 if (NULL!=p)
2643 {
2644 return p+1;
2645 }
2646 else
2647 {
2648 return path;
2649 }
2650 }
2651
2652
2653
2654
2655
2656
2657
2658
2659 expublic void ndrx_volatile_strcpy(volatile char *dest, const volatile char *src, size_t dest_size)
2660 {
2661 size_t i;
2662
2663 for (i = 0; i < dest_size - 1 && src[i] != '\0'; ++i)
2664 {
2665 dest[i] = src[i];
2666 }
2667 dest[i] = '\0';
2668 }
2669
2670
2671
2672
2673
2674
2675
2676 expublic void ndrx_volatile_memcy(volatile char *dest, const volatile char *src, size_t n)
2677 {
2678 size_t i;
2679
2680 for (i=0; i<n; i++)
2681 {
2682 dest[i] = src[i];
2683 }
2684 }
2685
2686
2687
2688
2689
2690
2691
2692
2693 expublic int ndrx_file_lock(int fd, int do_wait)
2694 {
2695 int ret=EXSUCCEED;
2696 struct flock fl;
2697 int cmd=F_SETLK;
2698 API_ENTRY;
2699
2700 if (do_wait)
2701 {
2702 cmd=F_SETLKW;
2703 }
2704
2705 fl.l_type = F_WRLCK;
2706 fl.l_whence = SEEK_SET;
2707 fl.l_start = 0;
2708 fl.l_len = 0;
2709
2710 if (fcntl(fd, cmd, &fl) == -1)
2711 {
2712 int err=errno;
2713
2714 NDRX_LOG(log_error, "Error acquiring write lock (cmd=%d): %s",
2715 cmd, strerror(err));
2716
2717 if (EACCES==err || EAGAIN==err)
2718 {
2719 _Nset_error_fmt(NEBUSY, "failed to lock fd=%d, cmd=%d: %s", fd, cmd, strerror(err));
2720 }
2721 else
2722 {
2723 _Nset_error_fmt(NEUNIX, "failed to lock fd=%d, cmd=%d: %s", fd, cmd, strerror(err));
2724 }
2725
2726 EXFAIL_OUT(ret);
2727 }
2728
2729 NDRX_LOG(log_info, "fd %d locked for writing", fd);
2730
2731 out:
2732 return ret;
2733 }
2734
2735
2736
2737
2738
2739
2740 expublic int ndrx_file_unlock(int fd)
2741 {
2742 int ret = EXSUCCEED;
2743 struct flock fl;
2744 API_ENTRY;
2745
2746 fl.l_type = F_UNLCK;
2747 fl.l_whence = SEEK_SET;
2748 fl.l_start = 0;
2749 fl.l_len = 0;
2750
2751 if (EXFAIL==fcntl(fd, F_SETLK, &fl))
2752 {
2753 int err=errno;
2754 NDRX_LOG(log_error, "Error unlocking fd %d: %s",
2755 fd, strerror(err));
2756 _Nset_error_fmt(NEUNIX, "failed to unlock fd %d: %s", fd, strerror(err));
2757 EXFAIL_OUT(ret);
2758 }
2759 out:
2760 return ret;
2761 }
2762
2763
2764