void conf_time(char *timefile) { lion_t *conf_file = NULL; char *tmp, *r; if (!timefile) { tmp = misc_strjoin(conf_file_name, "timestamp"); if ((r = strrchr(tmp, '/'))) *r = '.'; conf_file = lion_open(tmp, O_RDONLY, 0600, LION_FLAG_NONE, NULL); SAFE_FREE(tmp); } else { conf_file = lion_open(timefile, O_RDONLY, 0600, LION_FLAG_NONE, NULL); } // Not having a timestamp file is OK if (!conf_file) { return; } lion_set_handler(conf_file, conf_file_handler); do_exit = 0; while(!do_exit) lion_poll(0,1); do_exit = 0; }
void sites_init(void) { // Read the sites file into memory. This can be issued many times // to re-read it if there are changes. // Free any memory first incase we are to re-load the file. sites_free(); sites_id = 0; sites_file = lion_open(SITES_CONF, O_RDONLY, 0600, LION_FLAG_NONE, NULL); if (sites_file) { lion_set_handler(sites_file, sites_handler); if (sites_key) { lion_ssl_set(sites_file, LION_SSL_FILE); lion_ssl_setkey(sites_file, sites_key, strlen(sites_key)); } } }
static void root_http_list(request_t *node, lion_t *handle) { if (!root_secret) root_secret = rand(); // Connect and "get" the list of urls, attempting to match out those that we like. // Skin will filter out the types we handle, so we just need to find good urls. if (node->roothandle) { lion_disconnect(node->roothandle); } // Sanity check if ((node->root_index < 0 ) || (node->root_index > root_count)) return; // This root needs to be a HTTP type. if (!root_array[node->root_index].http_host) return; // Connect debugf("[root] http request connecting to %s:%d\n", root_array[node->root_index].http_host, root_array[node->root_index].http_port); node->roothandle = lion_connect(root_array[node->root_index].http_host, root_array[node->root_index].http_port, 0, 0, LION_FLAG_FULFILL, (void *)node); lion_set_handler(node->roothandle, root_request_handler); return; }
// // Connect to a url for them // void root_proxy(request_t *node) { debugf("[root] proxy '%s' %p %p\n", node->cgi_host, node, node->roothandle); if (node->cgi_secret != root_secret) { request_reply(node, 500, "Incorrect cgi code"); SAFE_FREE(node->cgi_host); return; } // Connect to host, option port. Issue the request, then // whatever is sent back, we send to Media Device. // Lets connect! Already connected due to keep-alive? if (node->cgi_host && node->roothandle) { debugf("[root] re-using connection\n"); root_proxy_send(node, node->roothandle); return; } debugf("[root] proxy connecting to http://%s:%u/%s ....\n", node->cgi_host, node->cgi_port, node->cgi_file); node->roothandle = lion_connect(node->cgi_host, node->cgi_port, 0, 0, LION_FLAG_FULFILL, (void *) node); lion_set_handler(node->roothandle, root_proxy_handler); lion_enable_binary(node->roothandle); return; }
void settings_save(void) { lion_t *conf_file; // Using lion to read a config file, well, well... conf_file = lion_open(".FXP.One.settings", O_WRONLY|O_TRUNC|O_CREAT, 0600, LION_FLAG_NONE, NULL); if (!conf_file) { printf("settings: failed to create settings file!\n"); return; } // Write only, disable read or LiON thinks its at EOF lion_disable_read(conf_file); // Not needed but we don't want events in the main handlers. lion_set_handler(conf_file, settings_handler); lion_printf(conf_file, "# FXP.One settings file. Written automatically.\r\n"); lion_printf(conf_file, "CONF|VERSION=1.0\r\n"); // Command settings lion_printf(conf_file, "CONF|command_port=%d|command_ssl_only=%d", settings_values.command_port, (int)settings_values.command_ssl_only); lion_printf(conf_file, "|http_port=%d|http_ssl_only=%d", settings_values.http_port, (int)settings_values.http_ssl_only); if (settings_values.command_iface) lion_printf(conf_file, "|command_iface=%s", lion_ntoa(settings_values.command_iface)); if (settings_values.http_iface) lion_printf(conf_file, "|http_iface=%s", lion_ntoa(settings_values.http_iface)); lion_printf(conf_file, "\r\n"); lion_close(conf_file); settings_initialising = 0; }
void settings_init(void) { lion_t *conf_file; settings_defaults(); settings_initialising = 1; // Using lion to read a config file, well, well... conf_file = lion_open(".FXP.One.settings", O_RDONLY, 0600, LION_FLAG_NONE, NULL); if (conf_file) lion_set_handler(conf_file, settings_handler); else settings_save(); }
void conf_read(void) { lion_t *conf_file; conf_file = lion_open(conf_file_name, O_RDONLY, 0600, LION_FLAG_NONE, NULL); if (!conf_file) { perror("open:"); exit(1); } lion_set_handler(conf_file, conf_file_handler); do_exit = 0; while(!do_exit) lion_poll(0,1); do_exit = 0; }
void sites_save(void) { sites_file = lion_open(SITES_CONF, O_WRONLY|O_CREAT|O_TRUNC, 0600, LION_FLAG_NONE, NULL); if (sites_file) { lion_set_handler(sites_file, sites_handler); // We are writing, don't try to read the file. lion_disable_read(sites_file); if (sites_key) { lion_ssl_set(sites_file, LION_SSL_FILE); lion_ssl_setkey(sites_file, sites_key, strlen(sites_key)); } sites_listentries(sites_file, SITES_LIST_SAVE); // Write something to the file lion_close(sites_file); return; } printf("[sites]: Warning, failed to create sites file? Permissions? Disk full?\n"); }
int llrar_get(request_t *node, char *executable) { char buffer[1024]; int keep_process; debugf("[llrar] get file requested: '%s' ('%s')\n", node->path, node->dvdread_file ? node->dvdread_file : ""); // Alas, subtitle lookup will have wrong size:( if (node->rar_file && !lfnmatch("*.srt", node->rar_file, LFNM_CASEFOLD)) { node->bytes_size = 500 * 1024; } // HEAD MODE, DO NOTHING if (node->head_method) return 0; // Safety, we aren't called if this is not set in request.c if (!node->rar_file) return 0; // Now, we both need to url_decode this part, and re-assign. // name = request_url_decode(ar); // Keep process? keep_process = 0; debugf("[llrar] checking for resume: rar_name (%s), althandle (%p), name (%s), from (%"PRIu64") >= sent (%"PRIu64")\n", node->rar_name ? node->rar_name : "", node->althandle, node->rar_file ? node->rar_file : "", node->bytes_from, node->bytes_sent); if (node->rar_name && node->althandle && !mystrccmp(node->rar_file, node->rar_name) && node->bytes_from >= node->bytes_sent) { keep_process = 1; debugf("[llrar] resuming old unrar\n"); llrar_resumed_get++; } // Now, if we have special unrar with seek support, we should use it if // we are seeking far. if (keep_process) { // We thought we were going to keep the process, but lets see if the // seek is too big, we might as well abort, and use the seek feature. if ((node->bytes_from - node->bytes_sent) >= LLRAR_SEEK_TRIGGER) { keep_process = 0; debugf("[llrar] seek too large, respawning with seek: %"PRIu64" <= %"PRIu64"\n", node->bytes_from, node->bytes_sent); } } if (!keep_process) { #ifdef WITH_UNRAR_BUFFERS // We have decided we need to restart the unrar process here, // but as a special case, if we can satisfy the ENTIRE request // from cached-buffers, do so instead and update no variables. if (llrar_incaches(node)) return 0; #endif llrar_stop_process(node); // Copy the rar_file name to rar_name, so we can compare for resumes node->rar_name = strdup(node->rar_file); #ifdef WIN32 // Skip leading slash, since we skip that in the print. Then // convert all "/" to "\" since unrar.exe expects it. { char *r = node->rar_name; while (*r == '/') r++; while ((r = strchr(r, '/'))) *r = '\\'; } #endif debugf("[[llrar] using unrar with seek %"PRIu64".\n", node->bytes_from); if (node->dvdread_file) { debugf("[llrar] RARISO for '%s'\n", node->dvdread_file); snprintf(buffer, sizeof(buffer), "%s p -X \"%s\" -R \"%s\" -inul -c- -p- -y -cfg- -sk%"PRIu64" -- \"%s\" \"%s\"", executable, skin_get_rar(), node->dvdread_file, node->bytes_from, node->disk_path, (node->rar_name[0] == '/') ? &node->rar_name[1] : node->rar_name); } else { // Not ISO in RAR, straight... snprintf(buffer, sizeof(buffer), "%s p -inul -c- -p- -y -cfg- -sk%"PRIu64" -- \"%s\" \"%s\"", executable, node->bytes_from, node->disk_path, (node->rar_name[0] == '/') ? &node->rar_name[1] : node->rar_name); } // RARISO // Make it think we've already seen "seek" bytes. node->bytes_sent = node->bytes_from; debugf("[llrar] spawning new '%s'\n", buffer); node->unrar_parse = 0; llrar_spawned_get++; node->althandle = lion_system(buffer, 1, LION_FLAG_NONE, node); if (!node->althandle) { debugf("[llrar] failed to launch unrar\n"); llrar_fail(node); // request_reply(node, 513, "failed to launch unrar"); return -2; } // Set extract handler lion_set_handler(node->althandle, llrar_extract_handler); // Set binary mode lion_enable_binary(node->althandle); // Disable read until we are ready lion_disable_read(node->althandle); } // !keep_process // Set right chunk mode. llrar_compute_blocksize(node); debugf("[llrar] processing: sent (%"PRIu64") bytes_from (%"PRIu64") bytes_to (%"PRIu64")\n", node->bytes_sent, node->bytes_from, node->bytes_to); return 0; }
// // Take a http request node, which should have "cwd" filled in appropriately. // We then call dirlist to issue listing(s) for this path. // void llrar_list(request_t *node, char *executable) { char buffer[1024]; debugf("[llrar] file listing requested: %s - %s\n", node->disk_path, node->path); debugf(" process %d, dvdread_file '%s'\n", node->process_function, node->dvdread_file ? node->dvdread_file : ""); // If we already have a process running, kill it llrar_stop_process(node); SAFE_FREE(node->rar_name); // Spawn unrar //-ap$DIR -av- -c- -p- -y // ok, -ap$DIR does not work in listings. // but -ndirectory1/ -ndirectory1/directory2/ does appear to work. Needs // trailing slash, or it shows itself. // Old style was to use "-n/path" to attempt to list only one directory // within a .rar, but unrar has a bug where it will just not show the // directory names, etc. So, we change to using "v" to list. // Now we get one line with full path, followed by a line of details. // That way, we can skip the first space, then look for last "/", this is // the full path, and filenames. Spaces included. // // directory1/directory2/file2.avi // 7 17 242% 04-12-07 14:11 -rw-r--r-- 16B28489 m3b 2.9 // // We then filter out any entries for the path we care about, drop the // rest. No slash in filename means it is in root. // If we are listing ISO inside RAR, we need to also pass the filename // along with the rar name. "-R filename" if (/*(node->process_function == REQUEST_PROCESS_RARISO) &&*/ (node->dvdread_file)) { debugf("[llrar] RARISO for '%s' -X \"%s\" \n", node->dvdread_file, skin_get_rar()); snprintf(buffer, sizeof(buffer), "%s v -X \"%s\" -R \"%s\" -v -c- -p- -y -cfg- -- \"%s\"", executable, skin_get_rar(), node->dvdread_file, node->disk_path); } else { snprintf(buffer, sizeof(buffer), "%s v -v -c- -p- -y -cfg- -- \"%s\"", executable, node->disk_path); } node->rar_name = strdup("rar listing"); debugf("[llrar] spawning new '%s'\n", buffer); node->unrar_parse = 0; llrar_spawned_list++; node->althandle = lion_system(buffer, 1, LION_FLAG_NONE, node); if (!node->althandle) { debugf("[llrar] failed to launch unrar.\n"); // request_reply(node, 513, "failed to launch unrar"); // llrar_fail(node); request_finishdir(node); return; } // Set list handler lion_set_handler(node->althandle, llrar_handler); }
// // Take a http request node, which should have "cwd" filled in appropriately. // We then call dirlist to issue listing(s) for this path. // void root_list(request_t *node, char *newpath) { int flags; // Fetch the current directory. Note if they request "/" // we need to iterate all "root"s. debugf("[root] listing of '%s' requested\n", newpath); // FIXME, no paths. if (!root_count) return; // If next_list is 0 we only list one directory. If it is not 0, // we list that and increment. node->next_list = 0; if (!mystrccmp("/", newpath)) { // List more, if any. node->next_list = 1; } // Set handler to be here, temporarily lion_set_handler(node->tmphandle, root_handler); if (node->next_list) { debugf("[root] root listing, iterating roots\n"); node->next_list = 0; // Issue listing request root_next_list(node, node->tmphandle); return; } // HTTP method if ((node->root_index < 0) || (node->root_index >= root_count)) return; if (root_array[node->root_index].http_host) { root_http_list(node, node->tmphandle); return; } // Stop dirlisting at this one. node->next_list = root_count; // Some dirlist flags need to be passed down to libdirlist... flags = skin_get_sort_flags(node); flags &= (DIRLIST_SHOW_DIRSIZE|DIRLIST_SHOW_GENRE); debugf("[root] asking for dirlist of '%s' with precat of '%s'\n", newpath, node->path); // Just list dirlist_list(node->tmphandle, newpath, node->path, root_isregistered(node) ? (root_array[node->root_index].flags|DIRLIST_SHOW_DOT|flags) : (root_array[node->root_index].flags|flags), node); }
// // function for conf reading. Called when conf file has command specified. // // CMD : ROOT // Required : path // Optional : flags, http, proxy, subdir, dvdread // void root_cmd(char **keys, char **values, int items,void *optarg) { char *path, *flags, *http, *proxy, *subdir, *dvdread, *zfs, *url; root_t *tmp; // Requireds path = parser_findkey(keys, values, items, "PATH"); if (!path || !*path) { printf(" : [root] missing required field: PATH\n"); //do_exit = 1; return; } // Optionals flags = parser_findkey(keys, values, items, "FLAGS"); http = parser_findkey(keys, values, items, "HTTP"); proxy = parser_findkey(keys, values, items, "PROXY"); subdir = parser_findkey(keys, values, items, "SUBDIR"); dvdread = parser_findkey(keys, values, items, "DVDREAD"); zfs = parser_findkey(keys, values, items, "ZFS"); url = parser_findkey(keys, values, items, "URL"); if (zfs && *zfs) { char buffer[1024]; lion_t *spawn; // Spawn zfs list to find any file-systems with set attribute. // In future, it would perhaps be nicer to use libzfs. debugf(" : looking for ZFS filesystems\n"); snprintf(buffer, sizeof(buffer), "%s list -H -o mountpoint,%s", path, zfs); spawn = lion_system(buffer, 0, LION_FLAG_FULFILL, zfs); if (spawn) lion_set_handler(spawn, root_zfs_handler); return; // Don't allocate new buffers. } tmp = (root_t *) realloc(root_array, sizeof(root_t) * (root_count + 1)); if (!tmp) { debugf(" : out of memory allocating ROOT\n"); return; } // Increase our counter root_count++; // Assign us in. root_array = tmp; // The new area tmp = &root_array[ root_count - 1 ]; // Nobody likes -1 // Make it be cleared memset(tmp, 0, sizeof(*tmp)); #ifdef WIN32 // Change \ to / cos its prettier and works in browsers. // If its c:/ make it "c:\" // remove / if it ends with a slash { char *r; while ((r = strchr(path, '\\'))) *r = '/'; // Just c:/ ? if (path[0] && (path[1] == ':') && (path[2] == '/') && !path[3]) path[2] = '\\'; misc_stripslash(path); } #endif tmp->path = strdup(path); // Do we need to strdup? #if HAVE_PWD_H debugf("[root] '%s'\n", path); // Attempt to expand ~username, we only let the first character be ~, since // it does not make any sense to specify a path before it. if (path[0] == '~') { // Fetch out the username,if any. (~username/) or (~/) are valid. char *ar, *username; struct passwd *pw; ar = path; username = misc_digtoken(&ar, "/\r\n"); // Skip all leading "~"s while(username && *username == '~') username++; if (!username || !*username) { // Look up current user then. pw = getpwuid(getuid()); } else { // Look up by username pw = getpwnam(username); } // Lookup successful? if (pw) { SAFE_FREE(tmp->path); tmp->path = misc_strjoin(pw->pw_dir, ar); debugf("[root] expanded to '%s'\n", tmp->path); } // pw } #endif if (flags && *flags) tmp->flags = dirlist_a2f(flags); else tmp->flags = 0; // We no longer use the FLAGS part of ROOT. See skin_sort_* // Use 0 sorting for speed. tmp->flags = 0; // Things that are not allowed to be set. tmp->flags &= ~( DIRLIST_SHORT | DIRLIST_XML | DIRLIST_FILE | DIRLIST_SHOW_DOT); // Used to hide parential dirs // Essential flags. tmp->flags |= DIRLIST_LONG | DIRLIST_PIPE; if (http && *http) { // root.http if (!strncasecmp("http://", http, 7)) { char *ar, *host, *port = "80"; ar = &http[7]; host = misc_digtoken(&ar, "/:\r\n"); if (host) { // Optional port? if (misc_digtoken_optchar == ':') port = misc_digtoken(&ar, "/\r\n"); if (!port || !*port) port = "80"; tmp->http_host = strdup(host); tmp->http_port = atoi(port); tmp->http_file = strdup(ar); } } } if (url && *url) { if (!strncasecmp("http://", url, 7)) { tmp->url = strdup(url); } } if (proxy) tmp->proxy = 1; if (subdir) tmp->subdir = strdup(subdir); if (dvdread) tmp->dvdread = 1; debugf(" : [root] recognising '%s'\n", tmp->path); }