<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39614 >

First step: clean up in stdinhand. /aitoggle, /remove, /cmdlevel and
/cut support the arguments between quote marks.

Patch attached.

Index: server/stdinhand.c
===================================================================
--- server/stdinhand.c	(révision 13752)
+++ server/stdinhand.c	(copie de travail)
@@ -810,20 +810,29 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static bool toggle_ai_player(struct connection *caller, char *arg, bool check)
+static bool toggle_ai_player(struct connection *caller, char *str, bool check)
 {
   enum m_pre_result match_result;
   struct player *pplayer;
+  char *arg;
+  bool ret = TRUE;
 
+  if (get_tokens(str, &arg, 1, TOKEN_DELIMITERS) == 0) {
+    cmd_reply_no_such_player(CMD_AITOGGLE, caller, NULL, M_PRE_EMPTY);
+    return FALSE;
+  }
+
   pplayer = find_player_by_name_prefix(arg, &match_result);
 
   if (!pplayer) {
     cmd_reply_no_such_player(CMD_AITOGGLE, caller, arg, match_result);
-    return FALSE;
+    ret = FALSE;
   } else if (!check) {
     toggle_ai_player_direct(caller, pplayer);
   }
-  return TRUE;
+
+  free(arg);
+  return ret;
 }
 
 /**************************************************************************
@@ -940,26 +949,35 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static bool remove_player(struct connection *caller, char *arg, bool check)
+static bool remove_player(struct connection *caller, char *str, bool check)
 {
   enum m_pre_result match_result;
   struct player *pplayer;
   char name[MAX_LEN_NAME];
+  bool ret = FALSE;
+  char *arg;
 
-  pplayer=find_player_by_name_prefix(arg, &match_result);
-  
-  if(!pplayer) {
-    cmd_reply_no_such_player(CMD_REMOVE, caller, arg, match_result);
-    return FALSE;
-  }
-
   if (!(game.info.is_new_game && server_state == PRE_GAME_STATE)) {
     cmd_reply(CMD_REMOVE, caller, C_FAIL,
 	      _("Players cannot be removed once the game has started."));
     return FALSE;
   }
+
+  if (get_tokens(str, &arg, 1, TOKEN_DELIMITERS) == 0) {
+    cmd_reply_no_such_player(CMD_AITOGGLE, caller, NULL, M_PRE_EMPTY);
+    return FALSE;
+  }
+
+  pplayer = find_player_by_name_prefix(arg, &match_result);
+
+  if (!pplayer) {
+    cmd_reply_no_such_player(CMD_REMOVE, caller, arg, match_result);
+    goto end;
+  }
+
+  ret = TRUE;
   if (check) {
-    return TRUE;
+    goto end;
   }
 
   sz_strlcpy(name, pplayer->name);
@@ -969,7 +987,10 @@
 	      _("Removed player %s from the game."), name);
   }
   aifill(game.info.aifill);
-  return TRUE;
+
+end:
+  free(arg);
+  return ret;
 }
 
 /**************************************************************************
@@ -1159,8 +1180,8 @@
  set ptarget's cmdlevel to level if caller is allowed to do so
 **************************************************************************/
 static bool set_cmdlevel(struct connection *caller,
-			struct connection *ptarget,
-			enum cmdlevel_id level)
+			 struct connection *ptarget,
+			 enum cmdlevel_id level)
 {
   assert(ptarget != NULL);    /* only ever call me for specific connection */
 
@@ -1240,142 +1261,132 @@
 **************************************************************************/
 static bool cmdlevel_command(struct connection *caller, char *str, bool check)
 {
-  char arg_level[MAX_LEN_CONSOLE_LINE]; /* info, ctrl etc */
-  char arg_name[MAX_LEN_CONSOLE_LINE];	 /* a player name, or "new" */
-  char *cptr_s, *cptr_d;	 /* used for string ops */
-
+  char *args[2]; /* [0]: level name [1]: "new", "first" or a connection name */
+  int i, ntokens;
   enum m_pre_result match_result;
   enum cmdlevel_id level;
   struct connection *ptarget;
+  bool ret = FALSE;
 
-  /* find the start of the level: */
-  for (cptr_s = str; *cptr_s != '\0' && !my_isalnum(*cptr_s); cptr_s++) {
-    /* nothing */
-  }
+  ntokens = get_tokens(str, args, 2, TOKEN_DELIMITERS);
 
-  /* copy the level into arg_level[] */
-  for(cptr_d=arg_level; *cptr_s != '\0' && my_isalnum(*cptr_s); cptr_s++, cptr_d++) {
-    *cptr_d=*cptr_s;
-  }
-  *cptr_d='\0';
-  
-  if (arg_level[0] == '\0') {
+  if (ntokens == 0) {
     /* no level name supplied; list the levels */
 
-    cmd_reply(CMD_CMDLEVEL, caller, C_COMMENT, _("Command access levels in effect:"));
+    cmd_reply(CMD_CMDLEVEL, caller, C_COMMENT,
+              _("Command access levels in effect:"));
 
     conn_list_iterate(game.est_connections, pconn) {
       cmd_reply(CMD_CMDLEVEL, caller, C_COMMENT, "cmdlevel %s %s",
 		cmdlevel_name(pconn->access_level), pconn->username);
-    }
-    conn_list_iterate_end;
+    } conn_list_iterate_end;
     cmd_reply(CMD_CMDLEVEL, caller, C_COMMENT,
 	      _("Command access level for new connections: %s"),
 	      cmdlevel_name(default_access_level));
     cmd_reply(CMD_CMDLEVEL, caller, C_COMMENT,
 	      _("Command access level for first player to take it: %s"),
 	      cmdlevel_name(first_access_level));
-    return TRUE;
+    return TRUE; /* No need to free 0 strings */
   }
 
   /* a level name was supplied; set the level */
 
-  if ((level = cmdlevel_named(arg_level)) == ALLOW_UNRECOGNIZED) {
+  if ((level = cmdlevel_named(args[0])) == ALLOW_UNRECOGNIZED) {
     cmd_reply(CMD_CMDLEVEL, caller, C_SYNTAX,
 	      _("Error: command access level must be one of"
 		" 'none', 'info', 'ctrl', or 'hack'."));
-    return FALSE;
+    goto end;
   } else if (caller && level > caller->access_level) {
     cmd_reply(CMD_CMDLEVEL, caller, C_FAIL,
 	      _("Cannot increase command access level to '%s';"
 		" you only have '%s' yourself."),
-	      arg_level, cmdlevel_name(caller->access_level));
-    return FALSE;
+	      cmdlevel_name(level), cmdlevel_name(caller->access_level));
+    goto end;
   }
-  if (check) {
-    return TRUE; /* looks good */
-  }
 
-  /* find the start of the name: */
-  for (; *cptr_s != '\0' && !my_isalnum(*cptr_s); cptr_s++) {
-    /* nothing */
-  }
+  if (ntokens == 1) {
+    /* no playername supplied: set for all connections, and set the default */
 
-  /* copy the name into arg_name[] */
-  for(cptr_d=arg_name;
-      *cptr_s != '\0' && (*cptr_s == '-' || *cptr_s == ' ' || my_isalnum(*cptr_s));
-      cptr_s++ , cptr_d++) {
-    *cptr_d=*cptr_s;
-  }
-  *cptr_d='\0';
- 
-  if (arg_name[0] == '\0') {
-    /* no playername supplied: set for all connections, and set the default */
-    conn_list_iterate(game.est_connections, pconn) {
-      if (set_cmdlevel(caller, pconn, level)) {
-	cmd_reply(CMD_CMDLEVEL, caller, C_OK,
-		  _("Command access level set to '%s' for connection %s."),
-		  cmdlevel_name(level), pconn->username);
-      } else {
-	cmd_reply(CMD_CMDLEVEL, caller, C_FAIL,
-		  _("Command access level could not be set to '%s' for "
-		    "connection %s."),
-		  cmdlevel_name(level), pconn->username);
-        return FALSE;
-      }
-    }
-    conn_list_iterate_end;
-    
-    default_access_level = level;
-    cmd_reply(CMD_CMDLEVEL, caller, C_OK,
-		_("Command access level set to '%s' for new players."),
-		cmdlevel_name(level));
-    first_access_level = level;
-    cmd_reply(CMD_CMDLEVEL, caller, C_OK,
-		_("Command access level set to '%s' for first player to grab it."),
-		cmdlevel_name(level));
-  }
-  else if (strcmp(arg_name,"new") == 0) {
-    default_access_level = level;
-    cmd_reply(CMD_CMDLEVEL, caller, C_OK,
-		_("Command access level set to '%s' for new players."),
-		cmdlevel_name(level));
-    if (level > first_access_level) {
+    if (!check) {
+      conn_list_iterate(game.est_connections, pconn) {
+        if (set_cmdlevel(caller, pconn, level)) {
+          cmd_reply(CMD_CMDLEVEL, caller, C_OK,
+                    _("Command access level set to '%s' for connection %s."),
+                    cmdlevel_name(level), pconn->username);
+        } else {
+          cmd_reply(CMD_CMDLEVEL, caller, C_FAIL,
+                    _("Command access level could not be set to '%s'"
+                      " for connection %s."),
+                    cmdlevel_name(level), pconn->username);
+          /* Don't stop here, maybe other connection can get it */
+        }
+      } conn_list_iterate_end;
+  
+      default_access_level = level;
+      cmd_reply(CMD_CMDLEVEL, caller, C_OK,
+                _("Command access level set to '%s' for new players."),
+                cmdlevel_name(level));
       first_access_level = level;
       cmd_reply(CMD_CMDLEVEL, caller, C_OK,
-		_("Command access level set to '%s' for first player to grab it."),
-		cmdlevel_name(level));
+                _("Command access level set to '%s'"
+                  " for first player to grab it."),
+                cmdlevel_name(level));
     }
-  }
-  else if (strcmp(arg_name,"first") == 0) {
-    first_access_level = level;
-    cmd_reply(CMD_CMDLEVEL, caller, C_OK,
-		_("Command access level set to '%s' for first player to grab it."),
-		cmdlevel_name(level));
-    if (level < default_access_level) {
+  } else if (strcmp(args[1], "new") == 0) {
+    if (!check) {
       default_access_level = level;
       cmd_reply(CMD_CMDLEVEL, caller, C_OK,
-		_("Command access level set to '%s' for new players."),
-		cmdlevel_name(level));
+               _("Command access level set to '%s'"
+                 " for new players."),
+               cmdlevel_name(level));
+      if (level > first_access_level) {
+        first_access_level = level;
+        cmd_reply(CMD_CMDLEVEL, caller, C_OK,
+                  _("Command access level set to '%s'"
+                    " for first player to grab it."),
+                  cmdlevel_name(level));
+      }
     }
-  }
-  else if ((ptarget = find_conn_by_user_prefix(arg_name, &match_result))) {
-    if (set_cmdlevel(caller, ptarget, level)) {
+  } else if (strcmp(args[1], "first") == 0) {
+    if (!check) {
+      first_access_level = level;
       cmd_reply(CMD_CMDLEVEL, caller, C_OK,
-		_("Command access level set to '%s' for connection %s."),
-		cmdlevel_name(level), ptarget->username);
-    } else {
-      cmd_reply(CMD_CMDLEVEL, caller, C_FAIL,
-		_("Command access level could not be set to '%s'"
-		  " for connection %s."),
-		cmdlevel_name(level), ptarget->username);
-      return FALSE;
+                _("Command access level set to '%s'"
+                  " for first player to grab it."),
+                cmdlevel_name(level));
+      if (level < default_access_level) {
+        default_access_level = level;
+        cmd_reply(CMD_CMDLEVEL, caller, C_OK,
+                  _("Command access level set to '%s'"
+                    " for new players."),
+                  cmdlevel_name(level));
+      }
     }
+  } else if ((ptarget = find_conn_by_user_prefix(args[1], &match_result))) {
+    if (!check) {
+      if (set_cmdlevel(caller, ptarget, level)) {
+        cmd_reply(CMD_CMDLEVEL, caller, C_OK,
+                  _("Command access level set to '%s' for connection %s."),
+                  cmdlevel_name(level), ptarget->username);
+      } else {
+        cmd_reply(CMD_CMDLEVEL, caller, C_FAIL,
+                  _("Command access level could not be set to '%s'"
+                    " for connection %s."),
+                  cmdlevel_name(level), ptarget->username);
+        goto end;
+      }
+    }
   } else {
-    cmd_reply_no_such_conn(CMD_CMDLEVEL, caller, arg_name, match_result);
-    return FALSE;
+    cmd_reply_no_such_conn(CMD_CMDLEVEL, caller, args[1], match_result);
+    goto end;
   }
-  return TRUE;
+  ret = TRUE;
+
+end:
+  for (i = 0; i < ntokens; i++) {
+    free(args[i]);
+  }
+  return ret;
 }
 
 /**************************************************************************
@@ -3636,7 +3647,7 @@
       return TRUE;
     }
     notify_conn(game.est_connections, NULL, E_GAME_END,
-                   _("Game ended in a draw."));
+                _("Game ended in a draw."));
     server_state = GAME_OVER_STATE;
     force_end_of_sniff = TRUE;
     cmd_reply(CMD_END_GAME, caller, C_OK,
@@ -3746,34 +3757,48 @@
 /**************************************************************************
 ...
 **************************************************************************/
-static bool cut_client_connection(struct connection *caller, char *name, 
+static bool cut_client_connection(struct connection *caller, char *str, 
                                   bool check)
 {
   enum m_pre_result match_result;
   struct connection *ptarget;
   struct player *pplayer;
+  char *name;
+  bool was_connected, ret = FALSE;
+  
+  if (get_tokens(str, &name, 1, TOKEN_DELIMITERS) == 0) {
+    cmd_reply_no_such_conn(CMD_CUT, caller, NULL, M_PRE_EMPTY);
+    return FALSE;
+  }
 
   ptarget = find_conn_by_user_prefix(name, &match_result);
 
   if (!ptarget) {
     cmd_reply_no_such_conn(CMD_CUT, caller, name, match_result);
-    return FALSE;
-  } else if (check) {
-    return TRUE;
+    goto end;
   }
 
-  pplayer = !ptarget->observer ? ptarget->player : NULL;
+  ret = TRUE;
+  if (check) {
+    goto end;
+  }
 
+  pplayer = ptarget->player;
+  was_connected = pplayer ? pplayer->is_connected : FALSE;
+
   cmd_reply(CMD_CUT, caller, C_DISCONNECTED,
 	    _("Cutting connection %s."), ptarget->username);
   lost_connection_to_client(ptarget);
   close_connection(ptarget);
 
   /* if we cut the connection, unassign the login name */
-  if (pplayer) {
+  if (pplayer && was_connected && !pplayer->is_connected) {
     sz_strlcpy(pplayer->username, ANON_USER_NAME);
   }
-  return TRUE;
+
+end:
+  free(name);
+  return ret;
 }
 
 /**************************************************************************
@@ -4667,4 +4692,3 @@
 }
 
 #endif /* HAVE_LIBREADLINE */
-

_______________________________________________
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev

Reply via email to