int do_add_or_set()

in erts/etc/win32/erlsrv/erlsrv_interactive.c [668:893]


int do_add_or_set(int argc, wchar_t **argv){
  RegEntry *new_entries;
  RegEntry *default_entries;
  int add = 0;
  int i;
  int current;
  int set_comment = 0;
  new_entries = empty_reg_tab();
  default_entries = empty_reg_tab();
  if(argc < 3){
    fwprintf(stderr,L"%s: No servicename given!\n",argv[0]);
    do_usage(argv[0]);
    return 1;
  } 
  service_name = argv[2];
  if(!_wcsicmp(argv[1],L"add")){
    if(fetch_current(default_entries)){
      fwprintf(stderr,L"%s: A service with the name %s already "
	      L"exists.\n",
	      argv[0],service_name);
      return 1;
    }
    real_service_name = generate_real_service_name(service_name);
    if(!fill_in_defaults(new_entries)){
      fwprintf(stderr,L"%s: Internal error.\n", argv[0]);
      return 1;
    }
    add = 1;
  } else {
    if(!fetch_current(new_entries)){
      fwprintf(stderr,L"%s: No service with the name %s exists.\n",
	      argv[0], service_name);
      return 1;
    }
    real_service_name = new_entries[InternalServiceName].data.string;
  }

  if(!fill_in_defaults(default_entries)){
    fwprintf(stderr,L"%s: Internal error.\n", argv[0]);
    return 1;
  }

  /* make sure env is malloced... */
  new_entries[Env].data.string = envdup(new_entries[Env].data.string);

  for(i = 3; i < argc; ++i){
    switch((current = lookup_arg(argv[i]))){
    case Comment:
	set_comment = 1;
    case Machine:
    case WorkDir:
    case Args:
      if(i+1 >= argc){
	new_entries[current].data.string = 
	  default_entries[current].data.string;
	new_entries[current].data.expand.unexpanded = 
	  default_entries[current].data.expand.unexpanded;
      } else {
	new_entries[current].data.expand.unexpanded =
	  new_entries[current].data.string = argv[i+1];
	++i;
      }
      break;
    case SName:
      new_entries[Name].data.string = L"";
    case StopAction:
    case Name:
      if(i+1 >= argc ||
	 *argv[i+1] == L'-' || *argv[i+1] == L'/'){
	new_entries[current].data.string = 
	  default_entries[current].data.string;
      } else {
	new_entries[current].data.string = argv[i+1];
	++i;
      }
      break;
    case OnFail:
      if(i+1 >= argc ||
	 *argv[i+1] == L'-' || *argv[i+1] == L'/'){
	new_entries[current].data.value = 
	  default_entries[current].data.value;
      } else {
	if(!_wcsicmp(argv[i+1],L"reboot"))
	  new_entries[current].data.value = ON_FAIL_REBOOT;
	else if(!_wcsicmp(argv[i+1],L"restart"))
	  new_entries[current].data.value = ON_FAIL_RESTART;
	else if(!_wcsicmp(argv[i+1],L"restart_always"))
	  new_entries[current].data.value = ON_FAIL_RESTART_ALWAYS;
	else {
	  fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n",
		  argv[0],argv[i+1]);
	  return 1;
	}
	++i;
      }
      break;
    case DebugType:
      if(i+1 >= argc ||
	 *argv[i+1] == L'-' || *argv[i+1] == L'/'){
	new_entries[current].data.value = 
	  default_entries[current].data.value;
      } else {
	if(!_wcsicmp(argv[i+1],L"new"))
	  new_entries[current].data.value = DEBUG_TYPE_NEW;
	else if(!_wcsicmp(argv[i+1],L"reuse"))
	  new_entries[current].data.value = DEBUG_TYPE_REUSE;
	else if(!_wcsicmp(argv[i+1],L"console"))
	  new_entries[current].data.value = DEBUG_TYPE_CONSOLE;
	else {
	  fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n",
		  argv[0],argv[i+1]);
	  return 1;
	}
	++i;
      }
      break;
    case Priority:
      if(i+1 >= argc ||
	 *argv[i+1] == L'-' || *argv[i+1] == L'/'){
	new_entries[current].data.value = 
	  default_entries[current].data.value;
      } else {
	if(!_wcsicmp(argv[i+1],L"high"))
	  new_entries[current].data.value = HIGH_PRIORITY_CLASS;
	else if(!_wcsicmp(argv[i+1],L"low"))
	  new_entries[current].data.value = IDLE_PRIORITY_CLASS;
	else if(!_wcsicmp(argv[i+1],L"realtime"))
	  new_entries[current].data.value = REALTIME_PRIORITY_CLASS;
	else {
	  fwprintf(stderr,L"%s: Unrecognized keyword value %s.\n",
		  argv[0],argv[i+1]);
	  return 1;
	}
	++i;
      }
      break;
      
    case Env:
      if(i+1 >= argc ||
	 *argv[i+1] == L'-' || *argv[i+1] == L'/'){
	fwprintf(stderr,L"%s: %s requires a parameter.\n",
		argv[0],argv[i]);
	return 1;
      }
      new_entries[current].data.string = 
	edit_env(argv[i+1], new_entries[current].data.string);
      ++i;
      break;
    case InternalServiceName:
	if (!add) {
	    fwprintf(stderr,L"%s: %s only allowed when adding a new service.\n",
		    argv[0],argv[i]);
	    return 1;
	}
	if(i+1 >= argc){
	    fwprintf(stderr,L"%s: %s requires a parameter.\n",
		    argv[0],argv[i]);
	    return 1;
	}
	new_entries[InternalServiceName].data.expand.unexpanded =
	    new_entries[InternalServiceName].data.string = argv[i+1];
	++i;
	/* Discard old, should maybe be fred' but we'll exit anyway */
	real_service_name = new_entries[InternalServiceName].data.string;
	break;
    default:
      fwprintf(stderr,L"%s: Unrecognized option %s.\n", argv[0],
	      argv[i]);
      return 1;
    }
  }
  if(*new_entries[SName].data.string && 
     *new_entries[Name].data.string){
#if 0
    fwprintf(stderr,L"%s: Both -sname and -name specified.\n",
	    argv[0]);
    return 1;
#else
    new_entries[SName].data.string = L"";
#endif
  }
  if(add && !(*new_entries[SName].data.string) &&
     !(*new_entries[Name].data.string)){
    fwprintf(stderr,L"%s: Neither -sname nor -name specified.\n",
	    argv[0]);
    return 1;
  }

  if(add && !install_service()){
    fwprintf(stderr,L"%s: Unable to register %s service with service manager.\n",
	    argv[0], service_name);
    print_last_error();
    return 1;
  }
  if(!set_interactive(new_entries[DebugType].data.value == 
		      DEBUG_TYPE_CONSOLE)){
      fwprintf(stderr,L"%s: Warning, could not set correct interactive mode. %s\n",
	    argv[0], service_name);
      print_last_error();
      /* Not severe or??? */
  }
  /* Update registry */
  register_logkeys();
  set_keys(service_name, new_entries);
  /* Update service comment if needed */
  if(set_comment) {
      if (!set_service_comment(new_entries[Comment].data.string)) {
	  fwprintf(stderr,L"%s: Warning, could not set correct "
		  L"service description (comment) %s",
		  argv[0], service_name);
	  print_last_error();
      }
  }

  /* As I do this, I should also clean up the new entries, which is
     somewhat harder as I really dont know what is and what is not
     malloced, but we'll exit anyway, so... */
  cleanup_old();
  if(add)
    wprintf(L"%s: Service %s added to system.\n",
	   argv[0], service_name);
  else
    wprintf(L"%s: Service %s updated.\n",
	   argv[0], service_name);
  return 0;
}