Exemplo n.º 1
0
void net_loop (void) {
  delete_stdin_event = 0;
  if (verbosity >= E_DEBUG) {
    logprintf ("Starting netloop\n");
  }
  term_ev = event_new (TLS->ev_base, 0, EV_READ | EV_PERSIST, stdin_read_callback, 0);
  event_add (term_ev, 0);
  
  int last_get_state = time (0);
  while (1) {
    event_base_loop (TLS->ev_base, EVLOOP_ONCE);

    if (term_ev && delete_stdin_event) {
      logprintf ("delete stdin\n");
      event_free (term_ev);
      term_ev = 0;
    }

    #ifdef USE_LUA
      lua_do_all ();
    #endif
    
    #ifdef USE_PYTHON
      py_do_all ();
    #endif

    if (safe_quit && !TLS->active_queries) {
      printf ("All done. Exit\n");
      do_halt (0);
      safe_quit = 0;
    }
    if (sigterm_cnt > 0) {
      do_halt (0);
    }
    if (time (0) - last_get_state > 3600) {
      tgl_do_lookup_state (TLS);
      last_get_state = time (0);
    }
    
    write_state_file ();
    update_prompt ();
    
/*    if (unknown_user_list_pos) {
      int i;
      for (i = 0; i < unknown_user_list_pos; i++) {
        tgl_do_get_user_info (TLS, TGL_MK_USER (unknown_user_list[i]), 0, 0, 0);
      }
      unknown_user_list_pos = 0;
    }   */
  }

  if (term_ev) {
    event_free (term_ev);
    term_ev = 0;
  }
  
  if (verbosity >= E_DEBUG) {
    logprintf ("End of netloop\n");
  }
}
Exemplo n.º 2
0
static int tilib_ctl(device_t dev_base, device_ctl_t op)
{
	struct tilib_device *dev = (struct tilib_device *)dev_base;

	switch (op) {
        case DEVICE_CTL_RESET:
		if (dev->MSP430_Reset(RST_RESET, 0, 0) < 0) {
			report_error(dev, "MSP430_Reset");
			return -1;
		}
		return 0;

        case DEVICE_CTL_RUN:
		if (refresh_bps(dev) < 0)
			return -1;

		if (dev->MSP430_Run(RUN_TO_BREAKPOINT, 0) < 0) {
			report_error(dev, "MSP430_Run");
			return -1;
		}
		break;

        case DEVICE_CTL_HALT:
		return do_halt(dev);

        case DEVICE_CTL_STEP:
		return do_step(dev);
	}

	return 0;
}
Exemplo n.º 3
0
Arquivo: loop.c Projeto: AmesianX/tg
void export_auth_callback (struct tgl_state *TLSR, void *DC, int success) {
  assert (TLSR == TLS);
  if (!success) {
    logprintf ("Can not export auth\n");
    do_halt (1);
  }
}
Exemplo n.º 4
0
/** Actually change the ownership of something, and fix bits.
 * \param player the enactor.
 * \param thing object to change ownership of.
 * \param newowner new owner for thing.
 * \param preserve if 1, preserve privileges and don't halt.
 */
void
chown_object(dbref player, dbref thing, dbref newowner, int preserve)
{
  (void) undestroy(player, thing);
  if (God(player)) {
    Owner(thing) = newowner;
  } else {
    Owner(thing) = Owner(newowner);
  }
  /* Don't allow circular zones */
  Zone(thing) = NOTHING;
  if (GoodObject(Zone(newowner))) {
    dbref tmp;
    int ok_to_zone = 1;
    int zone_depth = MAX_ZONES;
    for (tmp = Zone(Zone(newowner)); GoodObject(tmp); tmp = Zone(tmp)) {
      if (tmp == thing) {
        notify(player, T("Circular zone broken."));
        ok_to_zone = 0;
        break;
      }
      if (tmp == Zone(tmp)) /* Ran into an object zoned to itself */
        break;
      zone_depth--;
      if (!zone_depth) {
        ok_to_zone = 0;
        notify(player, T("Overly deep zone chain broken."));
        break;
      }
    }
    if (ok_to_zone)
      Zone(thing) = Zone(newowner);
  }
  clear_flag_internal(thing, "CHOWN_OK");
  if (!preserve || !Wizard(player)) {
    clear_flag_internal(thing, "WIZARD");
    clear_flag_internal(thing, "ROYALTY");
    clear_flag_internal(thing, "TRUST");
    set_flag_internal(thing, "HALT");
    destroy_flag_bitmask("POWER", Powers(thing));
    Powers(thing) = new_flag_bitmask("POWER");
    do_halt(thing, "", thing);
  } else {
    if (preserve == 1 && (newowner != player) && Wizard(thing) &&
        !Wizard(newowner)) {
      notify_format(player,
                    T("Warning: WIZ flag reset on #%d because "
                      "@CHOWN/PRESERVE is to a non-WIZ flagged third-party."),
                    thing);
      clear_flag_internal(thing, "WIZARD");
    }
    if (!null_flagmask("POWER", Powers(thing)) || Wizard(thing) ||
        Royalty(thing) || Inherit(thing))
      notify_format(player,
                    T("Warning: @CHOWN/PRESERVE on an object (#%d) "
                      "with WIZ, ROY, INHERIT, or @power privileges."),
                    thing);
  }
}
Exemplo n.º 5
0
Arquivo: loop.c Projeto: AmesianX/tg
void sign_in_result (struct tgl_state *TLSR, void *extra, int success, struct tgl_user *U) {
  assert (TLSR == TLS);
  if (!success) {
    logprintf ("Can not login\n");
    do_halt (1);
  }
  signed_in_ok = 1;
}
Exemplo n.º 6
0
Arquivo: loop.c Projeto: AmesianX/tg
void on_get_config (void *extra, int success) {
  if (!success) {
    logprintf ("Can not get config.\n");
    do_halt (1);
  }
  config_got = 1;

}
Exemplo n.º 7
0
void do_key(char key)
{
    short i, j;
    while (ANYKEY())
    {
        readkeyboard();
        do_halt();
    }

    if (minefield[key])
    {
        // boom
        drawstring("Oops, you appear to have stepped", 0, 176);
        drawstring("on a rotten egg and died.       ", 0, 184);
        for (j = 0; j < 20; j++)
        {
            playfx(1);
            for (i = 0; i < 32*21; i++)
            {
                if (xorshift8() > 220)
                    *((char*)0x4000+192*32+i) = xorshift8() & 7;
            }
            for (i = 0; i < 51; i++) xorshift8();
            do_halt();
        }        
        reset_game();    
    }
    else
    {
        drawval(key, count_mines(key));
        if (minefound[key] == 0)
        {
            minefound[key] = 1;
            found++;
            if (found == total)
            {
                framecounter = 0;
                drawstring("Congratulations!! You did it!   ", 0, 176);
                drawstring("Step on a mine for a new game.  ", 0, 184);
            }
        }
        playfx(0);
    }    
}
Exemplo n.º 8
0
Arquivo: loop.c Projeto: AmesianX/tg
void sign_in_callback (struct tgl_state *TLSR, void *extra, int success, int registered, const char *mhash) {
  assert (TLSR == TLS);
  if (!success) {
    logprintf ("Can not send code\n");
    do_halt (1);
  }
  should_register = !registered;
  hash = strdup (mhash);
  assert (hash);
}
Exemplo n.º 9
0
// a few action functions:
//a function to reorient by a specified angle (in radians), then halt
void do_spin(double spin_ang) {
    ros::Rate loop_timer(1/g_sample_dt);
    double timer=0.0;
    double final_time = fabs(spin_ang)/g_spin_speed;
    g_twist_cmd.angular.z= sgn(spin_ang)*g_spin_speed;
    while(timer<final_time) {
          g_twist_commander.publish(g_twist_cmd);
          timer+=g_sample_dt;
          loop_timer.sleep(); 
          }  
    do_halt(); 
}
Exemplo n.º 10
0
int lakemont_halt(struct target *t)
{
	if (t->state == TARGET_RUNNING) {
		t->debug_reason = DBG_REASON_DBGRQ;
		if (do_halt(t) != ERROR_OK)
			return ERROR_FAIL;
		return ERROR_OK;
	} else {
		LOG_ERROR("%s target not running", __func__);
		return ERROR_FAIL;
	}
}
Exemplo n.º 11
0
//a function to move forward by a specified distance (in meters), then halt
void do_move(double distance) { // always assumes robot is already oriented properly
                                // but allow for negative distance to mean move backwards
    ros::Rate loop_timer(1/g_sample_dt);
    double timer=0.0;
    double final_time = fabs(distance)/g_move_speed;
    g_twist_cmd.angular.z = 0.0; //stop spinning
    g_twist_cmd.linear.x = sgn(distance)*g_move_speed;
    while(timer<final_time) {
          g_twist_commander.publish(g_twist_cmd);
          timer+=g_sample_dt;
          loop_timer.sleep(); 
          }  
    do_halt();
}
Exemplo n.º 12
0
void reset_game()
{
    unsigned char i;
    do_halt();
    do_port254(0);
    readkeyboard();
        
    cp((unsigned char*)0x4000, 6912, (char*)0x5b00);
    for (i = 0; i < 64; i++)
        setcolor(i,176/8,0x5);
    for (i = 0; i < 32; i++)
        setcolor(i,168/8,0x1);

    setup_mines();
    framecounter = 500;
    first = 1;
    found = 0;    
}
Exemplo n.º 13
0
//executeCB implementation: this is a member method that will get registered with the action server
// argument type is very long.  Meaning:
// actionlib is the package for action servers
// SimpleActionServer is a templated class in this package (defined in the "actionlib" ROS package)
// <example_action_server::demoAction> customizes the simple action server to use our own "action" message 
// defined in our package, "example_action_server", in the subdirectory "action", called "demo.action"
// The name "demo" is prepended to other message types created automatically during compilation.
// e.g.,  "demoAction" is auto-generated from (our) base name "demo" and generic name "Action"
void ExampleActionServer::executeCB(const actionlib::SimpleActionServer<example_action_server::demoAction>::GoalConstPtr& goal) {
    ROS_INFO("callback activated");
    double yaw_desired, yaw_current, travel_distance, spin_angle;
    nav_msgs::Path paths;
    geometry_msgs::Pose pose_desired;
    paths = goal->input;

    int npts = paths.poses.size();
    ROS_INFO("received path request with %d poses",npts);    

	int move = 0;
	for (int i=0;i<npts;i++) { //visit each subgoal
		// odd notation: drill down, access vector element, drill some more to get pose
		pose_desired = paths.poses[i].pose; //get first pose from vector of poses        
        	get_yaw_and_dist(g_current_pose, pose_desired,travel_distance, yaw_desired);
        	ROS_INFO("pose %d: desired yaw = %f; desired (x,y) = (%f,%f)",i,yaw_desired, 		 	
				pose_desired.position.x,pose_desired.position.y); 
        	ROS_INFO("current (x,y) = (%f, %f)",g_current_pose.position.x,g_current_pose.position.y);
        	ROS_INFO("travel distance = %f",travel_distance); 
		ROS_INFO("pose %d: desired yaw = %f",i,yaw_desired);        
		yaw_current = convertPlanarQuat2Phi(g_current_pose.orientation); //our current yaw--should use a sensor
		spin_angle = yaw_desired - yaw_current; // spin this much
		//spin_angle = min_spin(spin_angle);// but what if this angle is > pi?  then go the other way
		do_spin(spin_angle); // carry out this incremental action
		// we will just assume that this action was successful--really should have sensor feedback here
		g_current_pose.orientation = pose_desired.orientation; // assumes got to desired orientation precisely
		move = pose_desired.position.x;
		
		ROS_INFO("Move:  %d", move);
		do_move(move);
		
		if(as_.isPreemptRequested()){
		   do_halt();
		   ROS_WARN("Srv: goal canceled.");
		   result_.output = -1;
		   as_.setAborted(result_);
		   return;
		}
        }
	result_.output = 0;
	as_.setSucceeded(result_);
	ROS_INFO("Move finished.");
}
Exemplo n.º 14
0
void write_state_file (void) {
  if (binlog_enabled) { return; }
  static int wseq;
  static int wpts;
  static int wqts;
  static int wdate;
  if (wseq >= TLS->seq && wpts >= TLS->pts && wqts >= TLS->qts && wdate >= TLS->date) { return; }
  wseq = TLS->seq; wpts = TLS->pts; wqts = TLS->qts; wdate = TLS->date;
  int state_file_fd = open (get_state_filename (), O_CREAT | O_RDWR, 0600);
  if (state_file_fd < 0) {
    logprintf ("Can not write state file '%s': %m\n", get_state_filename ());
    do_halt (1);
  }
  int x[6];
  x[0] = STATE_FILE_MAGIC;
  x[1] = 0;
  x[2] = wpts;
  x[3] = wqts;
  x[4] = wseq;
  x[5] = wdate;
  assert (write (state_file_fd, x, 24) == 24);
  close (state_file_fd); 
}
Exemplo n.º 15
0
Arquivo: loop.c Projeto: AmesianX/tg
int loop (void) {
  //on_start ();
  tgl_set_callback (TLS, &upd_cb);
  //TLS->temp_key_expire_time = 60;
  struct event_base *ev = event_base_new ();
  tgl_set_ev_base (TLS, ev);
  tgl_set_net_methods (TLS, &tgl_conn_methods);
  tgl_set_timer_methods (TLS, &tgl_libevent_timers);
  assert (TLS->timer_methods);
  tgl_set_download_directory (TLS, get_downloads_directory ());
  tgl_register_app_id (TLS, TELEGRAM_CLI_APP_ID, TELEGRAM_CLI_APP_HASH); 
  tgl_init (TLS);
 
  if (binlog_enabled) {
    double t = tglt_get_double_time ();
    if (verbosity >= E_DEBUG) {
      logprintf ("replay log start\n");
    }
    tgl_replay_log (TLS);
    if (verbosity >= E_DEBUG) {
      logprintf ("replay log end in %lf seconds\n", tglt_get_double_time () - t);
    }
    tgl_reopen_binlog_for_writing (TLS);
  } else {
    read_auth_file ();
    read_state_file ();
    read_secret_chat_file ();
  }

  binlog_read = 1;
  #ifdef USE_LUA
    lua_binlog_end ();
  #endif
  
  if (sfd >= 0) {
    struct event *ev = event_new (TLS->ev_base, sfd, EV_READ | EV_PERSIST, accept_incoming, 0);
    event_add (ev, 0);
  }
  if (usfd >= 0) {
    struct event *ev = event_new (TLS->ev_base, usfd, EV_READ | EV_PERSIST, accept_incoming, 0);
    event_add (ev, 0);
  }
  update_prompt ();
   
  if (reset_authorization) {
    tgl_peer_t *P = tgl_peer_get (TLS, TGL_MK_USER (TLS->our_id));
    if (P && P->user.phone && reset_authorization == 1) {
      set_default_username (P->user.phone);
    }
    bl_do_reset_authorization (TLS);
  }

  net_loop (0, all_authorized);

  int i;
  for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i] && !tgl_authorized_dc (TLS, TLS->DC_list[i])) {
    assert (0);
  }

  if (!tgl_signed_dc (TLS, TLS->DC_working)) {
    if (disable_output) {
      fprintf (stderr, "Can not login without output\n");
      do_halt (1);
    }
    if (!default_username) {
      size_t size = 0;
      char *user = 0;

      if (!user) {
        printf ("Telephone number (with '+' sign): ");         
        if (net_getline (&user, &size) == -1) {
          perror ("getline()");
          do_halt (1);
        }
        set_default_username (user);
      }
    }
    tgl_do_send_code (TLS, default_username, sign_in_callback, 0);
    net_loop (0, sent_code);
   
    if (verbosity >= E_DEBUG) {
      logprintf ("%s\n", should_register ? "phone not registered" : "phone registered");
    }
    if (!should_register) {
      char *code = 0;
      size_t size = 0;
      printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): ");
      while (1) {
        if (net_getline (&code, &size) == -1) {
          perror ("getline()");
          do_halt (1);
        }
        if (!strcmp (code, "call")) {
          printf ("You typed \"call\", switching to phone system.\n");
          tgl_do_phone_call (TLS, default_username, hash, 0, 0);
          printf ("Calling you! Code: ");
          continue;
        }
        if (tgl_do_send_code_result (TLS, default_username, hash, code, sign_in_result, 0) >= 0) {
          break;
        }
        printf ("Invalid code. Try again: ");
        free (code);
      }
    } else {
      printf ("User is not registered. Do you want to register? [Y/n] ");
      char *code;
      size_t size;
      if (net_getline (&code, &size) == -1) {
        perror ("getline()");
        do_halt (1);
      }
      if (!*code || *code == 'y' || *code == 'Y') {
        printf ("Ok, starting registartion.\n");
      } else {
        printf ("Then try again\n");
        do_halt (1);
      }
      char *first_name;
      printf ("First name: ");
      if (net_getline (&first_name, &size) == -1) {
        perror ("getline()");
        do_halt (1);
      }
      char *last_name;
      printf ("Last name: ");
      if (net_getline (&last_name, &size) == -1) {
        perror ("getline()");
        do_halt (1);
      }
      printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): ");
      while (1) {
        if (net_getline (&code, &size) == -1) {
          perror ("getline()");
          do_halt (1);
        }
        if (!strcmp (code, "call")) {
          printf ("You typed \"call\", switching to phone system.\n");
          tgl_do_phone_call (TLS, default_username, hash, 0, 0);
          printf ("Calling you! Code: ");
          continue;
        }
        if (tgl_do_send_code_result_auth (TLS, default_username, hash, code, first_name, last_name, sign_in_result, 0) >= 0) {
          break;
        }
        printf ("Invalid code. Try again: ");
        free (code);
      }
    }

    net_loop (0, signed_in);    
    //bl_do_dc_signed (TLS->DC_working);
  }

  for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i] && !tgl_signed_dc (TLS, TLS->DC_list[i])) {
    tgl_do_export_auth (TLS, i, export_auth_callback, (void*)(long)TLS->DC_list[i]);    
    cur_a_dc = TLS->DC_list[i];
    net_loop (0, dc_signed_in);
    assert (tgl_signed_dc (TLS, TLS->DC_list[i]));
  }
  write_auth_file ();
  
  fflush (stdout);
  fflush (stderr);

  //read_state_file ();
  //read_secret_chat_file ();

  set_interface_callbacks ();

  tglm_send_all_unsent (TLS);
  tgl_do_get_difference (TLS, sync_from_start, get_difference_callback, 0);
  net_loop (0, dgot);
  assert (!(TLS->locks & TGL_LOCK_DIFF));
  TLS->started = 1;
  if (wait_dialog_list) {
    d_got_ok = 0;
    tgl_do_get_dialog_list (TLS, dlist_cb, 0);
    net_loop (0, dgot);
  }
  #ifdef USE_LUA
    lua_diff_end ();
  #endif

  if (start_command) {
    safe_quit = 1;
    while (*start_command) {
      char *start = start_command;
      while (*start_command && *start_command != '\n') {
        start_command ++;
      }
      if (*start_command) {
        *start_command = 0;
        start_command ++;
      } 
      interpreter_ex (start, 0);
    }
  }

  /*tgl_do_get_dialog_list (get_dialogs_callback, 0);
  if (wait_dialog_list) {
    dialog_list_got = 0;
    net_loop (0, dlgot);
  }*/

  return main_loop ();
}
Exemplo n.º 16
0
void main()
{   
//    unsigned char i;         
    
    y8 = 1;
    
    reset_game();
    /*
    for (i = 0; i < 40; i++)
        if (minefield[i] == 0)
            drawval(i, count_mines(i));
   */
    
    while(1)
    {
        drawscore();
        readkeyboard(); 
        if (KEYDOWN(1)) do_key(0);
        if (KEYDOWN(2)) do_key(1);
        if (KEYDOWN(3)) do_key(2);
        if (KEYDOWN(4)) do_key(3);
        if (KEYDOWN(5)) do_key(4);
        if (KEYDOWN(6)) do_key(5);
        if (KEYDOWN(7)) do_key(6);
        if (KEYDOWN(8)) do_key(7);
        if (KEYDOWN(9)) do_key(8);
        if (KEYDOWN(0)) do_key(9);
        if (KEYDOWN(Q)) do_key(10);
        if (KEYDOWN(W)) do_key(11);
        if (KEYDOWN(E)) do_key(12);
        if (KEYDOWN(R)) do_key(13);
        if (KEYDOWN(T)) do_key(14);
        if (KEYDOWN(Y)) do_key(15);
        if (KEYDOWN(U)) do_key(16);
        if (KEYDOWN(I)) do_key(17);
        if (KEYDOWN(O)) do_key(18);
        if (KEYDOWN(P)) do_key(19);
        if (KEYDOWN(A)) do_key(20);
        if (KEYDOWN(S)) do_key(21);
        if (KEYDOWN(D)) do_key(22);
        if (KEYDOWN(F)) do_key(23);
        if (KEYDOWN(G)) do_key(24);
        if (KEYDOWN(H)) do_key(25);
        if (KEYDOWN(J)) do_key(26);
        if (KEYDOWN(K)) do_key(27);
        if (KEYDOWN(L)) do_key(28);
        if (KEYDOWN(ENTER)) do_key(29);
        if (KEYDOWN(SHIFT)) do_key(30);
        if (KEYDOWN(Z)) do_key(31);
        if (KEYDOWN(X)) do_key(32);
        if (KEYDOWN(C)) do_key(33);
        if (KEYDOWN(V)) do_key(34);
        if (KEYDOWN(B)) do_key(35);
        if (KEYDOWN(N)) do_key(36);
        if (KEYDOWN(M)) do_key(37);
        if (KEYDOWN(SYM)) do_key(38);
        if (KEYDOWN(SPACE)) do_key(39);

        framecounter++;
        do_halt();
        if (framecounter > 500)
        {
            framecounter = 0;
                     // 12345678901234567890123456789012
            switch (infoloop)
            {
            case 0:
                drawstring("Welcome to \"Rotten Egg Mines\"   ", 0, 176);
                drawstring("By Jari Komppa http://iki.fi/sol", 0, 184);
                break;
            case 1:
                drawstring("How to play:                    ", 0, 176);
                drawstring("Press keys to find mines.       ", 0, 184);
                break;
            case 2:
            case 4:
            case 6:
            case 8:
                drawstring(". . . . . . . . . . . . . . . . ", 0, 176);
                drawstring(" . . . . . . . . . . . . . . . .", 0, 184);
                break;   
            case 3:
                drawstring("Sound effects played via        ", 0, 176);
                drawstring("BeepFX by Shiru                 ", 0, 184);
                break;   
            case 5:
                drawstring("Art made by using the           ", 0, 176);
                drawstring("Image Spectrumizer              ", 0, 184);
                break;   
            case 7:
                drawstring("Sources can be found at         ", 0, 176);
                drawstring("github.com/jarikomppa/speccy    ", 0, 184);
                break;   
            case 12:
                drawstring("    [ . . . . . . . . . . .]    ", 0, 176);
                drawstring("    [. . . . . . . . . . . ]    ", 0, 184);
                break;         
            case 13:
                drawstring("        [ . . . . . . .]        ", 0, 176);
                drawstring("        [. . . . . . . ]        ", 0, 184);
                break;         
            case 14:
                drawstring("            [ . . .]            ", 0, 176);
                drawstring("            [. . . ]            ", 0, 184);
                break;         
            case 15:
                drawstring("                                ", 0, 176);
                drawstring("                                ", 0, 184);
                break;         
            }
            infoloop++;
            if (infoloop == 16)
                infoloop = 0;
        }
    }       
}
Exemplo n.º 17
0
int
main(int argc, char *argv[])
{
	int c, i, fd;
	char *ptr;

	i = getdtablesize ();
	for (fd = 3; fd < i; fd++) close (fd);
	if (getpid () == 1)
	{
	    for (fd = 0; fd < 3; fd++) close (fd);
	    while (1) wait (NULL);  /*  Grim reaper never stops  */
	}
	sigsetmask (0); /*  simpleinit(8) blocks all signals: undo for ALRM  */
	for (i = 1; i < NSIG; i++) signal (i, SIG_DFL);

        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
        textdomain(PACKAGE);

#ifndef DEBUGGING
	if(setreuid (0, 0)) {
		fprintf(stderr, _("%s: Only root can shut a system down.\n"),
			argv[0]);
		exit(1);
	}
#endif

	if(*argv[0] == '-') argv[0]++;	/* allow shutdown as login shell */
	prog = argv[0];
	if((ptr = strrchr(argv[0], '/'))) prog = ++ptr;

	/* All names (halt, reboot, fasthalt, fastboot, shutdown)
	   refer to the same program with the same options,
	   only the defaults differ. */
	if(!strcmp("halt", prog)) {
		opt_reboot = 0;
		opt_quiet = 1;
		opt_fast = 0;
		timeout = 0;
	} else if(!strcmp("fasthalt", prog)) {
		opt_reboot = 0;
		opt_quiet = 1;
		opt_fast = 1;
		timeout = 0;
	} else if(!strcmp("reboot", prog)) {
		opt_reboot = 1;
		opt_quiet = 1;
		opt_fast = 0;
		timeout = 0;
	} else if(!strcmp("fastboot", prog)) {
		opt_reboot = 1;
		opt_quiet = 1;
		opt_fast = 1;
		timeout = 0;
	} else {
		/* defaults */
		opt_reboot = 0;
		opt_quiet = 0;
		opt_fast = 0;
		timeout = 2*60;
	}
		
	c = 0;
	while(++c < argc) {
		if(argv[c][0] == '-') {
			for(i = 1; argv[c][i]; i++) {
				switch(argv[c][i]) {
				case 'C':
					opt_use_config_file = 1;
					break;
				case 'h': 
					opt_reboot = 0;
					break;
				case 'r':
					opt_reboot = 1;
					break;
				case 'f':
					opt_fast = 1;
					break;
				case 'q':
					opt_quiet = 1;
					break;
				case 's':
					opt_single = 1;
					break;
				    
				default:
					usage();
				}
			}
		} else if(!strcmp("now", argv[c])) {
			timeout = 0;
		} else if(argv[c][0] == '+') {
			timeout = 60 * atoi(&argv[c][1]);
		} else if (isdigit(argv[c][0])) {
			char *colon;
			int hour = 0;
			int minute = 0;
			time_t tics;
			struct tm *tt;
			int now, then;
				
			if((colon = strchr(argv[c], ':'))) {
				*colon = '\0';
				hour = atoi(argv[c]);
				minute = atoi(++colon);
			} else usage();
				
			(void) time(&tics);
			tt = localtime(&tics);
				
			now = 3600 * tt->tm_hour + 60 * tt->tm_min;
			then = 3600 * hour + 60 * minute;
			timeout = then - now;
			if(timeout < 0) {
				fprintf(stderr, _("That must be tomorrow, "
					          "can't you wait till then?\n"));
				exit(1);
			}
		} else {
			xstrncpy(message, argv[c], sizeof(message));
			opt_msgset = 1;
		}
	}

	halt_action[0] = 0;

	/* No doubt we shall want to extend this some day
	   and register a series of commands to be executed
	   at various points during the shutdown sequence,
	   and to define the number of milliseconds to sleep, etc. */
	if (opt_use_config_file) {
		char line[256], *p;
		FILE *fp;

		/*  Read and parse the config file */
		halt_action[0] = '\0';
		if ((fp = fopen (_PATH_SHUTDOWN_CONF, "r")) != NULL) {
			if (fgets (line, sizeof(line), fp) != NULL &&
			    strncasecmp (line, "HALT_ACTION", 11) == 0 &&
			    iswhitespace(line[11])) {
				p = index(line, '\n');
				if (p)
					*p = 0;		/* strip final '\n' */
				p = line+11;
				while(iswhitespace(*p))
					p++;
				strcpy(halt_action, p);
			}
			fclose (fp);
		}
	}

	if(!opt_quiet && !opt_msgset) {
		/* now ask for message, gets() is insecure */
		int cnt = sizeof(message)-1;
		char *ptr;
		
		printf("Why? "); fflush(stdout);
		
		ptr = message;
		while(--cnt >= 0 && (*ptr = getchar()) && *ptr != '\n') { 
			ptr++;
		}
		*ptr = '\0';
	} else if (!opt_msgset) {
		strcpy(message, _("for maintenance; bounce, bounce"));
	}

#ifdef DEBUGGING
	printf(_("timeout = %d, quiet = %d, reboot = %d\n"),
		timeout, opt_quiet, opt_reboot);
#endif
	
	/* so much for option-processing, now begin termination... */
	if(!(whom = getlogin()) || !*whom) whom = "ghost";
	if(strlen(whom) > 40) whom[40] = 0; /* see write_user() */

	setpriority(PRIO_PROCESS, 0, PRIO_MIN);
	signal(SIGINT,  int_handler);
	signal(SIGHUP,  int_handler);
	signal(SIGQUIT, int_handler);
	signal(SIGTERM, int_handler);

	chdir("/");

	if(timeout > 5*60) {
		sleep(timeout - 5*60);
		timeout = 5*60;
	}

	
	if((fd = open(_PATH_NOLOGIN, O_WRONLY|O_CREAT, 0644)) >= 0) {
		/* keep xgettext happy and leave \r\n outside strings */
		WRCRLF;
		WR(_("The system is being shut down within 5 minutes"));
		WRCRLF;
		write(fd, message, strlen(message));
		WRCRLF;
		WR(_("Login is therefore prohibited."));
		WRCRLF;
		close(fd);
	}
	
	signal(SIGPIPE, SIG_IGN);

	if(timeout > 0) {
		wall();
		sleep(timeout);
	}

	timeout = 0;
	wall();
	sleep(3);

	/* now there's no turning back... */
	signal(SIGINT,  SIG_IGN);

	/* do syslog message... */
	openlog(prog, LOG_CONS, LOG_AUTH);
	if (opt_reboot)
		syslog(LOG_NOTICE, _("rebooted by %s: %s"), 
		       whom, message);
	else
		syslog(LOG_NOTICE, _("halted by %s: %s"), 
		       whom, message);
	closelog();

	if(opt_fast)
		if((fd = open("/fastboot", O_WRONLY|O_CREAT, 0644)) >= 0)
			close(fd);

	kill(1, SIGTSTP);	/* tell init not to spawn more getty's */
	write_wtmp();
	if(opt_single)
		if((fd = open(_PATH_SINGLE, O_CREAT|O_WRONLY, 0644)) >= 0)
			close(fd);
		
	sync();

	signal(SIGTERM, SIG_IGN);
	if(fork() > 0) sleep(1000); /* the parent will die soon... */
	setpgrp();		/* so the shell wont kill us in the fall */

#ifndef DEBUGGING
	/* a gentle kill of all other processes except init */
	kill_mortals (SIGTERM);
	for (fd = 0; fd < 3; fd++) close (fd);
	stop_finalprog ();
	sleep (1);                    /*  Time for saves to start           */
	kill (1, SIGTERM);            /*  Tell init to kill spawned gettys  */
	usleep (100000);              /*  Wait for gettys to die            */
	my_puts ("");                 /*  Get past the login prompt         */
	system ("/sbin/initctl -r");  /*  Roll back services                */
	syncwait (1);
	my_puts ("Sending SIGTERM to all remaining processes...");
	kill (-1, SIGTERM);
	sleep (2);                    /*  Default 2, some people need 5     */

	kill (-1, SIGKILL);           /*  Now use brute force...            */

	/* turn off accounting */
	acct(NULL);
#endif
	/* RedHat and SuSE like to remove /etc/nologin.
	   Perhaps the usual sequence is
	      touch nologin; shutdown -h; fiddle with hardware;
	      boot; fiddle with software; rm nologin
	   and removing it here will be counterproductive.
	   Let us see whether people complain. */
	unlink(_PATH_NOLOGIN);

	/*  Tell init(8) to exec so that the old inode may be freed cleanly if
	    required. Need to sleep before remounting root read-only  */
	kill (1, SIGQUIT);

	sleep (1);	/* Time for processes to die and close files */
	syncwait (2);

	/* remove swap files and partitions using swapoff */
	swap_off();

	/* unmount disks... */
	unmount_disks();
	syncwait (1);

	if(opt_reboot) {
		my_reboot(LINUX_REBOOT_CMD_RESTART); /* RB_AUTOBOOT */
		my_puts(_("\nWhy am I still alive after reboot?"));
	} else {
		my_puts(_("\nNow you can turn off the power..."));

		/* allow C-A-D now, [email protected], re-fixed 8-Jul-96 */
		my_reboot(LINUX_REBOOT_CMD_CAD_ON); /* RB_ENABLE_CAD */
		sleep (1);  /*  Wait for devices to finish writing to media  */
		do_halt(halt_action);
	}
	/* NOTREACHED */
	exit(0); /* to quiet gcc */
}