Esempio n. 1
0
/* add/remove iptable drop rule to VIP */
static void
handle_iptable_rule_to_vip(ip_address_t *ipaddress, int cmd, char *ifname, void *unused)
{
	char  *argv[10];
	unsigned int i = 0;
	int if_specifier = -1;
	char *addr_str;

	if (global_data->vrrp_iptables_inchain[0] == '\0')
		return;

	if (IP_IS6(ipaddress)) {
		handle_iptable_rule_to_NA(ipaddress, cmd, ifname);
		argv[i++] = "ip6tables";
	} else {
		argv[i++] = "iptables";
	}

	addr_str = ipaddresstos(NULL, ipaddress);

	argv[i++] = cmd ? "-A" : "-D";
	argv[i++] = global_data->vrrp_iptables_inchain;
	argv[i++] = "-d";
	argv[i++] = addr_str;
	if (IP_IS6(ipaddress) && IN6_IS_ADDR_LINKLOCAL(&ipaddress->u.sin6_addr)) {
		if_specifier = i;
		argv[i++] = "-i";
		argv[i++] = ifname;
	}
	argv[i++] = "-j";
	argv[i++] = "DROP";
	argv[i] = NULL;

	if (fork_exec(argv) < 0)
		log_message(LOG_ERR, "Failed to %s iptable drop rule"
				     " to vip %s", (cmd) ? "set" : "remove", addr_str);
	else
		ipaddress->iptable_rule_set = (cmd != IPADDRESS_DEL);

	if (global_data->vrrp_iptables_outchain[0] == '\0')
		return;

	argv[2] = global_data->vrrp_iptables_outchain ;
	argv[3] = "-s";
	if (if_specifier >= 0)
		argv[if_specifier] = "-o";

	if (fork_exec(argv) < 0)
		log_message(LOG_ERR, "Failed to %s iptable drop rule"
				     " from vip %s", (cmd) ? "set" : "remove", addr_str);
}
Esempio n. 2
0
void ring(char *d)
{
	static char buf[BUF_SIZE];	
	snprintf(buf, BUF_SIZE, "%s %s", cmd.ring_prog, d);	
	dbg_print("Ringing %s", buf);
	fork_exec(buf);
}
Esempio n. 3
0
File: core.c Progetto: udoprog/svz
int
sv_exec(callspace *cs, int argv[])
{
    int *array = array_get(g_cs, argv[0]);
    int array_c = array_length(g_cs, argv[0]);

    char **fork_argv = malloc(sizeof(char*) * (array_c + 1));

    int i;
    char *arg;

    for (i = 0; i < array_c; i++)
    {
        arg = string_get(g_cs, array[i]);

        if (strcmp(arg, "%%") == 0)
        {
            fork_argv[i] = g_last_pid_str;
        }
        else
        {
            fork_argv[i] = arg;
        }
    }

    fork_argv[i+1] = NULL;

    return fork_exec(array_c, fork_argv);
}
/* Unregister with netreport, relay a status byte to the parent, clean up
 * the pid file, and bail. */
static void
failureExit(int exitCode) {
    fork_exec(TRUE, "/sbin/netreport", "-r", NULL, NULL);
    relay_exitcode(exitCode);
    doPidFile(NULL);
    exit(exitCode);
}
Esempio n. 5
0
/**
 * Run a serie of piped commands
 * @param n    number of commands in the pipe
 * @param cmds arrays of commands
 */
void fork_runline(int n, char **cmds){
  int in = STDIN_FILENO; // file descriptor for in -- initially set as stdin
  int out;
  int status;
  pid_t pid;
  int fd[2]; // file descriptor for piping

  //for each command, create a fork to execute except the last one.
  for(int i=0 ; i<n-1 ; i++){
    pipe(fd);
    out = fd[1]; // fd[1] is write end of the pipe
    pid = fork_exec(in, out, cmds[i]);

    //only parent process of the fork_exec will reach here
    waitpid(pid, &status, 0); // wait for its child to finish first!

    // close(fd[0]); //TODO where to put this

    close(out); // no noweed for writing since the child will write
    in = fd[0]; // now the in side of the pipe became in for the next command

  }

  //Last stage of the pipeline -- redirect in to be stdin
  if(in!=STDIN_FILENO)
    dup2(in,STDIN_FILENO);

  char *cmd = cmds[n-1];
  char * const cmdArgv[INPUT_SIZE] = {cmd, NULL};
  // fflush(stdout);
  execvp(cmdArgv[0], cmdArgv);
  perror("last");
  exit(-1);
}
Esempio n. 6
0
int main(int argc, char argv[])
{
   pid_t pid[10];

   fork_exec("ping 127.0.0.1", FALSE, &pid[0]);
   fork_exec("ping 127.0.0.1", FALSE, &pid[1]);

   /* lacy */
   if(argc == 1)
      sleep(2);
   else
      sleep(60*60); // 1h

   kill(pid[0],SIGTERM);
   kill(pid[1],SIGKILL);
   blocking_wait_on_child(pid[0]);
   blocking_wait_on_child(pid[1]);

   return 0;
}
Esempio n. 7
0
/*
 * While inside interactive mode, launch the external command cmd on the given
 * file.
 */
void
wins_launch_external (char *file, char *cmd)
{
  char *arg[] = { cmd, file, NULL };
  int pid;

  wins_prepare_external ();
  if ((pid = fork_exec (NULL, NULL, cmd, arg)))
    child_wait (NULL, NULL, pid);
  wins_unprepare_external ();
}
Esempio n. 8
0
void rclick_taskbar(int x)
{
	XEvent ev;
	int mousex, mousey;
	Rect bounddims;
	unsigned int current_item = UINT_MAX;
	Window constraint_win;
	XSetWindowAttributes pattr;

	get_mouse_position(&mousex, &mousey);

	bounddims.x = 0;
	bounddims.y = 0;
	bounddims.width = DisplayWidth(dsply, screen);
	bounddims.height = BARHEIGHT();

	constraint_win = XCreateWindow(dsply, root, bounddims.x, bounddims.y, bounddims.width, bounddims.height, 0, CopyFromParent, InputOnly, CopyFromParent, 0, &pattr);
	XMapWindow(dsply, constraint_win);

	if (!(XGrabPointer(dsply, root, False, MouseMask, GrabModeAsync, GrabModeAsync, constraint_win, None, CurrentTime) == GrabSuccess))
	{
		XDestroyWindow(dsply, constraint_win);
		return;
	}
	draw_menubar();
	update_menuitem(INT_MAX); // force initial highlight
	current_item = update_menuitem(x);
	do
	{
		XMaskEvent(dsply, MouseMask|KeyMask, &ev);
		switch (ev.type)
		{
			case MotionNotify:
				current_item = update_menuitem(ev.xmotion.x);
				break;
			case ButtonRelease:
				if (current_item != UINT_MAX)
				{
					fork_exec(menuitems[current_item].command);
				}
				break;
			case KeyPress:
				XPutBackEvent(dsply, &ev);
				break;
		}
	}
	while (ev.type != ButtonPress && ev.type != ButtonRelease && ev.type != KeyPress);

	redraw_taskbar();
	XUnmapWindow(dsply, constraint_win);
	XDestroyWindow(dsply, constraint_win);
	ungrab();
}
void
context_callback ( MBTrayApp *app )
{
#ifdef USE_LIBSN
  if (CONTEXT_APP_WANT_SN)
    {
      sn_activate(CONTEXT_APP, CONTEXT_APP " " CONTEXT_APP_ARGS);      
      return;
    }
#endif

  fork_exec(CONTEXT_APP " " CONTEXT_APP_ARGS);
}
Esempio n. 10
0
/**
 * @brief Make sure the country code is effective imediately
 *
 * @param path		Path of command
 * @param argv[]	Arguments
 * @param idx		Index
 *
 * @return			0			Success
 					!0 			Failed
 */
static int set_ccode_cmd(int idx)
{
	const char *argv[4];
	int ret;

	argv[0] = "wl";
	argv[1] = "country";
	argv[2] = g_ccode[idx].code;
	argv[3] = NULL;

	ret = fork_exec("/bin/wl", (char *const *) argv);
	if (0 != ret)
	{
		DEBUG("%s, set ccode failed\n", __FUNCTION__);
	}

	return ret;
}
Esempio n. 11
0
static int
do_exec (ssh_event event,
         ssh_channel chan,
         const gchar *cmd)
{
  socket_t fd;
  short events;

  fd = fork_exec (cmd);
  if (fd < 0)
    return -1;

  cb.userdata = GINT_TO_POINTER (fd);
  ssh_callbacks_init(&cb);
  ssh_set_channel_callbacks (chan, &cb);

  events = POLLIN | POLLOUT | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
  if (ssh_event_add_fd (event, fd, events, fd_data, chan) != SSH_OK)
    g_return_val_if_reached(-1);

  return 0;
}
Esempio n. 12
0
int
ewmh_handle_root_message(Wm *w, XClientMessageEvent *e)
{
  /* Handle client messages _sent_ to root window */

   Client *c = NULL;

   dbg("%s() called\n", __func__);

   if (e->message_type == w->atoms[_NET_ACTIVE_WINDOW])
     {
       dbg("%s() got active window message for win %li", __func__, e->window);
       if ((c = wm_find_client(w, e->window, WINDOW)) != NULL)
	 {
	   if (c->type == MBCLIENT_TYPE_DIALOG
	       && c->trans != NULL)
	     {
	       /* 
                * If an attempt has been made to activate a hidden
                * dialog, activate its parent app first.
                *
                * Note this is mainly to work with some task selectors
                * ( eg the gnome one, which activates top dialog ).
                *
                * XXX wm_activate_client() should probably do this.
	       */

	       Client *parent = c->trans;

	       while (parent->trans != NULL)
		 parent = parent->trans;

	       if (parent != wm_get_visible_main_client(w))
		 wm_activate_client(parent);
	     }
	   /* Likely activated by a TN so start pinging if aggresive setup */
	   if (w->config->ping_aggressive 
	       && c->type == MBCLIENT_TYPE_APP
	       && c != wm_get_visible_main_client(w))
	     ewmh_ping_client_start (c);
	   wm_activate_client(c);
	 }
       return 1;
     } 
   else if (e->message_type == w->atoms[_NET_CLOSE_WINDOW]) 
     {
       if ((c = wm_find_client(w, e->window, WINDOW)) != NULL)
	 client_deliver_delete(c);
       return 1;
     } 
   else if (e->message_type == w->atoms[WM_PROTOCOLS]
	    && e->data.l[0] == w->atoms[_NET_WM_PING]) 
     {
       if ((c = wm_find_client(w, e->data.l[1], WINDOW)) != NULL)
	 {
	   dbg("%s() pong from %s\n", __func__, c->name);

	   /* We got a response to a ping. stop pinging it now
	    * until close button is pressed again. 
	   */
	   if (c->ping_handler_called)
	     {
	       int len;
	       char *buf;
	       /* aha! this was thought be be dead but has come
		* alive again..
	       */
	       len = strlen(w->config->ping_handler) + 32;
	       buf = malloc(len);

	       if (buf)
		 {
		   snprintf(buf, len-1, "%s %i %li 1",
			    w->config->ping_handler,
			    c->pid,
			    c->window);
		   
		   fork_exec(buf);
		   
		   free(buf);
		 }
	     }

	   if (w->config->ping_aggressive)
	     {
	       if (c->pings_pending >= 0)
		 c->pings_pending--;
	     }
	   else
	     {
	       /* Regular pinging, assume 1 reply and the  
		* app is alive. 
	       */
	       if (c->pings_pending > 0) 
		 {
		   ewmh_ping_client_stop(c);
		 }
	     }
	 }
     } 
   else if (e->message_type == w->atoms[WINDOW_STATE]) 
     {
       if (e->data.l[1] == w->atoms[WINDOW_STATE_FULLSCREEN]
	   && ((c = wm_find_client(w, e->window, WINDOW)) != NULL)
	   && c->type == MBCLIENT_TYPE_APP)
	 {
	   dbg("got EWMH fullscreen state change\n");
	   switch (e->data.l[0])
	     {
	     case _NET_WM_STATE_REMOVE:
	       if (c->flags & CLIENT_FULLSCREEN_FLAG)
		 main_client_toggle_fullscreen(c);
	       break;
	     case _NET_WM_STATE_ADD:
	       if (!(c->flags & CLIENT_FULLSCREEN_FLAG))
		 main_client_toggle_fullscreen(c);
	       break;
	     case _NET_WM_STATE_TOGGLE:
	       main_client_toggle_fullscreen(c);
	       break;
	     }
	 }
       else if (e->data.l[1] == w->atoms[WINDOW_STATE_ABOVE]
		&& ((c = wm_find_client(w, e->window, WINDOW)) != NULL)
		&& c->type == MBCLIENT_TYPE_DIALOG)
	 {
	   dbg("got EWMH above state change\n");
	   switch (e->data.l[0])
	     {
	     case _NET_WM_STATE_REMOVE:
	       c->flags &= ~CLIENT_HAS_ABOVE_STATE;
	       break;
	     case _NET_WM_STATE_ADD:
	       c->flags |= CLIENT_HAS_ABOVE_STATE;
	       break;
	     case _NET_WM_STATE_TOGGLE:
	       c->flags ^= CLIENT_HAS_ABOVE_STATE;
	       break;
	     }
	   wm_activate_client(c);
	 }
       return 1;
     } 
   else if (e->message_type == w->atoms[_NET_SHOW_DESKTOP]
	    && wm_get_desktop(w) ) 
     {
       dbg("%s() got desktop message\n", __func__);
       if (e->data.l[0] == 1)
	 { 			/* Show the desktop, if not shown */
	   if (!(w->flags & DESKTOP_RAISED_FLAG))
	     wm_toggle_desktop(w);
	 } else {                 /* Hide the desktop, if shown */
	   if (w->flags & DESKTOP_RAISED_FLAG)
	     wm_toggle_desktop(w);
	 }
     }
   
   return 0;
}
int 
main(int argc, char **argv)
{
  int i, x, y;

  /* Config Parameters */
  int switch_count      = 1;
  char *img_file        = NULL;
  char *dotdesktop_file = NULL;
  MBDotDesktop *dd      = NULL;
  Bool start_app        = False;
  char png_path[256]    = { 0 };

  TrayApp = mb_tray_app_new ( "mb-applet-launcher",
			      resize_callback,
			      paint_callback,
			      &argc,
			      &argv );  

  for (i = 1; i < argc; i++) {
    if (argv[i][0] == '-')
      {

	if (!strcmp ("--title", argv[i]) || !strcmp ("-n", argv[i])) {
	  if (++i>=argc) usage (argv[0]);
	  win_panel_title = argv[i];
	  switch_count += 2;
	  continue;
	}

	if (!strcmp ("--kill", argv[i]) || !strcmp ("-k", argv[i])) {
	  action = ACTION_KILL;
	  switch_count++;
	  continue;
	}

	if (!strcmp ("--start", argv[i]) || !strcmp ("-s", argv[i])) {
	  start_app = True;
	  switch_count++;
	  continue;
	}
	
	if (!strcmp ("--kill", argv[i]) || !strcmp ("-k", argv[i])) {
	  action = ACTION_KILL;
	  switch_count++;
	  continue;
	}
	
	if (!strcmp ("--relaunch", argv[i]) || !strcmp ("-l", argv[i])) {
	  action = ACTION_NONE;
	  switch_count++;
	  continue;
	}
	
	if (!strcmp ("--message", argv[i]) || !strcmp ("-m", argv[i])) {
	  action = ACTION_MESSAGE_DOCK;
	  switch_count++;
	  continue;
	}

	if (!strcmp ("--no-animation", argv[i]) || !strcmp ("-na", argv[i])) {
	  DoAnimation = False;
	  switch_count++;
	  continue;
	}

	if (!strcmp ("--desktop", argv[i])) {
	  if (++i>=argc) usage (argv[0]);
	  dotdesktop_file = argv[i];
	  switch_count += 2;
	  continue;
	}
	usage(argv[0]);
      }
    else break;
  }

  if (argc-switch_count < 2 && dotdesktop_file == NULL) usage(argv[0]);

  dpy    = mb_tray_app_xdisplay(TrayApp);
  screen = mb_tray_app_xscreen(TrayApp);

  atom_wm_state  = XInternAtom(dpy, "WM_STATE", False);
  atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
  atom_wm_protos = XInternAtom(dpy, "WM_PROTOCOLS", False);

  pb = mb_pixbuf_new(dpy, mb_tray_app_xscreen(TrayApp));

  if (dotdesktop_file != NULL)
    {
      if ((dd = mb_dotdesktop_new_from_file(dotdesktop_file)) != NULL
	  && mb_dotdesktop_get(dd, "Name")
	  && mb_dotdesktop_get(dd, "Icon")
	  && mb_dotdesktop_get(dd, "Exec") )
	{

	  img_file = mb_dotdesktop_get(dd, "Icon");

	  if (img_file[0] != '/')
	    {
	      snprintf(png_path, 256, "%s/pixmaps/%s", DATADIR,  
		       mb_dotdesktop_get(dd, "Icon") );
	      img_file = strdup(png_path);
	    }

	  cmd_str  = mb_dotdesktop_get_exec(dd);
	  if (!win_panel_title) 
	    win_panel_title = mb_dotdesktop_get(dd, "Name");
#ifdef USE_LIBSN

	  if (mb_dotdesktop_get(dd, "SingleInstance")
	      && !strcasecmp(mb_dotdesktop_get(dd, "SingleInstance"), 
			     "true"))
	    {
	      action = ACTION_SI;
	    }
	  else if (mb_dotdesktop_get(dd, "StartupNotify")
		   && !strcasecmp(mb_dotdesktop_get(dd, "StartupNotify"), 
				  "true"))
	    {
	      action = ACTION_SN;
	    }
	  else   
#endif
	    if (mb_dotdesktop_get(dd, "X-MB-NoWindow")
		&& !strcasecmp(mb_dotdesktop_get(dd, "X-MB-NoWindow"), 
			       "true"))
	      {
		DoAnimation = False;
		action = ACTION_NONE;
	      }	
	}
      else
	{
	  fprintf(stderr,"%s: failed to parse %s\n", 
		  argv[0], dotdesktop_file); 
	  exit(1);
	}

    } else {
      img_file = argv[switch_count];

      if (img_file[0] != '/')
	{
	  /* FIXME: should really get from theme */
	  snprintf(png_path, 256, "%s/pixmaps/%s", DATADIR, img_file);
	  img_file = strdup(png_path);
	}

      cmd_str  = arr_to_str(&argv[switch_count+1], argc - switch_count - 1);
    }

  if (!(img_icon = mb_pixbuf_img_new_from_file(pb, img_file)))
    {
      fprintf(stderr, "%s: failed to load image %s \n", 
	      argv[0], img_file );
      exit(1);
    }

  /* make active button image */
  img_icon_active = mb_pixbuf_img_clone(pb, img_icon);

  for (x=0; x<mb_pixbuf_img_get_width(img_icon); x++)
    for (y=0; y<mb_pixbuf_img_get_height(img_icon); y++)
      {
	int aa;
	unsigned char r,g,b,a;
	mb_pixbuf_img_get_pixel (pb, img_icon_active, x, y, &r, &g, &b, &a);

	aa = (int)a;
	aa -=  0x80; if (aa < 0) aa = 0;

	mb_pixbuf_img_set_pixel_alpha(img_icon_active, x, y, aa);
      }


#ifdef USE_LIBSN
  if (action == ACTION_SN || action == ACTION_SI)
    sn_dpy = sn_display_new (dpy, NULL, NULL);
#endif

  mb_tray_app_set_xevent_callback (TrayApp, xevent_callback );

  mb_tray_app_set_button_callback (TrayApp, button_callback );


  if (win_panel_title == NULL) 	/* XXX UTF8 naming */
    {
      win_panel_title = malloc( strlen(argv[1+switch_count]) +
				strlen(" Launcher") + 1 ); 
      strcpy(win_panel_title, argv[1+switch_count]);
      strcat(win_panel_title, " Launcher");
    }
  
  mb_tray_app_set_name (TrayApp, win_panel_title);

  XSelectInput(dpy, mb_tray_app_xrootwin(TrayApp), SubstructureNotifyMask);

  signal(SIGCHLD, SIG_IGN);

  mb_tray_app_set_icon(TrayApp, pb, img_icon);

  /* make sure we always end up on the left of the panel */
  mb_tray_app_request_offset (TrayApp, -1); 

  if (start_app)
    {
      switch(action)
	{
#ifdef USE_LIBSN
	case ACTION_SN:
	  sn_activate(win_panel_title, cmd_str);
	  break;
	case ACTION_SI:
	  si_activate(win_panel_title, cmd_str);
	  break;
#endif
	case ACTION_NONE:
	  fork_exec(cmd_str);
	  break;
	case ACTION_KILL:
	case ACTION_TOGGLE_WIN_STATE:
	  fork_exec(cmd_str);
	  win_launched = get_launch_window();
	  break;
	}
    }

  mb_tray_app_main (TrayApp);

  XCloseDisplay(dpy);
  exit(0);
}
void
button_callback (MBTrayApp *app, int x, int y, Bool is_released )
{
  int abs_x, abs_y;
  Bool do_anim = False;

  ButtonIsDown = True;
  if (is_released)
    {
      ButtonIsDown = False;
      mb_tray_app_repaint (app);
      switch (action)
	{
	case ACTION_NONE:
	  fork_exec(cmd_str);
	  do_anim = DoAnimation;
	  break;
	case ACTION_KILL:
	  if (win_launched && win_exists(win_launched, mb_tray_app_xrootwin(app)))
	    {
	      kill_launched_win(win_launched);
	      win_launched = None;
	    } else {
	      fork_exec(cmd_str);
	      win_launched = get_launch_window();
	    }
	  break;
	case ACTION_TOGGLE_WIN_STATE:
	  if (win_launched && win_exists(win_launched, mb_tray_app_xrootwin(app)))
	    {
	      XWindowAttributes win_attrib;
	      XGetWindowAttributes(dpy, win_launched, &win_attrib);
	      
	      if (win_attrib.map_state == IsUnmapped ||
		  get_win_state(win_launched) != NormalState)
		XMapRaised(dpy, win_launched);
	      else
		XIconifyWindow(dpy, win_launched, screen);
	    }
	  else
	    {
	      fork_exec(cmd_str);
	      win_launched = get_launch_window();
	    }
	  break;
	case ACTION_MESSAGE_DOCK:
	  send_panel_message(cmd_str);
	  break;
#ifdef USE_LIBSN
	case ACTION_SN:
	  do_anim = DoAnimation;
	  sn_activate(win_panel_title, cmd_str);
	  break;
	case ACTION_SI:
	  do_anim = DoAnimation;
	  si_activate(win_panel_title, cmd_str);
	  break;
#endif
	}

      if (do_anim)
	{
	  mb_tray_app_get_absolute_coords (app, &abs_x, &abs_y); 

	  mb_util_animate_startup(mb_tray_app_xdisplay (app), 
				  abs_x,
				  abs_y,
				  mb_tray_app_width (app),
				  mb_tray_app_height (app));
	}
    } else mb_tray_app_repaint (app);


}
Esempio n. 15
0
static void
handle_iptable_rule_to_NA(ip_address_t *ipaddress, int cmd, char *ifname, bool force)
{
	char  *argv[14];
	unsigned int i = 0;
	int if_specifier = -1;
	int type_specifier ;
	char *addr_str;

	if (global_data->vrrp_iptables_inchain[0] == '\0')
		return;

	addr_str = ipaddresstos(NULL, ipaddress);

	argv[i++] = "ip6tables";
	argv[i++] = cmd ? "-A" : "-D";
	argv[i++] = global_data->vrrp_iptables_inchain;
	argv[i++] = "-d";
	argv[i++] = addr_str;
	if (IN6_IS_ADDR_LINKLOCAL(&ipaddress->u.sin6_addr)) {
		if_specifier = i;
		argv[i++] = "-i";
		argv[i++] = ifname;
	}
	argv[i++] = "-p";
	argv[i++] = "icmpv6";
	argv[i++] = "--icmpv6-type";
	type_specifier = i;
	argv[i++] = "136";
	argv[i++] = "-j";
	argv[i++] = "ACCEPT";
	argv[i] = NULL;

	if (fork_exec(argv) < 0 && !force)
		log_message(LOG_ERR, "Failed to %s ip6table rule to accept NAs sent"
				     " to vip %s", (cmd) ? "set" : "remove", addr_str);

	argv[type_specifier] = "135";

	if (fork_exec(argv) < 0 && !force)
		log_message(LOG_ERR, "Failed to %s ip6table rule to accept NSs sent"
				     " to vip %s", (cmd) ? "set" : "remove", addr_str);

	if (global_data->vrrp_iptables_outchain[0] == '\0')
		return;

	argv[2] = global_data->vrrp_iptables_outchain;
	argv[3] = "-s";
	if (if_specifier >= 0)
		argv[if_specifier] = "-o";

	/* Allow NSs to be sent - this should only happen if the underlying interface
	   doesn't have an IPv6 address */
	if (fork_exec(argv) < 0 && !force)
		log_message(LOG_ERR, "Failed to %s ip6table rule to allow NSs to be"
				     " sent from vip %s", (cmd) ? "set" : "remove", addr_str);

	argv[type_specifier] = "136";

	/* Allow NAs to be sent in reply to an NS */
	if (fork_exec(argv) < 0 && !force)
		log_message(LOG_ERR, "Failed to %s ip6table rule to allow NAs to be"
				     " sent from vip %s", (cmd) ? "set" : "remove", addr_str);
}
int suspend_test(void)
{
	char wakelock_dmask[16] = "";
	char earlysuspend_dmask[16] = "";
	time_t now;
	time_t expiration;
	int success_count = 0;
	int rv;
	int i = 0;
	int k;
	int num_success = 0;
	int ret;
	unsigned int core1_status;
	unsigned int core2_status;
	unsigned int core3_status;
	unsigned int dual_core = 0;
	signed long usb_active;
	int num_cores = 0;
	char *ss_pid;


	fprintf(stdout, "Determine if wakelock node is there \n");
	g_wakelock_exists = file_exists(WAKELOCK_NODE);

	if (g_wakelock_exists) {

		fprintf(stdout, "reset the sensors data setting \n");
		rv = write_string_to_file(NULL, SENSOR_SETTINGS, "0\n");
		if (rv < 0) {
			fprintf(stdout, "unable to set sensor settings: %s\n", strerror(-rv));
			goto suspend_test_early_bailout;
		}

		fprintf(stdout, "sleep for sensor daemon to pick up the setting \n");
		sleep(2);

		fprintf(stdout, "Save current wakelock debug mask\n");
		rv = read_from_file(
			NULL,
			WAKELOCK_DEBUG_MASK_NODE,
			wakelock_dmask,
			sizeof(wakelock_dmask) - 1);

		if (rv < 0) {
			fprintf(stdout,
				"cannot read %s: %s\n",
				WAKELOCK_DEBUG_MASK_NODE,
				strerror(-rv));
			goto suspend_test_bailout;
		}

		wakelock_dmask[rv] = '\0';

		fprintf(stdout,
			"Turn on additional wakelock debug info\n");
		rv = write_string_to_file(
			NULL, WAKELOCK_DEBUG_MASK_NODE, "22\n");
		if (rv < 0) {
			fprintf(stdout,
				"cannot write to %s: %s\n",
				WAKELOCK_DEBUG_MASK_NODE,
				strerror(-rv));
			goto suspend_test_bailout;
		}

		fprintf(stdout, "Add wakelock to hold off suspend till we suspend ourselves\n");
		rv = write_string_to_file(
			NULL, WAKELOCK_LOCK_NODE, SUSPENDPC_WAKELOCK);

		if (rv < 0) {
			fprintf(stdout, "cannot write to %s: %s\n",
				WAKELOCK_LOCK_NODE, strerror(-rv));
			goto suspend_test_bailout;
		}
	}

	fprintf(stdout, "Save current earlysuspend debug mask\n");
	rv = read_from_file(
		NULL,
		EARLYSUSPEND_DEBUG_MASK_NODE,
		earlysuspend_dmask,
		sizeof(earlysuspend_dmask) - 1);

	if (rv < 0) {
		fprintf(stdout,
			"cannot read %s: %s\n",
			EARLYSUSPEND_DEBUG_MASK_NODE,
			strerror(-rv));
		goto suspend_test_bailout;
	}

	earlysuspend_dmask[rv] = '\0';

	fprintf(stdout, "turn on early suspend logs\n");
	rv = write_string_to_file(
		NULL, EARLYSUSPEND_DEBUG_MASK_NODE, "5\n");

	if (rv < 0) {
		fprintf(stdout,
			"cannot write to %s: %s\n",
			EARLYSUSPEND_DEBUG_MASK_NODE,
			strerror(-rv));
		goto suspend_test_bailout;
	}


	fprintf(stdout, "Check whether power management is up\n");
	if (!file_exists(PM_STATS_NODE)) {
		fprintf(stdout, "power management is not available\n");
		goto suspend_test_bailout;
	}

	fprintf(stdout, "Determine the power management module\n");

	if (directory_exists(SYS_PM_8x60)) {
		g_sys_pm = SYS_PM_8x60;
		if (file_exists_with_prefix(SYS_PM_8x60, SLEEP_MODE_NODE_CORE_3))
			num_cores = 4;
		else if (file_exists_with_prefix(SYS_PM_8x60, SLEEP_MODE_NODE_CORE_1))
			num_cores = 2;
		else
			num_cores = 1;
	}
	else {
		fprintf(stdout, "power management is not available\n");
		goto suspend_test_bailout;
	}

	fprintf(stdout, "Delay tests for some time for usb cable to be plugged out\n");
	if (g_delay_test_sec) {
		unsigned int seconds = g_delay_test_sec;
		while (seconds)
			seconds = sleep(seconds);
	}

	/*
	 *  check if the usb wakelock has been released before
	 *  proceeding with the test
	 */
	if (g_wakelock_exists) {
		/*
		 *  capture the usb wakelock stats
		 */
		rv = read_from_file(NULL, WAKELOCK_NODE, g_wakelock_stats,
				    sizeof(g_wakelock_stats) - 1);

		usb_active = parse_wakelock_stats_for_active_wl(
			g_wakelock_stats, "\"msm_otg\"");

		if (usb_active != 0) {
			fprintf(stdout, " the usb wakelock is still held by the system\n");
			goto suspend_test_bailout;
		}
	}

	/*
	 *  determine resume command
	 */
	do {
		rv = write_string_to_file(NULL, POWER_NODE, POWER_STANDBY);
		if (rv > 0) {
			g_resume_command = POWER_STANDBY;
			break;
		}

		rv = write_string_to_file(
			NULL, POWER_NODE, POWER_ON);

		if (rv > 0) {
			g_resume_command = POWER_ON;
			break;
		}

		fprintf(stdout, "cannot write to %s: %s\n",
			POWER_NODE, strerror(-rv));

		goto suspend_test_bailout;
	} while (0);

	fprintf(stdout, "Set suspend configuration\n");
	if (num_cores == 4) {
		write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_0, 1);
		write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_1, 1);
		write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_2, 1);
		write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_3, 1);
	}
	else if (num_cores == 2) {
		write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_0, 1);
		write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_1, 1);
	}
	else if (num_cores == 1) {
		write_int_to_file(g_sys_pm, SLEEP_MODE_NODE_CORE_0, 1);
	}

	fprintf(stdout, "Turn off idle power collapse and mp-decision\n");
	if ((num_cores == 2) || (num_cores == 4)) {
		if (num_cores == 4) {
			write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_2, 0);
			write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_3, 0);
			write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_2, 0);
			write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_3, 0);
		}

		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_0, 0);
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_1, 0);
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_0, 0);
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_1, 0);

		fprintf(stdout, "Turn off mp-decision before testing suspend\n");
		rv = fork_exec("stop", "mpdecision", NULL, NULL, 0);
		if (rv < 0) {
			fprintf(stdout, "cannot turn off mp-decision: %s\n", strerror(-rv));
			goto suspend_test_bailout;
		}

		fprintf(stdout, "Now explicitly turn ON core 1 if not ON already\n");
		core1_status = read_unsigned_int_from_file(NULL, HOTPLUG_NODE_CORE_1);
		fprintf(stdout, "core1_status = %d\n", core1_status);
		if (!core1_status) {
			fprintf(stdout, "turning on core 1\n");
			rv = write_int_to_file(NULL, HOTPLUG_NODE_CORE_1, 1);
		}

		if (num_cores == 4) {
			fprintf(stdout, "Now explicitly turn ON core 2 if not ON already\n");
			core2_status = read_unsigned_int_from_file(NULL, HOTPLUG_NODE_CORE_2);
			fprintf(stdout, "core2_status = %d\n", core2_status);
			if (!core2_status) {
				fprintf(stdout, "turning on core 2\n");
				rv = write_int_to_file(NULL, HOTPLUG_NODE_CORE_2, 1);
			}

			fprintf(stdout, "Now explicitly turn ON core 3 if not ON already\n");
			core3_status = read_unsigned_int_from_file(NULL, HOTPLUG_NODE_CORE_3);
			fprintf(stdout, "core3_status = %d\n", core3_status);
			if (!core3_status) {
				fprintf(stdout, "turning on core 3\n");
				rv = write_int_to_file(NULL, HOTPLUG_NODE_CORE_3, 1);
			}
		}
	}
	else if (num_cores == 1) {
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_0, 0);
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_0, 0);
	}

	fprintf(stdout, "Clear kernel log\n");
	rv = fork_exec("dmesg", "-c", NULL, NULL, 1);
	if (rv < 0) {
		fprintf(stdout,
			"dmesg -c failed: %s\n", strerror(-rv));
		goto suspend_test_bailout;
	}

	fprintf(stdout, "Clear power management stats\n");
	rv = write_string_to_file(NULL, PM_STATS_NODE, "reset\n");
	if (rv < 0) {
		fprintf(stdout,	"cannot write to %s: %s\n",
			PM_STATS_NODE, strerror(-rv));
		goto suspend_test_bailout;
	}

	fprintf(stdout, "Set wakeup time\n");
	rv = write_int_to_file(
		g_sys_pm, SLEEP_TIME_OVERRIDE_NODE, g_wakeup_sec);
	if (rv < 0) {
		fprintf(stdout,	"cannot write to %s%s: %s\n", g_sys_pm,
			SLEEP_TIME_OVERRIDE_NODE, strerror(-rv));
		goto suspend_test_bailout;
	}

	if (g_wakelock_exists) {
		fprintf(stdout, "Remove the suspend wakelock before issuing the suspend command\n");
		rv = write_string_to_file(
			NULL, WAKELOCK_UNLOCK_NODE, SUSPENDPC_WAKELOCK);

		if (rv < 0) {
			fprintf(stdout, "cannot write to %s: %s\n",
				WAKELOCK_UNLOCK_NODE, strerror(-rv));
			goto suspend_test_bailout;
		}
	}

	for (i = 0; i < g_num_iter; i++) {

		msg("beginning iteration %d for suspend\n", i);
		fprintf(stdout, "Determine expiration time\n");
		now = time(NULL);
		if (now == (time_t)-1) {
			fprintf(stdout,
				"time() failed: %s\n", strerror(errno));
			continue;
		}

		expiration = now  + g_timeout_sec;

		fprintf(stdout, "Issue suspend command\n");
		rv = write_string_to_file(NULL, POWER_NODE, "mem\n");
		if (rv < 0) {
			fprintf(stdout,	"cannot write to %s: %s\n",
				POWER_NODE, strerror(-rv));
			i++;
			goto suspend_test_late_bailout;
		}

		k = 0;
		do {
			usleep(300 * 1000);

			if (k % 10 == 0) {
				fprintf(stdout,
					"load power management stats\n");
			}

			rv = read_from_file(NULL, PM_STATS_NODE, g_pm_stats,
					    sizeof(g_pm_stats) - 1);

			if (rv < 0) {
				fprintf(stdout,	"cannot read %s: %s\n",
					PM_STATS_NODE, strerror(-rv));
				goto suspend_test_bailout_cur_iter;
			}

			if (rv == sizeof(g_pm_stats) - 1) {
				fprintf(stdout,	"buffer too small for %s\n",
					PM_STATS_NODE);
				i++;
				goto suspend_test_late_bailout;
			}

			g_pm_stats[rv] = '\0';

			if (k % 10 == 0) {
				fprintf(stdout, "Look for suspend event\n");
			}

			success_count = parse_pm_stats_count(g_pm_stats,
							     "\n[cpu 0] suspend:\n  count: ");

			if (success_count < 0 ) {
				fprintf(stdout,	"bad count(s) from "
					"power management stats\n");
				i++;
				goto suspend_test_late_bailout;
			}

			if (success_count > num_success)
				break;

			if (k % 10 == 0) {
				fprintf(stdout, "Check timeout\n");
			}

			now = time(NULL);
			if (now == (time_t)-1) {
				fprintf(stdout,	"time() failed: %s\n",
					strerror(errno));
				goto suspend_test_bailout_cur_iter;
			}

			k++;
		} while (now < expiration);

suspend_test_bailout_cur_iter:

		if (g_resume_command != NULL) {
			fprintf(stdout, "Issue resume command\n");
			rv = write_string_to_file(
				NULL, POWER_NODE, g_resume_command);

			if (rv < 0) {
				fprintf(stdout,	"cannot write to %s: %s\n",
					POWER_NODE, strerror(-rv));
				i++;
				goto suspend_test_late_bailout;
			}
		}

		if (success_count > num_success) {
			fprintf(stdout, "Suspend/resume succeeded on iteration %d\n", i + 1);
			msg("Suspend/resume succeeded on iteration %d\n", i + 1);
			num_success++;
		}

		if (now >= expiration) {
			fprintf(stdout, "Suspend/resume timed out on iteration %d\n", i + 1);
			msg("Suspend/resume timed out on iteration %\n", i + 1);
			i++;
			break;
		}
	}


	fprintf(stdout, "====BEGIN power management stats====\n");
	fflush(stdout);
	rv = write_to_fd(STDOUT_FILENO, g_pm_stats, strlen(g_pm_stats));
	if (rv < 0)
		fprintf(stdout,	"cannot write out power management stats\n");
	fprintf(stdout, "====END power management stats====\n");

	if (g_wakelock_exists) {
		fprintf(stdout, "====BEGIN wakelock stats====\n");
		fflush(stdout);
		rv = fork_exec("cat", WAKELOCK_NODE, NULL, NULL, 0);
		if (rv < 0)
			fprintf(stdout, "cannot dump %s\n", WAKELOCK_NODE);
		fprintf(stdout, "====END wakelock stats====\n");
	}


suspend_test_late_bailout:

	if (g_resume_command != NULL) {
		fprintf(stdout, "Issue resume command\n");
		rv = write_string_to_file(
			NULL, POWER_NODE, g_resume_command);

		if (rv < 0) {
			fprintf(stdout,	"cannot write to %s: %s\n",
				POWER_NODE, strerror(-rv));
			goto suspend_test_bailout;
		}
	}

suspend_test_bailout:

	fprintf(stdout, "Unset wakeup time\n");
	rv = write_string_to_file(
		g_sys_pm, SLEEP_TIME_OVERRIDE_NODE, "0\n");

	if ((num_cores == 2) || (num_cores == 4)) {
		/* restore idle power collapse */

		if (num_cores == 4) {

			write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_2, 1);
			write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_3, 1);
			write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_2, 1);
			write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_3, 1);
		}

		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_0, 1);
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_1, 1);
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_0, 1);
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_1, 1);

		fprintf(stdout, "Turn mp-decision back on\n");
		rv = fork_exec("start", "mpdecision", NULL, NULL, 0);
	}
	else if (num_cores == 1) {

		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_CORE_0, 1);
		write_int_to_file(g_sys_pm, IDLE_SLEEP_MODE_NODE_STD_CORE_0, 1);
	}


	fprintf(stdout, "Release suspend wakelock\n");
	rv = write_string_to_file(
		NULL, WAKELOCK_UNLOCK_NODE, SUSPENDPC_WAKELOCK);

	fprintf(stdout, "Restore wakelock debug mask\n");
	if (g_wakelock_exists) {
		rv = write_string_to_file(NULL,
					  WAKELOCK_DEBUG_MASK_NODE, wakelock_dmask);
		if (rv < 0) {
			fprintf(stdout,
				"cannot write to %s: %s\n",
				WAKELOCK_DEBUG_MASK_NODE,
				strerror(-rv));
		}
	}

	fprintf(stdout, "Restore earlysuspend debug mask\n");
	rv = write_string_to_file(NULL,
				  EARLYSUSPEND_DEBUG_MASK_NODE, earlysuspend_dmask);
	if (rv < 0) {
		fprintf(stdout,
			"cannot write to %s: %s\n",
			EARLYSUSPEND_DEBUG_MASK_NODE,
			strerror(-rv));
	}

	fprintf(stdout, "Restore the sensor settings\n");

	fprintf(stdout, "set the sensors data setting\n");
	rv = write_string_to_file(NULL, SENSOR_SETTINGS, "1\n");

	fprintf(stdout, "sleep for sometime for the sensors daemon to pick up the setting\n");
	sleep(2);

suspend_test_early_bailout:


	fprintf(stdout, "====BEGIN kernel log====\n");
	fflush(stdout);
	rv = fork_exec("dmesg", NULL, NULL, NULL, 0);
	if (rv < 0)
		fprintf(stdout,	"cannot dump kernel log\n");
	fprintf(stdout, "====END kernel log====\n");

	fprintf(stdout, "====BEGIN userspace log====\n");
	fflush(stdout);
	rv = fork_exec("logcat", "-d", "-v", "time", 0);
	if (rv < 0)
		fprintf(stdout,	"cannot dump userspace log\n");
	fprintf(stdout, "====END userspace log====\n");

	fprintf(stdout, "\n Suspend/resume test succeeded %d out of %d times\n", num_success, i);


	if (num_success == g_num_iter)
		return EXIT_SUCCESS;
	else
		return EXIT_FAILURE;

}
Esempio n. 17
0
int
main(int argc, char **argv) {
    int status;
    pid_t waited;
    char *device, *real_device, *physicalDevice = NULL;
    char *boot = NULL;
    shvarFile *ifcfg;
    sigset_t blockedsigs, unblockedsigs;
    int pppdPid = 0;
    int timeout = 30;
    char *temp;
    gboolean dying = FALSE;
    int sendsig;
    gboolean connectedOnce = FALSE;
    int maxfail = 0;		// MAXFAIL Patch <*****@*****.**>

    if (argc < 2) {
	fprintf (stderr, "usage: ppp-watch <interface-name> [boot]\n");
	exit(30);
    }

    if (strncmp(argv[1], "ifcfg-", 6) == 0) {
	device = argv[1] + 6;
    } else {
	device = argv[1];
    }

    detach(device); /* Prepare a child process to monitor pppd.  When we
		       return, we'll be in the child. */

    if ((argc > 2) && (strcmp("boot", argv[2]) == 0)) {
	boot = argv[2];
    }

    ifcfg = shvarfilesGet(device);
    if (ifcfg == NULL)
	failureExit(28);

    real_device = svGetValue(ifcfg, "DEVICE");
    if (real_device == NULL)
	real_device = device;

    doPidFile(real_device);

    /* We'll want to know which signal interrupted our sleep below, so
     * attach a signal handler to these. */
    set_signal(SIGTERM, signal_tracker);
    set_signal(SIGINT, signal_tracker);
    set_signal(SIGHUP, signal_tracker);
    set_signal(SIGIO, signal_tracker);
    set_signal(SIGCHLD, signal_tracker);

    /* We time out only if we're being run at boot-time. */
    if (boot) {
	temp = svGetValue(ifcfg, "BOOTTIMEOUT");
	if (temp) {
	    timeout = atoi(temp);
	    if (timeout < 1) timeout = 1;
	    free(temp);
	} else {
	    timeout = 30;
	}
	set_signal(SIGALRM, signal_tracker);
	alarm(timeout);
    }

    /* Register us to get a signal when something changes. Yes, that's vague. */
    fork_exec(TRUE, "/sbin/netreport", NULL, NULL, NULL);

    /* Reset theSigchld, which should have been triggered by netreport. */
    theSigchld = 0;

    /* We don't set up the procmask until after we have received the netreport
     * signal.  Do so now. */
    sigemptyset(&blockedsigs);
    sigaddset(&blockedsigs, SIGTERM);
    sigaddset(&blockedsigs, SIGINT);
    sigaddset(&blockedsigs, SIGHUP);
    sigaddset(&blockedsigs, SIGIO);
    sigaddset(&blockedsigs, SIGCHLD);
    if (boot) {
	sigaddset(&blockedsigs, SIGALRM);
    }
    sigprocmask(SIG_BLOCK, &blockedsigs, NULL);

    sigfillset(&unblockedsigs);
    sigdelset(&unblockedsigs, SIGTERM);
    sigdelset(&unblockedsigs, SIGINT);
    sigdelset(&unblockedsigs, SIGHUP);
    sigdelset(&unblockedsigs, SIGIO);
    sigdelset(&unblockedsigs, SIGCHLD);
    if (boot) {
	sigdelset(&unblockedsigs, SIGALRM);
    }
    sigprocmask(SIG_UNBLOCK, &unblockedsigs, NULL);

    /* Initialize the retry timeout using the RETRYTIMEOUT setting. */
    temp = svGetValue(ifcfg, "RETRYTIMEOUT");
    if (temp) {
	timeout = atoi(temp);
	free(temp);
    } else {
	timeout = 30;
    }

    /* Start trying to bring the interface up. */
    fork_exec(FALSE, IFUP_PPP, "daemon", device, boot);

    while (TRUE) {
	/* Wait for a signal. */
	if (!theSigterm &&
	    !theSigint &&
	    !theSighup &&
	    !theSigio &&
	    !theSigchld &&
	    !theSigalrm) {
	    sigsuspend(&unblockedsigs);
	}

	/* If we got SIGTERM or SIGINT, give up and hang up. */
	if (theSigterm || theSigint) {
	    theSigterm = theSigint = 0;

	    /* If we've already tried to exit this way, use SIGKILL instead
	     * of SIGTERM, because pppd's just being stubborn. */
	    if (dying) {
		sendsig = SIGKILL;
	    } else {
		sendsig = SIGTERM;
	    }
	    dying = TRUE;

	    /* Get the pid of our child pppd. */
	    pppLogicalToPhysical(&pppdPid, device, NULL);

	    /* We don't know what our child pid is.  This is very confusing. */
	    if (!pppdPid) {
		failureExit(35);
	    }

	    /* Die, pppd, die. */
	    kill(pppdPid, sendsig);
	    if (sendsig == SIGKILL) {
		kill(-pppdPid, SIGTERM); /* Give it a chance to die nicely, then
					    kill its whole process group. */
		usleep(2500000);
		kill(-pppdPid, sendsig);
		hangup(ifcfg);
		failureExit(32);
	    }
	}

	/* If we got SIGHUP, reload and redial. */
	if (theSighup) {
	    theSighup = 0;

	    /* Free and reload the configuration structure. */
	    if (ifcfg->parent)
		svCloseFile(ifcfg->parent);
	    svCloseFile(ifcfg);
	    ifcfg = shvarfilesGet(device);

	    /* Get the PID of our child pppd. */
	    pppLogicalToPhysical(&pppdPid, device, NULL);
	    kill(pppdPid, SIGTERM);

	    /* We'll redial when the SIGCHLD arrives, even if PERSIST is
	     * not set (the latter handled by clearing the "we've connected
	     * at least once" flag). */
	    connectedOnce = FALSE;

 	    /* We don't want to delay before redialing, either, so cut
	     * the retry timeout to zero. */
	    timeout = 0;
	}

	/* If we got a SIGIO (from netreport, presumably), check if the
	 * interface is up and return zero (via our parent) if it is. */
	if (theSigio) {
	    theSigio = 0;

	    pppLogicalToPhysical(NULL, device, &physicalDevice);
	    if (physicalDevice) {
		if (interfaceIsUp(physicalDevice)) {
		    /* The interface is up, so report a success to a parent if
		     * we have one.  Any errors after this we just swallow. */
		    relay_exitcode(0);
		    connectedOnce = TRUE;
		    alarm(0);
		}
		free(physicalDevice);
	    }
	}

	/* If we got a SIGCHLD, then pppd died (possibly because we killed it),
	 * and we need to restart it after timeout seconds. */
	if (theSigchld) {
	    theSigchld = 0;

	    /* Find its pid, which is also its process group ID. */
	    waited = waitpid(-1, &status, 0);
	    if (waited == -1) {
		continue;
	    }

	    /* Now, we need to kill any children of pppd still in pppd's
	     * process group, in case they are hanging around.
	     * pppd is dead (we just waited for it) but there is no
	     * guarantee that its children are dead, and they will
	     * hold the modem if we do not get rid of them.
	     * We have kept the old pid/pgrp around in pppdPid.  */
	    if (pppdPid) {
		kill(-pppdPid, SIGTERM); /* give it a chance to die nicely */
		usleep(2500000);
		kill(-pppdPid, SIGKILL);
		hangup(ifcfg);
	    }
	    pppdPid = 0;

	    /* Bail if the child exitted abnormally or we were already
	     * signalled to kill it. */
	    if (!WIFEXITED(status)) {
		failureExit(29);
	    }
	    if (dying) {
		failureExit(WEXITSTATUS(status));
	    }

	    /* Error conditions from which we do not expect to recover
	     * without user intervention -- do not fill up the logs.  */
	    switch (WEXITSTATUS(status)) {
	    case 1: case 2: case 3: case 4: case 6:
	    case 7: case 9: case 14: case 17:
		failureExit(WEXITSTATUS(status));
		break;
	    default:
		break;
	    }

            /* PGB 08/20/02: We no longer retry connecting MAXFAIL
	       times on a failed connect script unless RETRYCONNECT is
	       true. */
	    if ((WEXITSTATUS(status) == 8) &&
		!svTrueValue(ifcfg, "RETRYCONNECT", FALSE)) {
                failureExit(WEXITSTATUS(status));
            }

	    /* If we've never connected, or PERSIST is set, dial again, up
	     * to MAXFAIL times. */
	    if ((WEXITSTATUS(status) == 8) ||
	        !connectedOnce ||
		svTrueValue(ifcfg, "PERSIST", FALSE)) {
		/* If we've been connected (i.e., if we didn't force a redial,
		 * but the connection went down) wait for DISCONNECTTIMEOUT
		 * seconds before redialing. */
		if (connectedOnce) {
		    connectedOnce = FALSE;
		    temp = svGetValue(ifcfg, "DISCONNECTTIMEOUT");
		    if (temp) {
			timeout = atoi(temp);
			free(temp);
		    } else {
			timeout = 2;
		    }
		}
		sigprocmask(SIG_UNBLOCK, &blockedsigs, NULL);
		sleep(timeout);
		sigprocmask(SIG_BLOCK, &blockedsigs, NULL);
		if (!theSigterm &&
		    !theSigint &&
		    !theSighup &&
		    !theSigio &&
		    !theSigchld &&
		    !theSigalrm) {
		    fork_exec(FALSE, IFUP_PPP, "daemon", device, boot);
		}
		/* Reinitialize the retry timeout. */
		temp = svGetValue(ifcfg, "RETRYTIMEOUT");
		if (temp) {
		    timeout = atoi(temp);
		    free(temp);
		} else {
		    timeout = 30;
		}
// Scott Sharkey <*****@*****.**>
// MAXFAIL Patch...
		temp = svGetValue(ifcfg, "MAXFAIL");
		if (temp) {
		    maxfail = atoi(temp);
		    free(temp);
		} else {
		    maxfail = 0;
		}
		if ( maxfail != 0 ) {
		    dialCount++;
		    if ( dialCount >= maxfail )
			failureExit(WEXITSTATUS(status));
		} 
	    } else {
		failureExit(WEXITSTATUS(status));
	    }
	}

	/* We timed out, and we're running at boot-time. */
	if (theSigalrm) {
	    failureExit(34);
	}
    }
}
Esempio n. 18
0
int mmc_umount_all(const char *mmc_device)
{
    FILE *fp = fopen("/proc/mounts", "r");
    if (!fp)
        fwup_err(EXIT_FAILURE, "/proc/mounts");

    char *todo[64] = {0};
    int todo_ix = 0;
    int ultimate_rc = 0;

    char line[FWUP_BLOCK_SIZE] = {0};
    while (!feof(fp) &&
            fgets(line, sizeof(line), fp)) {
        char devname[64];
        char mountpoint[256];
        if (sscanf(line, "%63s %255s", devname, mountpoint) != 2)
            continue;

        if (strstr(devname, mmc_device) == devname) {
            // mmc_device is a prefix of this device, i.e. mmc_device is /dev/sdc
            // and /dev/sdc1 is mounted.

            if (todo_ix == NUM_ELEMENTS(todo))
                fwup_errx(EXIT_FAILURE, "Device mounted too many times");

            // strings from /proc/mounts are escaped, so unescape them
            todo[todo_ix++] = unescape_string(mountpoint);
        }
    }
    fclose(fp);

    int mtab_exists = (access("/etc/mtab", F_OK) != -1);
    for (int i = 0; i < todo_ix; i++) {
        if (mtab_exists) {
            // If /etc/mtab, then call umount(8) so that
            // gets updated correctly.
            int rc = fork_exec("/bin/umount", todo[i]);
            if (rc != 0) {
                fwup_warnx("Error calling umount on '%s'", todo[i]);
                ultimate_rc = -1;
            }
        } else {
            // No /etc/mtab, so call the kernel directly.
#if HAS_UMOUNT
            if (umount(todo[i]) < 0) {
                fwup_warnx("umount %s", todo[i]);
                ultimate_rc = -1;
            }
#else
            // If no umount on this platform, warn, but don't
            // return failure.
            fwup_warnx("umount %s: not supported", todo[i]);
#endif
        }
    }

    for (int i = 0; i < todo_ix; i++)
        free(todo[i]);

    return ultimate_rc;
}
Esempio n. 19
0
int main(int argc, char *argv[], char *envp[])
{
	char line_buffer[MAX_BUFFER]; // 사용자로부터 입력을 받음
	char **command;		// parsing된 line에 대한 포인터
	int flag_fa;		// file append에 대한 플래그
	int flag_bg;		// background excution에 대한 플래그
	FILE *fp = stdout;	// redirection file pointer for internal command

	// ls -al을 저장할 공간과
	// less /<fullpath>/readme를 저장할 공간이 필요해
	char *alias[] = {
		"ls",
		"-al",
		"less"
	};

	char path_readme[MAX_BUFFER]; // fullpath를 저장할 공간 readme 파일을 위한 것임

	// 쉘을 실행하는 방법은 3가지
	// 1. myshell이 있는 디렉토리에서 path없이 실행
	// 	ex) ./myshell
	// 2. 외부 디렉토리에서 myshell을 경로로 실행
	// 	ex) /home/test/myshell
	// 3. myshell이 있는 디렉토리가 path가 있어서 실행
	// 	ex) myshell
	// 	이런 경우에는 executable한 path를 어떻게 알아내냐?
	// 아무래도 생각하기에는
	// 1번일 가능성이 높은 것으로 사료됨
	// 아래의 코드는 1번을 고려해서 작성
	strncpy(line_buffer, getcwd(NULL, 0), MAX_BUFFER); // SHELL
	strncpy(path_readme, line_buffer, MAX_BUFFER); // readme

	strncat(line_buffer, "/myshell", MAX_BUFFER); // SHELL
	strncat(path_readme, "/readme", MAX_BUFFER); // readme

	setenv("SHELL", line_buffer, 1); // 1. ix.

	if(argv[1]) // for batchfile
		if(!freopen(argv[1], "r", stdin))
			exit(STDIN_FAIL);

	while(!feof(stdin)) {

		if(argc < 2) // batchfile에서는 프롬프트 안나오게 하기 위해서
			printf("%s>", getcwd(NULL, 0));

		if(fgets(line_buffer, MAX_BUFFER, stdin)) {

			flag_fa = OFF;
			flag_bg = OFF;

			if(fp != stdout)
				fclose(fp);
			
			command = line_parser(line_buffer, &flag_fa, &flag_bg);

			// 이쪽 아래로는 line_buffer를
			// strcpy나 strcat 용도로 사용해도 괜찮음
		
			if(command[CMD_RUN]) {

				// internal command alias
				// 왜 내부 커맨드 + .. 하면 디렉토리가 변경되는거지? // 파싱을 잘못해섴
				// NULL을 마지막에 넣어주지 않았기 때문임
				
				// 내부 커맨드의 리다이렉션을 위한 파일 오픈
				if(NULL == (fp = fopen(command[CMD_STDOUT], flag_fa ? "a" : "w")))
					fp = stdout;

				//pstatus(command, fp, flag_fa, flag_bg);
	
				switch(internal_cmd(command[CMD_RUN])) {
					case i_cd: // OLDPWD도 갱신해야하나? 우선은 갱신해놓기로 함
						{
							// 물론 아래의 선언은 필요하지 않다
							// 그렇지만 일관성 측면에서는 더 좋은거 같기도 하다
							char *target_dir = command[CMD_RUN + 1];
							
							if(target_dir)
								if(chdir(target_dir))
									printf("%s : No such directory\n", target_dir);
								else {
									setenv("OLDPWD", getenv("PWD"), 1);
									setenv("PWD", getcwd(NULL, 0), 1);
								}
							else
								printf("%s\n", getcwd(NULL, 0));
						} continue;
					case i_dir:
						// internal command and alias이기 때문에
						// ls -al로 실행하면 될꺼 같다
						// 문제는 뭐냐면 ls a b c 이런것도 가능하다는거다...
						// arg는 최대 64개를 넘지 않는다고 가정한다
						{
							int arg_counter = CMD_RUN;
							while(command[arg_counter++])
								;
							while(arg_counter-- > CMD_RUN + 2)
								command[arg_counter] = command[arg_counter - 1];

							command[CMD_RUN] = alias[0]; // ls
							command[CMD_RUN + 1] = alias[1]; // -al

							//pstatus(command, fp, flag_fa, flag_bg);

						} break; 
					case i_environ:
						{
							char **env = envp;
							while(*env)
								fprintf(fp, "%s\n", *env++);
							fprintf(fp, "\n");
						} continue;
					case i_clr:
						{
							fprintf(stdout, "");
							fflush(stdout);
						} continue;
					case i_echo:
						{
							char **comment = command + CMD_RUN;
							while(*++comment)
								fprintf(fp, "%s ", *comment);
							fprintf(fp, "\n");
						} continue;
					case i_help:
						{
							// index 접근법을 좀 바꿀까?
							command[CMD_RUN] = alias[2]; // less
							command[CMD_RUN + 1] = path_readme;
							command[CMD_RUN + 2] = NULL;
						} break;
					case i_pause:
						{
							pdebug("pause");
							struct termios term;
							// echo off
							tcgetattr(STDIN_FILENO, &term);
							term.c_lflag ^= ECHO;
							tcsetattr(STDIN_FILENO, TCSANOW, &term);

							printf("Press Enter to continue...\n");
							fgets(line_buffer, MAX_BUFFER, stdin);

							// echo on
							tcgetattr(STDIN_FILENO, &term); // 이건 없어도 작동할듯?
							term.c_lflag ^= ECHO;
							tcsetattr(STDIN_FILENO, TCSANOW, &term);

						} continue;
					case i_myshell: // for batchfile
						{
							command[CMD_RUN] = getenv("SHELL");
						} break;
					case i_quit:
						exit(0);
				}

				fork_exec(command, flag_fa, flag_bg);
			}
		}
	}

	exit(0);
	// return 0도 물론 가능하지만 
	// forking과 exec를 하므로
	// 좀더 안전하지 않을까?
}
Esempio n. 20
0
/* create or wait for an NFS-safe lockfile and fetch url with curl or wget */
int fetch(char *url, const char *destdir)
{
	int lockfd, status=0;
	char outfile[PATH_MAX], partfile[PATH_MAX];
	char *name, *p;
	struct flock fl = {
		.l_type = F_WRLCK,
		.l_whence = SEEK_SET,
		.l_start = 1,
		.l_len = 0,
	};
	struct cmdarray curlcmd = {
		.argc = 5,
		.argv = { "curl", "-L", "-f", "-o", partfile, NULL }
	};
	struct cmdarray wgetcmd = {
		.argc = 3,
		.argv = { "wget", "-O", partfile, NULL }
	};

	name = strrchr(url, '/');
	if (name == NULL)
		errx(1, "%s: no '/' in url", url);
	p = strstr(url, "::");
	if (p != NULL) {
		name = url;
		*p = '\0';
		url = p + 2;
	} else {
		name++;
	}

	snprintf(outfile, sizeof(outfile), "%s/%s", destdir, name);
	snprintf(lockfile, sizeof(lockfile), "%s.lock", outfile);
	snprintf(partfile, sizeof(partfile), "%s.part", outfile);

	lockfd = open(lockfile, O_WRONLY|O_CREAT, 0660);
	if (lockfd < 0)
		err(1, "%s", lockfile);

	if (fcntl(lockfd, F_SETLK, &fl) < 0) {
		int i;
		printf("Waiting for %s ...\n", lockfile);
		for (i=0; i<10; i++) {
			int r = fcntl(lockfd, F_SETLKW, &fl);
			if (r == 0)
				break;
			if (r == -1 && errno != ESTALE)
				err(1, "fcntl(F_SETLKW)");
			sleep(1);
		}
	}

	if (access(outfile, F_OK) == 0)
		goto fetch_done;

	if (access(partfile, F_OK) == 0) {
		printf("Partial download found. Trying to resume.\n");
		add_opt(&curlcmd, "-C");
		add_opt(&curlcmd, "-");
		add_opt(&wgetcmd, "-c");
	}

	add_opt(&curlcmd, url);
	add_opt(&wgetcmd, url);

	status = fork_exec(curlcmd.argv, 0);

	/* CURLE_RANGE_ERROR (33)
	   The server does not support or accept range requests. */
	if (status == 33)
		unlink(partfile);

	/* is we failed execute curl, then fallback to wget */
	if (status == 201)
		status = fork_exec(wgetcmd.argv, 1);

	/* only rename completed downloads */
	if (status == 0)
		rename(partfile, outfile);

fetch_done:
	unlink(lockfile);
	close(lockfd);
	lockfile[0] = '\0';
	return status;
}

void sighandler(int sig)
{
	switch(sig) {
	case SIGABRT:
	case SIGINT:
	case SIGQUIT:
	case SIGTERM:
		unlink(lockfile);
		exit(0);
		break;
	default:
		break;
	}
}

/* exit codes get passed through from curl/wget (so we can check in abuild
   whether the server does not support resuming). Additional exit codes:
   200: fork failed
   201: curl/wget could not be started
   202: curl/wget did not terminate normally
   203: usage displayed */
int main(int argc, char *argv[])
{
	int opt;
	char *destdir = "/var/cache/distfiles";

	program = argv[0];
	while ((opt = getopt(argc, argv, "hd:")) != -1) {
		switch (opt) {
		case 'h':
			return usage(0);
			break;
		case 'd':
			destdir = optarg;
			break;
		default:
			printf("Unknown option '%c'\n", opt);
			return usage(1);
			break;
		}
	}

	argv += optind;
	argc -= optind;

	if (argc != 1)
		return usage(203);

	signal(SIGABRT, sighandler);
	signal(SIGINT, sighandler);
	signal(SIGQUIT, sighandler);
	signal(SIGTERM, sighandler);

	return fetch(argv[0], destdir);
}