void env_relocate (void) { DEBUGF ("%s[%d] offset = 0x%lx\n", __FUNCTION__,__LINE__, gd->reloc_off); #ifdef CONFIG_AMIGAONEG3SE enable_nvram(); #endif #ifdef ENV_IS_EMBEDDED /* * The environment buffer is embedded with the text segment, * just relocate the environment pointer */ env_ptr = (env_t *)((ulong)env_ptr + gd->reloc_off); DEBUGF ("%s[%d] embedded ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #else /* * We must allocate a buffer for the environment */ env_ptr = (env_t *)malloc (CFG_ENV_SIZE); DEBUGF ("%s[%d] malloced ENV at %p\n", __FUNCTION__,__LINE__,env_ptr); #endif /* * After relocation to RAM, we can always use the "memory" functions */ env_get_char = env_get_char_memory; if (gd->env_valid == 0) { #if defined(CONFIG_GTH) || defined(CFG_ENV_IS_NOWHERE) /* Environment not changable */ puts ("Using default environment\n\n"); #else puts ("*** Warning - bad CRC, using default environment\n\n"); show_boot_progress (-60); #endif } #ifdef CFG_PREBOOT_OVERRIDE if (preboot_override) gd->env_valid = 0; #endif if (gd->env_valid == 0) default_env(); else { env_relocate_spec (); } gd->env_addr = (ulong)&(env_ptr->data); #ifdef CONFIG_AMIGAONEG3SE disable_nvram(); #endif }
void create_env(char **env) { int fd; char *len; int i; if (!env[0]) env = default_env(); fd = open(ENV_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644); len = ft_itoa(ft_ctablen(env)); write(fd, len, ft_strlen(len)); write(fd, "\n", 1); i = 0; while (env[i]) { write(fd, env[i], ft_strlen(env[i])); write(fd, "\n", 1); i++; } close(fd); }
static void use_default() { puts ("*** Warning - bad CRC or NAND, using default environment\n\n"); default_env(); }
int main(int argc, char *argv[]){ /* extract program name from path. e.g. /path/to/MArCd -> MArCd */ const char* separator = strrchr(argv[0], '/'); if ( separator ){ program_name = separator + 1; } else { program_name = argv[0]; } default_env(); int ret; int option_index = 0; int op; #ifdef HAVE_INIPARSER_H if ( config::load(argc, argv) != 0 ){ /* passing argv so it can read -f/--config */ return 1; /* error already shown */ } #endif while ( (op = getopt_long(argc, argv, shortopts, longopts, &option_index)) != -1 ){ switch (op){ case '?': /* error */ exit(1); case 0: /* long opt */ break; case 'b': /* --daemon */ daemon_mode = 1; break; case 's': /* --syslog */ syslog_flag = true; break; case FLAG_USER: /* --user */ config::set_drop_username(optarg); break; case FLAG_GROUP: /* --group */ config::set_drop_group(optarg); break; case FLAG_DROP_PRIV: /** --drop */ drop_priv_flag = true; break; case FLAG_NODROP_PRIV: /** --no-drop */ drop_priv_flag = false; break; case 'f': #ifndef HAVE_INIPARSER_H fprintf(stderr, "%s: configuration files not supported (build with --with-iniparser)\n", program_name); #endif break; case 'H': strncpy(db_hostname, optarg, sizeof(db_hostname)); db_hostname[sizeof(db_hostname)-1] = '\0'; break; case 'N': strncpy(db_name, optarg, sizeof(db_name)); db_name[sizeof(db_name)-1] = '\0'; break; case 'u': strncpy(db_username, optarg, sizeof(db_username)); db_username[sizeof(db_username)-1] = '\0'; break; case 'p': if ( strcmp(optarg, "-") == 0 ){ /* read password from stdin */ strncpy(db_password, getpass("mysql password: "******"Invalid port given to --relay: %s. Ignored\n", optarg); } } break; case FLAG_DATADIR: free(rrdpath); rrdpath = strdup(optarg); break; case FLAG_PIDFILE: pidfile = optarg; break; case 'v': /* --verbose */ verbose_flag = 1; break; case 'q': /* --quiet */ verbose_flag = 0; break; case 'd': /* --debug */ debug_flag = 1; break; case 'h': /* --help */ show_usage(); exit(0); default: if ( option_index >= 0 ){ fprintf(stderr, "flag --%s declared but not handled\n", longopts[option_index].name); } else { fprintf(stderr, "flag -%c declared but not handled\n", op); } abort(); } } /* database */ if ( argc > optind ){ strncpy(db_name, argv[optind], sizeof(db_name)); db_name[sizeof(db_name)-1] = '\0'; } setup_output(); /* test if possible to drop privileges */ if ( drop_priv_flag && getuid() != 0 ){ Log::message(MAIN, "Not executing as uid=0, cannot drop privileges.\n"); drop_priv_flag = 0; } /* Drop privileges. * Done before forking since unlinking requires write permission to folder so * if it fails to write it will fail unlinking. It is also done before * check_env so it actually check environment for the dropped user instead of * root. */ if ( drop_priv_flag ){ privilege_drop(); } /* sanity checks */ show_env(); if ( !check_env() ){ return 1; } if ( daemon_mode ){ /* opening file before fork since it will be a fatal error if it fails to write the pid */ FILE* fp = fopen(pidfile, "w"); if ( !fp ){ Log::fatal(MAIN, "failed to open '%s` for writing: %s\n", pidfile, strerror(errno)); return 1; } Log::message(MAIN, "Forking to background\n"); pid_t pid = fork(); if ( pid ){ /* parent */ fprintf(fp, "%d\n", pid); fclose(fp); /* change owner of pidfile */ if ( drop_priv_flag ){ if ( chown(pidfile, drop_uid, drop_gid) != 0 ){ Log::error("failed to change owner of '%s`, will probably fail to unlink it later: %s\n", pidfile, strerror(errno)); } } return 0; } fclose(fp); } /* initialize daemons */ pthread_barrier_t barrier; int threads = 1; threads += (int)have_control_daemon; threads += (int)have_relay_daemon; pthread_barrier_init(&barrier, NULL, threads); control.addr = relay.addr; if ( have_control_daemon && (ret=Daemon::instantiate<Control>(2000, &barrier)) != 0 ){ Log::fatal(MAIN, "Failed to initialize control daemon, terminating.\n"); if ( daemon_mode && unlink(pidfile) == -1 ){ Log::fatal(MAIN, "Failed to remove pidfile: %s\n", strerror(errno)); } return ret; } if ( have_relay_daemon && (ret=Daemon::instantiate<Relay>(2000, &barrier)) != 0 ){ Log::fatal(MAIN, "Failed to initialize relay daemon, terminating.\n"); if ( daemon_mode && unlink(pidfile) == -1 ){ Log::fatal(MAIN, "Failed to remove pidfile: %s\n", strerror(errno)); } return ret; } /* install signal handler */ signal(SIGINT, handle_signal); signal(SIGTERM, handle_signal); /* release all threads and wait for them to finish*/ pthread_barrier_wait(&barrier); if ( daemon_mode ){ Log::message(MAIN, "Threads started. Going to sleep.\n"); } else { Log::message(MAIN, "Threads started. Going to sleep. Abort with SIGINT\n"); } Daemon::join_all(); /* cleanup */ free(rrdpath); if ( daemon_mode && unlink(pidfile) == -1 ){ Log::fatal(MAIN, "Failed to remove pidfile: %s\n", strerror(errno)); } Log::message(MAIN, "%s terminated.\n", program_name); return 0; }