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;
}