1 /* This file is part of GNU Pies.
2    Copyright (C) 2007-2020 Sergey Poznyakoff
3 
4    GNU Pies is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 3, or (at your option)
7    any later version.
8 
9    GNU Pies is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with GNU Pies.  If not, see <http://www.gnu.org/licenses/>. */
16 
17 #include "pies.h"
18 #include "prog.h"
19 
20 static struct prog *proghead, *progtail;
21 static struct grecs_symtab *conn_tab;
22 
23 struct prog *
progman_locate(const char * name)24 progman_locate (const char *name)
25 {
26   struct prog *prog;
27 
28   for (prog = proghead; prog; prog = prog->next)
29     if (strcmp (prog_tag (prog), name) == 0)
30       break;
31   return prog;
32 }
33 
34 int
progman_foreach(int (* filter)(struct prog *,void * data),void * data)35 progman_foreach (int (*filter) (struct prog *, void *data), void *data)
36 {
37   struct prog *prog;
38   int rc = 0;
39   for (prog = proghead; prog; )
40     {
41       struct prog *next = prog->next;
42       if ((rc = filter (prog, data)) != 0)
43 	break;
44       prog = next;
45     }
46   return rc;
47 }
48 
49 static struct prog *
prog_lookup_by_pid(pid_t pid)50 prog_lookup_by_pid (pid_t pid)
51 {
52   struct prog *prog;
53 
54   for (prog = proghead; prog; prog = prog->next)
55     if (prog->pid == pid)
56       break;
57   return prog;
58 }
59 
60 struct component *
progman_lookup_component(const char * tag)61 progman_lookup_component (const char *tag)
62 {
63   struct prog *prog;
64   for (prog = proghead; prog; prog = prog->next)
65     if (IS_COMPONENT (prog) && strcmp (prog_tag (prog), tag) == 0)
66       return prog->v.p.comp;
67   return NULL;
68 }
69 
70 struct component *
progman_lookup_tcpmux(const char * service,const char * master)71 progman_lookup_tcpmux (const char *service, const char *master)
72 {
73   struct prog *prog;
74   for (prog = proghead; prog; prog = prog->next)
75     if (IS_COMPONENT (prog)
76 	&& ISCF_TCPMUX (prog->v.p.comp->flags)
77 	&& prog->active
78 	&& prog->v.p.comp->service
79 	&& strcasecmp (prog->v.p.comp->service, service) == 0
80 	&& prog->v.p.comp->tcpmux
81 	&& strcmp (prog->v.p.comp->tcpmux, master) == 0)
82       return prog->v.p.comp;
83   return NULL;
84 }
85 
86 void prog_stop (struct prog *prog, int sig);
87 static int prog_start_prerequisites (struct prog *prog);
88 
89 char const *
prog_tag(struct prog const * prog)90 prog_tag (struct prog const *prog)
91 {
92   switch (prog->type)
93      {
94      case TYPE_COMPONENT:
95        return prog->v.p.comp->tag;
96 
97      case TYPE_COMMAND:
98        return prog->v.c.tag;
99      }
100    abort ();
101  }
102 
103 void
link_prog(struct prog * prog,struct prog * ref)104 link_prog (struct prog *prog, struct prog *ref)
105 {
106   if (!ref)
107     {
108       prog->prev = NULL;
109       prog->next = proghead;
110       if (proghead)
111 	proghead->prev = prog;
112       else
113 	progtail = prog;
114       proghead = prog;
115     }
116   else
117     {
118       struct prog *x;
119 
120       prog->prev = ref;
121       prog->next = ref->next;
122 
123       if ((x = ref->next))
124 	x->prev = prog;
125       else
126 	progtail = prog;
127 
128       ref->next = prog;
129     }
130 }
131 
132 void
unlink_prog(struct prog * pp)133 unlink_prog (struct prog *pp)
134 {
135   struct prog *x;
136 
137   if ((x = pp->prev))
138     x->next = pp->next;
139   else
140     proghead = pp->next;
141   if ((x = pp->next))
142     x->prev = pp->prev;
143   else
144     progtail = pp->prev;
145 }
146 
147 static inline void
prog_stop_redirectors(struct prog * p)148 prog_stop_redirectors (struct prog *p)
149 {
150   if (p->v.p.redir[RETR_OUT] != -1)
151     {
152       deregister_socket (p->v.p.redir[RETR_OUT]);
153       p->v.p.redir[RETR_OUT] = -1;
154     }
155   if (p->v.p.redir[RETR_ERR] != -1)
156     {
157       deregister_socket (p->v.p.redir[RETR_ERR]);
158       p->v.p.redir[RETR_ERR] = -1;
159     }
160 }
161 
162 void
destroy_prog(struct prog ** pp)163 destroy_prog (struct prog **pp)
164 {
165   struct prog *p = *pp;
166 
167   unlink_prog (p);
168   switch (p->type)
169     {
170     case TYPE_COMPONENT:
171       environ_free (p->v.p.env);
172       if (p->v.p.comp->flags & CF_EXPANDENV)
173 	argv_free (p->v.p.argv);
174       component_ref_decr (p->v.p.comp);
175       if (p->v.p.status == status_listener && p->v.p.socket != -1)
176 	deregister_socket (p->v.p.socket);
177 	/* FIXME: Remove also all dependent progs (esp. tcpmux) */
178       prog_stop_redirectors (p);
179       break;
180 
181     case TYPE_COMMAND:
182       free (p->v.c.tag);
183       free (p->v.c.command);
184     }
185   free (p);
186   *pp = NULL;
187 }
188 
189 /* Given the component COMP find the element of the program list
190    after which to link in the new prog associated with that COMP.
191    The progs in the resulting list must be arranged exactly in the
192    same order as the corresponding components. Points to note:
193    1. If comp->prog is already present, follow progs in its next
194    chain until the last one that points to the same COMP is found.
195    2. Otherwise, if that component is not the first one, step back
196    to the previous component and do the same for its comp->prog chain.
197    3. Return the prog found.
198 */
199 static struct prog *
find_prog_ref(struct component * comp)200 find_prog_ref (struct component *comp)
201 {
202   struct prog *prog;
203 
204   if (!comp->prog)
205     {
206       comp = comp->prev;
207       if (!comp)
208 	return NULL;
209     }
210 
211   if (comp->prog)
212     {
213       for (prog = comp->prog;
214 	   prog->next
215 	     && IS_COMPONENT (prog->next)
216 	     && prog->next->v.p.comp == comp;
217 	   prog = prog->next)
218 	;
219     }
220   else
221     prog = NULL;
222   return prog;
223 }
224 
225 static struct prog *
register_prog0(struct component * comp)226 register_prog0 (struct component *comp)
227 {
228   struct prog *newp;
229 
230   newp = grecs_zalloc (sizeof (*newp));
231   newp->type = TYPE_COMPONENT;
232   newp->pid = 0;
233   newp->v.p.comp = comp;
234   newp->v.p.socket = -1;
235 
236   if (comp->mode == pies_comp_inetd)
237     newp->v.p.status = status_listener;
238   else
239     newp->v.p.status = status_stopped;
240 
241   if ((comp->flags & CF_DISABLED)
242       || comp->mode == pies_comp_ondemand
243       || comp->mode == pies_comp_shutdown)
244     newp->active = 0;
245   else
246     newp->active = 1;
247 
248   switch (comp->mode)
249     {
250     case pies_comp_exec:
251     case pies_comp_startup:
252     case pies_comp_shutdown:
253       break;
254 
255     default:
256       comp->redir[RETR_OUT].type = redir_null;
257     }
258 
259   link_prog (newp, find_prog_ref (comp));
260   component_ref_incr (comp);
261   return newp;
262 }
263 
264 void
register_prog(struct component * comp)265 register_prog (struct component *comp)
266 {
267   comp->prog = register_prog0 (comp);
268 }
269 
270 void
register_command(char * tag,char * command,pid_t pid)271 register_command (char *tag, char *command, pid_t pid)
272 {
273   struct prog *newp = grecs_zalloc (sizeof (*newp));
274   newp->type = TYPE_COMMAND;
275   newp->pid = pid;
276   newp->v.c.tag = grecs_strdup (tag);
277   newp->v.c.command = command;
278   link_prog (newp, progtail);
279 }
280 
281 static inline int
progman_startup_phase(void)282 progman_startup_phase (void)
283 {
284   struct prog *prog;
285 
286   for (prog = proghead; prog; prog = prog->next)
287     {
288       if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup
289 	  && prog->v.p.status == status_running)
290 	return 1;
291     }
292   return 0;
293 }
294 
295 int
progman_waiting_p(void)296 progman_waiting_p (void)
297 {
298   struct prog *prog;
299 
300   for (prog = proghead; prog; prog = prog->next)
301     {
302       if (IS_COMPONENT (prog)
303 	  && prog->v.p.status == status_running
304 	  && (prog->wait || prog->v.p.comp->mode == pies_comp_startup))
305 	{
306 	  debug (3, ("%s: waiting for %s (%lu)",
307 		     __FUNCTION__, prog_tag (prog),
308 		     (unsigned long) prog->pid));
309 	  return 1;
310 	}
311     }
312   return 0;
313 }
314 
315 int
redirect_to_file(struct prog * master,int stream)316 redirect_to_file (struct prog *master, int stream)
317 {
318   struct passwd *pw;
319   int fd = open (master->v.p.comp->redir[stream].v.file, O_RDWR|O_CREAT,
320 		 0644 & ~master->v.p.comp->umask);
321   if (fd == -1)
322     {
323       logmsg (LOG_ERR, _("cannot open output file %s: %s"),
324 		master->v.p.comp->redir[stream].v.file,
325 		strerror (errno));
326       return -1;
327     }
328   /* Fix file ownership */
329   if (master->v.p.comp->privs.user
330       && (pw = getpwnam (master->v.p.comp->privs.user)) != NULL)
331     {
332       if (chown (master->v.p.comp->redir[stream].v.file,
333 		 pw->pw_uid, pw->pw_gid))
334 	logmsg (LOG_ERR, "chown %s: %s",
335 		master->v.p.comp->redir[stream].v.file,
336 		strerror (errno));
337     }
338   /* Position to the end of file */
339   if (lseek (fd, 0, SEEK_END) == -1)
340     {
341       if (errno != ESPIPE)
342 	logmsg (LOG_ERR, "lseek(%s): %s",
343 		master->v.p.comp->redir[stream].v.file,
344 		strerror (errno));
345     }
346   return fd;
347 }
348 
349 struct read_buffer
350 {
351   struct prog *master;
352   int stream;
353   char text[PIES_LOG_BUF_SIZE];
354   size_t len;
355   int overflow;
356 };
357 
358 static int
redirect_read(int fd,void * data)359 redirect_read (int fd, void *data)
360 {
361   struct read_buffer *rb = data;
362   int n;
363   int prio = rb->master->v.p.comp->redir[rb->stream].v.prio;
364   char const *tag = prog_tag (rb->master);
365   pid_t pid = rb->master->pid;
366   char *p;
367   static char *retr_stream_name[] = {
368     [RETR_OUT] = "stdout",
369     [RETR_ERR] = "stderr"
370   };
371 
372   n = read (fd, rb->text + rb->len, sizeof (rb->text) - rb->len);
373   if (n == -1)
374     {
375       if (errno != EINTR)
376 	{
377 	  logmsg (LOG_INFO, _("%s: %s while reading %s"),
378 		  tag, strerror (errno), retr_stream_name[rb->stream]);
379 	  rb->master->v.p.redir[rb->stream] = -1;
380 	  close (fd);
381 	  deregister_socket (fd);
382 	  return -1;
383 	}
384     }
385   else if (n == 0)
386     {
387       logmsg (LOG_INFO, _("%s: EOF on %s"),
388 	      tag, retr_stream_name[rb->stream]);
389       rb->master->v.p.redir[rb->stream] = -1;
390       close (fd);
391       deregister_socket (fd);
392     }
393   else
394     {
395       rb->len += n;
396 
397       while (rb->len)
398 	{
399 	  p = memchr (rb->text, '\n', rb->len);
400 	  if (p)
401 	    {
402 	      *p++ = 0;
403 	      if (rb->overflow)
404 		rb->overflow = 0;
405 	      else
406 		pies_syslog_message (prio, rb->text, tag, pid);
407 	      n = rb->len - (p - rb->text);
408 	      if (n > 0)
409 		memmove (rb->text, p, n);
410 	      rb->len = n;
411 	    }
412 	  else if (rb->len == sizeof (rb->text))
413 	    {
414 	      rb->text[sizeof (rb->text) - 1] = 0;
415 	      pies_syslog_message (prio, rb->text, tag, pid);
416 	      rb->len = 0;
417 	      rb->overflow = 1;
418 	    }
419 	  else
420 	    break;
421 	}
422     }
423   return 0;
424 }
425 
426 static void
read_buffer_free(void * p)427 read_buffer_free (void *p)
428 {
429   free (p);
430 }
431 
432 int
redirect_to_syslog(struct prog * master,int stream,int * fd)433 redirect_to_syslog (struct prog *master, int stream, int *fd)
434 {
435   struct read_buffer *rb;
436   int p[2];
437 
438   if (pipe (p))
439     {
440       logmsg (LOG_CRIT, "pipe: %s", strerror (errno));
441       return -1;
442     }
443 
444   rb = grecs_zalloc (sizeof (*rb));
445   rb->master = master;
446   rb->stream = stream;
447   rb->len = 0;
448   rb->overflow = 0;
449 
450   register_socket (p[0], redirect_read, NULL, NULL, rb, read_buffer_free);
451   *fd = p[0];
452   return p[1];
453 }
454 
455 void
free_redirector(struct redirector * rp)456 free_redirector (struct redirector *rp)
457 {
458   if (rp->type == redir_file)
459     free (rp->v.file);
460 }
461 
462 int
open_redirector(struct prog * master,int stream,int * fd)463 open_redirector (struct prog *master, int stream, int *fd)
464 {
465   switch (master->v.p.comp->redir[stream].type)
466     {
467     case redir_null:
468       *fd = -1;
469       break;
470 
471     case redir_file:
472       *fd = -1;
473       return redirect_to_file (master, stream);
474 
475     case redir_syslog:
476       return redirect_to_syslog (master, stream, fd);
477     }
478   return -1;
479 }
480 
481 
482 static unsigned
conn_class_hasher(void * data,unsigned long n_buckets)483 conn_class_hasher (void *data, unsigned long n_buckets)
484 {
485   struct conn_class *pcclass = data;
486   unsigned char const *tag = (unsigned char const *)pcclass->tag;
487   size_t value = 0;
488   unsigned char ch;
489   size_t len;
490 
491   while ((ch = *tag++))
492     value = (value * 31 + ch) % n_buckets;
493 
494   for (tag = (const unsigned char *)&pcclass->sa_storage,
495 	 len = pcclass->sa_len;
496        len;
497        tag++, len--)
498     value = (value * 31 + *tag) % n_buckets;
499   return value;
500 }
501 
502 /* Compare two strings for equality.  */
503 static int
conn_class_compare(void const * data1,void const * data2)504 conn_class_compare (void const *data1, void const *data2)
505 {
506   struct conn_class const *p1 = data1;
507   struct conn_class const *p2 = data2;
508 
509   return !(p1->sa_len == p2->sa_len &&
510 	   memcmp (&p1->sa_storage, &p2->sa_storage, p1->sa_len) == 0 &&
511 	   strcmp (p1->tag, p2->tag) == 0);
512 }
513 
514 static void
conn_class_free(void * data)515 conn_class_free (void *data)
516 {
517   free (data);
518 }
519 
520 static int
conn_class_copy(void * a,void * b)521 conn_class_copy(void *a, void *b)
522 {
523   memcpy (a, b, sizeof(struct conn_class));
524   memset (b, 0, sizeof(struct conn_class));
525   return 0;
526 }
527 
528 static struct conn_class *
conn_class_lookup(const char * tag,union pies_sockaddr_storage const * sa_storage_ptr,size_t sa_len)529 conn_class_lookup (const char *tag,
530 		  union pies_sockaddr_storage const *sa_storage_ptr,
531 		  size_t sa_len)
532 {
533   int install = 1;
534   struct conn_class *probe, *ret;
535 
536   probe = grecs_malloc (sizeof (probe[0]));
537   probe->tag = tag;
538   probe->sa_storage = *sa_storage_ptr;
539   probe->sa_len = sa_len;
540   switch (probe->sa_storage.s.sa_family)
541     {
542     case AF_INET:
543       probe->sa_storage.s_in.sin_port = 0;
544       break;
545 
546     case AF_UNIX:
547       break;
548 
549     default:
550       logmsg (LOG_ERR, _("unexpected address family: %d"),
551 	      probe->sa_storage.s.sa_family);
552       break;
553     }
554 
555   probe->count = 0;
556   if (!conn_tab)
557     {
558       conn_tab = grecs_symtab_create(sizeof (struct conn_class),
559 				     conn_class_hasher,
560 				     conn_class_compare,
561 				     conn_class_copy,
562 				     NULL,
563 				     conn_class_free);
564       if (!conn_tab)
565 	grecs_alloc_die ();
566     }
567 
568   ret = grecs_symtab_lookup_or_install (conn_tab, probe, &install);
569   if (!ret)
570     {
571       logmsg (LOG_CRIT, "cannot allocate conn_class: %s",
572 	      strerror (errno));
573       abort ();
574     }
575   free (probe);
576   return ret;
577 }
578 
579 static void
conn_class_report(int prio,struct conn_class * pcclass)580 conn_class_report (int prio, struct conn_class *pcclass)
581 {
582   char *s = sockaddr_to_astr ((struct sockaddr *)&pcclass->sa_storage,
583 			      pcclass->sa_len);
584   logmsg (prio, _("connections in class %s/%s: %lu"),
585 	  pcclass->tag, s, (unsigned long)pcclass->count);
586   free (s);
587 }
588 
589 static void
conn_class_remove(struct conn_class * pcclass)590 conn_class_remove (struct conn_class *pcclass)
591 {
592   if (!conn_tab)
593     {
594       logmsg (LOG_CRIT, "attempt to free unexisting conn_class %p", pcclass);
595       conn_class_report (LOG_CRIT, pcclass);
596       abort ();
597     }
598   grecs_symtab_remove (conn_tab, pcclass);
599 }
600 
601 
602 #define ENV_PROTO         "PROTO"
603 #define ENV_SOCKTYPE      "SOCKTYPE"
604 #define ENV_LOCALIP       "LOCALIP"
605 #define ENV_LOCALPORT     "LOCALPORT"
606 #define ENV_LOCALHOST     "LOCALHOST"
607 #define ENV_REMOTEIP      "REMOTEIP"
608 #define ENV_REMOTEPORT    "REMOTEPORT"
609 #define ENV_REMOTEHOST    "REMOTEHOST"
610 static char *sockenv_var[] = {
611   ENV_PROTO,
612   ENV_SOCKTYPE,
613   ENV_LOCALIP,
614   ENV_LOCALPORT,
615   ENV_LOCALHOST,
616   ENV_REMOTEIP,
617   ENV_REMOTEPORT,
618   ENV_REMOTEHOST,
619   NULL
620 };
621 
622 static inline void
debug_environ(struct prog * prog,int l)623 debug_environ (struct prog *prog, int l)
624 {
625   if (debug_level >= l)
626     {
627       int i;
628       char **env = environ_ptr (prog->v.p.env);
629       logmsg_printf (LOG_DEBUG, "environment: ");
630       for (i = 0; env[i]; i++)
631 	logmsg_printf (LOG_DEBUG, "%s ", env[i]);
632       logmsg_printf (LOG_DEBUG, "\n");
633     }
634 }
635 
636 /* Pass socket information in environment variables. */
637 void
prog_sockenv(struct prog * prog)638 prog_sockenv (struct prog *prog)
639 {
640   char buf[INT_BUFSIZE_BOUND (uintmax_t)];
641   char *p;
642   struct hostent *host;
643   union pies_sockaddr_storage sa_server;
644   socklen_t len = sizeof (sa_server);
645   union pies_sockaddr_storage *sa_client = &prog->v.p.sa_storage;
646   socklen_t cltlen = prog->v.p.sa_len;
647   const char *proto = NULL;
648 
649   if (!(prog->v.p.comp->flags & CF_SOCKENV))
650     return;
651 
652   if (socket_type_to_str (prog->v.p.comp->socket_type, &proto))
653     proto = umaxtostr (prog->v.p.comp->socket_type, buf);
654   environ_set (prog->v.p.env, ENV_SOCKTYPE, proto);
655 
656   if (prog->v.p.comp->socket_url)
657     proto = prog->v.p.comp->socket_url->proto_s;
658   else if (prog->v.p.listener)
659     proto = prog->v.p.listener->v.p.comp->socket_url->proto_s;
660   else if (ISCF_TCPMUX (prog->v.p.comp->flags))
661     proto = "TCP";
662 
663   environ_set (prog->v.p.env, ENV_PROTO, proto);
664 
665   if (getsockname (prog->v.p.socket,
666 		   (struct sockaddr *) &sa_server, &len) < 0)
667     logmsg (LOG_WARNING, "getsockname(): %s", strerror (errno));
668   else if (sa_server.s.sa_family == AF_INET)
669     {
670       p = inet_ntoa (sa_server.s_in.sin_addr);
671       if (p)
672 	environ_set (prog->v.p.env, ENV_LOCALIP, p);
673 
674       p = umaxtostr (ntohs (sa_server.s_in.sin_port), buf);
675       environ_set (prog->v.p.env, ENV_LOCALPORT, p);
676 
677       if (prog->v.p.comp->flags & CF_RESOLVE)
678 	{
679 	  if ((host = gethostbyaddr ((char *) &sa_server.s_in.sin_addr,
680 				     sizeof (sa_server.s_in.sin_addr),
681 				     AF_INET)) == NULL)
682 	    logmsg (LOG_WARNING, "gethostbyaddr: %s", strerror (errno));
683 	  else
684 	    environ_set (prog->v.p.env, ENV_LOCALHOST, host->h_name);
685 	}
686     }
687 
688   if (cltlen > 0 && sa_client->s.sa_family == AF_INET)
689     {
690       p = inet_ntoa (sa_client->s_in.sin_addr);
691       if (p)
692 	environ_set (prog->v.p.env, ENV_REMOTEIP, p);
693 
694       p = umaxtostr (ntohs (sa_client->s_in.sin_port), buf);
695       environ_set (prog->v.p.env, ENV_REMOTEPORT, p);
696 
697       if (prog->v.p.comp->flags & CF_RESOLVE)
698 	{
699 	  if ((host = gethostbyaddr ((char *) &sa_client->s_in.sin_addr,
700 				     sizeof (sa_client->s_in.sin_addr),
701 				     AF_INET)) == NULL)
702 	    logmsg (LOG_WARNING, "gethostbyaddr: %s",
703 		    strerror (errno));
704 	  else
705 	    environ_set (prog->v.p.env, ENV_REMOTEHOST, host->h_name);
706 	}
707     }
708   /* FIXME: $REMOTEINFO ? */
709   debug_environ (prog, 4);
710 }
711 
712 static int
check_rate(struct prog * prog,unsigned testtime,size_t max_count)713 check_rate (struct prog *prog, unsigned testtime, size_t max_count)
714 {
715   time_t now;
716 
717   time (&now);
718 
719   if (prog->v.p.timestamp + testtime > now)
720     prog->v.p.failcount++;
721   else
722     {
723       prog->v.p.failcount = 0;
724       prog->v.p.timestamp = now;
725     }
726 
727   if (prog->v.p.failcount > max_count)
728     {
729       prog->v.p.timestamp = now;
730       prog->v.p.status = status_sleeping;
731       pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM);
732       return 1;
733     }
734 
735   return 0;
736 }
737 
738 static int
check_spawn_rate(struct prog * prog)739 check_spawn_rate (struct prog *prog)
740 {
741   if (check_rate (prog, TESTTIME, MAXSPAWN))
742     {
743       logmsg (LOG_NOTICE,
744 	      ngettext ("%s is respawning too fast, disabled for %d minute",
745 			"%s is respawning too fast, disabled for %d minutes",
746 			SLEEPTIME / 60),
747 	      prog_tag (prog), SLEEPTIME / 60);
748       return 1;
749     }
750   return 0;
751 }
752 
753 static int
check_connection_rate(struct prog * prog)754 check_connection_rate (struct prog *prog)
755 {
756   size_t max_rate = prog->v.p.comp->max_rate
757 		       ? prog->v.p.comp->max_rate : default_max_rate;
758   if (max_rate && check_rate (prog, 60, max_rate))
759     {
760       logmsg (LOG_NOTICE,
761 	      ngettext ("%s is starting too often, disabled for %d minute",
762 			"%s is starting too often, disabled for %d minutes",
763 			SLEEPTIME / 60),
764 	      prog_tag (prog), SLEEPTIME / 60);
765       return 1;
766     }
767   return 0;
768 }
769 
770 static int
prog_open_socket(struct prog * prog)771 prog_open_socket (struct prog *prog)
772 {
773   prog->v.p.socket = create_socket (prog->v.p.comp->socket_url,
774 				    prog->v.p.comp->socket_type,
775 				    prog->v.p.comp->privs.user,
776 				    prog->v.p.comp->umask);
777   if (prog->v.p.socket == -1)
778     {
779       prog->v.p.status = status_stopped;
780       prog->active = 0;
781       return 1;
782     }
783   if (listen (prog->v.p.socket, 8))
784     {
785       logmsg (LOG_ERR, "listen: %s", strerror (errno));
786       close (prog->v.p.socket);
787       prog->v.p.socket = -1;
788       prog->v.p.status = status_stopped;
789       prog->active = 0;
790       return 1;
791     }
792   return 0;
793 }
794 
795 static void
progman_ws_error(const char * fmt,...)796 progman_ws_error (const char *fmt, ...)
797 {
798   va_list ap;
799 
800   va_start (ap, fmt);
801   vlogmsg (LOG_ERR, fmt, ap);
802   va_end (ap);
803 }
804 
805 /*
806  * Initialization of the environment and argc/argv members of
807  * struct prog.  For regular components this is done in the main
808  * process, so that argv can be reported correctly via the ctl
809  * interface.  For tcpmux components, which are run from the
810  * listener child, this is not so.  That does little harm as
811  * these components are not visible from the ctl interface anyway.
812  */
813 static int
prog_init(struct prog * prog)814 prog_init (struct prog *prog)
815 {
816   if ((prog->v.p.env = environ_create (environ)) == NULL)
817     {
818       logmsg (LOG_CRIT, "environ_create: %s", strerror (errno));
819       return -1;
820     }
821 
822   if (prog->v.p.comp->flags & CF_SOCKENV)
823     {
824       size_t i;
825       for (i = 0; sockenv_var[i]; i++)
826 	environ_unset (prog->v.p.env, sockenv_var[i], NULL);
827     }
828 
829   if (envop_exec (prog->v.p.comp->envop, prog->v.p.env))
830     {
831       logmsg (LOG_CRIT, "environ_exec: %s", strerror (errno));
832       return -1;
833     }
834 
835   if (SYSVINIT_ACTIVE)
836     {
837       size_t i;
838       for (i = 0; sysvinit_environ_hint[i]; i++)
839 	{
840 	  if (environ_add (prog->v.p.env, sysvinit_environ_hint[i]))
841 	    {
842 	      logmsg (LOG_CRIT, "environ_add: %s", strerror (errno));
843 	      return -1;
844 	    }
845 	}
846     }
847   debug_environ (prog, 4);
848 
849   if (prog->v.p.comp->flags & CF_EXPANDENV)
850     {
851       struct wordsplit ws;
852 
853       ws.ws_env = (const char **) environ_ptr (prog->v.p.env);
854       ws.ws_error = progman_ws_error;
855       if (wordsplit (prog->v.p.comp->command, &ws,
856 		     WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | WRDSF_NOCMD | WRDSF_ENV | WRDSF_ERROR))
857 	{
858 	  logmsg (LOG_ERR, _("%s: can't split command line: %s"),
859 		  prog_tag (prog), wordsplit_strerror (&ws));
860 	  return -1;
861 	}
862       wordsplit_get_words (&ws, &prog->v.p.argc, &prog->v.p.argv);
863       wordsplit_free (&ws);
864     }
865   else
866     {
867       prog->v.p.argc = prog->v.p.comp->argc;
868       prog->v.p.argv = prog->v.p.comp->argv;
869     }
870 
871   if (debug_level >= 1 && prog->v.p.argv)
872     {
873       int i;
874       logmsg_printf (LOG_DEBUG, "executing");
875       for (i = 0; i < prog->v.p.argc; i++)
876 	logmsg_printf (LOG_DEBUG, " %s", quotearg (prog->v.p.argv[i]));
877       logmsg_printf (LOG_DEBUG, "\n");
878     }
879   return 0;
880 }
881 
882 static void
prog_start_prologue(struct prog * prog)883 prog_start_prologue (struct prog *prog)
884 {
885   if (prog->v.p.comp->dir)
886     {
887       debug (1, (_("chdir %s"), prog->v.p.comp->dir));
888       if (chdir (prog->v.p.comp->dir))
889 	logmsg (LOG_ERR, _("%s: cannot change to directory %s: %s"),
890 		prog_tag (prog), prog->v.p.comp->dir, strerror (errno));
891     }
892 
893   pies_priv_setup (&prog->v.p.comp->privs);
894   if (prog->v.p.comp->umask)
895     umask (prog->v.p.comp->umask);
896 
897   set_limits (prog_tag (prog),
898 	      prog->v.p.comp->limits ?
899 	      prog->v.p.comp->limits : pies_limits);
900 }
901 
902 static void
prog_execute(struct prog * prog)903 prog_execute (struct prog *prog)
904 {
905   environ = environ_ptr (prog->v.p.env);
906   if (prog->v.p.comp->builtin)
907     {
908       mf_proctitle_format ("inetd %s",
909 			   prog->v.p.comp->builtin->service);
910       prog->v.p.comp->builtin->fun (0, prog->v.p.comp);
911       _exit (0);
912     }
913 
914   execvp (prog->v.p.comp->program ?
915 	  prog->v.p.comp->program : prog->v.p.argv[0],
916 	  prog->v.p.argv);
917   //FIXME: pies_syslog?
918   syslog (LOG_CRIT, _("cannot start `%s': %s"), prog_tag (prog),
919 	  strerror (errno));
920   _exit (EX_SOFTWARE);
921 }
922 
923 /*
924  * Run a TCPMUX component.  This function is invoked from a child
925  * process.
926  */
927 void
progman_run_comp(struct component * comp,int fd,union pies_sockaddr_storage * sa,socklen_t salen)928 progman_run_comp (struct component *comp, int fd,
929 		  union pies_sockaddr_storage *sa, socklen_t salen)
930 {
931   struct prog *prog = register_prog0 (comp);
932   prog->v.p.socket = fd;
933   prog->v.p.sa_storage = *sa;
934   prog->v.p.sa_len = salen;
935   prog->v.p.cclass = conn_class_lookup (comp->tag, sa, salen);
936   if (prog_init (prog))
937     _exit (127);
938   prog_start_prologue (prog);
939   prog_sockenv (prog);
940   prog_execute (prog);
941 }
942 
943 static void
prog_start(struct prog * prog)944 prog_start (struct prog *prog)
945 {
946   pid_t pid;
947   int redir[2];
948 
949   if (prog->pid > 0 || !IS_COMPONENT (prog))
950     return;
951 
952   if (is_sysvinit (prog->v.p.comp))
953     {
954       if (!SYSVINIT_ACTIVE)
955 	{
956 	  if (prog->active)
957 	    {
958 	      logmsg (LOG_NOTICE, "disabling sysvinit component %s",
959 		      prog_tag (prog));
960 	      prog->v.p.status = status_stopped;
961 	      prog->active = 0;
962 	    }
963 	  return;
964 	}
965     }
966 
967   /* This call returns 1 in two cases: Either prog is marked as disabled,
968      in which case there's nothing more to do, or one or more of its
969      prerequisites are in status_stopping. In the latter case either the
970      components in question will exit or a SIGALRM will get delivered. In
971      both cases, it will cause further processing of `prog'. */
972   if (prog_start_prerequisites (prog))
973     return;
974 
975   switch (prog->v.p.comp->mode)
976     {
977     case pies_comp_exec:
978       if (check_spawn_rate (prog))
979 	return;
980       break;
981 
982     case pies_comp_pass_fd:
983       if (check_spawn_rate (prog))
984 	return;
985       debug (1, (_("unlinking %s"), prog->v.p.comp->pass_fd_socket));
986       if (unlink (prog->v.p.comp->pass_fd_socket) && errno != ENOENT)
987 	{
988 	  logfuncall ("unlink", prog->v.p.comp->pass_fd_socket, errno);
989 	  return;
990 	}
991       if (prog_open_socket (prog))
992 	return;
993       break;
994 
995     case pies_comp_accept:
996       if (check_spawn_rate (prog))
997 	return;
998       if (prog_open_socket (prog))
999 	return;
1000       break;
1001 
1002     case pies_comp_inetd:
1003       /* Wait until an incoming connection is requested */
1004       if (prog->v.p.socket == -1)
1005 	return;
1006 
1007     default:
1008       break;
1009     }
1010 
1011   debug (1, (_("starting %s"), prog_tag (prog)));
1012 
1013   if (prog->v.p.comp->rmfile)
1014     {
1015       debug (1, (_("unlinking %s"), prog->v.p.comp->rmfile));
1016       if (unlink (prog->v.p.comp->rmfile) && errno != ENOENT)
1017 	logmsg (LOG_ERR, _("%s: cannot remove file `%s': %s"),
1018 		prog_tag (prog), prog->v.p.comp->rmfile, strerror (errno));
1019     }
1020 
1021   if (prog->v.p.comp->builtin && prog->v.p.comp->builtin->single_process)
1022     {
1023       prog->v.p.comp->builtin->fun (prog->v.p.socket, prog->v.p.comp);
1024       return;
1025     }
1026 
1027   if (prog_init (prog))
1028     return; //FIXME
1029 
1030   redir[RETR_OUT] = open_redirector (prog, RETR_OUT,
1031 				     &prog->v.p.redir[RETR_OUT]);
1032   redir[RETR_ERR] = open_redirector (prog, RETR_ERR,
1033 				     &prog->v.p.redir[RETR_ERR]);
1034 
1035   switch (pid = fork ())
1036     {
1037       /* The child branch.  */
1038     case 0:
1039       signal_setup (SIG_DFL);
1040       setsid ();
1041       prog_start_prologue (prog);
1042       switch (prog->v.p.comp->mode)
1043 	{
1044 	case pies_comp_accept:
1045 	case pies_comp_inetd:
1046 	  prog_sockenv (prog);
1047 
1048 	  dup2 (prog->v.p.socket, 0);
1049 	  dup2 (prog->v.p.socket, 1);
1050 	  close (prog->v.p.socket);
1051 	  prog->v.p.socket = -1;
1052 	  break;
1053 
1054 	default:
1055 	  if (SYSVINIT_ACTIVE)
1056 	    {
1057 	      int fd = console_open (O_RDWR|O_NOCTTY);
1058 	      if (fd < 0)
1059 		{
1060 		  logmsg (LOG_CRIT, "open(%s): %s",
1061 			  console_device, strerror (errno));
1062 		  fd = open ("/dev/null", O_RDWR);
1063 		}
1064 	      if (fd != 0)
1065 		dup2 (fd, 0);
1066 	      if (fd != 1)
1067 		dup2 (fd, 1);
1068 	      if (fd != 2)
1069 		dup2 (fd, 2);
1070 	    }
1071 	  else
1072 	    {
1073 	      if (prog->v.p.comp->flags & CF_NULLINPUT)
1074 		{
1075 		  close(0);
1076 		  if (open("/dev/null", O_RDONLY) != 0)
1077 		    {
1078 		      logmsg (LOG_CRIT, "can't open /dev/null: %s",
1079 			      strerror(errno));
1080 		      _exit(127);
1081 		    }
1082 		}
1083 
1084 	      if (redir[RETR_OUT] == -1)
1085 		{
1086 		  close (1);
1087 		  open ("/dev/null", O_WRONLY);
1088 		}
1089 	      else if (redir[RETR_OUT] != 1)
1090 		{
1091 		  dup2 (redir[RETR_OUT], 1);
1092 		}
1093 	    }
1094 	  break;
1095 	}
1096 
1097       if (!SYSVINIT_ACTIVE)
1098 	{
1099 	  if (redir[RETR_ERR] == -1)
1100 	    {
1101 	      if (!DIAG_OUTPUT (DIAG_TO_STDERR))
1102 		{
1103 		  close (2);
1104 		  open ("/dev/null", O_WRONLY);
1105 		}
1106 	    }
1107 	  else if (redir[RETR_ERR] != 1)
1108 	    {
1109 	      dup2 (redir[RETR_ERR], 2);
1110 	    }
1111 	}
1112 
1113       /* Close unneeded descripitors */
1114       pies_close_fds ((prog->v.p.comp->mode == pies_comp_pass_fd
1115 	               ? prog->v.p.socket : 2) + 1);
1116 
1117       prog_execute (prog);
1118 
1119 
1120     case -1:
1121       logmsg (LOG_CRIT,
1122 		      _("cannot run `%s': fork failed: %s"),
1123 	      prog_tag (prog), strerror (errno));
1124       break;
1125 
1126     default:
1127       if (prog->v.p.comp->mode == pies_comp_pass_fd)
1128 	{
1129 	  pass_fd (prog->v.p.comp->pass_fd_socket, prog->v.p.socket,
1130 		   prog->v.p.comp->pass_fd_timeout ?
1131 		    prog->v.p.comp->pass_fd_timeout : DEFAULT_PASS_FD_TIMEOUT);
1132 	  /* FIXME: Error code */;
1133 	}
1134       if (prog->v.p.comp->flags & CF_WAIT)
1135 	{
1136 	  disable_socket (prog->v.p.socket);
1137 	}
1138       else if (prog->v.p.comp->mode == pies_comp_accept ||
1139 	       prog->v.p.comp->mode == pies_comp_inetd ||
1140 	       prog->v.p.comp->mode == pies_comp_pass_fd)
1141 	close (prog->v.p.socket);
1142       else if (is_sysvinit (prog->v.p.comp))
1143 	sysvinit_acct (SYSV_ACCT_PROC_START, "", prog_tag (prog), pid, "");
1144 
1145       if (redir[RETR_OUT] != -1)
1146 	close (redir[RETR_OUT]);
1147       if (redir[RETR_ERR])
1148 	close (redir[RETR_ERR]);
1149       prog->pid = pid;
1150       prog->v.p.status = status_running;
1151       debug (1, (_("%s started, pid=%lu"), prog_tag (prog),
1152 		 (unsigned long) pid));
1153     }
1154 }
1155 
1156 int
check_acl(pies_acl_t acl,struct sockaddr * s,socklen_t salen,pies_identity_t identity)1157 check_acl (pies_acl_t acl, struct sockaddr *s, socklen_t salen,
1158 	   pies_identity_t identity)
1159 {
1160   struct acl_input input;
1161   int rc;
1162 
1163   if (!acl)
1164     return 0;
1165 
1166   input.addr = s;
1167   input.addrlen = salen;
1168   input.identity = identity;
1169 
1170   rc = pies_acl_check (acl, &input, 1);
1171   if (rc == 0)
1172     {
1173       char *p = sockaddr_to_astr (s, salen);
1174       logmsg (LOG_ERR, _("access from %s blocked"), p);
1175       free (p);
1176       return 1;
1177     }
1178 
1179   return 0;
1180 }
1181 
1182 void
fd_report(int fd,const char * msg)1183 fd_report (int fd, const char *msg)
1184 {
1185   size_t len;
1186 
1187   if (!msg)
1188     return;
1189 
1190   for (len = strlen (msg); len; )
1191     {
1192       ssize_t rc = write (fd, msg, len);
1193       if (rc == -1)
1194 	{
1195 	  logmsg (LOG_ERR,
1196 		  _("error writing to socket: %s"),
1197 		  strerror (errno));
1198 	  break;
1199 	}
1200       else if (rc == 0)
1201 	break;
1202       len -= rc;
1203       msg += rc;
1204     }
1205 }
1206 
1207 static int
_prog_accept(struct prog * p)1208 _prog_accept (struct prog *p)
1209 {
1210   int fd;
1211   struct prog *pinst;
1212   union pies_sockaddr_storage addr;
1213   socklen_t addrlen = sizeof addr;
1214   struct conn_class *pcclass;
1215 
1216   fd = accept (p->v.p.socket, (struct sockaddr*) &addr, &addrlen);
1217   if (fd == -1)
1218     {
1219       logfuncall ("accept", NULL, errno);
1220       return 1;
1221     }
1222 
1223   if (debug_level >= 1)
1224     {
1225       char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen);
1226       logmsg (LOG_DEBUG, _("%s wants %s"), s, prog_tag (p));
1227       free (s);
1228     }
1229 
1230   if (check_acl (p->v.p.comp->acl, (struct sockaddr *)&addr, addrlen, NULL)
1231       || check_acl (pies_acl, (struct sockaddr *)&addr, addrlen, NULL))
1232     {
1233       fd_report (fd, p->v.p.comp->access_denied_message);
1234       close (fd);
1235       return 1;
1236     }
1237 
1238   if (p->v.p.comp->max_instances &&
1239       p->v.p.num_instances >= p->v.p.comp->max_instances)
1240     {
1241       char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen);
1242       logmsg (LOG_ERR,
1243 	      _("%s: access from %s denied: too many instances running"),
1244 	      prog_tag (p), s);
1245       free (s);
1246       fd_report (fd, p->v.p.comp->max_instances_message);
1247       close (fd);
1248       return 1;
1249     }
1250 
1251   pcclass = conn_class_lookup (prog_tag (p), &addr, addrlen);
1252   if (p->v.p.comp->max_ip_connections &&
1253       pcclass->count >= p->v.p.comp->max_ip_connections)
1254     {
1255       char *s = sockaddr_to_astr ((struct sockaddr *)&addr, addrlen);
1256       logmsg (LOG_ERR,
1257 	      _("%s: access from %s denied: "
1258 		"too many connections from that ip"),
1259 	      prog_tag (p), s);
1260       free (s);
1261       fd_report (fd, p->v.p.comp->max_ip_connections_message);
1262       close (fd);
1263       return 1;
1264     }
1265 
1266   if (check_connection_rate (p))
1267     {
1268       disable_socket (p->v.p.socket);
1269       close (fd);
1270       return 1;
1271     }
1272 
1273   pcclass->count++;
1274 
1275   if (debug_level > 1)
1276     conn_class_report (LOG_DEBUG, pcclass);
1277 
1278   pinst = register_prog0 (p->v.p.comp);
1279   pinst->v.p.socket = fd;
1280   pinst->v.p.listener = p;
1281   pinst->v.p.sa_storage = addr;
1282   pinst->v.p.sa_len = addrlen;
1283   pinst->v.p.cclass = pcclass;
1284   prog_start (pinst);
1285   close (fd);
1286   pinst->v.p.socket = -1;
1287 
1288   p->v.p.num_instances++;
1289   return 0;
1290 }
1291 
1292 static int
_prog_wait(struct prog * p)1293 _prog_wait (struct prog *p)
1294 {
1295   struct prog *pinst;
1296 
1297   debug (1, (_("someone wants %s"), prog_tag (p)));
1298 
1299   if (p->v.p.comp->max_instances
1300       && p->v.p.num_instances >= p->v.p.comp->max_instances)
1301     {
1302       logmsg (LOG_ERR,
1303 	      _("%s: too many instances running, dropping connection"),
1304 	      prog_tag (p));
1305       return 1;
1306     }
1307 
1308   pinst = register_prog0 (p->v.p.comp);
1309   pinst->v.p.socket = p->v.p.socket;
1310   pinst->v.p.listener = p;
1311   prog_start (pinst);
1312 
1313   pinst->v.p.socket = -1;
1314 
1315   p->v.p.num_instances++;
1316   return 0;
1317 }
1318 
1319 int
progman_accept(int socket,void * data)1320 progman_accept (int socket, void *data)
1321 {
1322   struct prog *p = data;
1323 
1324   if (p->v.p.comp->socket_type == SOCK_STREAM
1325       && !(p->v.p.comp->flags & CF_WAIT))
1326     return _prog_accept (p);
1327 
1328   return _prog_wait (p);
1329 }
1330 
1331 static int
prog_create_socket(struct prog * prog,void * data)1332 prog_create_socket (struct prog *prog, void *data)
1333 {
1334   if (IS_COMPONENT (prog) && prog->v.p.status == status_listener)
1335     {
1336       struct component *comp = prog->v.p.comp;
1337       if (!ISCF_TCPMUX (comp->flags) && prog->v.p.socket == -1)
1338 	{
1339 	  int fd = create_socket (comp->socket_url,
1340 				  comp->socket_type,
1341 				  comp->privs.user, comp->umask);
1342 	  if (fd == -1)
1343 	    destroy_prog (&prog);
1344 	  else if (register_program_socket (comp->socket_type, fd, prog, NULL))
1345 	    {
1346 	      close (fd);
1347 	      destroy_prog (&prog);
1348 	    }
1349 	  else
1350 	    prog->v.p.socket = fd;
1351 	}
1352     }
1353   return 0;
1354 }
1355 
1356 void
progman_create_sockets(void)1357 progman_create_sockets (void)
1358 {
1359   progman_foreach (prog_create_socket, NULL);
1360 }
1361 
1362 void
progman_recompute_alarm(void)1363 progman_recompute_alarm (void)
1364 {
1365   struct prog *prog;
1366   time_t now = time (NULL);
1367   time_t alarm_time = 0, x;
1368 
1369   debug (2, ("Recomputing alarm settings"));
1370   for (prog = proghead; prog; prog = prog->next)
1371     if (IS_COMPONENT (prog))
1372       {
1373 	switch (prog->v.p.status)
1374 	  {
1375 	  case status_sleeping:
1376 	    x = SLEEPTIME - (now - prog->v.p.timestamp);
1377 	    if (alarm_time == 0 || x < alarm_time)
1378 	      alarm_time = x;
1379 	    break;
1380 
1381 	  case status_stopping:
1382 	    x = shutdown_timeout - (now - prog->v.p.timestamp);
1383 	    if (alarm_time == 0 || x < alarm_time)
1384 	      alarm_time = x;
1385 	    break;
1386 
1387 	  default:
1388 	    break;
1389 	  }
1390       }
1391   debug (2, ("alarm=%lu", (unsigned long)alarm_time));
1392   if (alarm_time)
1393     alarm (alarm_time);
1394 }
1395 
1396 void
program_init_startup(void)1397 program_init_startup (void)
1398 {
1399   struct prog *prog;
1400 
1401   for (prog = proghead; prog; prog = prog->next)
1402     if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
1403       {
1404 	debug (1, ("running startup components"));
1405 	break;
1406       }
1407 
1408   for (; prog; prog = prog->next)
1409     if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_startup)
1410       {
1411 	prog_start (prog);
1412       }
1413 }
1414 
1415 void
progman_start(void)1416 progman_start (void)
1417 {
1418   struct prog *prog;
1419 
1420   if (progman_waiting_p ())
1421     /* Noting to do if there are processes left in the previous runlevel
1422        (in sysv-init mode) or startup components running. */
1423     return;
1424 
1425   debug (1, ("starting components"));
1426   for (prog = proghead; prog; prog = prog->next)
1427     if (IS_COMPONENT (prog))
1428       {
1429 	switch (prog->v.p.status)
1430 	  {
1431 	  case status_stopped:
1432 	  case status_sleeping:
1433 	    prog_start (prog);
1434 	    break;
1435 
1436 	  case status_running:
1437 	  case status_stopping:
1438 	  case status_finished:
1439 	    break;
1440 
1441 	  case status_listener:
1442 	    if (!prog->active)
1443 	      disable_socket (prog->v.p.socket);
1444 	    else
1445 	      enable_socket (prog->v.p.socket);
1446 	  }
1447       }
1448 }
1449 
1450 static void
check_stopping(struct prog * prog,time_t now)1451 check_stopping (struct prog *prog, time_t now)
1452 {
1453   if (now - prog->v.p.timestamp >= shutdown_timeout)
1454     {
1455       if (prog->pid == 0)
1456 	logmsg (LOG_EMERG,
1457 		_("INTERNAL ERROR: attempting to kill nonexistent process %s"),
1458 		prog_tag (prog));
1459       else if (prog->v.p.comp->flags & CF_SIGGROUP)
1460 	kill (-prog->pid, SIGKILL);
1461       else
1462 	kill (prog->pid, SIGKILL);
1463     }
1464   else
1465     pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM);
1466 }
1467 
1468 void
progman_wake_sleeping(int onalrm)1469 progman_wake_sleeping (int onalrm)
1470 {
1471   struct prog *prog;
1472   time_t now = time (NULL);
1473 
1474   debug (1, (_("checking for components to start")));
1475 
1476   for (prog = proghead; prog; prog = prog->next)
1477     {
1478       if (IS_ACTIVE_COMPONENT (prog) && prog->wait)
1479 	{
1480 	  /* The following works on the assumption that prog->wait is
1481 	     set when enabling the component and gets cleared right after
1482 	     it has finished. */
1483 	  if (prog->v.p.status != status_running)
1484 	    prog_start (prog);
1485 	  return;
1486 	}
1487     }
1488 
1489   for (prog = proghead; prog; prog = prog->next)
1490     switch (prog->v.p.status)
1491       {
1492       case status_sleeping:
1493 	if (IS_ACTIVE_COMPONENT (prog))
1494 	  {
1495 	    if (now - prog->v.p.timestamp >= SLEEPTIME)
1496 	      {
1497 		if (prog->v.p.comp->mode == pies_comp_inetd)
1498 		  {
1499 		    prog->v.p.status = status_listener;
1500 		    enable_socket (prog->v.p.socket);
1501 		  }
1502 		else
1503 		  {
1504 		    prog->v.p.status = status_running;
1505 		    prog->v.p.failcount = 0;
1506 		    prog->v.p.timestamp = 0;
1507 		    prog_start (prog);
1508 		  }
1509 	      }
1510 	    /* If there is no alarm pending, recompute next alarm.
1511 	       This allows to cope with eventual clock inaccuracies. */
1512 	    if (onalrm)
1513 	      pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM);
1514 	  }
1515 	break;
1516 
1517       case status_stopping:
1518 	check_stopping (prog, now);
1519 	break;
1520 
1521       case status_stopped:
1522 	if (IS_ACTIVE_COMPONENT (prog))
1523 	  prog_start (prog);
1524 	break;
1525 
1526       default:
1527 	break;
1528       }
1529 }
1530 
1531 static int
prog_start_prerequisites(struct prog * prog)1532 prog_start_prerequisites (struct prog *prog)
1533 {
1534   int ret = 0;
1535   pies_depmap_pos_t pos;
1536   struct component *comp;
1537   int warned = 0;
1538 
1539   if (!prog->active)
1540     return 1;
1541   for (comp = component_depmap_first (depmap_col, prog->v.p.comp->arridx, &pos);
1542        comp;
1543        comp = component_depmap_next (pos))
1544     {
1545       struct prog *p;
1546 
1547       if (!comp->prog || comp->flags & CF_PRECIOUS)
1548 	continue;
1549       if (!warned)
1550 	{
1551 	  debug (1, ("starting prerequisites of %s", prog_tag (prog)));
1552 	  warned = 1;
1553 	}
1554 
1555       if (!prog->active)
1556 	return 1;
1557 
1558       p = comp->prog;
1559       switch (p->v.p.status)
1560 	{
1561 	case status_running:
1562 	  continue;
1563 
1564 	case status_stopped:
1565 	  break;
1566 
1567 	case status_listener:
1568 	  continue;
1569 
1570 	case status_sleeping:
1571 	  /* FIXME: What to do in this case? */
1572 	  break;
1573 
1574 	case status_stopping:
1575 	  check_stopping (p, time (NULL));
1576 	  ret = 1;
1577 	  continue;
1578 
1579 	case status_finished:
1580 	  continue;
1581 	}
1582       prog_start (p);
1583       if (p->v.p.comp->mode == pies_comp_once
1584 	  || p->v.p.status != status_running)//FIXME
1585 	ret = 1;
1586     }
1587   depmap_end (pos);
1588 
1589   return ret;
1590 }
1591 
1592 void
prog_stop_dependents(struct prog * prog)1593 prog_stop_dependents (struct prog *prog)
1594 {
1595   struct component *comp;
1596   pies_depmap_pos_t pos;
1597   int warned = 0;
1598 
1599   prog_stop_redirectors (prog);
1600   for (comp = component_depmap_first (depmap_row, prog->v.p.comp->arridx, &pos);
1601        comp;
1602        comp = component_depmap_next (pos))
1603     {
1604       struct prog *dp = comp->prog;
1605       if (!dp) /* should not happen */
1606 	continue;
1607       if (!warned && dp->pid)
1608 	{
1609 	  debug (1, ("stopping dependencies of %s", prog_tag (prog)));
1610 	  warned = 1;
1611 	}
1612       prog_stop (dp, SIGTERM);
1613     }
1614   depmap_end (pos);
1615 }
1616 
1617 void
prog_stop(struct prog * prog,int sig)1618 prog_stop (struct prog *prog, int sig)
1619 {
1620   if (prog->pid == 0)
1621     return;
1622   if (prog->type == TYPE_COMPONENT)
1623     {
1624       if (prog->v.p.status == status_running)
1625 	{
1626 	  prog->v.p.status = status_stopping;
1627 	  prog->v.p.timestamp = time (NULL);
1628 	  pies_schedule_children (PIES_CHLD_RESCHEDULE_ALARM);
1629 	}
1630     }
1631   debug (1, ("stopping %s (%lu)", prog_tag (prog), (unsigned long) prog->pid));
1632   if (prog->type == TYPE_COMPONENT && prog->v.p.comp->flags & CF_SIGGROUP)
1633     kill (-prog->pid, sig);
1634   else
1635     kill (prog->pid, sig);
1636 }
1637 
1638 static void
print_status(const char * tag,pid_t pid,int status,int expect_term)1639 print_status (const char *tag, pid_t pid, int status, int expect_term)
1640 {
1641   int prio;
1642 
1643   if (SYSVINIT_ACTIVE)
1644     {
1645       if (debug_level <= 1)
1646 	return;
1647       prio = LOG_DEBUG;
1648     }
1649   else
1650     prio = LOG_ERR;
1651 
1652   if (WIFEXITED (status))
1653     {
1654       if (WEXITSTATUS (status) == 0)
1655 	debug (1, (_("%s (%lu) exited successfully"),
1656 		   tag, (unsigned long) pid));
1657       else
1658 	logmsg (prio, _("%s (%lu) exited with status %d"),
1659 		tag, (unsigned long) pid,
1660 		WEXITSTATUS (status));
1661     }
1662   else if (WIFSIGNALED (status))
1663     {
1664       char const *coremsg = "";
1665 
1666       if (expect_term && WTERMSIG (status) == SIGTERM)
1667 	prio = LOG_DEBUG;
1668 
1669 #ifdef WCOREDUMP
1670       if (WCOREDUMP (status))
1671 	coremsg = _(" (core dumped)");
1672 #endif
1673       logmsg (prio, _("%s (%lu) terminated on signal %d%s"),
1674 	      tag, (unsigned long) pid,
1675 	      WTERMSIG (status), coremsg);
1676     }
1677   else if (WIFSTOPPED (status))
1678     logmsg (prio, _("%s (%lu) stopped on signal %d"),
1679 	    tag, (unsigned long) pid,
1680 	    WSTOPSIG (status));
1681   else
1682     logmsg (prio, _("%s (%lu) terminated with unrecognized status: %d"),
1683 	    tag, (unsigned long) pid, status);
1684 }
1685 
1686 static void propagate_child_exit (pid_t) ATTRIBUTE_NORETURN;
1687 
1688 static void
propagate_child_exit(pid_t pid)1689 propagate_child_exit (pid_t pid)
1690 {
1691   int wait_status;
1692 
1693   while (waitpid (pid, &wait_status, 0) == -1)
1694     if (errno != EINTR)
1695       {
1696 	logfuncall ("waitpid", NULL, errno);
1697 	exit (EX_OSERR);
1698       }
1699 
1700   if (WIFSIGNALED (wait_status))
1701     {
1702       int sig = WTERMSIG (wait_status);
1703       signal (sig, SIG_DFL);
1704       raise (sig);
1705     }
1706   else if (WIFEXITED (wait_status))
1707     exit (WEXITSTATUS (wait_status));
1708   exit (127);
1709 }
1710 
1711 char *
wordsplit_string(struct wordsplit const * ws)1712 wordsplit_string (struct wordsplit const *ws)
1713 {
1714   char *ret, *p;
1715   size_t count = ws->ws_wordc + ws->ws_offs;
1716   char **argv = grecs_calloc (count, sizeof (argv[0]));
1717   size_t i;
1718   size_t len = 0;
1719 
1720   for (i = 0; i < count; i++)
1721     {
1722       argv[i] = quotearg_n (i, ws->ws_wordv[i]);
1723       len += strlen (argv[i]);
1724     }
1725   len += count;
1726   ret = grecs_malloc (len);
1727 
1728   for (i = 0, p = ret; i < count; i++)
1729     {
1730       strcpy (p, argv[i]);
1731       p += strlen (argv[i]);
1732       *p++ = ' ';
1733     }
1734   p[-1] = 0;
1735   free (argv);
1736   return ret;
1737 }
1738 
1739 void
send_msg(char * rcpts,const char * msg_text)1740 send_msg (char *rcpts, const char *msg_text)
1741 {
1742   int i, j, k;
1743   pid_t child_pid, grand_child_pid;
1744   struct wordsplit ws;
1745   int p[2];
1746   size_t size;
1747 
1748   ws.ws_offs = mailer_argc;
1749   ws.ws_delim = ",";
1750   if (wordsplit (rcpts, &ws,
1751 		 WRDSF_NOVAR | WRDSF_NOCMD | WRDSF_DELIM | WRDSF_DOOFFS))
1752     {
1753       logmsg (LOG_ERR,
1754 	      _("cannot parse recipient address list (%s)"),
1755 	      rcpts);
1756       return;
1757     }
1758 
1759   debug (1, (_("sending notification to %s"), rcpts));
1760 
1761   /* Copy mailer arguments */
1762   for (i = 0; i < mailer_argc; i++)
1763     ws.ws_wordv[i] = mailer_argv[i];
1764   /* j - number of the recipient;
1765      i - index of the ws_wordv being converted;
1766      k - index of the ws_wordv to store the converted value to.
1767 
1768      Normally i == k, unless there are some invalid ws_wordv's,
1769      in which case i > k.
1770   */
1771   for (j = 0, k = i; j < ws.ws_wordc; j++, i++)
1772     {
1773       char *arg = ws.ws_wordv[i];
1774       size_t len;
1775 
1776       while (*arg && c_isblank (*arg))
1777 	arg++;
1778       len = strlen (arg);
1779       if (len > 0)
1780 	{
1781 	  while (len > 0 && c_isblank (arg[len - 1]))
1782 	    len--;
1783 	}
1784       if (len == 0)
1785 	continue;
1786       if (arg[0] == '<' && arg[len-1] == '>')
1787 	{
1788 	  arg++;
1789 	  len -= 2;
1790 	}
1791       if (len == 0)
1792 	continue;
1793       memmove (ws.ws_wordv[k], arg, len);
1794       ws.ws_wordv[k][len] = 0;
1795       k++;
1796     }
1797   ws.ws_wordv[k] = NULL;
1798 
1799   /* Fork a child: */
1800   child_pid = fork ();
1801 
1802   if (child_pid < 0)
1803     {
1804       wordsplit_free (&ws);
1805       logmsg (LOG_ERR,
1806 	      _("cannot send mail: fork failed: %s"), strerror (errno));
1807       return;
1808     }
1809 
1810   if (child_pid)
1811     {
1812       char *cmd = wordsplit_string (&ws);
1813       wordsplit_free (&ws);
1814       debug (1, (_("started mailer: %s, pid=%lu"),
1815 		   cmd, (unsigned long) child_pid));
1816       register_command (mailer_program, cmd, child_pid);
1817       return;
1818     }
1819 
1820   /* Child process */
1821   /* ============= */
1822   signal_setup (SIG_DFL);
1823   setsid ();
1824   if (pipe (p))
1825     {
1826       logmsg (LOG_ERR, _("cannot send mail: pipe failed: %s"),
1827 	      strerror (errno));
1828       wordsplit_free (&ws);
1829       exit (EX_OSERR);
1830     }
1831 
1832   grand_child_pid = fork ();
1833   if (grand_child_pid < 0)
1834     {
1835       logmsg (LOG_ERR,
1836 	      _("cannot send mail: fork failed: %s"), strerror (errno));
1837       return;
1838     }
1839 
1840   if (grand_child_pid == 0)
1841     {
1842       /* Grand-child */
1843       /* =========== */
1844       if (p[0] != 0 && p[1] != 0)
1845 	close (0);
1846       close (p[1]);
1847       dup2 (p[0], 0);
1848       execv (mailer_program, ws.ws_wordv);
1849       exit (127);
1850     }
1851 
1852   /* Child again */
1853   close (p[0]);
1854 
1855   size = strlen (msg_text);
1856   while (size)
1857     {
1858       ssize_t rc = write (p[1], msg_text, size);
1859       if (rc <= 0)
1860 	{
1861 	  logmsg (LOG_ERR, _("cannot write to pipe: %s"),
1862 		  rc == 0 ? "EOF" : strerror (errno));
1863 	  break;
1864 	}
1865       size -= rc;
1866       msg_text += rc;
1867     }
1868   close (p[1]);
1869 
1870   propagate_child_exit (grand_child_pid);
1871 }
1872 
1873 static const char default_termination_message[] =
1874 "From: <>\n"
1875 "X-Agent: ${canonical_program_name} (${package} ${version})\n"
1876 "Subject: Component ${component} ${termination} ${retcode}.\n"
1877 "\n";
1878 
1879 struct notify_closure
1880 {
1881   const char *tag;
1882   int status;
1883   struct action *act;
1884 };
1885 
1886 static int
notify_get_tag(char ** ret,void * data)1887 notify_get_tag (char **ret, void *data)
1888 {
1889   struct notify_closure const *clos = data;
1890   char *s = strdup (clos->tag);
1891   if (!s)
1892     return WRDSE_NOSPACE;
1893   *ret = s;
1894   return WRDSE_OK;
1895 }
1896 
1897 static int
notify_get_termination(char ** ret,void * data)1898 notify_get_termination (char **ret, void *data)
1899 {
1900   struct notify_closure const *clos = data;
1901   char const *msg;
1902   char *s;
1903 
1904   if (WIFEXITED (clos->status))
1905     /* TRANSLATORS: The subject of this statement is 'component' */
1906     msg = _("exited with code");
1907   else if (WIFSIGNALED (clos->status))
1908     /* TRANSLATORS: The subject of this statement is 'component' */
1909     msg = _("terminated on signal");
1910   else
1911     msg = "UNKNOWN";
1912 
1913   s = strdup (msg);
1914   if (!s)
1915     return WRDSE_NOSPACE;
1916   *ret = s;
1917   return WRDSE_OK;
1918 }
1919 
1920 static int
notify_get_retcode(char ** ret,void * data)1921 notify_get_retcode (char **ret, void *data)
1922 {
1923   struct notify_closure const *clos = data;
1924   char *s = NULL;
1925   size_t l = 0;
1926 
1927   if (WIFEXITED (clos->status))
1928     grecs_asprintf (&s, &l, "%d", WEXITSTATUS (clos->status));
1929   else if (WIFSIGNALED (clos->status))
1930     grecs_asprintf (&s, &l, "%d", WTERMSIG (clos->status));
1931   else
1932     s = strdup ("UNKNOWN");
1933   if (!s)
1934     return WRDSE_NOSPACE;
1935   *ret = s;
1936   return WRDSE_OK;
1937 }
1938 
1939 struct notify_variable
1940 {
1941   char *name;
1942   size_t name_length;
1943   int (*get) (char **ret, void *data);
1944 };
1945 
1946 static struct notify_variable notify_vartab[] = {
1947 #define S(s) #s, sizeof(#s)-1
1948   { S(component),     notify_get_tag },
1949   { S(termination),   notify_get_termination },
1950   { S(retcode),       notify_get_retcode },
1951 #undef S
1952   { NULL }
1953 };
1954 
1955 static int
notify_getvar(char ** ret,const char * vptr,size_t vlen,void * data)1956 notify_getvar (char **ret, const char *vptr, size_t vlen, void *data)
1957 {
1958   struct notify_variable *var;
1959   for (var = notify_vartab; var->name; var++)
1960     if (var->name_length == vlen && memcmp (var->name, vptr, vlen) == 0)
1961       return var->get (ret, data);
1962   return WRDSE_UNDEF;
1963 }
1964 
1965 static void
notify(const char * tag,int status,struct action * act)1966 notify (const char *tag, int status, struct action *act)
1967 {
1968   const char *env[] = {
1969 #define PROGRAM_NAME_IDX 1
1970     "program_name", NULL,
1971 #define INSTANCE_IDX 3
1972     "instance", NULL,
1973     "canonical_program_name", "pies",
1974     "package", PACKAGE_NAME,
1975     "version", PACKAGE_VERSION,
1976     NULL
1977   };
1978   struct wordsplit ws;
1979   struct notify_closure closure;
1980 
1981   closure.tag = tag;
1982   closure.status = status;
1983   closure.act = act;
1984 
1985   env[PROGRAM_NAME_IDX] = program_name;
1986   env[INSTANCE_IDX] = instance;
1987 
1988   ws.ws_env = env;
1989   ws.ws_getvar = notify_getvar;
1990   ws.ws_closure = &closure;
1991   if (wordsplit (act->message ? act->message : default_termination_message,
1992 		 &ws,
1993 		 WRDSF_NOSPLIT | WRDSF_NOCMD | WRDSF_QUOTE |
1994 		 WRDSF_ENV | WRDSF_ENV_KV |
1995 		 WRDSF_GETVAR | WRDSF_CLOSURE))
1996     {
1997       logmsg (LOG_ERR, "wordsplit: %s", wordsplit_strerror (&ws));
1998       return;
1999     }
2000   send_msg (act->addr, ws.ws_wordv[0]);
2001   wordsplit_free (&ws);
2002 }
2003 
2004 static int
status_matches_p(struct action * act,unsigned status)2005 status_matches_p (struct action *act, unsigned status)
2006 {
2007   int i;
2008 
2009   if (act->nstat == 0)
2010     return 1;
2011   for (i = 0; i < act->nstat; i++)
2012     if (act->status[i] == status)
2013       return 1;
2014   return 0;
2015 }
2016 
2017 static void
run_command(struct action * act,struct prog * prog,unsigned retcode,pid_t child_pid)2018 run_command (struct action *act, struct prog *prog, unsigned retcode,
2019 	     pid_t child_pid)
2020 {
2021   pid_t pid, master_pid;
2022   char *argv[4];
2023   char buf[INT_BUFSIZE_BOUND (uintmax_t)];
2024 
2025   master_pid = getpid ();
2026 
2027   /* FIXME: optionally set output redirectors for this command? */
2028   pid = fork ();
2029 
2030   if (pid == (pid_t) -1)
2031     {
2032       logmsg (LOG_ERR, "fork: %s", strerror (errno));
2033       return;
2034     }
2035 
2036   if (pid == 0)
2037     {
2038       debug (1, (_("executing %s"), act->command));
2039       /* Child */
2040       setsid ();
2041       setenv ("PIES_VERSION", PACKAGE_VERSION, 1);
2042       setenv ("PIES_COMPONENT", prog_tag (prog), 1);
2043       setenv ("PIES_MASTER_PID", umaxtostr (master_pid, buf), 1);
2044       setenv ("PIES_PID", umaxtostr (child_pid, buf), 1);
2045       if (retcode & STATUS_SIG_BIT)
2046 	setenv ("PIES_SIGNAL", umaxtostr (STATUS_CODE (retcode), buf), 1);
2047       else
2048 	setenv ("PIES_STATUS", umaxtostr (STATUS_CODE (retcode), buf), 1);
2049 
2050       pies_close_fds (3);
2051 
2052       argv[0] = "/bin/sh";
2053       argv[1] = "-c";
2054       argv[2] = act->command;
2055       argv[3] = NULL;
2056 
2057       execv (argv[0], argv);
2058       exit (127);
2059     }
2060 
2061   /* Master */
2062   debug (1, (_("started command: %s, pid=%lu"),
2063 	     act->command, (unsigned long) pid));
2064   register_command ((char*) _("[action]"), grecs_strdup (act->command), pid);
2065 }
2066 
2067 static void
react(struct prog * prog,int status,pid_t pid)2068 react (struct prog *prog, int status, pid_t pid)
2069 {
2070   unsigned retcode;
2071   struct grecs_list *list = prog->v.p.comp->act_list;
2072 
2073   if (!list)
2074     list = default_component.act_list;
2075 
2076   if (WIFEXITED (status))
2077     {
2078       retcode = WEXITSTATUS (status);
2079       debug (1, (_("%s: terminated with code %d"), prog_tag (prog), retcode));
2080     }
2081   else if (WIFSIGNALED (status))
2082     {
2083       retcode = WTERMSIG (status);
2084       debug (1, (_("%s: terminated on signal %d"), prog_tag (prog), retcode));
2085       retcode |= STATUS_SIG_BIT;
2086     }
2087   else
2088     {
2089       debug (1, (_("%s: unrecognized termination status"), prog_tag (prog)));
2090       /* Enforce default action: */
2091       list = NULL;
2092     }
2093 
2094   if (list)
2095     {
2096       struct grecs_list_entry *ep;
2097       for (ep = list->head; ep; ep = ep->next)
2098 	{
2099 	  struct action *act = ep->data;
2100 
2101 	  if (status_matches_p (act, retcode))
2102 	    {
2103 	      if (act->command)
2104 		{
2105 		  run_command (act, prog, retcode, pid);
2106 		}
2107 
2108 	      switch (act->act)
2109 		{
2110 		case action_restart:
2111 		  if (prog->v.p.comp->mode != pies_comp_inetd)
2112 		    prog_start (prog);
2113 		  break;
2114 
2115 		case action_disable:
2116 		  logmsg (LOG_NOTICE, _("disabling component %s"),
2117 			  prog_tag (prog));
2118 		  prog->active = 0;
2119 		  /* FIXME:
2120 		     if (prog->v.p.comp->mode == pies_comp_inetd)
2121 		     disable_socket (prog->v.p.socket);
2122 		  */
2123 		}
2124 	      if (act->addr)
2125 		notify (prog_tag (prog), status, act);
2126 	      break;
2127 	    }
2128 	}
2129     }
2130 
2131   if (!list && prog->v.p.comp->mode != pies_comp_inetd)
2132     /* Default action: */
2133     prog_start (prog);
2134 }
2135 
2136 void
progman_cleanup(int expect_term)2137 progman_cleanup (int expect_term)
2138 {
2139   pid_t pid;
2140   int status;
2141 
2142   if (!expect_term)
2143     expect_term = progman_waiting_p ();
2144   while ((pid = waitpid (-1, &status, WNOHANG)) > 0)
2145     {
2146       struct prog *prog = prog_lookup_by_pid (pid);
2147       if (!prog)
2148 	{
2149 	  print_status (_("unknown child"), pid, status, expect_term);
2150 	  continue;
2151 	}
2152       prog->pid = 0;
2153       switch (prog->type)
2154 	{
2155 	case TYPE_COMPONENT:
2156 	  print_status (prog_tag (prog), pid, status, expect_term);
2157 	  prog->stop = 0;
2158 	  if (prog->v.p.comp->mode == pies_comp_inetd)
2159 	    {
2160 	      struct prog *listener = prog->v.p.listener;
2161 
2162 	      listener->v.p.num_instances--;
2163 	      if (prog->v.p.cclass)
2164 		{
2165 		  prog->v.p.cclass->count--;
2166 		  if (debug_level > 1)
2167 		    conn_class_report (LOG_DEBUG, prog->v.p.cclass);
2168 		  if (prog->v.p.cclass->count == 0)
2169 		    {
2170 		      conn_class_remove (prog->v.p.cclass);
2171 		      prog->v.p.cclass = NULL;
2172 		    }
2173 		}
2174 
2175 	      prog_stop_redirectors (prog);
2176 	      if (listener->v.p.num_instances == 0
2177 		  && !component_is_active (prog->v.p.comp))
2178 		destroy_prog (&listener);
2179 	      else
2180 		{
2181 		  if (!expect_term)
2182 		    react (listener, status, pid);
2183 		  if (listener->v.p.comp->flags & CF_WAIT)
2184 		    enable_socket (listener->v.p.socket);
2185 		}
2186 	      destroy_prog (&prog);
2187 	    }
2188 	  else
2189 	    {
2190 	      if (PIES_SYSVINIT_ENABLED
2191 		  && prog->v.p.comp->mode >= pies_mark_sysvinit
2192 		  && prog->v.p.comp->mode != pies_comp_ondemand)
2193 		{
2194 		  sysvinit_acct (SYSV_ACCT_PROC_STOP, "", prog_tag (prog),
2195 				 pid, "");
2196 		  prog->v.p.status = status_finished;
2197 
2198 		  if (prog->wait)
2199 		    {
2200 		      pies_schedule_children (PIES_CHLD_WAKEUP);
2201 		      prog->wait = 0;
2202 		    }
2203 		}
2204 	      else if (prog->v.p.comp->mode == pies_comp_startup)
2205 		{
2206 		  prog->v.p.status = status_finished;
2207 		  if (!progman_startup_phase ())
2208 		    pies_schedule_children (PIES_CHLD_WAKEUP);
2209 		}
2210 	      else
2211 		{
2212 		  if (is_sysvinit (prog->v.p.comp))
2213 		    sysvinit_acct (SYSV_ACCT_PROC_STOP, "",
2214 				   prog_tag (prog), pid, "");
2215 
2216 		  prog->v.p.status = status_stopped;
2217 		  prog_stop_dependents (prog);
2218 		  if (!expect_term)
2219 		    react (prog, status, pid);
2220 		}
2221 
2222 	      if (!component_is_active (prog->v.p.comp))
2223 		destroy_prog (&prog);
2224 	    }
2225 
2226 	  break;
2227 
2228 	case TYPE_COMMAND:
2229 	  print_status (prog_tag (prog), pid, status, expect_term);
2230 	  destroy_prog (&prog);
2231 	  break;
2232 	}
2233     }
2234 
2235   if (!expect_term)
2236     /* This will also recompute alarm settings, if necessary */
2237     progman_wake_sleeping (0);
2238 }
2239 
2240 void
progman_stop_component(struct prog ** progptr)2241 progman_stop_component (struct prog **progptr)
2242 {
2243   struct prog *prog = *progptr;
2244   if (prog && IS_COMPONENT (prog))
2245     {
2246       switch (prog->v.p.status)
2247 	{
2248 	case status_running:
2249 	  logmsg (LOG_INFO, _("stopping component %s"), prog_tag (prog));
2250 	  prog_stop (prog, SIGTERM);
2251 	  break;
2252 
2253 	case status_listener:
2254 	  prog_deactivate_listener (prog);
2255 	  /* fall through */
2256 	case status_stopped:
2257 	  prog->stop = 0;
2258 	  if (!component_is_active (prog->v.p.comp))
2259 	    destroy_prog (progptr);
2260 	  break;
2261 
2262 	case status_sleeping:
2263 	  if (!component_is_active (prog->v.p.comp))
2264 	    destroy_prog (progptr);
2265 	  else if (prog->stop)
2266 	    prog->stop = 0;
2267 	  else
2268 	    {
2269 	      logmsg (LOG_INFO, _("waking up component %s"), prog_tag (prog));
2270 	      prog->v.p.failcount = 0;
2271 	    }
2272 	  break;
2273 
2274 	case status_stopping:
2275 	  break;
2276 
2277 	case status_finished:
2278 	  prog->stop = 0;
2279 	  if (!component_is_active (prog->v.p.comp))
2280 	    destroy_prog (progptr);
2281 	  else
2282 	    logmsg (LOG_INFO,
2283 		    _("stopping component %s: component not started"),
2284 		    prog_tag (prog));
2285 	}
2286     }
2287 }
2288 
2289 void
prog_deactivate_listener(struct prog * prog)2290 prog_deactivate_listener (struct prog *prog)
2291 {
2292   logmsg (LOG_INFO, _("deactivating listener %s"), prog_tag (prog));
2293   if (prog->v.p.socket != -1)
2294     {
2295       deregister_socket (prog->v.p.socket);
2296       prog->v.p.socket = -1;
2297     }
2298 }
2299 
2300 int
prog_activate_listener(struct prog * prog)2301 prog_activate_listener (struct prog *prog)
2302 {
2303   struct component *comp = prog->v.p.comp;
2304 
2305   logmsg (LOG_INFO, _("activating listener %s"), prog_tag (prog));
2306   if (comp->mode == pies_comp_inetd && !ISCF_TCPMUX (comp->flags)
2307       && prog->v.p.socket == -1)
2308     {
2309       int fd = create_socket (comp->socket_url,
2310 			      comp->socket_type,
2311 			      comp->privs.user, comp->umask);
2312       if (fd == -1)
2313 	return -1;
2314       else if (register_program_socket (comp->socket_type, fd, prog, NULL))
2315 	{
2316 	  close (fd);
2317 	  return -1;
2318 	}
2319       else
2320 	prog->v.p.socket = fd;
2321     }
2322   return 0;
2323 }
2324 
2325 /* Starting at PROG, find first program component marked for termination. */
2326 static struct prog *
prog_to_stop(struct prog * prog)2327 prog_to_stop (struct prog *prog)
2328 {
2329   for (; prog; prog = prog->next)
2330     if (IS_COMPONENT (prog) && prog->stop)
2331       break;
2332   return prog;
2333 }
2334 
2335 #define DIAG_CON \
2336   (SYSVINIT_ACTIVE ? (DIAG_TO_STDERR|DIAG_REOPEN_LOG) : diag_output)
2337 
2338 /* Stop all program components marked for termination.  Wait at most
2339    2*shutdown_timeout seconds. */
2340 void
progman_gc(void)2341 progman_gc (void)
2342 {
2343   time_t start;
2344   struct prog *prog, *next;
2345 
2346   /* Find first marked prog */
2347   prog = prog_to_stop (proghead);
2348   if (!prog)
2349     return;
2350 
2351   /* First round: */
2352   /* Gracefully stop it and all marked programs that follow */
2353   diagmsg (DIAG_CON, LOG_INFO, "Sending processes the TERM signal");
2354   start = time (NULL);
2355   do
2356     {
2357       next = prog->next;
2358       progman_stop_component (&prog);
2359     }
2360   while ((prog = prog_to_stop (next)));
2361 
2362   /* Wait for them to terminate */
2363   while (1)
2364     {
2365       progman_cleanup (1);
2366       prog = prog_to_stop (proghead);
2367       if (!prog)
2368 	return;
2369       if (time (NULL) - start < shutdown_timeout)
2370 	sleep (1);
2371       else
2372 	break;
2373     }
2374 
2375   /* Second round: */
2376   /* Kill the remaining programs with SIGKILL */
2377   diagmsg (DIAG_CON, LOG_INFO, "Sending processes the KILL signal");
2378   start = time (NULL);
2379   do
2380     {
2381       next = prog->next;
2382       prog_stop (prog, SIGKILL);
2383     }
2384   while ((prog = prog_to_stop (next)));
2385 
2386   /* Wait for them to terminate */
2387   while (1)
2388     {
2389       progman_cleanup (1);
2390       prog = prog_to_stop (proghead);
2391       if (!prog)
2392 	return;
2393       if (time (NULL) - start < shutdown_timeout)
2394 	sleep (1);
2395       else
2396 	break;
2397     }
2398 
2399   /* FIXME: Report remaining programs */
2400 
2401 }
2402 
2403 static int
start_shutdown(struct prog * prog,void * data)2404 start_shutdown (struct prog *prog, void *data)
2405 {
2406   if (IS_COMPONENT (prog) && prog->v.p.comp->mode == pies_comp_shutdown)
2407     {
2408       int *p = data;
2409       if (!*p)
2410 	{
2411 	    diagmsg (DIAG_CON, LOG_INFO, "Starting shutdown components");
2412 	    *p = 1;
2413 	}
2414       prog->active = 1;
2415       prog_start (prog);
2416       prog->stop = 1;
2417     }
2418   return 0;
2419 }
2420 
2421 void
program_shutdown(void)2422 program_shutdown (void)
2423 {
2424   time_t start = time (NULL);
2425   int sd = 0;
2426 
2427   /* Activate shutdown components. */
2428   progman_foreach (start_shutdown, &sd);
2429   while (prog_to_stop (proghead))
2430     {
2431       progman_cleanup (1);
2432       if (time (NULL) - start < shutdown_timeout)
2433 	sleep (1);
2434       else
2435 	{
2436 	  progman_gc ();
2437 	  break;
2438 	}
2439     }
2440 }
2441 
2442 static int
mark_for_stopping(struct prog * prog,void * data)2443 mark_for_stopping (struct prog *prog, void *data)
2444 {
2445   if (IS_COMPONENT (prog))
2446     prog->stop = 1;
2447   return 0;
2448 }
2449 
2450 void
progman_stop(void)2451 progman_stop (void)
2452 {
2453   progman_foreach (mark_for_stopping, NULL);
2454   progman_gc ();
2455   program_shutdown ();
2456 }
2457 
2458 /* EOF */
2459