erlsrv_interactive.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 1,092 行 · 第 1/2 页
C
1,092 行
printf("%s: Service %s stopped.\n", argv[0],service_name); }#endif if(!disable_service()){ fprintf(stderr,"%s: Failed to disable service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { printf("%s: Service %s disabled.\n", argv[0],service_name); return 0; } } if(!_stricmp(action,"enable")){ if(!enable_service()){ fprintf(stderr,"%s: Failed to enable service %s.\n", argv[0],service_name); print_last_error(); return 1; } else { printf("%s: Service %s enabled.\n", argv[0],service_name); return 0; } } fprintf(stderr,"%s: Unrecignized argument %s.\n", argv[0],action); return 1;}int do_add_or_set(int argc, char **argv){ RegEntry *new_entries; RegEntry *default_entries; int add = 0; int i; int current; new_entries = empty_reg_tab(); default_entries = empty_reg_tab(); if(argc < 3){ fprintf(stderr,"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; if(!_stricmp(argv[1],"add")){ if(fetch_current(default_entries)){ fprintf(stderr,"%s: A service with the name %s already " "exists.\n", argv[0],service_name); return 1; } real_service_name = generate_real_service_name(service_name); if(!fill_in_defaults(new_entries)){ fprintf(stderr,"%s: Internal error.\n", argv[0]); return 1; } add = 1; } else { if(!fetch_current(new_entries)){ fprintf(stderr,"%s: No service with the name %s exists.\n", argv[0], service_name); return 1; } real_service_name = new_entries[InternalServiceName].data.bytes; } if(!fill_in_defaults(default_entries)){ fprintf(stderr,"%s: Internal error.\n", argv[0]); return 1; } /* make sure env is malloced... */ new_entries[Env].data.bytes = envdup(new_entries[Env].data.bytes); for(i = 3; i < argc; ++i){ switch((current = lookup_arg(argv[i]))){ case Machine: case WorkDir: case Args: if(i+1 >= argc){ new_entries[current].data.bytes = default_entries[current].data.bytes; new_entries[current].data.expand.unexpanded = default_entries[current].data.expand.unexpanded; } else { new_entries[current].data.expand.unexpanded = new_entries[current].data.bytes = argv[i+1]; ++i; } break; case SName: new_entries[Name].data.bytes = ""; case StopAction: case Name: if(i+1 >= argc || *argv[i+1] == '-' || *argv[i+1] == '/'){ new_entries[current].data.bytes = default_entries[current].data.bytes; } else { new_entries[current].data.bytes = argv[i+1]; ++i; } break; case OnFail: if(i+1 >= argc || *argv[i+1] == '-' || *argv[i+1] == '/'){ new_entries[current].data.value = default_entries[current].data.value; } else { if(!_stricmp(argv[i+1],"reboot")) new_entries[current].data.value = ON_FAIL_REBOOT; else if(!_stricmp(argv[i+1],"restart")) new_entries[current].data.value = ON_FAIL_RESTART; else if(!_stricmp(argv[i+1],"restart_always")) new_entries[current].data.value = ON_FAIL_RESTART_ALWAYS; else { fprintf(stderr,"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } ++i; } break; case DebugType: if(i+1 >= argc || *argv[i+1] == '-' || *argv[i+1] == '/'){ new_entries[current].data.value = default_entries[current].data.value; } else { if(!_stricmp(argv[i+1],"new")) new_entries[current].data.value = DEBUG_TYPE_NEW; else if(!_stricmp(argv[i+1],"reuse")) new_entries[current].data.value = DEBUG_TYPE_REUSE; else if(!_stricmp(argv[i+1],"console")) new_entries[current].data.value = DEBUG_TYPE_CONSOLE; else { fprintf(stderr,"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } ++i; } break; case Priority: if(i+1 >= argc || *argv[i+1] == '-' || *argv[i+1] == '/'){ new_entries[current].data.value = default_entries[current].data.value; } else { if(!_stricmp(argv[i+1],"high")) new_entries[current].data.value = HIGH_PRIORITY_CLASS; else if(!_stricmp(argv[i+1],"low")) new_entries[current].data.value = IDLE_PRIORITY_CLASS; else if(!_stricmp(argv[i+1],"realtime")) new_entries[current].data.value = REALTIME_PRIORITY_CLASS; else { fprintf(stderr,"%s: Unrecognized keyword value %s.\n", argv[0],argv[i+1]); return 1; } ++i; } break; case Env: if(i+1 >= argc || *argv[i+1] == '-' || *argv[i+1] == '/'){ fprintf(stderr,"%s: %s requires a parameter.\n", argv[0],argv[i]); return 1; } new_entries[current].data.bytes = edit_env(argv[i+1], new_entries[current].data.bytes); ++i; break; default: fprintf(stderr,"%s: Unrecognized option %s.\n", argv[0], argv[i]); return 1; } } if(*new_entries[SName].data.bytes && *new_entries[Name].data.bytes){#if 0 fprintf(stderr,"%s: Both -sname and -name specified.\n", argv[0]); return 1;#else new_entries[SName].data.bytes = "";#endif } if(add && !(*new_entries[SName].data.bytes) && !(*new_entries[Name].data.bytes)){ fprintf(stderr,"%s: Neither -sname nor -name specified.\n", argv[0]); return 1; } if(add && !install_service()){ fprintf(stderr,"%s: Unable to register 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)){ fprintf(stderr,"%s: Warning, could not set correct interactive mode.\n", argv[0], service_name); print_last_error(); /* Not severe or??? */ } /* Update registry */ register_logkeys(); set_keys(service_name, new_entries); /* 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) printf("%s: Service %s added to system.\n", argv[0], service_name); else printf("%s: Service %s updated.\n", argv[0], service_name); return 0;}int do_rename(int argc, char **argv){ RegEntry *current = empty_reg_tab(); RegEntry *dummy = empty_reg_tab(); SC_HANDLE scm; SC_HANDLE service; if(argc < 3){ fprintf(stderr,"%s: No old servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } if(argc < 4){ fprintf(stderr,"%s: No new servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[3]; if(fetch_current(dummy)){ fprintf(stderr,"%s: A service with the name %s already " "exists.\n", argv[0],service_name); return 1; } service_name = argv[2]; if(!fetch_current(current)){ fprintf(stderr,"%s: Error, old service name %s does not exist.\n", argv[0],service_name); return 1; } real_service_name = _strdup(current[InternalServiceName].data.bytes); if(!open_service_config(&scm,&service)){ fprintf(stderr,"%s: Error, unable to communicate with service control" " manager.\n", argv[0]); print_last_error(); return 1; } if(!ChangeServiceConfig(service, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, argv[3])){ fprintf(stderr,"%s: Error, unable to communicate with service control" " manager.\n", argv[0]); print_last_error(); CloseServiceHandle(scm); CloseServiceHandle(service); return 1; } CloseServiceHandle(scm); CloseServiceHandle(service); if(remove_keys(service_name) != 0) fprintf(stderr,"%s: Warning, old service parameter keys could not " "be removed, continuing.\n", argv[0]); /* Update registry */ register_logkeys(); set_keys(argv[3], current); printf("%s: Service %s renamed to %s.\n", argv[0], service_name, argv[3]); return 0;}int do_remove(int argc, char **argv){ RegEntry *current = empty_reg_tab(); int rem_res; BOOL found; if(argc < 3){ fprintf(stderr,"%s: No servicename given!\n",argv[0]); do_usage(argv[0]); return 1; } service_name = argv[2]; found = fetch_current(current); if(found){ real_service_name = _strdup(current[InternalServiceName].data.bytes); } else { real_service_name = _strdup(service_name); } if(found) free_keys(current); if(stop_service() && !wait_service_trans(SERVICE_RUNNING, SERVICE_STOP_PENDING, SERVICE_STOPPED, 60)){ fprintf(stderr,"%s: Failed to stop running service %s.\n", argv[0],service_name); print_last_error(); return 1; } if(!remove_service()){ fprintf(stderr,"%s: Unable to remove service (not enough " "privileges?)\n",argv[0]); print_last_error(); return 1; } if((rem_res = remove_keys(service_name)) > 0){ fprintf(stderr,"%s: Warning, service parameter keys belonged to old " "erlsrv version.\n", argv[0]); /* Backward compatibility... */ } else if(rem_res < 0) { fprintf(stderr,"%s: Error, service parameter keys nonexistent.\n", argv[0]); return 1; } printf("%s: Service %s removed from system.\n", argv[0], service_name); return 0;}BOOL list_one(char *servicename, RegEntry *keys, BOOL longlist){ char *onfail; char *prio; char *debugtype; switch(keys[OnFail].data.value){ case ON_FAIL_RESTART: onfail = "restart"; break; case ON_FAIL_RESTART_ALWAYS: onfail = "restart_always"; break; case ON_FAIL_REBOOT: onfail = "reboot"; break; default: onfail = "ignore"; } switch(keys[DebugType].data.value){ case DEBUG_TYPE_NEW: debugtype = "new"; break; case DEBUG_TYPE_REUSE: debugtype = "reuse"; break; case DEBUG_TYPE_CONSOLE: debugtype = "console"; break; default: debugtype = "none"; } switch(keys[Priority].data.value){ case HIGH_PRIORITY_CLASS: prio = "high"; break; case IDLE_PRIORITY_CLASS: prio = "low"; break; case REALTIME_PRIORITY_CLASS: prio = "realtime"; break; case NORMAL_PRIORITY_CLASS: prio = "default"; break; default: prio = "unknown/faulty"; } if(longlist){ char *env = envdup(keys[Env].data.bytes); char **arg = env_to_arg(env); char **pek = arg; printf("Service name: %s\n", servicename); printf("StopAction: %s\n", keys[StopAction].data.bytes); printf("OnFail: %s\n",onfail); printf("Machine: %s\n", keys[Machine].data.expand.unexpanded); printf("WorkDir: %s\n", keys[WorkDir].data.expand.unexpanded); if(*keys[SName].data.bytes) printf("SName: %s\n", keys[SName].data.bytes); else printf("Name: %s\n", keys[Name].data.bytes); printf("Priority: %s\n",prio); printf("DebugType: %s\n",debugtype); printf("Args: %s\n", keys[Args].data.expand.unexpanded); printf("Env:\n"); while(*pek){ printf("\t%s\n",*pek); ++pek; } /* env is easier to free...*/ env = arg_to_env(arg); free(env); } else { printf("%s\t%s\t%s\t%s\t%s\n", servicename, (*keys[Name].data.bytes) ? keys[Name].data.bytes : keys[SName].data.bytes, prio, onfail, keys[Args].data.expand.unexpanded); } return TRUE;} int do_list(int argc, char **argv){ if(argc < 3){ RegEntryDesc *all_keys = get_all_keys(); if(!all_keys){ fprintf(stderr,"%s: No services found in registry.\n", argv[0]); return 0; } printf("Service\t(S)Name\tPrio\tOnFail\tArgs\n"); while(all_keys->servicename){ list_one(all_keys->servicename,all_keys->entries,FALSE); ++all_keys; } return 0; } else { RegEntry *keys; service_name = argv[2]; keys = get_keys(service_name); if(!keys){ fprintf(stderr,"%s: Could not retrieve any " "registered data for %s.\n",argv[0],service_name); return 1; } list_one(service_name, keys, TRUE); } return 0;}#define READ_CHUNK 100#define ARGV_CHUNK 20char *safe_get_line(void){ int lsize = READ_CHUNK; char *line = malloc(READ_CHUNK); int pos = 0; int ch; while((ch = getchar()) != EOF && ch != '\n'){ if(pos + 1 >= lsize){ line = realloc(line,(lsize += READ_CHUNK)); assert(line); } line[pos++] = ch; } if(ch == EOF || !pos){ free(line); return NULL; } line[pos] = '\0'; return line;}void read_arguments(int *pargc, char ***pargv){ int argc = 0; int asize = ARGV_CHUNK; char **argv = malloc(ARGV_CHUNK*sizeof(char *)); char *tmp; argv[0] = (*pargv)[0]; argc = 1; while((tmp = safe_get_line()) != NULL){ if(argc + 1 >= asize){ argv = realloc(argv,(asize += ARGV_CHUNK)*sizeof(char *)); assert(argv); } argv[argc++] = tmp; } argv[argc] = NULL; *pargc = argc; *pargv = argv;} int interactive_main(int argc, char **argv){ char *action = argv[1]; if(!_stricmp(action,"readargs")){ read_arguments(&argc,&argv); action = argv[1]; } if(!_stricmp(action,"set") || !_stricmp(action,"add")) return do_add_or_set(argc,argv); if(!_stricmp(action,"rename")) return do_rename(argc,argv); if(!_stricmp(action,"remove")) return do_remove(argc,argv); if(!_stricmp(action,"list")) return do_list(argc,argv); if(!_stricmp(action,"start") || !_stricmp(action,"stop") || !_stricmp(action,"enable") || !_stricmp(action,"disable")) return do_manage(argc,argv); if(_stricmp(action,"?") && _stricmp(action,"/?") && _stricmp(action,"-?") && *action != 'h' && *action != 'H') fprintf(stderr,"%s: action %s not implemented.\n",argv[0],action); do_usage(argv[0]); return 1;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?