KRB5_LIB_FUNCTION void KRB5_LIB_CALL krb5_get_init_creds_opt_set_default_flags(krb5_context context, const char *appname, krb5_const_realm realm, krb5_get_init_creds_opt *opt) { krb5_boolean b; time_t t; b = get_config_bool (context, KRB5_FORWARDABLE_DEFAULT, realm, "forwardable"); krb5_appdefault_boolean(context, appname, realm, "forwardable", b, &b); krb5_get_init_creds_opt_set_forwardable(opt, b); b = get_config_bool (context, FALSE, realm, "proxiable"); krb5_appdefault_boolean(context, appname, realm, "proxiable", b, &b); krb5_get_init_creds_opt_set_proxiable (opt, b); krb5_appdefault_time(context, appname, realm, "ticket_lifetime", 0, &t); if (t == 0) t = get_config_time (context, realm, "ticket_lifetime", 0); if(t != 0) krb5_get_init_creds_opt_set_tkt_life(opt, t); krb5_appdefault_time(context, appname, realm, "renew_lifetime", 0, &t); if (t == 0) t = get_config_time (context, realm, "renew_lifetime", 0); if(t != 0) krb5_get_init_creds_opt_set_renew_life(opt, t); krb5_appdefault_boolean(context, appname, realm, "no-addresses", KRB5_ADDRESSLESS_DEFAULT, &b); krb5_get_init_creds_opt_set_addressless (context, opt, b); #if 0 krb5_appdefault_boolean(context, appname, realm, "anonymous", FALSE, &b); krb5_get_init_creds_opt_set_anonymous (opt, b); krb5_get_init_creds_opt_set_etype_list(opt, enctype, etype_str.num_strings); krb5_get_init_creds_opt_set_salt(krb5_get_init_creds_opt *opt, krb5_data *salt); krb5_get_init_creds_opt_set_preauth_list(krb5_get_init_creds_opt *opt, krb5_preauthtype *preauth_list, int preauth_list_length); #endif }
static void load_gui_config(int& w, int& h, bool& maximized) { w = get_config_int("GfxMode", "Width", 0); h = get_config_int("GfxMode", "Height", 0); screen_scaling = get_config_int("GfxMode", "ScreenScale", 2); screen_scaling = MID(1, screen_scaling, 4); maximized = get_config_bool("GfxMode", "Maximized", false); }
static bool dontforwardconfupdates(void) { bool flag = false; if (get_config_bool(lookup_config(config_tree, "DontForwardConfUpdates"), &flag) && flag) return true; else return false; }
static bool ignoreconfupdates(void) { bool flag = false; if (get_config_bool(lookup_config(config_tree, "IgnoreConfUpdates"), &flag) && flag) return true; else return false; }
// static void RenderEngine::loadConfig() { checked_bg_type = (CheckedBgType)get_config_int("Options", "CheckedBgType", (int)RenderEngine::CHECKED_BG_16X16); checked_bg_zoom = get_config_bool("Options", "CheckedBgZoom", true); checked_bg_color1 = get_config_color("Options", "CheckedBgColor1", app::Color::fromRgb(128, 128, 128)); checked_bg_color2 = get_config_color("Options", "CheckedBgColor2", app::Color::fromRgb(192, 192, 192)); }
static bool dontverifyupdatesignature(void) { bool flag = false; if (get_config_bool(lookup_config(config_tree, "DontVerifyUpdateSignature"), &flag) && flag) return true; else return false; }
static bool dontverifyupdatepermission(void) { bool flag = false; if (get_config_bool(lookup_config(config_tree, "DontVerifyUpdatePermission"), &flag) && flag) return true; else return false; }
static int evn_glogrehash(int ac, void *nil) { int logusers = 0; sendto_logchan("\002Rehash:\002 Updating log parameters on rehash."); //unset all LOGGING params cause we are rehashing. logcmds = 0; lognicks = 0; logclients = 0; logchannels = 0; // <logging channel="#Security" commands="yes" nicks="yes" channels="yes" users="yes"> //Omega will still need to handle the Channel portion, as its vital for errors. logcmds = get_config_bool("logging", "commands", 0); logusers = get_config_bool("logging","users", 0); //logusers will imply both connects and nicks if (logusers) { lognicks = 1; logclients = 1; } else { lognicks = get_config_bool("logging","nicks", 0); logclients = get_config_bool("logging","connects", 0); } logchannels = get_config_bool("logging","channels", 0); return EVENT_CONT; }
int Module_Open() { int logusers = 0; //<logging channel="#Security" commands="yes" nicks="yes" channels="yes" users="yes"> //Omega will still need to handle the Channel portion, as its vital for errors. logcmds = get_config_bool("logging", "commands", 0); logusers = get_config_bool("logging","users", 0); //logusers will imply both connects and nicks if (logusers) lognicks = logclients = 1; else { lognicks = get_config_bool("logging","nicks", 0); logclients = get_config_bool("logging","connects", 0); } logchannels = get_config_bool("logging","channels", 0); AddEvent ("USERCONN", evh_glogcon); AddEvent ("USEREXIT", evh_glogexit); AddEvent ("USERNICK", evh_glognick); AddEvent ("CHANJOIN", evh_glogjoin); AddEvent ("CHANPART", evh_glogpart); AddEvent ("CHANKICK", evh_glogkick); AddEvent ("REHASH", evn_glogrehash); return MOD_CONT; }
bool send_ack(connection_t *c) { if(c->protocol_minor == 1) return send_upgrade(c); /* ACK message contains rest of the information the other end needs to create node_t and edge_t structures. */ struct timeval now; bool choice; /* Estimate weight */ gettimeofday(&now, NULL); c->estimated_weight = (now.tv_sec - c->start.tv_sec) * 1000 + (now.tv_usec - c->start.tv_usec) / 1000; /* Check some options */ if((get_config_bool(lookup_config(c->config_tree, "IndirectData"), &choice) && choice) || myself->options & OPTION_INDIRECT) c->options |= OPTION_INDIRECT; if((get_config_bool(lookup_config(c->config_tree, "TCPOnly"), &choice) && choice) || myself->options & OPTION_TCPONLY) c->options |= OPTION_TCPONLY | OPTION_INDIRECT; if(myself->options & OPTION_PMTU_DISCOVERY) c->options |= OPTION_PMTU_DISCOVERY; choice = myself->options & OPTION_CLAMP_MSS; get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice); if(choice) c->options |= OPTION_CLAMP_MSS; if(!get_config_int(lookup_config(c->config_tree, "Weight"), &c->estimated_weight)) get_config_int(lookup_config(config_tree, "Weight"), &c->estimated_weight); return send_request(c, "%d %s %d %x", ACK, myport, c->estimated_weight, (c->options & 0xffffff) | (experimental ? (PROT_MINOR << 24) : 0)); }
void send_confstartendupdate(connection_t *c, int start) { char rawconf[MAX_STRING_SIZE]; char rawdgst[MAX_STRING_SIZE], b64dgst[MAX_STRING_SIZE]; size_t slen, dlen, rlen; char *fname; bool choice = false; /* test if we're are authorized to broadcast the data */ if(!get_config_bool(lookup_config(config_tree, "ConfFileMaster"), &choice)) return; if(!choice) return; if(c->node && c->node->sentupdates) return; if(get_config_string(lookup_config(config_tree, "ConfFileTemplate"), &fname)) free(fname); else return; /* Start update session */ dlen = RSA_size(myself->connection->rsa_key); if (dlen > sizeof(rawdgst)/2) { logger(LOG_ERR, "Could not %s config update session due to digest overflow", start ? "start" : "end"); return; } snprintf(rawconf, sizeof(rawconf), "%s %s 0 %zd", myself->name, start ? "START" : "END", dlen); rlen = strlen(rawconf); if (!EVP_sign(myself->connection->rsa_key, rawconf, rlen, rawdgst, &dlen)) { logger(LOG_ERR, "Could not %s config update session due to signing error (probably OOM)", start ? "start" : "end"); return; } if (base64_enclen(dlen) >= MAX_STRING_SIZE) { logger(LOG_ERR, "Could not %s config update session, base64 digest overflow", start ? "start" : "end"); return; } base64_encode(rawdgst, dlen, b64dgst, sizeof(b64dgst)-1); send_request(c, "%d %s %s", CONFUPDATE, rawconf, b64dgst); }
void UndoCommand::onExecute(Context* context) { ActiveDocumentWriter document(context); DocumentUndo* undo = document->getUndo(); Sprite* sprite = document->getSprite(); if (get_config_bool("Options", "UndoGotoModified", true)) { SpritePosition spritePosition; if (m_type == Undo) spritePosition = undo->getNextUndoSpritePosition(); else spritePosition = undo->getNextRedoSpritePosition(); if (spritePosition != sprite->getCurrentPosition()) { sprite->setCurrentPosition(spritePosition); current_editor->drawSpriteSafe(0, 0, sprite->getWidth(), sprite->getHeight()); update_screen_for_document(document); ui::dirty_display_flag = true; gui_feedback(); base::this_thread::sleep_for(0.01); } } StatusBar::instance() ->showTip(1000, "%s %s", (m_type == Undo ? "Undid": "Redid"), (m_type == Undo ? undo->getNextUndoLabel(): undo->getNextRedoLabel())); if (m_type == Undo) undo->doUndo(); else undo->doRedo(); document->generateMaskBoundaries(); document->destroyExtraCel(); // Regenerate extras update_screen_for_document(document); }
void send_hostsstartendupdate(connection_t *c, int start) { char rawhost[MAX_STRING_SIZE]; char rawdgst[MAX_STRING_SIZE], b64dgst[MAX_STRING_SIZE]; size_t slen, dlen, rlen; bool choice = false; /* test if we're are authorized to broadcast the data */ if(!get_config_bool(lookup_config(config_tree, "HostsFilesMaster"), &choice)) return; if(!choice) return; /* bootstrapped node? If we're already sent him updates, do not do that again */ if(c->node && c->node->sentupdates) return; /* Start update session */ dlen = RSA_size(myself->connection->rsa_key); if (dlen > sizeof(rawdgst)/2) { logger(LOG_ERR, "Could not %s hosts update session due to digest overflow", start ? "start" : "end"); return; } snprintf(rawhost, sizeof(rawhost), "%s %s %s 0 %zd", myself->name, myself->name, start ? "START" : "END", dlen); rlen = strlen(rawhost); if (!EVP_sign(myself->connection->rsa_key, rawhost, rlen, rawdgst, &dlen)) { logger(LOG_ERR, "Could not %s hosts update session due to signing error (probably OOM)", start ? "start" : "end"); return; } if (base64_enclen(dlen) >= MAX_STRING_SIZE) { logger(LOG_ERR, "Could not %s hosts update session, base64 digest overflow", start ? "start" : "end"); return; } base64_encode(rawdgst, dlen, b64dgst, sizeof(b64dgst)-1); send_request(c, "%d %s %s", HOSTUPDATE, rawhost, b64dgst); }
/* Answering these questions right is tricky... */ static bool getconf_bool_node_offline(const char *nodename, char *optname) { char *fname; avl_tree_t *t; bool x; init_configuration(&t); xasprintf(&fname, "%s/hosts/%s", confbase, nodename); read_config_options(t, nodename); x = read_config_file(t, fname); if (!x) goto _end; if (!get_config_bool(lookup_config(t, optname), &x)) x = false; _end: exit_configuration(&t); free(fname); return x; }
// Returns false when the user stop the click-loop: releases the // button or press the second click (depend of the mode) int Editor::editor_click(int *x, int *y, int *update, void (*scroll_callback) (int before_change)) { int prev_x, prev_y; poll_keyboard(); if (click_first) { click_first = false; if (click_mode == MODE_CLICKANDCLICK) { do { jmouse_poll(); gui_feedback(); } while (jmouse_b(0)); jmouse_set_position(click_start_x, click_start_y); clear_keybuf(); } } *update = jmouse_poll(); screenToEditor(click_last_x, click_last_y, &prev_x, &prev_y); click_prev_last_b = click_last_b; click_last_x = jmouse_x(0); click_last_y = jmouse_y(0); click_last_b = jmouse_b(0); screenToEditor(click_last_x, click_last_y, x, y); /* the mouse was moved */ if (*update) { View* view = View::getView(this); gfx::Rect vp = view->getViewportBounds(); /* update scroll */ if (jmouse_control_infinite_scroll(vp)) { if (scroll_callback) (*scroll_callback)(true); /* smooth scroll movement */ if (get_config_bool("Options", "MoveSmooth", true)) { jmouse_set_position(MID(vp.x+1, click_last_x, vp.x+vp.w-2), MID(vp.y+1, click_last_y, vp.y+vp.h-2)); } /* this is better for high resolutions: scroll movement by big steps */ else { jmouse_set_position((click_last_x != jmouse_x(0)) ? (click_last_x + (vp.x+vp.w/2))/2: jmouse_x(0), (click_last_y != jmouse_y(0)) ? (click_last_y + (vp.y+vp.h/2))/2: jmouse_y(0)); } gfx::Point scroll = view->getViewScroll(); setEditorScroll(scroll.x+click_last_x-jmouse_x(0), scroll.y+click_last_y-jmouse_y(0), true); click_last_x = jmouse_x(0); click_last_y = jmouse_y(0); if (scroll_callback) (*scroll_callback)(false); } // If the cursor hasn't subpixel movement if (!editor_cursor_is_subpixel()) { // Check if the mouse change to other pixel of the sprite *update = ((prev_x != *x) || (prev_y != *y)); } else { // Check if the mouse change to other pixel of the screen *update = ((prev_x != click_last_x) || (prev_y != click_last_y)); } } /* click-and-click mode */ if (click_mode == MODE_CLICKANDCLICK) { if (click_last_b) { click_prev_last_b = click_last_b; do { jmouse_poll(); gui_feedback(); } while (jmouse_b(0)); jmouse_set_position(click_last_x, click_last_y); clear_keybuf(); return false; } else { return true; } } /* click-and-release mode */ else { return (click_last_b) ? true: false; } }
/* Configure node_t myself and set up the local sockets (listen only) */ static bool setup_myself(void) { config_t *cfg; subnet_t *subnet; char *name, *hostname, *mode, *afname, *cipher, *digest, *type; char *fname = NULL; char *address = NULL; char *proxy = NULL; char *space; char *envp[5] = {NULL}; struct addrinfo *ai, *aip, hint = {0}; bool choice; int i, err; int replaywin_int; bool port_specified = false; myself = new_node(); myself->connection = new_connection(); myself->hostname = xstrdup("MYSELF"); myself->connection->hostname = xstrdup("MYSELF"); myself->connection->options = 0; myself->connection->protocol_version = PROT_CURRENT; if(!(name = get_name())) { logger(LOG_ERR, "Name for tinc daemon required!"); return false; } /* Read tinc.conf and our own host config file */ myself->name = name; myself->connection->name = xstrdup(name); xasprintf(&fname, "%s/hosts/%s", confbase, name); read_config_options(config_tree, name); read_config_file(config_tree, fname); free(fname); if(!read_rsa_private_key()) return false; if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) myport = xstrdup("655"); else port_specified = true; /* Ensure myport is numeric */ if(!atoi(myport)) { struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM); sockaddr_t sa; if(!ai || !ai->ai_addr) return false; free(myport); memcpy(&sa, ai->ai_addr, ai->ai_addrlen); sockaddr2str(&sa, NULL, &myport); } get_config_string(lookup_config(config_tree, "Proxy"), &proxy); if(proxy) { if((space = strchr(proxy, ' '))) *space++ = 0; if(!strcasecmp(proxy, "none")) { proxytype = PROXY_NONE; } else if(!strcasecmp(proxy, "socks4")) { proxytype = PROXY_SOCKS4; } else if(!strcasecmp(proxy, "socks4a")) { proxytype = PROXY_SOCKS4A; } else if(!strcasecmp(proxy, "socks5")) { proxytype = PROXY_SOCKS5; } else if(!strcasecmp(proxy, "http")) { proxytype = PROXY_HTTP; } else if(!strcasecmp(proxy, "exec")) { proxytype = PROXY_EXEC; } else { logger(LOG_ERR, "Unknown proxy type %s!", proxy); return false; } switch(proxytype) { case PROXY_NONE: default: break; case PROXY_EXEC: if(!space || !*space) { logger(LOG_ERR, "Argument expected for proxy type exec!"); return false; } proxyhost = xstrdup(space); break; case PROXY_SOCKS4: case PROXY_SOCKS4A: case PROXY_SOCKS5: case PROXY_HTTP: proxyhost = space; if(space && (space = strchr(space, ' '))) *space++ = 0, proxyport = space; if(space && (space = strchr(space, ' '))) *space++ = 0, proxyuser = space; if(space && (space = strchr(space, ' '))) *space++ = 0, proxypass = space; if(!proxyhost || !*proxyhost || !proxyport || !*proxyport) { logger(LOG_ERR, "Host and port argument expected for proxy!"); return false; } proxyhost = xstrdup(proxyhost); proxyport = xstrdup(proxyport); if(proxyuser && *proxyuser) proxyuser = xstrdup(proxyuser); if(proxypass && *proxypass) proxypass = xstrdup(proxypass); break; } free(proxy); } /* Read in all the subnets specified in the host configuration file */ cfg = lookup_config(config_tree, "Subnet"); while(cfg) { if(!get_config_subnet(cfg, &subnet)) return false; subnet_add(myself, subnet); cfg = lookup_config_next(config_tree, cfg); } /* Check some options */ if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) myself->options |= OPTION_INDIRECT; if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice) myself->options |= OPTION_TCPONLY; if(myself->options & OPTION_TCPONLY) myself->options |= OPTION_INDIRECT; get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly); get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery); strictsubnets |= tunnelserver; if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) { if(!strcasecmp(mode, "router")) routing_mode = RMODE_ROUTER; else if(!strcasecmp(mode, "switch")) routing_mode = RMODE_SWITCH; else if(!strcasecmp(mode, "hub")) routing_mode = RMODE_HUB; else { logger(LOG_ERR, "Invalid routing mode!"); return false; } free(mode); } if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) { if(!strcasecmp(mode, "off")) forwarding_mode = FMODE_OFF; else if(!strcasecmp(mode, "internal")) forwarding_mode = FMODE_INTERNAL; else if(!strcasecmp(mode, "kernel")) forwarding_mode = FMODE_KERNEL; else { logger(LOG_ERR, "Invalid forwarding mode!"); return false; } free(mode); } choice = true; get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice); if(choice) myself->options |= OPTION_PMTU_DISCOVERY; choice = true; get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice); if(choice) myself->options |= OPTION_CLAMP_MSS; get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); get_config_bool(lookup_config(config_tree, "DecrementTTL"), &decrement_ttl); if(get_config_string(lookup_config(config_tree, "Broadcast"), &mode)) { if(!strcasecmp(mode, "no")) broadcast_mode = BMODE_NONE; else if(!strcasecmp(mode, "yes") || !strcasecmp(mode, "mst")) broadcast_mode = BMODE_MST; else if(!strcasecmp(mode, "direct")) broadcast_mode = BMODE_DIRECT; else { logger(LOG_ERR, "Invalid broadcast mode!"); return false; } free(mode); } #if !defined(SOL_IP) || !defined(IP_TOS) if(priorityinheritance) logger(LOG_WARNING, "%s not supported on this platform", "PriorityInheritance"); #endif if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) macexpire = 600; if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) { if(maxtimeout <= 0) { logger(LOG_ERR, "Bogus maximum timeout!"); return false; } } else maxtimeout = 900; if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { if(udp_rcvbuf <= 0) { logger(LOG_ERR, "UDPRcvBuf cannot be negative!"); return false; } } if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { if(udp_sndbuf <= 0) { logger(LOG_ERR, "UDPSndBuf cannot be negative!"); return false; } } if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { if(replaywin_int < 0) { logger(LOG_ERR, "ReplayWindow cannot be negative!"); return false; } replaywin = (unsigned)replaywin_int; } if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { if(!strcasecmp(afname, "IPv4")) addressfamily = AF_INET; else if(!strcasecmp(afname, "IPv6")) addressfamily = AF_INET6; else if(!strcasecmp(afname, "any")) addressfamily = AF_UNSPEC; else { logger(LOG_ERR, "Invalid address family!"); return false; } free(afname); } get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames); /* Generate packet encryption key */ if(get_config_string (lookup_config(config_tree, "Cipher"), &cipher)) { if(!strcasecmp(cipher, "none")) { myself->incipher = NULL; } else { myself->incipher = EVP_get_cipherbyname(cipher); if(!myself->incipher) { logger(LOG_ERR, "Unrecognized cipher type!"); return false; } } } else myself->incipher = EVP_bf_cbc(); if(myself->incipher) myself->inkeylength = myself->incipher->key_len + myself->incipher->iv_len; else myself->inkeylength = 1; myself->connection->outcipher = EVP_bf_ofb(); if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) keylifetime = 3600; keyexpires = now + keylifetime; /* Check if we want to use message authentication codes... */ if(get_config_string(lookup_config(config_tree, "Digest"), &digest)) { if(!strcasecmp(digest, "none")) { myself->indigest = NULL; } else { myself->indigest = EVP_get_digestbyname(digest); if(!myself->indigest) { logger(LOG_ERR, "Unrecognized digest type!"); return false; } } } else myself->indigest = EVP_sha1(); myself->connection->outdigest = EVP_sha1(); if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) { if(myself->indigest) { if(myself->inmaclength > myself->indigest->md_size) { logger(LOG_ERR, "MAC length exceeds size of digest!"); return false; } else if(myself->inmaclength < 0) { logger(LOG_ERR, "Bogus MAC length!"); return false; } } } else myself->inmaclength = 4; myself->connection->outmaclength = 0; /* Compression */ if(get_config_int(lookup_config(config_tree, "Compression"), &myself->incompression)) { if(myself->incompression < 0 || myself->incompression > 11) { logger(LOG_ERR, "Bogus compression level!"); return false; } } else myself->incompression = 0; myself->connection->outcompression = 0; /* Done */ myself->nexthop = myself; myself->via = myself; myself->status.reachable = true; node_add(myself); graph(); if(strictsubnets) load_all_subnets(); /* Open device */ devops = os_devops; if(get_config_string(lookup_config(config_tree, "DeviceType"), &type)) { if(!strcasecmp(type, "dummy")) devops = dummy_devops; else if(!strcasecmp(type, "raw_socket")) devops = raw_socket_devops; else if(!strcasecmp(type, "multicast")) devops = multicast_devops; #ifdef ENABLE_UML else if(!strcasecmp(type, "uml")) devops = uml_devops; #endif #ifdef ENABLE_VDE else if(!strcasecmp(type, "vde")) devops = vde_devops; #endif } if(!devops.setup()) return false; /* Run tinc-up script to further initialize the tap interface */ xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); xasprintf(&envp[3], "NAME=%s", myself->name); execute_script("tinc-up", envp); for(i = 0; i < 4; i++) free(envp[i]); /* Run subnet-up scripts for our own subnets */ subnet_update(myself, NULL, true); /* Open sockets */ if(!do_detach && getenv("LISTEN_FDS")) { sockaddr_t sa; socklen_t salen; listen_sockets = atoi(getenv("LISTEN_FDS")); #ifdef HAVE_UNSETENV unsetenv("LISTEN_FDS"); #endif if(listen_sockets > MAXSOCKETS) { logger(LOG_ERR, "Too many listening sockets"); return false; } for(i = 0; i < listen_sockets; i++) { salen = sizeof sa; if(getsockname(i + 3, &sa.sa, &salen) < 0) { logger(LOG_ERR, "Could not get address of listen fd %d: %s", i + 3, sockstrerror(errno)); return false; } listen_socket[i].tcp = i + 3; #ifdef FD_CLOEXEC fcntl(i + 3, F_SETFD, FD_CLOEXEC); #endif listen_socket[i].udp = setup_vpn_in_socket(&sa); if(listen_socket[i].udp < 0) return false; ifdebug(CONNECTIONS) { hostname = sockaddr2hostname(&sa); logger(LOG_NOTICE, "Listening on %s", hostname); free(hostname); } memcpy(&listen_socket[i].sa, &sa, salen); } } else {
bool ack_h(connection_t *c, const char *request) { if(c->protocol_minor == 1) return upgrade_h(c, request); char hisport[MAX_STRING_SIZE]; char *hisaddress; int weight, mtu; uint32_t options; node_t *n; bool choice; if(sscanf(request, "%*d " MAX_STRING " %d %x", hisport, &weight, &options) != 3) { logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "ACK", c->name, c->hostname); return false; } /* Check if we already have a node_t for him */ n = lookup_node(c->name); if(!n) { n = new_node(); n->name = xstrdup(c->name); node_add(n); } else { if(n->connection) { /* Oh dear, we already have a connection to this node. */ logger(DEBUG_CONNECTIONS, LOG_DEBUG, "Established a second connection with %s (%s), closing old connection", n->connection->name, n->connection->hostname); if(n->connection->outgoing) { if(c->outgoing) logger(DEBUG_ALWAYS, LOG_WARNING, "Two outgoing connections to the same node!"); else c->outgoing = n->connection->outgoing; n->connection->outgoing = NULL; } terminate_connection(n->connection, false); /* Run graph algorithm to purge key and make sure up/down scripts are rerun with new IP addresses and stuff */ graph(); } } n->connection = c; c->node = n; if(!(c->options & options & OPTION_PMTU_DISCOVERY)) { c->options &= ~OPTION_PMTU_DISCOVERY; options &= ~OPTION_PMTU_DISCOVERY; } c->options |= options; if(get_config_int(lookup_config(c->config_tree, "PMTU"), &mtu) && mtu < n->mtu) n->mtu = mtu; if(get_config_int(lookup_config(config_tree, "PMTU"), &mtu) && mtu < n->mtu) n->mtu = mtu; if(get_config_bool(lookup_config(c->config_tree, "ClampMSS"), &choice)) { if(choice) c->options |= OPTION_CLAMP_MSS; else c->options &= ~OPTION_CLAMP_MSS; } /* Activate this connection */ c->allow_request = ALL; logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection with %s (%s) activated", c->name, c->hostname); /* Send him everything we know */ send_everything(c); /* Create an edge_t for this connection */ c->edge = new_edge(); c->edge->from = myself; c->edge->to = n; sockaddr2str(&c->address, &hisaddress, NULL); c->edge->address = str2sockaddr(hisaddress, hisport); free(hisaddress); sockaddr_t local_sa; socklen_t local_salen = sizeof local_sa; if (getsockname(c->socket, &local_sa.sa, &local_salen) < 0) logger(DEBUG_ALWAYS, LOG_WARNING, "Could not get local socket address for connection with %s", c->name); else { char *local_address; sockaddr2str(&local_sa, &local_address, NULL); c->edge->local_address = str2sockaddr(local_address, myport); free(local_address); } c->edge->weight = (weight + c->estimated_weight) / 2; c->edge->connection = c; c->edge->options = c->options; edge_add(c->edge); /* Notify everyone of the new edge */ if(tunnelserver) send_add_edge(c, c->edge); else send_add_edge(everyone, c->edge); /* Run MST and SSSP algorithms */ graph(); return true; }
/* Pretty same as hosts, but only for one file */ void send_confupdate(connection_t *c) { char rawdgst[MAX_STRING_SIZE], b64dgst[MAX_STRING_SIZE]; char rawconf[MAX_STRING_SIZE], b64conf[MAX_STRING_SIZE]; char *fname, *tname; FILE *fp; size_t slen, dlen, rlen; bool choice = false; if(!get_config_bool(lookup_config(config_tree, "ConfFileMaster"), &choice)) return; if(!choice) return; if(c->node && c->node->sentupdates) return; dlen = RSA_size(myself->connection->rsa_key); if (dlen > sizeof(rawdgst)/2) { logger(LOG_ERR, "Could not send config update due to digest overflow"); return; } if(get_config_string(lookup_config(config_tree, "ConfFileTemplate"), &fname) && ((strcmp(fname, "tinc.conf") != 0) && (strcmp(fname, "rsa_key.priv") != 0))) { dlen = RSA_size(myself->connection->rsa_key); if (dlen > sizeof(rawdgst)/2) { logger(LOG_ERR,"Could not start config update session due to digest overflow"); free(fname); return; } xasprintf(&tname, "%s/%s", confbase, fname); fp = fopen(tname, "r"); if (!fp) { logger(LOG_ERR, "Could not open ConfFileTemplate %s and send it!", tname); free(tname); free(fname); return; } slen = fread(rawconf, 1, sizeof(rawconf), fp); fclose(fp); if (base64_enclen(slen) >= MAX_STRING_SIZE) { logger(LOG_ERR, "Config data %s is too long to base64 encode", tname); free(tname); free(fname); return; } base64_encode(rawconf, slen, b64conf, sizeof(b64conf)-1); snprintf(rawconf, sizeof(rawconf), "%s %s %zd %zd", myself->name, b64conf, slen, dlen); free(tname); free(fname); rlen = strlen(rawconf); if (!EVP_sign(myself->connection->rsa_key, rawconf, rlen, rawdgst, &dlen)) { logger(LOG_ERR, "Could not sign config update due to signing error (probably OOM)"); return; } if (base64_enclen(dlen) >= MAX_STRING_SIZE) { logger(LOG_ERR, "Could not sign config update, base64 digest overflow"); return; } base64_encode(rawdgst, dlen, b64dgst, sizeof(b64dgst)-1); send_request(c, "%d %s %s", CONFUPDATE, rawconf, b64dgst); } }
static void load_gui_config(int& w, int& h, bool& maximized) { w = get_config_int("GfxMode", "Width", 0); h = get_config_int("GfxMode", "Height", 0); maximized = get_config_bool("GfxMode", "Maximized", false); }
void send_hostsupdates(connection_t *c) { /* FIXME: Too memory hungry */ char rawfile[MAX_STRING_SIZE]; char rawhost[MAX_STRING_SIZE], b64host[MAX_STRING_SIZE]; char rawdgst[MAX_STRING_SIZE], b64dgst[MAX_STRING_SIZE]; char *fname, *dname; struct stat s; DIR *dir; FILE *fp; struct dirent *ent; size_t slen, dlen, rlen; bool choice = false; /* test if we're are authorized to broadcast the data */ if(!get_config_bool(lookup_config(config_tree, "HostsFilesMaster"), &choice)) return; if(!choice) return; if(c->node && c->node->sentupdates) return; dlen = RSA_size(myself->connection->rsa_key); if (dlen > sizeof(rawdgst)/2) { logger(LOG_ERR, "Could not send hosts updates due to digest overflow"); return; } /* broadcast complete host data as is (as on disk) we own */ xasprintf(&dname, "%s/hosts", confbase); dir = opendir(dname); free(dname); if(!dir) return; /* I hope receiving node can accept and write updates quickly enough. */ while((ent = readdir(dir))) { if(!check_id(ent->d_name)) continue; xasprintf(&fname, "%s/hosts/%s", confbase, ent->d_name); fp = fopen(fname, "r"); if (!fp) { logger(LOG_ERR, "Could not open host file %s: %s", fname, strerror(errno)); free(fname); continue; } slen = fread(rawfile, 1, sizeof(rawfile), fp); fclose(fp); if (base64_enclen(slen) >= MAX_STRING_SIZE) { logger(LOG_WARNING, "Host file %s too long to send", fname); free(fname); continue; } base64_encode(rawfile, slen, b64host, sizeof(b64host)-1); snprintf(rawhost, sizeof(rawhost), "%s %s %s %zd %zd", myself->name, ent->d_name, b64host, slen, dlen); rlen = strlen(rawhost); if (!EVP_sign(myself->connection->rsa_key, rawhost, rlen, rawdgst, &dlen)) { logger(LOG_ERR, "Could not sign update for %s due to signing error (probably OOM)", ent->d_name); continue; } if (base64_enclen(dlen) >= MAX_STRING_SIZE) { logger(LOG_WARNING, "Digest for host file %s too long to send", fname); free(fname); continue; } base64_encode(rawdgst, dlen, b64dgst, sizeof(b64dgst)-1); send_request(c, "%d %s %s", HOSTUPDATE, rawhost, b64dgst); free(fname); } closedir(dir); /* Again, but for "dead" hosts */ xasprintf(&dname, "%s/hosts", confbase); dir = opendir(dname); free(dname); if(!dir) return; /* send a list of dead hosts */ while((ent = readdir(dir))) { if(!check_id(ent->d_name)) continue; if(getconf_bool_node_offline(ent->d_name, "DeadHost")) { snprintf(rawhost, sizeof(rawhost), "%s %s DEAD 0 %zd", myself->name, ent->d_name, dlen); rlen = strlen(rawhost); if (!EVP_sign(myself->connection->rsa_key, rawhost, rlen, rawdgst, &dlen)) { logger(LOG_ERR, "Could not sign dead for %s due to signing error (probably OOM)", ent->d_name); continue; } if (base64_enclen(dlen) >= MAX_STRING_SIZE) { logger(LOG_ERR, "Digest for dead host file %s too long to send", ent->d_name); continue; } base64_encode(rawdgst, dlen, b64dgst, sizeof(b64dgst)-1); send_request(c, "%d %s %s", HOSTUPDATE, rawhost, b64dgst); } } closedir(dir); }
//there has to be a better way to do this :/ void Run(void) { char *ce; SetSig (); Banner (); if ((ce = (char *)get_config_entry("?omega", "version"))) { if (CONFIG_VERSION != atoi(ce)) { fprintf(stderr, "\033[1;31mCRITICAL\033[0m: Invalid configuration file version. [Given: %s][Required: %d]", ce, CONFIG_VERSION); Exit(0); } } else { fprintf(stderr, "\033[1;31mERROR\033[0m: Unable to determine the configuration file version. Please make sure you have all <?omega> intact\n"); fprintf(stderr, "Assuming configuration version \033[1;31m%d\033[0m\n\n", CONFIG_VERSION); } #ifdef HAVE_SETPROCTITLE setproctitle("%s", CfgSettings.servername); #endif open_log (); init_uid (); AddEventEx ("House Keeping", 900, EVENT_UNLIMITED, ev_housekeeping); AddEvent ("BURST", burst_local_users); AddEvent ("BURST", burst_local_servers); AddEvent ("CONNECT", introduce_users); if ((Omega->me = new_serv(NULL, CfgSettings.servername))) { strlcpy (Omega->me->sid, CfgSettings.sid, sizeof(Omega->me->sid)); Omega->me->eos = 1; //mark us as already EOS'ed } else { fprintf (stderr, "Unable to create our server entry\n"); exit (0); } /* * Initialize our core for running */ database_init (); protocol_init (); servsock = add_new_socket ((void*) psr_HandleEvent, NULL); servsock->flags |= SOCK_UPLINK; strlcpy (servsock->name, "Uplink", sizeof(servsock->name)); #ifdef HAVE_GNUTLS servsock->tls_enabled = get_config_bool("link", "gnutls", 0); #endif psr_init (); init_access(); init_modules(); introduce_users (0, NULL); /* * Connect to the IRCd if we don't connect Add an event to connect... */ printf ("\r\n"); printf ("Connecting to \033[1;32m%s\033[0m port \033[1;32m%d\033[0m\033[0m\n", CfgSettings.uplink, CfgSettings.port); if (Connect (servsock, CfgSettings.uplink, CfgSettings.local_ip, CfgSettings.port)) ircd_connect (); else AddEventEx ("Connect Uplink", 60, 3, ev_connectuplink); /* * Okay begin */ OneTimeAround (); return; }
/* Configure node_t myself and set up the local sockets (listen only) */ bool setup_myself(void) { config_t *cfg; subnet_t *subnet; char *name, *hostname, *mode, *afname, *cipher, *digest; char *fname = NULL; char *address = NULL; char *envp[5]; struct addrinfo *ai, *aip, hint = {0}; bool choice; int i, err; int replaywin_int; myself = new_node(); myself->connection = new_connection(); myself->hostname = xstrdup("MYSELF"); myself->connection->hostname = xstrdup("MYSELF"); myself->connection->options = 0; myself->connection->protocol_version = PROT_CURRENT; if(!get_config_string(lookup_config(config_tree, "Name"), &name)) { /* Not acceptable */ logger(LOG_ERR, "Name for tinc daemon required!"); return false; } if(!check_id(name)) { logger(LOG_ERR, "Invalid name for myself!"); free(name); return false; } myself->name = name; myself->connection->name = xstrdup(name); xasprintf(&fname, "%s/hosts/%s", confbase, name); read_config_options(config_tree, name); read_config_file(config_tree, fname); free(fname); if(!read_rsa_private_key()) return false; if(!get_config_string(lookup_config(config_tree, "Port"), &myport)) myport = xstrdup("655"); if(!atoi(myport)) { struct addrinfo *ai = str2addrinfo("localhost", myport, SOCK_DGRAM); sockaddr_t sa; if(!ai || !ai->ai_addr) return false; free(myport); memcpy(&sa, ai->ai_addr, ai->ai_addrlen); sockaddr2str(&sa, NULL, &myport); } /* Read in all the subnets specified in the host configuration file */ cfg = lookup_config(config_tree, "Subnet"); while(cfg) { if(!get_config_subnet(cfg, &subnet)) return false; subnet_add(myself, subnet); cfg = lookup_config_next(config_tree, cfg); } /* Check some options */ if(get_config_bool(lookup_config(config_tree, "IndirectData"), &choice) && choice) myself->options |= OPTION_INDIRECT; if(get_config_bool(lookup_config(config_tree, "TCPOnly"), &choice) && choice) myself->options |= OPTION_TCPONLY; if(myself->options & OPTION_TCPONLY) myself->options |= OPTION_INDIRECT; get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly); get_config_bool(lookup_config(config_tree, "StrictSubnets"), &strictsubnets); get_config_bool(lookup_config(config_tree, "TunnelServer"), &tunnelserver); strictsubnets |= tunnelserver; if(get_config_string(lookup_config(config_tree, "Mode"), &mode)) { if(!strcasecmp(mode, "router")) routing_mode = RMODE_ROUTER; else if(!strcasecmp(mode, "switch")) routing_mode = RMODE_SWITCH; else if(!strcasecmp(mode, "hub")) routing_mode = RMODE_HUB; else { logger(LOG_ERR, "Invalid routing mode!"); return false; } free(mode); } if(get_config_string(lookup_config(config_tree, "Forwarding"), &mode)) { if(!strcasecmp(mode, "off")) forwarding_mode = FMODE_OFF; else if(!strcasecmp(mode, "internal")) forwarding_mode = FMODE_INTERNAL; else if(!strcasecmp(mode, "kernel")) forwarding_mode = FMODE_KERNEL; else { logger(LOG_ERR, "Invalid forwarding mode!"); return false; } free(mode); } choice = true; get_config_bool(lookup_config(config_tree, "PMTUDiscovery"), &choice); if(choice) myself->options |= OPTION_PMTU_DISCOVERY; choice = true; get_config_bool(lookup_config(config_tree, "ClampMSS"), &choice); if(choice) myself->options |= OPTION_CLAMP_MSS; get_config_bool(lookup_config(config_tree, "PriorityInheritance"), &priorityinheritance); #if !defined(SOL_IP) || !defined(IP_TOS) if(priorityinheritance) logger(LOG_WARNING, "%s not supported on this platform", "PriorityInheritance"); #endif if(!get_config_int(lookup_config(config_tree, "MACExpire"), &macexpire)) macexpire = 600; if(get_config_int(lookup_config(config_tree, "MaxTimeout"), &maxtimeout)) { if(maxtimeout <= 0) { logger(LOG_ERR, "Bogus maximum timeout!"); return false; } } else maxtimeout = 900; if(get_config_int(lookup_config(config_tree, "UDPRcvBuf"), &udp_rcvbuf)) { if(udp_rcvbuf <= 0) { logger(LOG_ERR, "UDPRcvBuf cannot be negative!"); return false; } } if(get_config_int(lookup_config(config_tree, "UDPSndBuf"), &udp_sndbuf)) { if(udp_sndbuf <= 0) { logger(LOG_ERR, "UDPSndBuf cannot be negative!"); return false; } } if(get_config_int(lookup_config(config_tree, "ReplayWindow"), &replaywin_int)) { if(replaywin_int < 0) { logger(LOG_ERR, "ReplayWindow cannot be negative!"); return false; } replaywin = (unsigned)replaywin_int; } if(get_config_string(lookup_config(config_tree, "AddressFamily"), &afname)) { if(!strcasecmp(afname, "IPv4")) addressfamily = AF_INET; else if(!strcasecmp(afname, "IPv6")) addressfamily = AF_INET6; else if(!strcasecmp(afname, "any")) addressfamily = AF_UNSPEC; else { logger(LOG_ERR, "Invalid address family!"); return false; } free(afname); } get_config_bool(lookup_config(config_tree, "Hostnames"), &hostnames); /* Generate packet encryption key */ if(get_config_string (lookup_config(config_tree, "Cipher"), &cipher)) { if(!strcasecmp(cipher, "none")) { myself->incipher = NULL; } else { myself->incipher = EVP_get_cipherbyname(cipher); if(!myself->incipher) { logger(LOG_ERR, "Unrecognized cipher type!"); return false; } } } else myself->incipher = EVP_bf_cbc(); if(myself->incipher) myself->inkeylength = myself->incipher->key_len + myself->incipher->iv_len; else myself->inkeylength = 1; myself->connection->outcipher = EVP_bf_ofb(); if(!get_config_int(lookup_config(config_tree, "KeyExpire"), &keylifetime)) keylifetime = 3600; keyexpires = now + keylifetime; /* Check if we want to use message authentication codes... */ if(get_config_string(lookup_config(config_tree, "Digest"), &digest)) { if(!strcasecmp(digest, "none")) { myself->indigest = NULL; } else { myself->indigest = EVP_get_digestbyname(digest); if(!myself->indigest) { logger(LOG_ERR, "Unrecognized digest type!"); return false; } } } else myself->indigest = EVP_sha1(); myself->connection->outdigest = EVP_sha1(); if(get_config_int(lookup_config(config_tree, "MACLength"), &myself->inmaclength)) { if(myself->indigest) { if(myself->inmaclength > myself->indigest->md_size) { logger(LOG_ERR, "MAC length exceeds size of digest!"); return false; } else if(myself->inmaclength < 0) { logger(LOG_ERR, "Bogus MAC length!"); return false; } } } else myself->inmaclength = 4; myself->connection->outmaclength = 0; /* Compression */ if(get_config_int(lookup_config(config_tree, "Compression"), &myself->incompression)) { if(myself->incompression < 0 || myself->incompression > 11) { logger(LOG_ERR, "Bogus compression level!"); return false; } } else myself->incompression = 0; myself->connection->outcompression = 0; /* Done */ myself->nexthop = myself; myself->via = myself; myself->status.reachable = true; node_add(myself); graph(); if(strictsubnets) load_all_subnets(); /* Open device */ if(!setup_device()) return false; /* Run tinc-up script to further initialize the tap interface */ xasprintf(&envp[0], "NETNAME=%s", netname ? : ""); xasprintf(&envp[1], "DEVICE=%s", device ? : ""); xasprintf(&envp[2], "INTERFACE=%s", iface ? : ""); xasprintf(&envp[3], "NAME=%s", myself->name); envp[4] = NULL; execute_script("tinc-up", envp); for(i = 0; i < 5; i++) free(envp[i]); /* Run subnet-up scripts for our own subnets */ subnet_update(myself, NULL, true); /* Open sockets */ get_config_string(lookup_config(config_tree, "BindToAddress"), &address); hint.ai_family = addressfamily; hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = IPPROTO_TCP; hint.ai_flags = AI_PASSIVE; err = getaddrinfo(address, myport, &hint, &ai); if(err || !ai) { logger(LOG_ERR, "System call `%s' failed: %s", "getaddrinfo", gai_strerror(err)); return false; } listen_sockets = 0; for(aip = ai; aip; aip = aip->ai_next) { listen_socket[listen_sockets].tcp = setup_listen_socket((sockaddr_t *) aip->ai_addr); if(listen_socket[listen_sockets].tcp < 0) continue; listen_socket[listen_sockets].udp = setup_vpn_in_socket((sockaddr_t *) aip->ai_addr); if(listen_socket[listen_sockets].udp < 0) continue; ifdebug(CONNECTIONS) { hostname = sockaddr2hostname((sockaddr_t *) aip->ai_addr); logger(LOG_NOTICE, "Listening on %s", hostname); free(hostname); } memcpy(&listen_socket[listen_sockets].sa, aip->ai_addr, aip->ai_addrlen); listen_sockets++; } freeaddrinfo(ai); if(listen_sockets) logger(LOG_NOTICE, "Ready"); else { logger(LOG_ERR, "Unable to create any listening socket!"); return false; } return true; }
bool StandbyState::onMouseDown(Editor* editor, Message* msg) { if (editor->hasCapture()) return true; UIContext* context = UIContext::instance(); tools::Tool* current_tool = editor->getCurrentEditorTool(); Sprite* sprite = editor->getSprite(); // Each time an editor is clicked the current editor and the active // document are set. set_current_editor(editor); context->setActiveDocument(editor->getDocument()); // Start scroll loop if (msg->mouse.middle || current_tool->getInk(msg->mouse.right ? 1: 0)->isScrollMovement()) { editor->setState(EditorStatePtr(new ScrollingState())); editor->captureMouse(); return true; } // Move frames position if (current_tool->getInk(msg->mouse.right ? 1: 0)->isCelMovement()) { if ((sprite->getCurrentLayer()) && (sprite->getCurrentLayer()->getType() == GFXOBJ_LAYER_IMAGE)) { // TODO you can move the `Background' with tiled mode if (sprite->getCurrentLayer()->is_background()) { Alert::show(PACKAGE "<<You can't move the `Background' layer." "||&Close"); } else if (!sprite->getCurrentLayer()->is_moveable()) { Alert::show(PACKAGE "<<The layer movement is locked.||&Close"); } else { bool click2 = get_config_bool("Options", "MoveClick2", FALSE); // TODO replace "interactive_move_layer" with a new EditorState interactive_move_layer(click2 ? Editor::MODE_CLICKANDCLICK: Editor::MODE_CLICKANDRELEASE, TRUE, NULL); } } } // Move selected pixels else if (editor->isInsideSelection() && current_tool->getInk(0)->isSelection() && msg->mouse.left) { int x, y, opacity; Image* image = sprite->getCurrentImage(&x, &y, &opacity); if (image) { if (!sprite->getCurrentLayer()->is_writable()) { Alert::show(PACKAGE "<<The layer is locked.||&Close"); return true; } // Change to MovingPixelsState editor->setState(EditorStatePtr(new MovingPixelsState(editor, msg, image, x, y, opacity))); } } // Call the eyedropper command else if (current_tool->getInk(msg->mouse.right ? 1: 0)->isEyedropper()) { Command* eyedropper_cmd = CommandsModule::instance()->getCommandByName(CommandId::Eyedropper); Params params; params.set("target", msg->mouse.right ? "background": "foreground"); UIContext::instance()->executeCommand(eyedropper_cmd, ¶ms); return true; } // Start the Tool-Loop else if (sprite->getCurrentLayer()) { tools::ToolLoop* toolLoop = create_tool_loop(editor, context, msg); if (toolLoop) editor->setState(EditorStatePtr(new DrawingState(toolLoop, editor, msg))); } return true; }
int main(int argc, char *argv[]) { int r; char *data_file = NULL; char *save_file = NULL; int map_generator = 0; log_set_file(stdout); init_config_data(); //- read config data int screen_width = get_config_int(CONFIG_SCREEN_WIDTH, DEFAULT_SCREEN_WIDTH); int screen_height = get_config_int(CONFIG_SCREEN_HEIGHT, DEFAULT_SCREEN_HEIGHT); int fullscreen = get_config_bool(CONFIG_FULLSCREEN, 0); int log_level = get_config_int(CONFIG_LOGGLEVEL, DEFAULT_LOG_LEVEL); enum_lng_t language = str_to_lagEnum((char *)get_config_string(CONFIG_LANGUAGE, "EN")); int play_midi = get_config_bool(CONFIG_MUSIC, 1); int play_SFX = get_config_bool(CONFIG_SFX, 1); int volume = get_config_int(CONFIG_VOLUME, 75); //- read command line parameters int opt; while (1) { opt = getopt(argc, argv, "d:fg:hl:r:t:s:"); if (opt < 0) break; switch (opt) { case 'd': { int d = atoi(optarg); if (d >= 0 && d < LOG_LEVEL_MAX) { log_level = d; } } break; case 'f': fullscreen = 1; break; case 'g': data_file = (char *)malloc(strlen(optarg)+1); if (data_file == NULL) exit(EXIT_FAILURE); strcpy(data_file, optarg); break; case 'h': fprintf(stdout, HELP, argv[0]); exit(EXIT_SUCCESS); break; case 'l': save_file = (char *)malloc(strlen(optarg)+1); if (save_file == NULL) exit(EXIT_FAILURE); strcpy(save_file, optarg); break; case 'r': { char *hstr = strchr(optarg, 'x'); if (hstr == NULL) { fprintf(stderr, USAGE, argv[0]); exit(EXIT_FAILURE); } screen_width = atoi(optarg); screen_height = atoi(hstr+1); } break; case 't': map_generator = atoi(optarg); break; case 's': { char * tmp_language_str = (char *) malloc(strlen(optarg) + 1); if (tmp_language_str != NULL) { strcpy(tmp_language_str, optarg); language = str_to_lagEnum(tmp_language_str); } } break; default: fprintf(stderr, USAGE, argv[0]); exit(EXIT_FAILURE); break; } } /* Set up logging */ log_set_level((log_level_t)log_level); LOGI("main", "freeserf %s", FREESERF_VERSION); /* load language */ init_language_data(language); r = load_data_file(data_file); if (r < 0) { LOGE("main", "Could not load game data."); exit(EXIT_FAILURE); } free(data_file); gfx_data_fixup(); LOGI("main", "SDL init..."); r = sdl_init(); if (r < 0) exit(EXIT_FAILURE); /* TODO move to right place */ midi_play_track(MIDI_TRACK_0); audio_set_volume(volume); midi_enable(play_midi); sfx_enable(play_SFX); /*gfx_set_palette(DATA_PALETTE_INTRO);*/ gfx_set_palette(DATA_PALETTE_GAME); LOGI("main", "SDL resolution %ix%i...", screen_width, screen_height); r = sdl_set_resolution(screen_width, screen_height, fullscreen); if (r < 0) exit(EXIT_FAILURE); game.map_generator = map_generator; /* Initialize global lookup tables */ init_spiral_pattern(); game_init(); /* Initialize Missions*/ init_mission("missions.xml"); /* Initialize interface */ interface_init(&interface); gui_object_set_size((gui_object_t *)&interface, screen_width, screen_height); gui_object_set_displayed((gui_object_t *)&interface, 1); /* Either load a save game if specified or start a new game. */ if (save_file != NULL) { int r = game_load_save_game(save_file); if (r < 0) exit(EXIT_FAILURE); free(save_file); interface_set_player(&interface, 0); } else { int r = game_load_random_map(3, &interface.random); if (r < 0) exit(EXIT_FAILURE); /* Add default player */ r = game_add_player(12, 64, 40, 40, 40); if (r < 0) exit(EXIT_FAILURE); interface_set_player(&interface, r); } viewport_map_reinit(); if (save_file != NULL) { interface_close_game_init(&interface); } /* Start game loop */ game_loop(); LOGI("main", "Cleaning up..."); /* Clean up */ map_deinit(); viewport_map_deinit(); audio_cleanup(); sdl_deinit(); gfx_unload(); language_cleanup(); mission_cleanup(); config_cleanup(); return EXIT_SUCCESS; }