add: SetCursor (B_CURSOR_SYSTEM_DEFAULT);
context: void ABSApp::ProcessScriptingMessage (  BMessage *MessagePntr,  struct property_info *PropInfoPntr){  bool        ArgumentBool = false;  bool        ArgumentGotBool = false;  bool        ArgumentGotInt32 = false;  bool        ArgumentGotString = false;  int32       ArgumentInt32 = 0;  const char *ArgumentString = NULL;  BString     CommandText;  status_t    ErrorCode;  int         i;  BMessage    ReplyMessage (B_MESSAGE_NOT_UNDERSTOOD);  ssize_t     StringBufferSize;  BMessage    TempBMessage;  BPath       TempPath;  char        TempString [PATH_MAX + 1024];  if (g_QuitCountdown >= 0 && !g_CommandLineMode)  {    g_QuitCountdown = -1;    cerr << "Quit countdown aborted due to a scripting command arriving.\n";  }  ErrorCode = MessagePntr->FindData (g_DataName, B_STRING_TYPE,    (const void **) &ArgumentString, &StringBufferSize);  if (ErrorCode == B_OK)  {    if (PropInfoPntr->extra_data != PN_EVALUATE_STRING &&    PropInfoPntr->extra_data != PN_SPAM_STRING &&    PropInfoPntr->extra_data != PN_GENUINE_STRING &&    strlen (ArgumentString) >= PATH_MAX)    {      sprintf (TempString, "\"data\" string of a scripting message is too "        "long, for SET %s action", PropInfoPntr->name);      ErrorCode = B_NAME_TOO_LONG;      goto ErrorExit;    }    ArgumentGotString = true;  }  else if (MessagePntr->FindBool (g_DataName, &ArgumentBool) == B_OK)    ArgumentGotBool = true;  else if (MessagePntr->FindInt32 (g_DataName, &ArgumentInt32) == B_OK)    ArgumentGotInt32 = true;  /* Prepare a Human readable description of the scripting command. */  switch (PropInfoPntr->commands[0])  {    case B_SET_PROPERTY:      CommandText.SetTo ("Set ");      break;    case B_GET_PROPERTY:      CommandText.SetTo ("Get ");      break;    case B_COUNT_PROPERTIES:      CommandText.SetTo ("Count ");      break;    case B_CREATE_PROPERTY:      CommandText.SetTo ("Create ");      break;    case B_DELETE_PROPERTY:      CommandText.SetTo ("Delete ");      break;    case B_EXECUTE_PROPERTY:      CommandText.SetTo ("Execute ");      break;    default:      sprintf (TempString, "Bug: scripting command for \"%s\" has an unknown "        "action code %d", PropInfoPntr->name,        (int) PropInfoPntr->commands[0]);      ErrorCode = -1;      goto ErrorExit;  }  CommandText.Append (PropInfoPntr->name);  /* Add on the argument value to our readable command, if there is one. */  if (ArgumentGotString)  {    CommandText.Append (" \"");    CommandText.Append (ArgumentString);    CommandText.Append ("\"");  }  if (ArgumentGotBool)    CommandText.Append (ArgumentBool ? " true" : " false");  if (ArgumentGotInt32)  {    sprintf (TempString, " %ld", ArgumentInt32);    CommandText.Append (TempString);  }  /* From now on the scripting command has been recognized and is in the  correct format, so it always returns a B_REPLY message.  A readable version  of the command is also added to make debugging easier. */  ReplyMessage.what = B_REPLY;  ReplyMessage.AddString ("CommandText", CommandText);  /* Now actually do the command.  First prepare a default error message. */  sprintf (TempString, "Operation code %d (get, set, count, etc) "    "unsupported for property %s",    (int) PropInfoPntr->commands[0], PropInfoPntr->name);  ErrorCode = B_BAD_INDEX;  switch (PropInfoPntr->extra_data)  {    case PN_DATABASE_FILE:      switch (PropInfoPntr->commands[0])      {        case B_GET_PROPERTY: /* Get the database file name. */          ReplyMessage.AddString (g_ResultName, m_DatabaseFileName);          break;        case B_SET_PROPERTY: /* Set the database file name to a new one. */          if (!ArgumentGotString)          {            ErrorCode = B_BAD_TYPE;            sprintf (TempString, "You need to specify a string for the "              "SET %s command", PropInfoPntr->name);            goto ErrorExit;          }          ErrorCode = TempPath.SetTo (ArgumentString, NULL /* leaf */,            true /* normalize - verifies parent directories exist */);          if (ErrorCode != B_OK)          {            sprintf (TempString, "New database path name of \"%s\" is invalid "              "(parent directories must exist)", ArgumentString);            goto ErrorExit;          }          if ((ErrorCode = SaveDatabaseIfNeeded (TempString)) != B_OK)            goto ErrorExit;          MakeDatabaseEmpty (); /* So that the new one gets loaded if used. */          if (strlen (TempPath.Leaf ()) > NAME_MAX-strlen(g_BackupSuffix)-1)          {            /* Truncate the name so that there is enough space for the backup            extension.  Approximately. */            strcpy (TempString, TempPath.Leaf ());            TempString [NAME_MAX - strlen (g_BackupSuffix) - 1] = 0;            TempPath.GetParent (&TempPath);            TempPath.Append (TempString);          }          m_DatabaseFileName.SetTo (TempPath.Path ());          m_SettingsHaveChanged = true;          break;        case B_CREATE_PROPERTY: /* Make a new database file plus more. */          if ((ErrorCode = CreateDatabaseFile (TempString)) != B_OK)            goto ErrorExit;          break;        case B_DELETE_PROPERTY: /* Delete the file and its backups too. */          if ((ErrorCode = DeleteDatabaseFile (TempString)) != B_OK)            goto ErrorExit;          break;        case B_COUNT_PROPERTIES:          if ((ErrorCode = LoadDatabaseIfNeeded (TempString)) != B_OK)            goto ErrorExit;          ReplyMessage.AddInt32 (g_ResultName, m_WordCount);          break;        default: /* Unknown operation code, error message already set. */          goto ErrorExit;      }      break;    case PN_SPAM:    case PN_SPAM_STRING:    case PN_GENUINE:    case PN_GENUINE_STRING:    case PN_UNCERTAIN:      switch (PropInfoPntr->commands[0])      {        case B_COUNT_PROPERTIES: /* Get the number of spam/genuine messages. */          if ((ErrorCode = LoadDatabaseIfNeeded (TempString)) != B_OK)            goto ErrorExit;          if (PropInfoPntr->extra_data == PN_SPAM ||          PropInfoPntr->extra_data == PN_SPAM_STRING)            ReplyMessage.AddInt32 (g_ResultName, m_TotalSpamMessages);          else            ReplyMessage.AddInt32 (g_ResultName, m_TotalGenuineMessages);          break;        case B_SET_PROPERTY: /* Add spam/genuine/uncertain to database. */          if (!ArgumentGotString)          {            ErrorCode = B_BAD_TYPE;            sprintf (TempString, "You need to specify a string (%s) "              "for the SET %s command",              (PropInfoPntr->extra_data == PN_GENUINE_STRING ||              PropInfoPntr->extra_data == PN_SPAM_STRING)              ? "text of the message to be added"              : "pathname of the file containing the text to be added",              PropInfoPntr->name);            goto ErrorExit;          }          if ((ErrorCode = LoadDatabaseIfNeeded (TempString)) != B_OK)            goto ErrorExit;          if (PropInfoPntr->extra_data == PN_GENUINE ||          PropInfoPntr->extra_data == PN_SPAM ||          PropInfoPntr->extra_data == PN_UNCERTAIN)            ErrorCode = AddFileToDatabase (              (PropInfoPntr->extra_data == PN_SPAM) ? CL_SPAM :              ((PropInfoPntr->extra_data == PN_GENUINE) ? CL_GENUINE :              CL_UNCERTAIN),              ArgumentString, TempString /* ErrorMessage */);          else            ErrorCode = AddStringToDatabase (              (PropInfoPntr->extra_data == PN_SPAM_STRING) ?              CL_SPAM : CL_GENUINE,              ArgumentString, TempString /* ErrorMessage */);          if (ErrorCode != B_OK)            goto ErrorExit;          break;        default: /* Unknown operation code, error message already set. */          goto ErrorExit;      }      break;    case PN_IGNORE_PREVIOUS_CLASSIFICATION:      switch (PropInfoPntr->commands[0])      {        case B_GET_PROPERTY:          ReplyMessage.AddBool (g_ResultName, m_IgnorePreviousClassification);          break;        case B_SET_PROPERTY:          if (!ArgumentGotBool)          {            ErrorCode = B_BAD_TYPE;            sprintf (TempString, "You need to specify a boolean (true/yes, "              "false/no) for the SET %s command", PropInfoPntr->name);            goto ErrorExit;          }          m_IgnorePreviousClassification = ArgumentBool;          m_SettingsHaveChanged = true;          break;        default: /* Unknown operation code, error message already set. */          goto ErrorExit;      }      break;    case PN_SERVER_MODE:      switch (PropInfoPntr->commands[0])      {        case B_GET_PROPERTY:          ReplyMessage.AddBool (g_ResultName, g_ServerMode);          break;        case B_SET_PROPERTY:          if (!ArgumentGotBool)          {            ErrorCode = B_BAD_TYPE;            sprintf (TempString, "You need to specify a boolean (true/yes, "              "false/no) for the SET %s command", PropInfoPntr->name);            goto ErrorExit;          }          g_ServerMode = ArgumentBool;          m_SettingsHaveChanged = true;          break;        default: /* Unknown operation code, error message already set. */          goto ErrorExit;      }      break;    case PN_FLUSH:      if (PropInfoPntr->commands[0] == B_EXECUTE_PROPERTY &&      (ErrorCode = SaveDatabaseIfNeeded (TempString)) == B_OK)        break;      goto ErrorExit;    case PN_PURGE_AGE:      switch (PropInfoPntr->commands[0])      {        case B_GET_PROPERTY:          ReplyMessage.AddInt32 (g_ResultName, m_PurgeAge);          break;        case B_SET_PROPERTY:          if (!ArgumentGotInt32)          {            ErrorCode = B_BAD_TYPE;            sprintf (TempString, "You need to specify a 32 bit integer "              "for the SET %s command", PropInfoPntr->name);            goto ErrorExit;          }          m_PurgeAge = ArgumentInt32;          m_SettingsHaveChanged = true;          break;        default: /* Unknown operation code, error message already set. */          goto ErrorExit;      }      break;    case PN_PURGE_POPULARITY:      switch (PropInfoPntr->commands[0])      {        case B_GET_PROPERTY:          ReplyMessage.AddInt32 (g_ResultName, m_PurgePopularity);          break;        case B_SET_PROPERTY:          if (!ArgumentGotInt32)          {            ErrorCode = B_BAD_TYPE;            sprintf (TempString, "You need to specify a 32 bit integer "              "for the SET %s command", PropInfoPntr->name);            goto ErrorExit;          }          m_PurgePopularity = ArgumentInt32;          m_SettingsHaveChanged = true;          break;        default: /* Unknown operation code, error message already set. */          goto ErrorExit;      }      break;    case PN_PURGE:      if (PropInfoPntr->commands[0] == B_EXECUTE_PROPERTY &&      (ErrorCode = LoadDatabaseIfNeeded (TempString)) == B_OK &&      (ErrorCode = PurgeOldWords (TempString)) == B_OK)        break;      goto ErrorExit;    case PN_OLDEST:      if (PropInfoPntr->commands[0] == B_GET_PROPERTY &&      (ErrorCode = LoadDatabaseIfNeeded (TempString)) == B_OK)      {        ReplyMessage.AddInt32 (g_ResultName, m_OldestAge);        break;      }      goto ErrorExit;    case PN_EVALUATE:    case PN_EVALUATE_STRING:      if (PropInfoPntr->commands[0] == B_SET_PROPERTY)      {        if (!ArgumentGotString)        {          ErrorCode = B_BAD_TYPE;          sprintf (TempString, "You need to specify a string for the "            "SET %s command", PropInfoPntr->name);          goto ErrorExit;        }        if ((ErrorCode = LoadDatabaseIfNeeded (TempString)) == B_OK)        {          if (PropInfoPntr->extra_data == PN_EVALUATE)          {            if ((ErrorCode = EvaluateFile (ArgumentString, &ReplyMessage,            TempString)) == B_OK)              break;          }          else /* PN_EVALUATE_STRING */          {            if ((ErrorCode = EvaluateString (ArgumentString, StringBufferSize,            &ReplyMessage, TempString)) == B_OK)              break;          }        }      }      goto ErrorExit;    case PN_RESET_TO_DEFAULTS:      if (PropInfoPntr->commands[0] == B_EXECUTE_PROPERTY)      {        DefaultSettings ();        break;      }      goto ErrorExit;    case PN_INSTALL_THINGS:      if (PropInfoPntr->commands[0] == B_EXECUTE_PROPERTY &&      (ErrorCode = InstallThings (TempString)) == B_OK)        break;      goto ErrorExit;    case PN_SCORING_MODE:      switch (PropInfoPntr->commands[0])      {        case B_GET_PROPERTY:          ReplyMessage.AddString (g_ResultName,            g_ScoringModeNames[m_ScoringMode]);          break;        case B_SET_PROPERTY:          i = SM_MAX;          if (ArgumentGotString)            for (i = 0; i < SM_MAX; i++)            {              if (strcasecmp (ArgumentString, g_ScoringModeNames [i]) == 0)              {                m_ScoringMode = (ScoringModes) i;                m_SettingsHaveChanged = true;                break;              }            }          if (i >= SM_MAX) /* Didn't find a valid scoring mode word. */          {            ErrorCode = B_BAD_TYPE;            sprintf (TempString, "You used the unrecognized \"%s\" as "              "a scoring mode for the SET %s command.  Should be one of: ",              ArgumentGotString ? ArgumentString : "not specified",              PropInfoPntr->name);            for (i = 0; i < SM_MAX; i++)            {              strcat (TempString, g_ScoringModeNames [i]);              if (i < SM_MAX - 1)                strcat (TempString, ", ");            }            goto ErrorExit;          }          break;        default: /* Unknown operation code, error message already set. */          goto ErrorExit;      }      break;    case PN_TOKENIZE_MODE:      switch (PropInfoPntr->commands[0])      {        case B_GET_PROPERTY:          ReplyMessage.AddString (g_ResultName,            g_TokenizeModeNames[m_TokenizeMode]);          break;        case B_SET_PROPERTY:          i = TM_MAX;          if (ArgumentGotString)            for (i = 0; i < TM_MAX; i++)            {              if (strcasecmp (ArgumentString, g_TokenizeModeNames [i]) == 0)              {                m_TokenizeMode = (TokenizeModes) i;                m_SettingsHaveChanged = true;                break;              }            }          if (i >= TM_MAX) /* Didn't find a valid tokenize mode word. */          {            ErrorCode = B_BAD_TYPE;            sprintf (TempString, "You used the unrecognized \"%s\" as "              "a tokenize mode for the SET %s command.  Should be one of: ",              ArgumentGotString ? ArgumentString : "not specified",              PropInfoPntr->name);            for (i = 0; i < TM_MAX; i++)            {              strcat (TempString, g_TokenizeModeNames [i]);              if (i < TM_MAX - 1)                strcat (TempString, ", ");            }            goto ErrorExit;          }          break;        default: /* Unknown operation code, error message already set. */          goto ErrorExit;      }      break;    default:      sprintf (TempString, "Bug!  Unrecognized property identification "        "number %d (should be between 0 and %d).  Fix the entry in "        "the g_ScriptingPropertyList array!",        (int) PropInfoPntr->extra_data, PN_MAX - 1);      goto ErrorExit;  }  /* Success. */  ReplyMessage.AddInt32 ("error", B_OK);  ErrorCode = MessagePntr->SendReply (&ReplyMessage,    this /* Reply's reply handler */, 500000 /* send timeout */);  if (ErrorCode != B_OK)    cerr << "ProcessScriptingMessage failed to send a reply message, code " <<    ErrorCode << " (" << strerror (ErrorCode) << ")" << " for " <<    CommandText.String () << endl;  return;ErrorExit: /* Error message in TempString, return code in ErrorCode. */  ReplyMessage.AddInt32 ("error", ErrorCode);  ReplyMessage.AddString ("message", TempString);  DisplayErrorMessage (TempString, ErrorCode);  ErrorCode = MessagePntr->SendReply (&ReplyMessage,    this /* Reply's reply handler */, 500000 /* send timeout */);  if (ErrorCode != B_OK)    cerr << "ProcessScriptingMessage failed to send an error message, code " <<    ErrorCode << " (" << strerror (ErrorCode) << ")" << " for " <<    CommandText.String () << endl;}