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 #include <stdio.h>
0037 #include <stdlib.h>
0038 #include <time.h>
0039
0040 #include <unistd.h>
0041 #include <stdarg.h>
0042 #include <ctype.h>
0043 #include <memory.h>
0044 #include <errno.h>
0045 #include <signal.h>
0046 #include <limits.h>
0047 #include <pthread.h>
0048 #include <string.h>
0049 #include <dirent.h>
0050
0051 #include <ndrstandard.h>
0052 #include <ndebug.h>
0053 #include <nstdutil.h>
0054 #include <limits.h>
0055 #include <exhash.h>
0056 #include <sys_unix.h>
0057
0058 #include <utlist.h>
0059 #include <pwd.h>
0060 #include <regex.h>
0061
0062 #include "userlog.h"
0063 #include "exregex.h"
0064 #include "exparson.h"
0065 #include "atmi_int.h"
0066
0067
0068
0069
0070
0071
0072
0073
0074 #define MAX_ATFORKS 3
0075
0076
0077
0078
0079
0080
0081 #if defined(EX_OS_AIX) || defined(EX_OS_SUNOS)
0082 #define USE_STOCK_FORKING
0083 #endif
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 exprivate void (*M_prepare[MAX_ATFORKS])(void) = {NULL, NULL, NULL};
0094
0095 exprivate void (*M_parent[MAX_ATFORKS])(void) = {NULL, NULL, NULL};
0096
0097 exprivate void (*M_child[MAX_ATFORKS])(void) = {NULL, NULL, NULL};
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 expublic string_hash_t * ndrx_string_hash_add_cnt(string_hash_t **h, char *str)
0109 {
0110
0111 string_hash_t *el=NULL;
0112
0113 el = ndrx_string_hash_get(*h, str);
0114
0115 if (NULL!=el)
0116 {
0117 el->cnt++;
0118 }
0119 else
0120 {
0121 el = ndrx_string_hash_add(h, str);
0122 if (NULL!=el)
0123 {
0124 el->cnt=1;
0125 }
0126 }
0127
0128 return el;
0129 }
0130
0131
0132
0133
0134
0135
0136
0137 expublic string_hash_t * ndrx_string_hash_add(string_hash_t **h, char *str)
0138 {
0139 int ret = EXSUCCEED;
0140 string_hash_t * tmp = NDRX_CALLOC(1, sizeof(string_hash_t));
0141
0142 if (NULL==tmp)
0143 {
0144 #ifdef SYSCOMMON_ENABLE_DEBUG
0145 NDRX_LOG(log_error, "alloc of string_hash_t (%d) failed",
0146 sizeof(string_hash_t));
0147 #endif
0148 EXFAIL_OUT(ret);
0149 }
0150
0151 if (NULL==(tmp->str = strdup(str)))
0152 {
0153 #ifdef SYSCOMMON_ENABLE_DEBUG
0154 NDRX_LOG(log_error, "strdup() failed: %s", strerror(errno));
0155 #endif
0156 EXFAIL_OUT(ret);
0157 }
0158
0159
0160 EXHASH_ADD_KEYPTR( hh, (*h), tmp->str, strlen(tmp->str), tmp );
0161
0162
0163 out:
0164 if (EXSUCCEED==ret)
0165 {
0166 return tmp;
0167 }
0168 else
0169 {
0170 return NULL;
0171 }
0172 }
0173
0174
0175
0176
0177
0178
0179
0180 expublic string_hash_t * ndrx_string_hash_get(string_hash_t *h, char *str)
0181 {
0182 string_hash_t * r = NULL;
0183
0184 EXHASH_FIND_STR( h, str, r);
0185
0186 return r;
0187 }
0188
0189
0190
0191
0192
0193
0194 expublic void ndrx_string_hash_free(string_hash_t *h)
0195 {
0196 string_hash_t * r, *rt;
0197
0198 EXHASH_ITER(hh, h, r, rt)
0199 {
0200 EXHASH_DEL(h, r);
0201 NDRX_FREE(r->str);
0202 NDRX_FREE(r);
0203 }
0204 }
0205
0206
0207
0208
0209 expublic void ndrx_string_list_free(string_list_t* list)
0210 {
0211 string_list_t *elt, *tmp;
0212
0213 if (NULL!=list)
0214 {
0215 LL_FOREACH_SAFE(list,elt,tmp)
0216 {
0217 LL_DELETE(list,elt);
0218 if (NULL!=elt->qname)
0219 {
0220 NDRX_FREE(elt->qname);
0221 }
0222
0223 NDRX_FREE((char *)elt);
0224 }
0225 }
0226 }
0227
0228
0229
0230
0231
0232
0233
0234 expublic int ndrx_string_list_add(string_list_t**list, char *string)
0235 {
0236 int ret = EXSUCCEED;
0237 string_list_t* tmp = NULL;
0238
0239 if (NULL==(tmp = NDRX_CALLOC(1, sizeof(string_list_t))))
0240 {
0241 NDRX_LOG(log_error, "alloc of string_list_t (%d) failed",
0242 sizeof(string_list_t));
0243 EXFAIL_OUT(ret);
0244 }
0245
0246
0247 if (NULL==(tmp->qname = NDRX_STRDUP(string)))
0248 {
0249 NDRX_LOG(log_error, "Failed to strdup len (%d): %s",
0250 strlen(string)+1, strerror(errno));
0251 NDRX_FREE(tmp);
0252 EXFAIL_OUT(ret);
0253 }
0254
0255
0256 LL_APPEND(*list, tmp);
0257
0258 out:
0259 return ret;
0260 }
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 expublic int ndrx_string_list_splitadd(string_list_t**list, char *string, char *sep)
0271 {
0272 int ret = EXSUCCEED;
0273 string_list_t* tmp = NULL;
0274 char *temps = NULL;
0275 char *tag;
0276 char *value_ptr;
0277 char *tag_first;
0278 char *ent;
0279
0280 temps = NDRX_STRDUP(string);
0281 if (NULL==temps)
0282 {
0283 NDRX_LOG(log_error, "Failed to strdup: %s", strerror(errno));
0284 EXFAIL_OUT(ret);
0285 }
0286
0287 tag_first = temps;
0288
0289 NDRX_LOG(log_debug, "About token: [%s] by [%s]", tag_first, sep);
0290
0291 while ((tag = strtok_r(tag_first, sep, &value_ptr)))
0292 {
0293 if (NULL!=tag_first)
0294 {
0295 tag_first = NULL;
0296 }
0297
0298
0299 ent = ndrx_str_lstrip_ptr(tag, " \t");
0300
0301 ndrx_str_rstrip(ent, " \t");
0302
0303
0304 if (NULL==(tmp = NDRX_CALLOC(1, sizeof(string_list_t))))
0305 {
0306 NDRX_LOG(log_error, "calloc of string_list_t (%d) failed",
0307 sizeof(string_list_t));
0308 EXFAIL_OUT(ret);
0309 }
0310
0311 if (NULL==(tmp->qname = NDRX_STRDUP(ent)))
0312 {
0313 NDRX_LOG(log_error, "Failed to strdup len (%d): %s",
0314 strlen(ent)+1, strerror(errno));
0315 NDRX_FREE(tmp);
0316 EXFAIL_OUT(ret);
0317 }
0318
0319 NDRX_LOG(log_debug, "Adding [%s]", tmp->qname);
0320
0321 LL_APPEND(*list, tmp);
0322 }
0323
0324 out:
0325
0326 if (NULL!=temps)
0327 {
0328 NDRX_FREE(temps);
0329 }
0330
0331 return ret;
0332 }
0333
0334
0335
0336
0337
0338
0339
0340
0341 expublic string_list_t * ndrx_sys_ps_getchilds(pid_t ppid)
0342 {
0343
0344
0345
0346
0347
0348 char cmd[128];
0349 FILE *fp=NULL;
0350 string_list_t* ret = NULL;
0351 pid_t pid;
0352 char path[PATH_MAX];
0353 int is_error = EXFALSE;
0354
0355 #ifdef EX_OS_FREEBSD
0356
0357 NDRX_STRCPY_SAFE(cmd, "ps -wwaxo user,pid,ppid,%cpu,%mem,args");
0358 #elif EX_OS_SUNOS
0359 NDRX_STRCPY_SAFE(cmd, "ps -ef");
0360 #elif EX_OS_AIX
0361 NDRX_STRCPY_SAFE(cmd, "ps -ef");
0362 #else
0363 NDRX_STRCPY_SAFE(cmd, "ps -efww");
0364 #endif
0365
0366 fp = popen(cmd, "r");
0367
0368 if (fp == NULL)
0369 {
0370 NDRX_LOG(log_warn, "failed to run command [%s]: %s", cmd, strerror(errno));
0371 goto out;
0372 }
0373
0374 while (fgets(path, sizeof(path)-1, fp) != NULL)
0375 {
0376 if (EXSUCCEED==ndrx_proc_ppid_get_from_ps(path, &pid) && ppid == pid)
0377 {
0378 if (EXSUCCEED!=ndrx_string_list_add(&ret, path))
0379 {
0380 NDRX_LOG(log_error, "Failed to add [%s] to list of processes", path);
0381 is_error = EXTRUE;
0382 goto out;
0383 }
0384 }
0385 }
0386
0387 out:
0388
0389 if (fp!=NULL)
0390 {
0391 pclose(fp);
0392 }
0393
0394 if (is_error)
0395 {
0396 ndrx_string_list_free(ret);
0397 ret = NULL;
0398 }
0399
0400 return ret;
0401 }
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415 expublic string_list_t * ndrx_sys_ps_list(char *filter1, char *filter2,
0416 char *filter3, char *filter4, char *regex1)
0417 {
0418 FILE *fp=NULL;
0419 char cmd[128];
0420 char path[PATH_MAX];
0421 int ok;
0422 int i;
0423 string_list_t* tmp;
0424 string_list_t* ret = NULL;
0425 regex_t r1;
0426 int r1_alloc = EXFALSE;
0427 int is_error = EXFALSE;
0428
0429 #define MAX_FILTER 5
0430 char *filter[MAX_FILTER] = {filter1, filter2, filter3, filter4, regex1};
0431
0432 #ifdef EX_OS_FREEBSD
0433
0434 NDRX_STRCPY_SAFE(cmd, "ps -wwaxo user,pid,ppid,%cpu,%mem,args");
0435 #elif EX_OS_DARWIN
0436
0437 NDRX_STRCPY_SAFE(cmd, "ps -je");
0438 #elif EX_OS_SUNOS
0439 NDRX_STRCPY_SAFE(cmd, "ps -ef");
0440 #elif EX_OS_AIX
0441 NDRX_STRCPY_SAFE(cmd, "ps -ef");
0442 #else
0443 NDRX_STRCPY_SAFE(cmd, "ps -efww");
0444 #endif
0445
0446 if (EXEOS!=regex1[0])
0447 {
0448 if (EXSUCCEED!=ndrx_regcomp(&r1, regex1))
0449 {
0450 NDRX_LOG(log_error, "ndrx_sys_ps_list: Failed to compile regex1: [%s]", regex1);
0451 userlog("ndrx_sys_ps_list: Failed to compile regex1: [%s]", regex1);
0452 ret = NULL;
0453 goto out;
0454 }
0455
0456 r1_alloc = EXTRUE;
0457 }
0458
0459 #ifdef SYSCOMMON_ENABLE_DEBUG
0460 NDRX_LOG(log_debug, "Listing processes [%s] f1=[%s] f2=[%s] f3=[%s] f4=[%s] r1=[%s]",
0461 cmd, filter1, filter2, filter3, filter4, regex1);
0462 #endif
0463
0464
0465 fp = popen(cmd, "r");
0466 if (fp == NULL)
0467 {
0468 userlog("failed to run command [%s]: %s", cmd, strerror(errno));
0469 goto out;
0470 }
0471
0472
0473 while (fgets(path, sizeof(path)-1, fp) != NULL)
0474 {
0475
0476
0477
0478 ok = 0;
0479
0480 for (i = 0; i<MAX_FILTER; i++)
0481 {
0482
0483 if (EXEOS!=filter[i][0] && filter[i]==regex1
0484 && EXSUCCEED==ndrx_regexec(&r1, path))
0485 {
0486
0487 ok++;
0488 }
0489 else if (EXEOS!=filter[i][0] && strstr(path, filter[i]))
0490 {
0491
0492 ok++;
0493 }
0494 else if (EXEOS==filter[i][0])
0495 {
0496
0497 ok++;
0498 }
0499 else
0500 {
0501
0502 }
0503 }
0504
0505
0506
0507 if (MAX_FILTER==ok)
0508 {
0509
0510 ndrx_chomp(path);
0511 if (EXSUCCEED!=ndrx_string_list_add(&ret, path))
0512 {
0513 is_error = EXTRUE;
0514 goto out;
0515 }
0516 }
0517 }
0518
0519 out:
0520
0521 if (fp!=NULL)
0522 {
0523 pclose(fp);
0524 }
0525
0526 if (r1_alloc)
0527 {
0528 ndrx_regfree(&r1);
0529 }
0530
0531 if (is_error)
0532 {
0533 ndrx_string_list_free(ret);
0534 ret=NULL;
0535 }
0536
0537 return ret;
0538
0539 }
0540
0541
0542
0543
0544
0545
0546
0547
0548 expublic int ndrx_sys_ps_list2hash(string_list_t *plist, ndrx_intmap_t **hash)
0549 {
0550 string_list_t* elt = NULL;
0551 pid_t pid;
0552 pid_t ppid;
0553 int ret = EXSUCCEED;
0554
0555 LL_FOREACH(plist,elt)
0556 {
0557 if (EXSUCCEED==ndrx_proc_pid_get_from_ps(elt->qname, &pid) &&
0558 EXSUCCEED==ndrx_proc_ppid_get_from_ps(elt->qname, &ppid) &&
0559 0!=pid &&
0560 0!=ppid)
0561 {
0562 if (NULL==ndrx_intmap_add(hash, (int)pid, (int)ppid))
0563 {
0564 EXFAIL_OUT(ret);
0565 }
0566 }
0567
0568 }
0569
0570 out:
0571
0572 if (EXSUCCEED!=ret)
0573 {
0574 ndrx_intmap_remove (hash);
0575 }
0576
0577 return ret;
0578 }
0579
0580
0581
0582
0583
0584
0585
0586
0587
0588 expublic int ndrx_sys_ps_hash2parents(ndrx_intmap_t **pshash, int pid, ndrx_intmap_t **parents)
0589 {
0590 int ret = EXSUCCEED;
0591 ndrx_intmap_t *cur = ndrx_intmap_find (pshash, pid);
0592
0593 while (NULL!=cur)
0594 {
0595 if (NULL==ndrx_intmap_add (parents, cur->value, 0))
0596 {
0597 EXFAIL_OUT(ret);
0598 }
0599
0600
0601 cur = ndrx_intmap_find (pshash, cur->value);
0602 }
0603
0604 out:
0605 return ret;
0606 }
0607
0608
0609
0610
0611 expublic char *ndrx_sys_get_cur_username(void)
0612 {
0613 uid_t uid = geteuid();
0614 struct passwd *pw = getpwuid(uid);
0615 if (pw)
0616 {
0617 return pw->pw_name;
0618 }
0619
0620 return "";
0621 }
0622
0623
0624
0625
0626
0627
0628
0629 expublic int ndrx_sys_get_hostname(char *out_hostname, long out_bufsz)
0630 {
0631 int ret = EXSUCCEED;
0632
0633 if (EXSUCCEED!=gethostname(out_hostname, out_bufsz))
0634 {
0635 userlog("Failed to get hostname: %s", strerror(errno));
0636 EXFAIL_OUT(ret);
0637 }
0638
0639 out:
0640 return ret;
0641 }
0642
0643
0644
0645
0646 expublic string_list_t* ndrx_sys_folder_list(char *path, int *return_status)
0647 {
0648 string_list_t* ret = NULL;
0649 struct dirent **namelist;
0650 int n, i;
0651 string_list_t* tmp;
0652 int len;
0653
0654 *return_status = EXSUCCEED;
0655
0656 n = scandir(path, &namelist, 0, alphasort);
0657 if (n < 0)
0658 {
0659
0660 #ifdef SYSCOMMON_ENABLE_DEBUG
0661 NDRX_LOG(log_error, "Failed to open queue directory [%s]: %s",
0662 path, strerror(errno));
0663 #endif
0664 goto exit_fail;
0665 }
0666 else
0667 {
0668 for (i=0; i<n; i++)
0669 {
0670
0671 if (0==strcmp(namelist[i]->d_name, ".") ||
0672 0==strcmp(namelist[i]->d_name, ".."))
0673 {
0674 NDRX_FREE(namelist[i]);
0675 continue;
0676 }
0677
0678 len = 1 + strlen(namelist[i]->d_name) + 1 ;
0679
0680 if (NULL==(tmp = NDRX_CALLOC(1, sizeof(string_list_t))))
0681 {
0682
0683 #ifdef SYSCOMMON_ENABLE_DEBUG
0684 NDRX_LOG(log_error, "alloc of mq_list_t (%d) failed: %s",
0685 sizeof(string_list_t), strerror(errno));
0686 #endif
0687 goto exit_fail;
0688 }
0689
0690 if (NULL==(tmp->qname = NDRX_MALLOC(len)))
0691 {
0692
0693 #ifdef SYSCOMMON_ENABLE_DEBUG
0694 NDRX_LOG(log_error,"alloc of %d bytes failed: %s",
0695 len, strerror(errno));
0696 #endif
0697 NDRX_FREE(tmp);
0698 goto exit_fail;
0699 }
0700
0701
0702 strcpy(tmp->qname, "/");
0703 strcat(tmp->qname, namelist[i]->d_name);
0704
0705
0706 LL_APPEND(ret, tmp);
0707
0708 NDRX_FREE(namelist[i]);
0709 }
0710 NDRX_FREE(namelist);
0711 }
0712
0713 return ret;
0714
0715 exit_fail:
0716
0717 *return_status = EXFAIL;
0718
0719 if (NULL!=ret)
0720 {
0721 ndrx_string_list_free(ret);
0722 ret = NULL;
0723 }
0724
0725 return ret;
0726 }
0727
0728
0729
0730
0731
0732 expublic void ndrx_proc_kill_list(string_list_t *list)
0733 {
0734 string_list_t* elt = NULL;
0735 int signals[] = {SIGTERM, SIGKILL};
0736 int i;
0737 int max_signals = 2;
0738 int was_any = EXFALSE;
0739 pid_t pid;
0740 char *fn = "ndrx_proc_kill_list";
0741 NDRX_LOG(log_info, "%s enter-> %p", fn, list);
0742
0743 for (i=0; i<max_signals; i++)
0744 {
0745 LL_FOREACH(list,elt)
0746 {
0747 if (EXSUCCEED==ndrx_proc_pid_get_from_ps(elt->qname, &pid))
0748 {
0749 NDRX_LOG(log_error, "! killing sig=%d "
0750 "pid=[%d] (%s)", signals[i], pid, elt->qname);
0751
0752 if (EXSUCCEED!=kill(pid, signals[i]))
0753 {
0754 NDRX_LOG(log_error, "failed to kill with signal %d pid %d: %s",
0755 signals[i], pid, strerror(errno));
0756 }
0757 else
0758 {
0759 was_any = EXTRUE;
0760 }
0761 }
0762 }
0763
0764 if (was_any && i<max_signals-1)
0765 {
0766
0767 sleep(EX_KILL_SLEEP_SECS);
0768 }
0769
0770 }
0771
0772 }
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782 expublic int ndrx_proc_children_get_recursive(string_list_t**list, pid_t pid)
0783 {
0784 int ret = EXSUCCEED;
0785 string_list_t* elt = NULL;
0786 string_list_t* children = NULL;
0787
0788 char *fn = "ndrx_get_childproc_recursive";
0789 NDRX_LOG(log_info, "%s enter-> list=%p, pid=%d", fn, list, pid);
0790
0791 children = ndrx_sys_ps_getchilds(pid);
0792
0793 LL_FOREACH(children,elt)
0794 {
0795 if (EXSUCCEED==ndrx_proc_pid_get_from_ps(elt->qname, &pid))
0796 {
0797
0798 if (EXSUCCEED!=ndrx_proc_children_get_recursive(list, pid))
0799 {
0800 EXFAIL_OUT(ret);
0801 }
0802
0803 if (EXSUCCEED!=ndrx_string_list_add(list, elt->qname))
0804 {
0805 EXFAIL_OUT(ret);
0806 }
0807
0808 }
0809 }
0810
0811 out:
0812 ndrx_string_list_free(children);
0813 return ret;
0814 }
0815
0816
0817
0818
0819
0820
0821
0822 expublic int ndrx_proc_pid_get_from_ps(char *psout, pid_t *pid)
0823 {
0824 char tmp[PATH_MAX+1];
0825 char *token;
0826 int ret = EXSUCCEED;
0827
0828 NDRX_STRCPY_SAFE(tmp, psout);
0829
0830
0831 if (NULL==(token = strtok(tmp, "\t ")))
0832 {
0833 NDRX_LOG(log_error, "missing username in ps -ef output");
0834 EXFAIL_OUT(ret);
0835 }
0836
0837
0838 token = strtok(NULL, "\t ");
0839 if (NULL==token)
0840 {
0841 NDRX_LOG(log_error, "missing pid in ps -ef output");
0842 EXFAIL_OUT(ret);
0843 }
0844 else
0845 {
0846 *pid = atoi(token);
0847 #ifdef SYSCOMMON_ENABLE_DEBUG
0848 NDRX_LOG(log_debug, "ndrx_get_pid_from_ps: Got %d as pid of [%s]", *pid, psout);
0849 #endif
0850 }
0851
0852 out:
0853 return ret;
0854 }
0855
0856
0857
0858
0859
0860
0861
0862
0863 expublic int ndrx_proc_get_line(int line_no, char *cmd, char *buf, int bufsz)
0864 {
0865 int ret = EXSUCCEED;
0866 FILE *fp=NULL;
0867 int line = 0;
0868 NDRX_LOG(log_debug, "%s: About to run: [%s]", __func__, cmd);
0869
0870 fp = popen(cmd, "r");
0871 if (fp == NULL)
0872 {
0873 #ifdef SYSCOMMON_ENABLE_DEBUG
0874 NDRX_LOG(log_warn, "failed to run command [%s]: %s", cmd, strerror(errno));
0875 #endif
0876 EXFAIL_OUT(ret);
0877 }
0878
0879 while (fgets(buf, bufsz, fp) != NULL)
0880 {
0881 line ++;
0882
0883 if (line==line_no)
0884 {
0885 break;
0886 }
0887 }
0888
0889 out:
0890
0891
0892 if (fp!=NULL)
0893 {
0894 pclose(fp);
0895 }
0896
0897 if (line!=line_no)
0898 {
0899 NDRX_LOG(log_error, "Extract lines: %d, but requested: %d",
0900 line, line_no);
0901 ret=EXFAIL;
0902 }
0903
0904 if (EXSUCCEED==ret)
0905 {
0906 ndrx_chomp(buf);
0907 }
0908
0909 return ret;
0910 }
0911
0912
0913
0914
0915
0916
0917
0918 expublic int ndrx_proc_ppid_get_from_ps(char *psout, pid_t *ppid)
0919 {
0920 char tmp[PATH_MAX+1];
0921 char *token;
0922 int ret = EXSUCCEED;
0923
0924 NDRX_STRCPY_SAFE(tmp, psout);
0925
0926
0927 if (NULL==(token = strtok(tmp, "\t ")))
0928 {
0929 NDRX_LOG(log_error, "missing username in ps -ef output (1)");
0930 EXFAIL_OUT(ret);
0931 }
0932
0933
0934 token = strtok(NULL, "\t ");
0935 if (NULL==token)
0936 {
0937 NDRX_LOG(log_error, "missing pid in ps -ef output (2)");
0938 EXFAIL_OUT(ret);
0939 }
0940
0941
0942 token = strtok(NULL, "\t ");
0943 if (NULL==token)
0944 {
0945 NDRX_LOG(log_error, "missing pid in ps -ef output (3)");
0946 EXFAIL_OUT(ret);
0947 }
0948 else
0949 {
0950 *ppid = atoi(token);
0951 #ifdef SYSCOMMON_ENABLE_DEBUG
0952 NDRX_LOG(log_debug, "Got %d as parent pid of [%s]", *ppid, psout);
0953 #endif
0954 }
0955
0956 out:
0957 return ret;
0958 }
0959
0960
0961
0962
0963
0964
0965
0966
0967 expublic int ndrx_proc_get_infos(pid_t pid, ndrx_proc_info_t *p_infos)
0968 {
0969 int ret = EXSUCCEED;
0970 char cmd[128];
0971 char line[PATH_MAX+1];
0972 long meminfo[16];
0973 int toks;
0974
0975
0976
0977
0978
0979
0980
0981
0982
0983
0984
0985
0986
0987
0988
0989
0990
0991
0992 #ifdef EX_OS_AIX
0993 snprintf(cmd, sizeof(cmd), "ps v %d", pid);
0994
0995 if (EXSUCCEED!=ndrx_proc_get_line(2, cmd, line, sizeof(line)))
0996 {
0997 NDRX_LOG(log_error, "Failed to get rss infos from [%s]", cmd);
0998 EXFAIL_OUT(ret);
0999 }
1000
1001 NDRX_LOG(log_debug, "Parsing output: [%s]", line);
1002
1003 toks = ndrx_tokens_extract(line, "%ld", (void *)meminfo,
1004 sizeof(long), N_DIM(meminfo), 0, 15);
1005
1006 if (toks<7)
1007 {
1008 NDRX_LOG(log_error, "Invalid tokens, expected at least 7, got %d", toks);
1009 EXFAIL_OUT(ret);
1010 }
1011
1012 p_infos->rss = meminfo[6];
1013
1014 snprintf(cmd, sizeof(cmd), "ps -o vsz -p %d", pid);
1015
1016 if (EXSUCCEED!=ndrx_proc_get_line(2, cmd, line, sizeof(line)))
1017 {
1018 NDRX_LOG(log_error, "Failed to get rss infos from [%s]", cmd);
1019 EXFAIL_OUT(ret);
1020 }
1021
1022 NDRX_LOG(log_debug, "Parsing output: [%s]", line);
1023
1024 toks = ndrx_tokens_extract(line, "%ld", (void *)meminfo,
1025 sizeof(long), N_DIM(meminfo), 0, 15);
1026
1027 if (toks!=1)
1028 {
1029 NDRX_LOG(log_error, "Invalid tokens, expected at least 1, got %d", toks);
1030 EXFAIL_OUT(ret);
1031 }
1032
1033 p_infos->vsz = meminfo[0];
1034
1035 #else
1036
1037 snprintf(cmd, sizeof(cmd), "ps -o rss,vsz -p%d", pid);
1038
1039 if (EXSUCCEED!=ndrx_proc_get_line(2, cmd, line, sizeof(line)))
1040 {
1041 NDRX_LOG(log_error, "Failed to get rss/vsz infos from [%s]", cmd);
1042 EXFAIL_OUT(ret);
1043 }
1044
1045 NDRX_LOG(log_debug, "Parsing output: [%s]", line);
1046
1047 toks = ndrx_tokens_extract(line, "%ld", (void *)meminfo,
1048 sizeof(long), N_DIM(meminfo), 0, 15);
1049
1050 if (2!=toks)
1051 {
1052 NDRX_LOG(log_error, "Invalid tokens, expected 2, got %d", toks);
1053 EXFAIL_OUT(ret);
1054 }
1055
1056 p_infos->rss = meminfo[0];
1057 p_infos->vsz = meminfo[1];
1058
1059 #endif
1060
1061
1062 NDRX_LOG(log_info, "extracted rss=%ld vsz=%ld", p_infos->rss, p_infos->vsz);
1063
1064 out:
1065
1066 NDRX_LOG(log_debug, "%s: returns %d", __func__, ret);
1067
1068 return ret;
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080 expublic int ndrx_sys_cmdout_test(char *fmt, pid_t pid, regex_t *p_re)
1081 {
1082 char cmd[PATH_MAX];
1083 FILE *fp=NULL;
1084 char *buf = NULL;
1085 size_t n = PATH_MAX;
1086 int ret = EXSUCCEED;
1087
1088
1089
1090 NDRX_MALLOC_OUT(buf, n, char);
1091
1092 snprintf(cmd, sizeof(cmd), fmt, pid);
1093
1094 fp = popen(cmd, "r");
1095
1096 if (fp == NULL)
1097 {
1098 NDRX_LOG(log_warn, "failed to run command [%s]: %s", cmd, strerror(errno));
1099 goto out;
1100 }
1101
1102 while (EXFAIL!=ndrx_getline(&buf, &n, fp))
1103 {
1104
1105 if (EXSUCCEED==ndrx_regexec(p_re, buf))
1106 {
1107 NDRX_LOG(log_debug, "Matched env [%s] for pid %d", buf, (int)pid);
1108 ret=EXTRUE;
1109 goto out;
1110 }
1111 }
1112
1113 out:
1114
1115
1116 if (fp!=NULL)
1117 {
1118 pclose(fp);
1119 }
1120
1121 if (NULL!=buf)
1122 {
1123 NDRX_FREE(buf);
1124 }
1125
1126 return ret;
1127 }
1128
1129
1130
1131
1132 expublic void ndrx_sys_banner(void)
1133 {
1134 NDRX_BANNER("");
1135 }
1136
1137
1138
1139
1140 expublic void ndrx_atfork_prepare(void)
1141 {
1142
1143 #ifndef USE_STOCK_FORKING
1144 int i;
1145
1146 for (i=MAX_ATFORKS-1; i>=0; i--)
1147 {
1148 if (NULL!=M_prepare[i])
1149 {
1150 M_prepare[i]();
1151 }
1152 }
1153 #endif
1154 }
1155
1156
1157
1158
1159 expublic void ndrx_atfork_parent(void)
1160 {
1161 #ifndef USE_STOCK_FORKING
1162 int i;
1163 for (i=0; i<MAX_ATFORKS; i++)
1164 {
1165 if (NULL!=M_parent[i])
1166 {
1167 M_parent[i]();
1168 }
1169 }
1170 #endif
1171 }
1172
1173
1174
1175
1176 expublic void ndrx_atfork_child(void)
1177 {
1178 #ifndef USE_STOCK_FORKING
1179 int i;
1180
1181
1182 ndrx_dbg_pid_update();
1183
1184 for (i=0; i<MAX_ATFORKS; i++)
1185 {
1186 if (NULL!=M_child[i])
1187 {
1188 M_child[i]();
1189 }
1190 }
1191 #endif
1192 }
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205 expublic pid_t ndrx_fork(void)
1206 {
1207 pid_t ret;
1208 int err;
1209
1210 #ifdef USE_STOCK_FORKING
1211
1212 ret = fork();
1213 err = errno;
1214
1215
1216 if (0==ret)
1217 {
1218 ndrx_dbg_pid_update();
1219 }
1220
1221 return ret;
1222
1223 #else
1224
1225 ndrx_atfork_prepare();
1226
1227 ret = fork();
1228 err = errno;
1229
1230 if (0==ret)
1231 {
1232 ndrx_atfork_child();
1233 }
1234 else
1235 {
1236 ndrx_atfork_parent();
1237 }
1238
1239 errno = err;
1240
1241 return ret;
1242 #endif
1243 }
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253 expublic int ndrx_atfork(void (*prepare)(void), void (*parent)(void),
1254 void (*child)(void))
1255 {
1256 #ifdef USE_STOCK_FORKING
1257 return pthread_atfork(prepare, parent, child);
1258 #else
1259 int i=0;
1260 int ret = EXSUCCEED;
1261
1262 for (i=0;i<MAX_ATFORKS;i++)
1263 {
1264
1265
1266
1267 if (prepare==M_prepare[i] &&
1268 parent==M_parent[i] &&
1269 child==M_child[i]
1270 )
1271 {
1272
1273 goto out;
1274 }
1275
1276 if (NULL==M_prepare[i] &&
1277 NULL==M_parent[i] &&
1278 NULL==M_child[i]
1279 )
1280 {
1281 break;
1282 }
1283 }
1284
1285 if (i==MAX_ATFORKS)
1286 {
1287 errno=ENOMEM;
1288 EXFAIL_OUT(ret);
1289 }
1290
1291 M_prepare[i] = prepare;
1292 M_parent[i] = parent;
1293 M_child[i] = child;
1294
1295 out:
1296 return ret;
1297 #endif
1298 }
1299
1300
1301
1302
1303
1304
1305
1306 expublic int ndrx_sys_sysv_user_res(ndrx_growlist_t *list, int res_type)
1307 {
1308 char cmd[128];
1309 FILE *fp=NULL;
1310 char path[PATH_MAX];
1311 char linematchstr[PATH_MAX];
1312 int ret = EXSUCCEED;
1313 regex_t linematch;
1314 int linematch_comp = EXFALSE;
1315 int sig_set = EXFALSE;
1316 struct sigaction act;
1317
1318
1319 ndrx_growlist_init(list, 256, sizeof(mdrx_sysv_res_t));
1320
1321 if (NDRX_SV_RESTYPE_QUE == res_type)
1322 {
1323 NDRX_STRCPY_SAFE(cmd, "ipcs -q");
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373 }
1374 else if (NDRX_SV_RESTYPE_SEM == res_type)
1375 {
1376 NDRX_STRCPY_SAFE(cmd, "ipcs -s");
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388 }
1389 else if (NDRX_SV_RESTYPE_SHM == res_type)
1390 {
1391 NDRX_STRCPY_SAFE(cmd, "ipcs -m");
1392 }
1393 #ifdef EX_OS_LINUX
1394 snprintf(linematchstr, sizeof(linematchstr), "^0x[0-9a-fA-F]+\\s*[0-9]+\\s*%s\\s",
1395 ndrx_sys_get_cur_username());
1396 #else
1397 snprintf(linematchstr, sizeof(linematchstr), "^.[ \\t\\r\\n\\v\\f]+[0-9]+[ \\t\\r\\n\\v\\f]+[x0-9a-fA-F]*[ \\t\\r\\n\\v\\f]+.{11}[ \\t\\r\\n\\v\\f]+%s[ \\t\\r\\n\\v\\f]",
1398 ndrx_sys_get_cur_username());
1399 #endif
1400
1401 if (EXSUCCEED!=ndrx_regcomp(&linematch, linematchstr))
1402 {
1403 userlog("Failed to compile regexp: %s", linematch);
1404 NDRX_LOG(log_error, "Failed to compile regexp: %s", linematch);
1405 EXFAIL_OUT(ret);
1406 }
1407 else
1408 {
1409 linematch_comp = EXTRUE;
1410 }
1411
1412 NDRX_LOG(log_debug, "Listing resources by: [%s]", cmd);
1413
1414
1415 sigaction(SIGCHLD, NULL, &act);
1416 signal(SIGCHLD, SIG_DFL);
1417 sig_set=EXTRUE;
1418
1419 fp = popen(cmd, "r");
1420
1421 if (fp == NULL)
1422 {
1423 NDRX_LOG(log_warn, "failed to run command [%s]: %s", cmd, strerror(errno));
1424 goto out;
1425 }
1426
1427 while (fgets(path, sizeof(path)-1, fp) != NULL)
1428 {
1429 if (EXSUCCEED==ndrx_regexec(&linematch, path))
1430 {
1431 int id;
1432 int key;
1433 int len = strlen(path);
1434 mdrx_sysv_res_t res;
1435
1436 if (len > 0 && '\n' == path[len-1])
1437 {
1438 path[len-1]=EXEOS;
1439 }
1440
1441 NDRX_LOG(log_debug, "Line matched: [%s]", path);
1442
1443
1444 if (1!=ndrx_tokens_extract(path, "%d", &id, sizeof(id), 1, 1, 1))
1445 {
1446 NDRX_LOG(log_error, "Failed to extract resource id from [%s]!",
1447 path);
1448 userlog("Failed to extract resource id from [%s]!",
1449 path);
1450 EXFAIL_OUT(ret);
1451 }
1452
1453 NDRX_LOG(log_debug, "Extract id %u", id);
1454
1455 #if EX_OS_LINUX
1456
1457
1458 if (1!=ndrx_tokens_extract(path, "%x", &key, sizeof(key), 1, 0, 0))
1459 {
1460 NDRX_LOG(log_error, "Failed to extract resource key from [%s]!",
1461 path);
1462 userlog("Failed to extract resource key from [%s]!",
1463 path);
1464 EXFAIL_OUT(ret);
1465 }
1466
1467 NDRX_LOG(log_debug, "Extract key %u", key);
1468 #else
1469
1470
1471 if (1!=ndrx_tokens_extract(path, "%x", &key, sizeof(key), 1, 2, 2))
1472 {
1473 NDRX_LOG(log_error, "Failed to extract resource key from [%s]!",
1474 path);
1475 userlog("Failed to extract resource key from [%s]!",
1476 path);
1477 EXFAIL_OUT(ret);
1478 }
1479
1480 NDRX_LOG(log_debug, "Extract key %u", key);
1481
1482 #endif
1483
1484
1485 res.id=id;
1486 res.key = key;
1487 res.restyp=res_type;
1488
1489 if (EXSUCCEED!=ndrx_growlist_append(list, (void *)&res))
1490 {
1491 NDRX_LOG(log_error, "Failed to add %u/%u to growlist!", id, key);
1492 userlog("Failed to add %u/%u to growlist!", id, key);
1493 EXFAIL_OUT(ret);
1494 }
1495 }
1496 }
1497
1498 out:
1499
1500 if (fp!=NULL)
1501 {
1502 pclose(fp);
1503 }
1504
1505 if (sig_set)
1506 {
1507 sigaction(SIGCHLD, &act, NULL);
1508 }
1509
1510 if (EXSUCCEED!=ret)
1511 {
1512 ndrx_growlist_free(list);
1513 }
1514
1515 if (linematch_comp)
1516 {
1517 ndrx_regfree(&linematch);
1518 }
1519
1520 return ret;
1521 }
1522
1523