The Assimilation Project
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
misc.c
Go to the documentation of this file.
1 
26 #define _GNU_SOURCE /* Needed for the F_[SG]ETPIPE_SZ definitions */
27 #include <projectcommon.h>
28 #include <stdlib.h>
29 #ifdef HAVE_UNISTD_H
30 # include <unistd.h>
31 #endif
32 #ifdef HAVE_SYS_UTSNAME_H
33 # include <sys/utsname.h>
34 #endif
35 #include <errno.h>
36 #include <string.h>
37 #include <sys/types.h>
38 #include <sys/stat.h>
39 #ifdef HAVE_FCNTL_H
40 # include <fcntl.h>
41 #endif
42 #ifndef WIN32
43 #include <sys/time.h>
44 #include <sys/resource.h>
45 #endif
46 #include <signal.h>
47 #include <misc.h>
48 
49 void assimilation_logger(const gchar *log_domain, GLogLevelFlags log_level,
50  const gchar *message, gpointer user_data);
51 const char * assim_syslogid = "assim";
52 FSTATIC void catch_pid_signal(int signum);
53 FSTATIC char * _shell_array_value(GSList* arrayvalue);
54 
56 #ifdef HAVE_UNAME
57 char *
58 proj_get_sysname(void)
59 {
60  struct utsname un; // System name, etc.
61  uname(&un);
62  return g_strdup(un.nodename);
63 }
64 #else
65 # ifdef HAVE_GETCOMPUTERNAME
66 char *
67 proj_get_sysname(void)
68 {
69 // BOOL WINAPI GetComputerName(_Out_ LPTSTR lpBuffer, _Inout_ LPDWORD lpnSize);
70 
71  char sn[MAX_COMPUTERNAME_LENGTH + 1];
72  DWORD snsize = sizeof(sn);
73  BOOL ret;
74 
75  ret = GetComputerName((LPSTR) sn, &snsize);
76  if(ret) {
77  return g_strdup(sn);
78  }
79 
80  return g_strdup("GetComputerName failed");
81 }
82 # else
83 # error "Need some function to get our computer name!"
84 # endif
85 #endif
86 
87 #ifndef WIN32
88 void
90 daemonize_me( gboolean stay_in_foreground,
91  const char* dirtorunin,
92  char* pidfile,
93  int minclosefd)
94 {
95  struct rlimit nofile_limits;
96  int nullperms[] = { O_RDONLY, O_WRONLY, O_WRONLY};
97  unsigned j;
98  getrlimit(RLIMIT_NOFILE, &nofile_limits);
99 
100  // g_warning("%s.%d: pid file is %s", __FUNCTION__, __LINE__, pidfile);
101  if (pidfile) {
102  if (are_we_already_running(pidfile, NULL) == PID_RUNNING) {
103  g_message("Already running.");
104  exit(0);
105  }
106  }
107 
108 #ifdef HAS_FORK
109  if (!stay_in_foreground) {
110  int k;
111  int childpid;
112 
113  (void)setsid();
114 
115 
116  for (k=0; k < 2; ++k) {
117  childpid = fork();
118  if (childpid < 0) {
119  g_error("Cannot fork [%s %d]", g_strerror(errno), errno);
120  exit(1);
121  }
122  if (childpid > 0) {
123  exit(0);
124  }
125  // Otherwise, we're the child.
126  // NOTE: probably can't drop a core in '/'
127  }
128  }
129 #endif
130  if (chdir(dirtorunin ? dirtorunin : "/" )) {
131  g_warning("%s.%d: Cannot change directory to [%s]", __FUNCTION__
132  , __LINE__, dirtorunin);
133  }
134  umask(027);
135  // Need to do this after forking and before closing our file descriptors
136  if (pidfile) {
137  if (are_we_already_running(pidfile, NULL) == PID_RUNNING) {
138  g_message("%s.%d: Already running.", __FUNCTION__, __LINE__);
139  exit(0);
140  }
141  // Exit if we can't create the requested pidfile
142  if (!create_pid_file(pidfile)) {
143  exit(1);
144  }
145  }
146  // Now make sure we don't have any funky file descriptors hanging around here...
147  if (!stay_in_foreground) {
148  int nullfd;
149  for (j=0; j < DIMOF(nullperms); ++j) {
150  close(j);
151  nullfd = open("/dev/null", nullperms[j]);
152 
153  if (nullfd < 0) {
154  g_error("%s.%d: Cannot open /dev/null(!)", __FUNCTION__, __LINE__);
155  exit(1);
156  }
157 
158  // Even more paranoia
159  if (nullfd != (int)j) {
160  if (dup2(nullfd, j) != (int)j) {
161  g_error("dup2(%d,%d) failed. World coming to end.", nullfd, j);
162  }
163  (void)close(nullfd);
164  }
165  }
166  }
167  if (minclosefd < (int)DIMOF(nullperms)) {
168  minclosefd = DIMOF(nullperms);
169  }
170  // A bit paranoid - but not so much as you might think...
171  for (j=minclosefd; j < nofile_limits.rlim_cur; ++j) {
172  close(j);
173  }
174 }
175 #else
176 void
177 daemonize_me( gboolean stay_in_foreground,
178  const char* dirtorunin,
179  const char* pidfile)
180 {
181  if (pidfile) {
182  if (are_we_already_running(pidfile, NULL) == PID_RUNNING) {
183  g_message("Already running.");
184  exit(0);
185  }
186  }
187  // Exit if we can't create the requested pidfile
188  if (!create_pid_file(pidfile)) {
189  exit(1);
190  }
191 }
192 #endif
193 
194 static gboolean syslog_opened = FALSE;
195 void
196 assimilation_openlog(const char* logname)
197 {
198 #ifndef WIN32
199  const int syslog_options = LOG_PID|LOG_NDELAY;
200  const int syslog_facility = LOG_DAEMON;
201 
202  if (!syslog_opened) {
203  g_log_set_handler (NULL, G_LOG_LEVEL_MASK | G_LOG_FLAG_FATAL | G_LOG_FLAG_RECURSION
204  , assimilation_logger, NULL);
205  }
206  assim_syslogid = strrchr(logname, '/');
207  if (assim_syslogid && assim_syslogid[1] != '\0') {
208  assim_syslogid += 1;
209  }else{
210  assim_syslogid = logname;
211  }
212  if (syslog_opened) {
213  closelog();
214  }
215  g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR);
216  openlog(assim_syslogid, syslog_options, syslog_facility);
217  syslog_opened = TRUE;
218 #endif
219 }
220 void
221 assimilation_logger(const gchar *log_domain,
222  GLogLevelFlags log_level,
223  const gchar *message,
224  gpointer ignored)
225 {
226 #ifdef WIN32
227 #define LOG_INFO 6
228 #define LOG_DEBUG 7
229 #define LOG_NOTICE 5
230 #define LOG_WARNING 4
231 #define LOG_ERR 3
232 #define LOG_CRIT 2
233 #define LOG_ALERT 1
234 #define LOG_EMERG 0
235 #endif
236  int syslogprio = LOG_INFO;
237  const char * prefix = "INFO:";
238 
239  (void)ignored;
240  if (!syslog_opened) {
242  }
243  if (log_level & G_LOG_LEVEL_DEBUG) {
244  syslogprio = LOG_DEBUG;
245  prefix = "DEBUG";
246  }
247  if (log_level & G_LOG_LEVEL_INFO) {
248  syslogprio = LOG_INFO;
249  prefix = "INFO";
250  }
251  if (log_level & G_LOG_LEVEL_MESSAGE) {
252  syslogprio = LOG_NOTICE;
253  prefix = "NOTICE";
254  }
255  if (log_level & G_LOG_LEVEL_WARNING) {
256  syslogprio = LOG_WARNING;
257  prefix = "WARN";
258  }
259  if (log_level & G_LOG_LEVEL_CRITICAL) {
260  syslogprio = LOG_ERR;
261  prefix = "ERROR";
262  }
263  if (log_level & G_LOG_LEVEL_ERROR) {
264  syslogprio = LOG_EMERG; // Or maybe LOG_CRIT ?
265  prefix = "EMERG";
266  }
267 #ifndef WIN32
268  syslog(syslogprio, "%s:%s %s", prefix
269  , log_domain == NULL ? "" : log_domain
270  , message);
271 #else
272  {
273  char msg[256];
274  g_snprintf(msg, sizeof(msg), "%s: %s:%s %s\n",assim_syslogid, prefix
275  , log_domain == NULL ? "" : log_domain
276  , message);
277  OutputDebugString((LPCSTR) msg);
278  }
279 #endif
280  fprintf(stderr, "%s: %s:%s %s\n", assim_syslogid, prefix
281  , log_domain == NULL ? "" : log_domain
282  , message);
283 }
284 
285 #ifdef WIN32
286 #define SEP '\\'
287 //@todo: these will be replaced when windows functionality cathes up
288 #define PROCSELFEXE "/"
289 #define PROCOTHEREXE "/"
290 #else
291 #define SEP '/'
292 #define PROCSELFEXE "/proc/self/exe"
293 #define PROCOTHEREXE "/proc/%d/exe"
294 #endif
295 #define MAXPIDLEN 16
296 #define MAXPATH 256
297 
298 static gboolean created_pid_file = FALSE;
299 
302 are_we_already_running( const char * pidfile
303 , int* pidarg)
304 {
305  char * pidcontents; // Contents of the pid file
306  int pid; // Pid from the pid file
307  char* ourexepath; // Pathname of our executable
308  char* ourexecmd; // command name of our executable
309  char* pidexepath; // Pathname of the 'pid' executable
310  char* pidexecmd; // command name the 'pid' executable
311 #ifdef WIN32
312  char w_ourexepath[MAXPATH];
313  int nSize = MAXPATH-1, ret;
314 #endif
315  char pidexename[sizeof(PROCOTHEREXE)+16]; // Name of /proc entry for 'pid'
316 
317  //g_debug("%s.%d: PID file path [%s]", __FUNCTION__, __LINE__, pidfile);
318  if (pidarg) {
319  *pidarg = 0;
320  }
321 
322  // Does the pid file exist?
323  if (!g_file_test(pidfile, G_FILE_TEST_IS_REGULAR)) {
324  //g_debug("%s.%d: PID file [%s] does not exist", __FUNCTION__, __LINE__, pidfile);
325  return PID_NOTRUNNING;
326  }
327  // Can we read it?
328  if (!g_file_get_contents(pidfile, &pidcontents, NULL, NULL)) {
329  //g_debug("%s.%d: PID file [%s] cannot be read", __FUNCTION__, __LINE__, pidfile);
330  return PID_NOTRUNNING;
331  }
332  // We assume it's passably well-formed...
333  pid = atoi(pidcontents);
334  g_free(pidcontents); pidcontents = NULL;
335  // Is it a legitimate pid value?
336  if (pid < 2) {
337  //g_debug("%s.%d: PID file [%s] contains pid %d", __FUNCTION__, __LINE__, pidfile, pid);
338  return PID_NOTRUNNING;
339  }
340  if (pidarg) {
341  *pidarg = pid;
342  }
343  // Is it still running?
344 #ifdef WIN32
345  if(TerminateProcess((void *)pid, 0) == 0)
346 #else
347  if (kill(pid, 0) < 0 && errno != EPERM)
348 #endif
349  {
350  //g_debug("%s.%d: PID %d is not running", __FUNCTION__, __LINE__, pid);
351  return PID_DEAD;
352  }
353  // Now let's see if it's "us" - our process
354  // That is, is it the same executable as we are?
355 
356  // So, what is the pathname of our executable?
357 #ifndef WIN32
358  ourexepath = g_file_read_link(PROCSELFEXE, NULL);
359 #else
360  ret = GetModuleFileName(NULL, w_ourexepath, nSize);
361  if(ret == 0) {
362  //g_debug("%s.%d: GetModuleFileName failed %d", __FUNCTION__, __LINE__, GetLastError());
363  return(PID_DEAD);
364  }
365  ourexepath = g_strdup(w_ourexepath);
366 #endif
367  if (NULL == ourexepath) {
368  return PID_RUNNING;
369  }
370  if (strrchr(ourexepath, SEP) != NULL) {
371  ourexecmd = strrchr(ourexepath, SEP)+1;
372  }else{
373  ourexecmd = ourexepath;
374  }
375  g_snprintf(pidexename, sizeof(pidexename), PROCOTHEREXE, pid);
376 
377  // What is the pathname of the executable that holds the pid lock?
378  pidexepath = g_file_read_link(pidexename, NULL);
379  if (pidexepath == NULL) {
380  g_free(ourexepath); ourexepath = NULL;
381  return (errno != EPERM ? PID_NOTUS : PID_RUNNING);
382  }
383  if (strrchr(pidexepath, SEP) != NULL) {
384  pidexecmd = strrchr(pidexepath, SEP)+1;
385  }else{
386  pidexecmd = pidexepath;
387  }
388  // Is it the same executable as we are?
389  if (strcmp(ourexecmd, pidexecmd) == 0) {
390  //g_debug("%s.%d: Link %s is the same as %s", __FUNCTION__, __LINE__, ourexepath
391  //, pidexepath);
392  g_free(ourexepath); ourexepath = NULL;
393  g_free(pidexepath); pidexepath = NULL;
394  return PID_RUNNING;
395  }
396  //g_debug("%s.%d: Link %s is NOT the same as %s", __FUNCTION__, __LINE__, ourexecmd
397  //, pidexecmd);
398  g_free(ourexepath); ourexepath = NULL;
399  g_free(pidexepath); pidexepath = NULL;
400  return PID_NOTUS;
401 }
402 
404 gboolean
405 create_pid_file(const char * pidfile)
406 {
407  char pidbuf[16];
408  GError* errptr = NULL;
409  PidRunningStat pstat;
410 
411 #if _MSC_VER
412 WINIMPORT
413 __out
414 void *
415 __stdcall
416 GetCurrentProcess();
417 #define GETPID GetCurrentProcessId()
418 #else
419 #define GETPID getpid()
420 #endif
421  //g_debug("%s.%d: Creating pid file %s for pid %d", __FUNCTION__, __LINE__, pidfile, GETPID);
422  pstat = are_we_already_running(pidfile, NULL);
423  if (PID_RUNNING == pstat) {
424  return FALSE;
425  }
426  g_snprintf(pidbuf, sizeof(pidbuf), "%6d\n", GETPID);
427  if (pstat == PID_DEAD || pstat == PID_NOTUS) {
428  //g_debug("%s.%d: Unlinking dead pid file %s", __FUNCTION__, __LINE__, pidfile);
429  g_unlink(pidfile);
430  }
431 
432  if (g_file_set_contents(pidfile, pidbuf, strlen(pidbuf), &errptr)) {
433  //g_debug("%s.%d: Successfully set file %s to content [%s]"
434  //, __FUNCTION__, __LINE__, pidfile, pidbuf);
435 #ifndef WIN32
436  if (chmod(pidfile, 0644) < 0) {
437  g_warning("%s.%d: Could not chmod pid file %s to 0644", __FUNCTION__, __LINE__
438  , pidfile);
439  }
440 #endif
441  created_pid_file = TRUE;
442  return TRUE;
443  }
444  g_critical("%s.%d: Cannot create pid file [%s]. Reason: %s"
445  , __FUNCTION__, __LINE__, pidfile, errptr->message);
446  fprintf(stderr, "%s.%d: Cannot create pid file [%s]. Reason: %s\n"
447  , __FUNCTION__, __LINE__, pidfile, errptr->message);
448  return FALSE;
449 }
451 char *
453  char *p_pidfile;
454 #ifndef WIN32
455  p_pidfile = g_build_filename(STD_PID_DIR, procname, NULL);
456 #else
457  const char * const *dirs = g_get_system_config_dirs();
458  p_pidfile = g_build_filename(dirs[0], procname, NULL);
459 #endif
460  //g_debug("%s.%d: pidfile = %s", __FUNCTION__, __LINE__, p_pidfile);
461  return(p_pidfile);
462 }
464 void
465 remove_pid_file(const char * pidfile)
466 {
467  if (created_pid_file) {
468  g_unlink(pidfile);
469  }
470 }
471 
473 int
474 kill_pid_service(const char * pidfile, int signal)
475 {
476  int service_pid = 0;
477  PidRunningStat pidstat;
478 
479  pidstat = are_we_already_running(pidfile, &service_pid);
480  if (pidstat == PID_RUNNING) {
481 #ifndef WIN32
482  return kill((pid_t)service_pid, signal);
483 #else
484  if(TerminateProcess((HANDLE) service_pid, signal) != 0) {
485  g_unlink(pidfile);
486  return(-1);
487  }
488 #endif
489  }
490  g_unlink(pidfile); // No harm in removing it...
491  return 0;
492 }
493 
494 static const char * saved_pidfile = NULL;
496 void
497 rmpid_and_exit_on_signal(const char * pidfile, int signal_in)
498 {
499 #ifndef WIN32
500  struct sigaction sigact;
501 #endif
502 
503  if (pidfile != NULL) {
504  saved_pidfile = pidfile;
505  }
506 #ifndef WIN32
507  memset(&sigact, 0, sizeof(sigact));
508  sigact.sa_handler = catch_pid_signal;
509  sigaction(signal_in, &sigact, NULL);
510 #else
511  signal(signal_in, catch_pid_signal);
512 #endif
513 }
514 FSTATIC void
515 catch_pid_signal(int unused_signum)
516 {
517  (void)unused_signum;
518  g_unlink(saved_pidfile);
519  exit(0);
520 }
521 
523 guint
525 {
526  // These exit codes from the Linux Standard Base
527  // http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html
528  switch (stat) {
529  case PID_NOTRUNNING:
530  return 3; // LSB: program is not running`
531 
532  case PID_DEAD: /*FALLTHROUGH*/
533  case PID_NOTUS: // This could be an excessively anal retentive check...
534  return 1; // LSB: program is dead and /var/run/pid exists
535 
536  case PID_RUNNING:
537  return 0; // LSB: program is running
538 
539  default: /*FALLTHROUGH*/
540  break;
541  }
542  return 4; // LSB: program or service status is unknown
543 }
544 
546 WINEXPORT gchar **
547 assim_merge_environ(const gchar * const* env
548 , ConfigContext* update)
549 {
550  int j;
551  int initenvcount;
552  int updatecount = 0;
553  gchar** result;
554  int resultelem = 0;
555  gchar** newenv = NULL;
556 
557  if (NULL == env) {
558  // The result of g_get_environ() has to be freed later...
559  // Store malloced copy in 'newenv' so that 'env' parameter can be const...
560  newenv = g_get_environ();
561  env = (const gchar* const*) newenv;
562  }
563 
564  for (initenvcount = 0; env[initenvcount]; ++initenvcount) {
565  ; /* Nothing - just count */
566  }
567  if (update) {
568  updatecount = update->keycount(update);
569  }
570 
571  // This is the worst case for the size needed...
572  result = (gchar**) g_malloc((updatecount+initenvcount+1)* sizeof(gchar*));
573 
574  if (update) {
575  GSList* updatekeys = NULL;
576  GSList* thiskeylist;
577 
578 
579  updatekeys = update->keys(update);
580 
581  // Put all our update keys in first...
582  for (thiskeylist = updatekeys; thiskeylist; thiskeylist=thiskeylist->next) {
583  char * thiskey = (char *)thiskeylist->data;
584  enum ConfigValType vtype= update->gettype(update, thiskey);
585  GString * gsvalue = g_string_new("");
586 
587  g_string_printf(gsvalue, "%s=", thiskey);
588 
589  switch (vtype) {
590  case CFG_BOOL:
591  // Do we want true/false -- or 1/0 ??
592  g_string_append(gsvalue, update->getbool(update, thiskey) ? "true" : "false");
593  break;
594 
595  case CFG_INT64:
596  g_string_append_printf(gsvalue, FMT_64BIT"d", update->getint(update,thiskey));
597  break;
598 
599  case CFG_STRING:
600  g_string_append(gsvalue, update->getstring(update, thiskey));
601  break;
602  case CFG_NETADDR: {
603  NetAddr* addr = update->getaddr(update,thiskey);
604  char * s = addr->baseclass.toString(&addr->baseclass);
605  g_string_append(gsvalue, s);
606  g_free(s);
607  // No need to unref 'addr' - it's not a copy
608  break;
609  }
610  case CFG_ARRAY:
611  g_string_append(gsvalue, _shell_array_value(
612  ( update->getarray(update,thiskey))));
613  break;
614  default:
615  g_string_free(gsvalue, TRUE);
616  gsvalue = NULL;
617  thiskeylist->data = thiskey = NULL;
618  continue;
619  }
620  result[resultelem] = g_string_free(gsvalue, FALSE);
621  gsvalue = NULL;
622  ++resultelem;
623  // The keys in the key list are NOT copies. Don't free them!!
624  // g_free(thiskey);
625  thiskeylist->data = thiskey = NULL;
626  }
627  // Done with 'updatekeys'
628  g_slist_free(updatekeys);
629  updatekeys = NULL;
630 
631  }
632 
633  // Now, add all the env vars not overridden by 'update'
634  for (j = 0; env[j]; ++j) {
635  char * envname;
636  char * eqpos;
637  eqpos = strchr(env[j], '=');
638  if (NULL == eqpos || eqpos == env[j]) {
639  continue;
640  }
641  envname = g_strndup(env[j], eqpos - env[j]);
642  // Make sure it isn't overridden before including it...
643  if (NULL == update || (update->gettype(update, envname) == CFG_EEXIST)) {
644  result[resultelem] = g_strdup(env[j]);
645  ++resultelem;
646  }
647  g_free(envname);
648  }
649  result[resultelem] = NULL;
650 
651  if (newenv) {
652  g_strfreev(newenv);
653  }
654  newenv = NULL;
655  env = NULL;
656  return result;
657 }
658 
660 FSTATIC char *
661 _shell_array_value(GSList* arrayvalue)
662 {
663  GString* gsvalue = g_string_new("");
664  const char * space = "";
665  GSList* thiselem;
666 
667  for (thiselem = arrayvalue; thiselem; thiselem=thiselem->next) {
668  ConfigValue* elem = CASTTOCLASS(ConfigValue, thiselem->data);
669  if (elem->valtype != CFG_STRING) {
670  continue;
671  }
672  g_string_append_printf(gsvalue, "%s%s", space, elem->u.strvalue);
673  space = " ";
674  }
675  return g_string_free(gsvalue, FALSE);
676 }
677 
679 WINEXPORT void
680 assim_free_environ(gchar ** env)
681 {
682  g_strfreev(env);
683 }
684 
685 
687 WINEXPORT gsize
688 setpipebuf(int fd, gsize bufsize)
689 {
690 #ifdef F_SETPIPE_SZ
691 # define SYS_MAX_PIPE_SIZE "/proc/sys/fs/pipe-max-size"
692  if (fcntl(fd, F_SETPIPE_SZ, (int)bufsize) < 0) {
693  int sysfsfd = open(SYS_MAX_PIPE_SIZE, O_WRONLY);
694  if (sysfsfd >= 0) {
695  char sizestr[32];
696  int rc;
697  snprintf(sizestr, sizeof(sizestr), "%zd\n", (size_t)bufsize);
698  // Try our best, and do the best we can...
699  rc = write(sysfsfd, sizestr, sizeof(sizestr)-1);
700  (void)rc;
701  (void)close(sysfsfd);
702  (void)fcntl(fd, F_SETPIPE_SZ, (int)bufsize);
703  }
704  }
705 #else
706  (void)bufsize;
707 #endif
708  // We've done the best we know how above, now check to see how it worked..
709  return getpipebuf(fd);
710 }
711 
713 WINEXPORT gsize
714 getpipebuf(int fd)
715 {
716 #ifdef F_GETPIPE_SZ
717  return (gsize)fcntl(fd, F_GETPIPE_SZ);
718 #else
719  (void)fd;
720  return 4096;
721 #endif
722 }
723 WINEXPORT void
724 assim_g_notify_unref(gpointer assimobj)
725 {
726  AssimObj* obj = CASTTOCLASS(AssimObj, assimobj);
727  obj->unref(obj);
728 }
Definition: misc.h:39
WINEXPORT gsize setpipebuf(int fd, gsize bufsize)
Set the buffer size of a pipe (if possible)
Definition: misc.c:688
const char *(* getstring)(const ConfigContext *, const char *name)
Get String value.
Definition: configcontext.h:86
enum ConfigValType valtype
Definition: configcontext.h:59
Defines miscellaneous interfaces.
char * proj_get_sysname(void)
Return a malloced string of the system name.
char * strvalue
Definition: configcontext.h:64
const char * procname
process name
Definition: nanoprobe.c:111
FSTATIC char * _shell_array_value(GSList *arrayvalue)
Return the value of an array in a shell-compatible way - to put in an environment variable...
Definition: misc.c:661
AssimObj baseclass
Definition: netaddr.h:44
#define PROCSELFEXE
Definition: misc.c:292
#define WINEXPORT
Definition: projectcommon.h:45
#define FSTATIC
Definition: projectcommon.h:31
enum ConfigValType(* gettype)(const ConfigContext *, const char *)
Return type.
Definition: configcontext.h:99
gint64(* getint)(const ConfigContext *, const char *name)
Get integer value.
Definition: configcontext.h:74
int signal
Definition: childprocess.c:238
gboolean create_pid_file(const char *pidfile)
Create a pid file for the current process.
Definition: misc.c:405
NetAddr *(* getaddr)(const ConfigContext *, const char *name)
Get NetAddr value.
Definition: configcontext.h:92
union _ConfigValue::@2 u
#define __FUNCTION__
GSList *(* getarray)(const ConfigContext *, const char *name)
Get array value.
Definition: configcontext.h:84
WINEXPORT void assim_g_notify_unref(gpointer assimobj)
Unref for glib notify.
Definition: misc.c:724
FSTATIC void catch_pid_signal(int signum)
Should be overridden with the name to appear in the logs.
Definition: misc.c:515
void assimilation_openlog(const char *logname)
Open logs in our style (syslog)
Definition: misc.c:196
void assimilation_logger(const gchar *log_domain, GLogLevelFlags log_level, const gchar *message, gpointer user_data)
Definition: misc.c:221
const char * assim_syslogid
Definition: misc.c:51
#define FMT_64BIT
Format designator for a 64 bit integer.
Definition: projectcommon.h:32
#define STD_PID_DIR
Definition: misc.h:32
gboolean(* getbool)(const ConfigContext *, const char *name)
Get boolean value.
Definition: configcontext.h:77
GSList *(* keys)(const ConfigContext *)
Return list of keys.
Project common header file.
#define DIMOF(a)
Definition: lldp_min.c:30
int kill_pid_service(const char *pidfile, int signal)
kill the service that goes with our current pid file - return negative iff pidfile pid is running and...
Definition: misc.c:474
#define GETPID
Definition: misc.h:40
PidRunningStat
Status of pid file and/or running processes referred to by it - analogous to "service status"...
Definition: misc.h:37
guint pidrunningstat_to_status(PidRunningStat stat)
Convert PidRunningStat to an exit code for status.
Definition: misc.c:524
void rmpid_and_exit_on_signal(const char *pidfile, int signal_in)
Remove PID file and exit when a signal is received.
Definition: misc.c:497
ConfigValType
Definition: configcontext.h:44
void remove_pid_file(const char *pidfile)
Remove the pid file that goes with this service iff we created one during this invocation.
Definition: misc.c:465
#define g_unlink(arg)
Definition: projectcommon.h:61
#define SEP
Definition: misc.c:291
The NetAddr class class represents a general network address - whether IP, MAC, or any other type of ...
Definition: netaddr.h:43
WINEXPORT gchar ** assim_merge_environ(const gchar *const *env, ConfigContext *update)
Merge ConfigContext into possibly NULL current environment, returning a new environment.
Definition: misc.c:547
gchar ** g_get_environ(void)
char * get_default_pid_fileName(const char *procname)
get default pid file name
Definition: misc.c:452
gchar *(* toString)(gconstpointer)
Produce malloc-ed string representation.
Definition: assimobj.h:58
guint(* keycount)(const ConfigContext *)
Return number of keys in object.
#define PROCOTHEREXE
Definition: misc.c:293
PidRunningStat are_we_already_running(const char *pidfile, int *pidarg)
See if the pid file suggests we are already running or not.
Definition: misc.c:302
WINEXPORT void assim_free_environ(gchar **env)
Free the result of assim_merge_env.
Definition: misc.c:680
#define MAXPATH
Definition: misc.c:296
#define CASTTOCLASS(Cclass, obj)
Safely cast 'obj' to C-class 'class' - verifying that it was registerd as being of type class ...
Definition: proj_classes.h:66
void(* unref)(gpointer)
Decrement reference count.
Definition: assimobj.h:57
WINEXPORT gsize getpipebuf(int fd)
Return the buffer size of a pipe - if not possible return 4096 (a good guess)
Definition: misc.c:714
void daemonize_me(gboolean stay_in_foreground, const char *dirtorunin, char *pidfile, int minclosefd)
Function to get system name (uname -n in UNIX terms)
Definition: misc.c:90