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 + -
显示快捷键?