int command_who_sub(object_t *node, void *arg1, void*arg2) { static object_t *user; if (!arg1) return 0; // 0 to stop iterating. user = (object_t *) arg1; switch(node->type) { case OBJECT_TYPE_NONE: lion_printf(user->handle, "[unknown-type]\r\n"); break; case OBJECT_TYPE_LISTEN: lion_printf(user->handle, "[ listening ]\r\n"); break; case OBJECT_TYPE_UNREGISTERED: lion_printf(user->handle, "[unregistered]\r\n"); break; case OBJECT_TYPE_REGISTERED: lion_printf(user->handle, "[ registered ] %s\r\n", node->username); break; } return 1; // 1 to keep iterating }
void conf_save(lion_t *savefile) { int i; for (i = 0; i < num_sites; i++) { if (sites[i]) { lion_printf(savefile, "TIMESTAMP|NAME=%s", sites[i]->name); lion_printf(savefile, "|LAST_CHECK=%lu", sites[i]->last_check); lion_printf(savefile, "\r\n"); } } }
// << CONNECT|SID=1 void site_cmd_connect(char **keys, char **values, int items,void *optarg) { fxpone_t *the_engine = optarg; char *sid; int i; sid = parser_findkey(keys, values, items, "SID"); if (!sid) return; for (i = 0; i < num_sites; i++) { if (sites[i] && (sites[i]->sid == atoi(sid))) { printf("Site %s processing dir '%s'\n", sites[i]->name, sites[i]->dirs[sites[i]->current_dir]); lion_printf(the_engine->handle, "CWD|SID=%u|PATH=%s\r\n", sites[i]->sid, sites[i]->dirs[sites[i]->current_dir]); } } }
void llrar_fail(request_t *node) { lion_printf(node->handle, "HTTP/1.1 500 unrar process failed\r\n\r\n"); lion_close(node->handle); }
void send_auth(fxpone_t *fxpone) { lion_printf(fxpone->handle, "AUTH|USER=%s|PASS=%s\r\n", fxpone->user, fxpone->pass); }
// << CWD|SID=2|REPLY=250|OK|MSG=250 CWD command successful. void site_cmd_cwd(char **keys, char **values, int items,void *optarg) { fxpone_t *the_engine = optarg; char *code, *sid, *msg; int i; unsigned int id; sid = parser_findkey(keys, values, items, "SID"); code = parser_findkey(keys, values, items, "CODE"); msg = parser_findkey(keys, values, items, "MSG"); if (!sid) return; id = atoi(sid); for (i = 0; i < num_sites; i++) { if (!sites[i]) continue; if (sites[i]->sid == id) { if (code && atoi(code) == 0) { lion_printf(the_engine->handle, "DIRLIST|SID=%u\r\n", sites[i]->sid); } else { printf("Site %s incorrect path '%s' : %s\n", sites[i]->name, sites[i]->dirs[ sites[i]->current_dir], msg ? msg : ""); sites[i]->failed = 1; lion_printf(the_engine->handle, "DISCONNECT|SID=%u\r\n", sites[i]->sid); } } } }
// WELCOME|name=FXP.Oned|version=0.1|build=359|protocol=1.2|SSL=optional void site_cmd_welcome(char **keys, char **values, int items,void *optarg) { fxpone_t *the_engine = optarg; char *ssl; ssl = parser_findkey(keys, values, items, "SSL"); if (ssl && !mystrccmp("disabled", ssl)) { send_auth(the_engine); return; } lion_printf(the_engine->handle, "SSL\r\n"); }
void site_ready(lion_t *engine, site_t *site) { lion_printf(engine,"SESSIONFREE|SID=%u\r\n", site->sid); site->sid = 0; num_done++; printf("%12s finished processing: %4u files (%3d/%3d)\n", site->name, site->num_files, num_done, num_sites); }
// >> AUTH|OK|MSG=Successful void site_cmd_auth(char **keys, char **values, int items,void *optarg) { fxpone_t *the_engine = optarg; char *code; code = parser_findkey(keys, values, items, "CODE"); // We didn't get code, or, code is non-zero if (!code || atoi(code)) { printf("Failed to authenticate with FXP.One\n"); do_exit = 1; return; } debugf("Successfully connected to FXP.One\n"); lion_printf(the_engine->handle, "SITELIST\r\n"); }
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; }
// FXPONE|HOST=127.0.0.1|PORT=8885|USER=admin|SSL=forced|TIMEFILE=name void conf_fxpone(char **keys, char **values, int items,void *optarg) { char *host, *port, *user, *pass, *ssl, *timefile; fxpone_t *fxpone; host = parser_findkey(keys, values, items, "HOST"); port = parser_findkey(keys, values, items, "PORT"); user = parser_findkey(keys, values, items, "USER"); pass = parser_findkey(keys, values, items, "PASS"); ssl = parser_findkey(keys, values, items, "SSL"); timefile = parser_findkey(keys, values, items, "TIMEFILE"); if (!host) { printf("FXPONE Entry in conf without HOST= field\n"); return; } // Don't need to save anymore #if 0 if (optarg) { // Saving lion_printf(optarg, "FXPONE|HOST=%s", host); if (port) lion_printf(optarg, "|PORT=%s", port); if (user) lion_printf(optarg, "|USER=%s", user); if (pass) lion_printf(optarg, "|PASS=%s", pass); if (ssl) lion_printf(optarg, "|ssl=%s", ssl); lion_printf(optarg, "\r\n"); return; } #endif // Create a new fxpone engine to connect to. fxpone = fxpone_newnode(); if (!fxpone) return; SAFE_COPY(fxpone->host, host); SAFE_COPY(fxpone->user, user); SAFE_COPY(fxpone->pass, pass); if (port) fxpone->port = atoi(port); else fxpone->port = 8885; if (ssl) fxpone->ssl = atoi(ssl); SAFE_COPY(fxpone->timefile, timefile); }
static void root_proxy_send(request_t *node, lion_t *handle) { lion_printf(handle, "%s /%s HTTP/1.1\r\n" "Host: %s\r\n", node->head_method ? "HEAD" : "GET", node->cgi_file, node->cgi_host); if (node->bytes_from && node->bytes_to) lion_printf(handle, "Range: bytes=%"PRIu64"-%"PRIu64"\r\n", node->bytes_from, node->bytes_to); else if (node->bytes_from) lion_printf(handle, "Range: bytes=%"PRIu64"-\r\n", node->bytes_from); else if (node->bytes_to) lion_printf(handle, "Range: bytes=0-%"PRIu64"\r\n", node->bytes_to); if ((node->type & REQUEST_TYPE_CLOSED)) lion_printf(handle, "Connection: close\r\n"); else lion_printf(handle, "Connection: keep-alive\r\n"); if ((node->type & REQUEST_TYPE_CLOSED)) { debugf("[root] Connection: closed\n"); SAFE_FREE(node->cgi_host); } else debugf("[root] Connection: keep-alive\n"); // End of header. lion_printf(handle, "\r\n"); node->bytes_sent = node->bytes_from; if (node->handle && (node->type & REQUEST_TYPE_KEEPALIVE)) { if (!node->bytes_to && !node->bytes_size) { debugf("[root] re-enabling socket as we have no size\n"); lion_enable_read(node->handle); } } }
void sites_listentries(lion_t *handle, int id) { sites_t *runner; if ((id == SITES_LIST_ALL) || (id == SITES_LIST_ALL_SHORT) || (id == SITES_LIST_SAVE)) { // Write all users for (runner = sites_head; runner; runner = runner->next ) { if (runner->name) { // Save out the required fields first, then the optionals. if (id == SITES_LIST_ALL_SHORT) { lion_printf(handle, "SITELIST|SITEID=%u|NAME=%s\r\n", runner->id, runner->name); } else { sites_listentry(handle, runner, id); } } // if name } // for runner } else { // ALL || SAVE runner = sites_getid(id); if (runner) sites_listentry(handle, runner, id); } }
//<< DIRLIST|SID=1|FID=0|NAME=giana_sounds|DATE=1057590000|SIZE=512|USER=nobody|GROUP=nobody|PERM=drwxrwxrwx|type=directory void site_cmd_dirlist(char **keys, char **values, int items,void *optarg) { fxpone_t *the_engine = optarg; char *sid, *name, *fid, *date, *size, *type, *end, *begin; int i; unsigned int id; site_t *site; file_t *file, **tmp; sid = parser_findkey(keys, values, items, "SID"); name = parser_findkey(keys, values, items, "NAME"); fid = parser_findkey(keys, values, items, "FID"); date = parser_findkey(keys, values, items, "DATE"); size = parser_findkey(keys, values, items, "SIZE"); type = parser_findkey(keys, values, items, "FTYPE"); begin = parser_findkey(keys, values, items, "BEGIN"); end = parser_findkey(keys, values, items, "END"); if (!sid) return; if (begin) return; id = atoi(sid); for (i = 0; i < num_sites; i++) { if (!sites[i]) continue; if (sites[i]->sid == id) { site = sites[i]; if (end) { site->current_dir++; if (site->current_dir >= site->num_dirs) { site_ready(the_engine->handle, site); return; } printf("Site %s processing dir '%s'\n", sites[i]->name, sites[i]->dirs[sites[i]->current_dir]); lion_printf(the_engine->handle, "CWD|SID=%u|PATH=%s\r\n", sites[i]->sid, sites[i]->dirs[sites[i]->current_dir]); return; } // Don't show entries in HIDE if (sites[i]->hide && file_listmatch(sites[i]->hide, name)) return; // SAFE_COPY(sites[i]->name, name); file = file_new(); if (!file) return; tmp = realloc(site->files, sizeof(file_t *)*(site->num_files + 1)); if (!tmp) { file_free(file); return; } site->files = tmp; site->files[ site->num_files ] = file; site->num_files++; SAFE_COPY(file->name, name); if (date) file->date = strtoul(date, NULL, 10); if (size) file->size = strtoull(size, NULL, 10); if (type && !mystrccmp("directory", type)) file->type = 1; // Remember the source path we came from file->current_dir = site->current_dir; } } }
int lion_userinput( connection_t *handle, void *user_data, int status, int size, char *line) { lion_t *new_handle = NULL; switch( status ) { case LION_CONNECTION_LOST: printf("Connection '%p' was lost.\n", handle); // A connection was lost, if we have "user_data" send the // reason across if (user_data) { lion_printf(user_data, "%s\r\n", line); lion_set_userdata(user_data, NULL); lion_close(user_data); } break; case LION_CONNECTION_CLOSED: printf("Connection '%p' was gracefully closed.\n", handle); // If a file finished, and we had a user_data (ie, socket) close it if (user_data) { lion_set_userdata(user_data, NULL); lion_close(user_data); } break; case LION_CONNECTION_NEW: printf("Connection '%p' has a new connection...\n", handle); // Accept the port new_handle = lion_accept(handle, 0, 0, NULL, NULL, NULL); break; // We have a new connection, send the greeting: // This isn't called here. We leave it for debugging reasons. case LION_CONNECTION_CONNECTED: printf("Connection '%p' is connected. \n", handle); // We get this msg for files too, so check it's actually a socket. #if 1 if (!user_data) { printf("Connecting...\n"); new_handle = lion_connect(remote_host, remote_port, NULL, 0, 0, handle); lion_set_userdata(handle, new_handle); // Disable reading from this socket, until we are connected. lion_disable_read( handle ); lion_setbinary(new_handle); lion_setbinary(handle); // Technically not needed. } else { lion_enable_read(user_data); } #endif break; case LION_BUFFER_USED: // If user_data is set (ie, file->socket) we pause the file. if (user_data) lion_disable_read( user_data ); break; case LION_BUFFER_EMPTY: // If user_data is set (ie, file->socket) we resume the file. if (user_data) lion_enable_read( user_data ); break; case LION_INPUT: // Not used, this sample uses binary. printf("<%p> input '%s'\n", handle, line); // If you want to send text mode, you can use // lion_printf(user_data, "%s\r\n", line); break; case LION_BINARY: // We got input, is "user_data" set? then send it to them // That means file -> socket. But data from socket is not sent to file. if (user_data) lion_output(user_data, line, size); break; } return 0; }
// >> SITELIST|SITEID=1|NAME=localhost|HOST=127.0.0.1|PORT=21|USER=mp3|PASS=mp3|PASSIVE=1|FXP_PASSIVE=2|CONTROL_TLS=2|DATA_TLS=2|optional_variable=roger moore void site_cmd_sitelist(char **keys, char **values, int items,void *optarg) { fxpone_t *the_engine = optarg; char *name, *siteid, *end; char *dskiplist, *dpasslist, *fskiplist, *fpasslist, *fskipempty; int i; end = parser_findkey(keys, values, items, "END"); name = parser_findkey(keys, values, items, "NAME"); siteid = parser_findkey(keys, values, items, "SITEID"); if (end) { // num_sitelist has how many sites we found and connected to // num_sites is how many we are waiting for before processing. num_sites = num_sitelist; return; } if (!name || !siteid) return; dskiplist = parser_findkey(keys, values, items, "DSKIPLIST"); dpasslist = parser_findkey(keys, values, items, "DPASSLIST"); fskiplist = parser_findkey(keys, values, items, "FSKIPLIST"); fpasslist = parser_findkey(keys, values, items, "FPASSLIST"); fskipempty = parser_findkey(keys, values, items, "FSKIPEMPTY"); for (i = 0; i < num_sites; i++) { if (!sites[i]) continue; if (!mystrccmp(sites[i]->name, name)) { sites[i]->siteid = atoi(siteid); SAFE_COPY(sites[i]->dskiplist, dskiplist); SAFE_COPY(sites[i]->dpasslist, dpasslist); SAFE_COPY(sites[i]->fskiplist, fskiplist); SAFE_COPY(sites[i]->fpasslist, fpasslist); if (fskipempty && (atoi(fskipempty) == 0)) sites[i]->fskipempty = 0; else sites[i]->fskipempty = 1; num_sitelist++; // IRC sets skip, so we dont do initial login if (!sites[i]->skip) lion_printf(the_engine->handle, "SESSIONNEW|SITEID=%u\r\n", atoi(siteid)); } } }
void sites_listentry(lion_t *handle, sites_t *runner, int id) { int i; // If we are in SAVE mode, we use differnt keyword and no ID sent. // Could be the same keyword, but wanted the seperation to avoid // confusion between keyword in sites file, and from connections via // command2.c if (id == SITES_LIST_SAVE) lion_printf(handle, "SITE|NAME=%s|HOST=%s|PORT=%u|USER=%s|PASS=%s|" "PASSIVE=%u|FXP_PASSIVE=%u|CONTROL_TLS=%u|" "DATA_TLS=%u", runner->name, runner->host ? runner->host : "", runner->port, runner->user ? runner->user : "", runner->pass ? runner->pass : "", runner->passive, runner->fxp_passive, runner->control_TLS, runner->data_TLS); else lion_printf(handle, "SITELIST|SITEID=%u|NAME=%s|HOST=%s|PORT=%u|USER=%s|PASS=%s|" "PASSIVE=%u|FXP_PASSIVE=%u|CONTROL_TLS=%u|" "DATA_TLS=%u", runner->id, runner->name, runner->host ? runner->host : "", runner->port, runner->user ? runner->user : "", runner->pass ? runner->pass : "", runner->passive, runner->fxp_passive, runner->control_TLS, runner->data_TLS); // Extended attributes if (runner->iface) lion_printf(handle, "|IFACE=%s", lion_ntoa(runner->iface)); if (runner->iport) lion_printf(handle, "|IPORT=%u", runner->iport); if (runner->desired_type != YNA_AUTO) lion_printf(handle, "|DESIRED_TYPE=%u", runner->desired_type); if (runner->resume != YNA_AUTO) lion_printf(handle, "|RESUME=%u", runner->resume); if (runner->resume_last != YNA_AUTO) lion_printf(handle, "|RESUME_LAST=%u", runner->resume_last); if (runner->pret != YNA_AUTO) lion_printf(handle, "|PRET=%u", runner->pret); if (runner->file_skiplist) lion_printf(handle, "|FSKIPLIST=%s", runner->file_skiplist); if (runner->directory_skiplist) lion_printf(handle, "|DSKIPLIST=%s", runner->directory_skiplist); if (runner->file_passlist) lion_printf(handle, "|FPASSLIST=%s", runner->file_passlist); if (runner->directory_passlist) lion_printf(handle, "|DPASSLIST=%s", runner->directory_passlist); if (runner->file_skipempty != YNA_AUTO) lion_printf(handle, "|FSKIPEMPTY=%u", runner->file_skipempty); if (runner->directory_skipempty != YNA_AUTO) lion_printf(handle, "|DSKIPEMPTY=%u", runner->directory_skipempty); if (runner->file_movefirst) lion_printf(handle, "|FMOVEFIRST=%s", runner->file_movefirst); if (runner->directory_movefirst) lion_printf(handle, "|DMOVEFIRST=%s", runner->directory_movefirst); // Any optional fields? if (runner->items && runner->keys && runner->values) { for (i = 0; i < runner->items; i++) { // We have to have keys, values is optional if (!runner->keys[i]) continue; lion_printf(handle, "|%s=%s", runner->keys[i], runner->values[i] ? runner->values[i] :""); } // for items } // if items lion_printf(handle, "\r\n"); }
int lion_userinput( lion_t *handle, void *user_data, int status, int size, char *line) { lion_t *new_handle = NULL; // printf("userinput %p %d\n", handle, status); switch( status ) { case LION_CONNECTION_LOST: printf("Connection '%p' was lost.\n", handle); break; case LION_CONNECTION_CLOSED: printf("Connection '%p' was gracefully closed.\n", handle); break; case LION_CONNECTION_NEW: printf("Connection '%p' has a new connection...\n", handle); // Accept the port new_handle = lion_accept(handle, 0, 0, NULL, NULL, NULL); break; case LION_CONNECTION_CONNECTED: printf("Connection '%p' is connected. \n", handle); break; case LION_BUFFER_USED: // If user_data is set (ie, file->socket) we pause the file. // if (user_data) // lion_disable_read( user_data ); break; case LION_BUFFER_EMPTY: // If user_data is set (ie, file->socket) we resume the file. if (user_data) lion_enable_read( user_data ); break; case LION_INPUT: // printf("[input] on %p -> '%s'\n", handle, line); if (!strncasecmp("ls ", line, 3)) { char *flags, *ar; ar = &line[3]; // grab the flags wanted flags = misc_digtoken(&ar, " -\r\n"); if (flags) { dirlist_list(handle, // Pass it handle so THIS userinput is called ar, NULL, dirlist_a2f(flags)|DIRLIST_USE_CRNL, handle); #if 0 dirlist_list(handle, // Pass it handle so THIS userinput is called ar, DIRLIST_SHORT|DIRLIST_PIPE, handle); dirlist_list(handle, // Pass it handle so THIS userinput is called ar, DIRLIST_SHORT|DIRLIST_PIPE, handle); #endif break; } lion_printf(handle, "parse error: see HELP\r\n"); } if (!strncasecmp("help", line, 4)) { lion_printf(handle, "LION contrib/libdirlist tester\r\n"); lion_printf(handle, "usage: ls -flags /directory/path/\r\n"); lion_printf(handle, " flags are: \r\n" " *-l long format\r\n" " -1 short format\r\n" " -X XML format\r\n" " -T print to temporary file, return name\r\n" " *-P print to pipe\r\n" " -N sort by name\r\n" " -t sort by date\r\n" " -s sort by size\r\n" " -C sort with case insensitive\r\n" " -r sort in reverse\r\n" " -R sort recursively\r\n" " -D sort directories before files\r\n" " -a display dot-entries\r\n\r\n"); } if (!strncasecmp("quit", line, 4)) { lion_close(handle); break; } if (handle && user_data) { // reply from LS lion_printf(handle, "%s\n", line); } break; case LION_BINARY: break; } return 0; }
// // Main session handler when we have a user as the owner. // void handler_withuser(session_t *session, int event, int id, int reply, char *line) { lion_t *huser = NULL; manager_t *node = NULL; int i; // If this session doesnt have a manager, do we care? if (!(node = manager_find_fromsession(session))) return; if (node->user && node->user->handle) huser = node->user->handle; switch(event) { case SESSION_EVENT_LOST: debugf("[handler_withuser] lost event\n"); // If the user owns it, notify them. if (huser && (node->locked == YNA_NO)) lion_printf(huser, "DISCONNECT|SID=%u|MSG=%s\r\n", node->id, line ? line : "(null)"); // We no longer have a session. node->old_session = node->session; node->session = NULL; break; case SESSION_EVENT_IDLE: debugf("[handler_withuser] idle event\n"); // If its this sessions first, lets send a connected msg too // If the user owns it, notify them. if (huser && (node->locked == YNA_NO)) { if (!node->connected) lion_printf(huser, "CONNECT|SID=%u%s\r\n", node->id, (session_feat(node->session)&FEATURE_SSL) ? "|SSL" : ""); node->connected = 1; lion_printf(huser, "IDLE|SID=%u\r\n", node->id); } break; case SESSION_EVENT_CMD: debugf("[handler_withuser]: id - %d %d\n", id, reply); switch(id) { case HANDLER_DIRLIST_SENDTO_USER: if (huser) { file_t **files = (file_t **) line; char *name; lion_printf(huser, "DIRLIST|SID=%u|BEGIN|items=%d\r\n", node->id, reply); // If we have RAW field, send it. for (i = 0; i < reply; i++) { name = misc_url_encode(files[i]->name); lion_printf(huser, "DIRLIST|SID=%u|FID=%u|NAME=%s|DATE=%lu|SIZE=%"PRIu64"|USER=%s|GROUP=%s|PERM=%s|FTYPE=%s%s%s\r\n", node->id, files[i]->fid, name, (unsigned long)files[i]->date, files[i]->size, files[i]->user, files[i]->group, files[i]->perm, files[i]->directory == YNA_YES ? "directory" : files[i]->soft_link == YNA_YES ? "link" : "file", files[i]->raw ? "|RAW=" : "", files[i]->raw ? files[i]->raw : ""); SAFE_FREE(name); } lion_printf(huser, "DIRLIST|SID=%u|END\r\n", node->id); // It's free'd after this. } break; // dirlist case HANDLER_QUOTE_REPLY: if (huser) lion_printf(huser, "QUOTE|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 0), line ? line : ""); break; case HANDLER_CWD_REPLY: if (huser) lion_printf(huser, "CWD|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 250), line ? line : ""); break; case HANDLER_PWD_REPLY: if (huser) { char *path; path = session_pwd_reply(node->session, reply, line); if (path) path = misc_url_encode(path); lion_printf(huser, "PWD|SID=%u|CODE=%d|PATH=%s|MSG=%s\r\n", node->id, handler_codeok(reply, 257), path ? path : "", line); } break; case HANDLER_SIZE_REPLY: if (huser) { lion64u_t size; if (line && sscanf((char *)line, "213 %"PRIu64, &size)) lion_printf(huser, "SIZE|SID=%u|CODE=%d|SIZE=%"PRIu64"|MSG=%s\r\n", node->id, handler_codeok(reply, 213), size, line ? line : ""); else lion_printf(huser, "SIZE|SID=%u|CODE=%d|MSG=%s\r\n", node->id, reply, line ? line : ""); } break; case HANDLER_DELE_REPLY: if (huser) lion_printf(huser, "DELE|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 257), line); break; case HANDLER_MKD_REPLY: if (huser) lion_printf(huser, "MKD|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 257), line); break; case HANDLER_RMD_REPLY: if (huser) lion_printf(huser, "RMD|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 257), line); break; case HANDLER_SITE_REPLY: if (huser) lion_printf(huser, "SITE|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 0), line); break; case HANDLER_RNFR_REPLY: if (reply == 350) node->user_flags |= MANAGER_USERFLAG_RNFR_OK; else if (huser) lion_printf(huser, "REN|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 350), line); break; case HANDLER_RNTO_REPLY: if (huser && (node->user_flags & MANAGER_USERFLAG_RNFR_OK)) lion_printf(huser, "REN|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 250), line); break; case HANDLER_MDTM_REPLY: if (huser) lion_printf(huser, "MDTM|SID=%u|CODE=%d|MSG=%s\r\n", node->id, handler_codeok(reply, 213), line); break; default: printf("[handle_withuser] SESSION_EVENT_CMD called for id %d/%02X\n", id, id); break; } // switch id break; case SESSION_EVENT_LOG: debugf("[handler_withuser] log: '%s'\n", line); if (huser && (node->user_flags&MANAGER_USERFLAG_LOG)) { char *encoded = NULL; if (line) encoded = misc_url_encode(line); lion_printf(huser, "LOG|SID=%u|MSG=%s\r\n", node->id, encoded ? encoded : "(null)"); SAFE_FREE(encoded); } break; default: debugf("[handler_withuser] event %d\n", event); break; } }
// // Main session handler when we have a user as the owner. // void handler_queue(session_t *session, int event, int id, int reply, char *line) { lion_t *huser = NULL; manager_t *node = NULL; queue_t *queue; int i; // If this session doesnt have a manager, do we care? if (!(node = manager_find_fromsession(session))) return; if (node->user && node->user->handle) huser = node->user->handle; // Find queue queue = queue_findbyqid(node->qid); if (!queue) return; switch(event) { case SESSION_EVENT_LOST: debugf("[handler_queue] lost event.\n"); // We no longer have a session. node->old_session = node->session; node->session = NULL; if (queue) { if (node->id == queue->north_sid) queue->north_sid = 0; if (node->id == queue->south_sid) queue->south_sid = 0; } //node->id = 0; //queue->state = QUEUE_ITEM_FAILED; break; case SESSION_EVENT_IDLE: debugf("[handler_queue] idle event\n"); #ifndef SLOW_QUEUE engine_nodelay = 1; #endif break; case SESSION_EVENT_CMD: if ((id != QUEUE_EVENT_DIRECTORY_PHASE_2_SRC_DIRLIST) && (id != QUEUE_EVENT_DIRECTORY_PHASE_2_DST_DIRLIST)) { debugf("[handler_queue] cmd event %d %d '%s'\n", id, reply, line); } else { debugf("[handler_queue] dirlist event %d %d %p\n", id, reply, line); } switch (id) { case QUEUE_EVENT_PHASE_1_SRC_CWD: if ((reply >= 200) && (reply <= 299)) { //if (reply == 250) { // Success // We want a way to know if we actually CD. Look for // "cached"? Kinda lame. if (!strstr(line, "cached")) if (queue->num_users) { char *name; name = misc_url_encode(queue->items->src.dirname); for (i = 0; i < queue->num_users; i++) if (queue->users[i] && queue->users[i]->handle) lion_printf(queue->users[i]->handle, "QS|QID=%u|SRCCWD=%s\r\n", queue->id, name); SAFE_FREE(name); } } else { // Initiate failure. queue_adderr_src(queue->items, line); } break; case QUEUE_EVENT_PHASE_1_DST_CWD: if ((reply >= 200) && (reply <= 299)) { //if (reply == 250) { // Success if (!strstr(line, "cached")) if (queue->num_users) { char *name; name = misc_url_encode(queue->items->dst.dirname); for (i = 0; i < queue->num_users; i++) if (queue->users[i] && queue->users[i]->handle) lion_printf(queue->users[i]->handle, "QS|QID=%u|DSTCWD=%s\r\n", queue->id, name); SAFE_FREE(name); } } else if ((reply >= 500)) { // Failed. Add error, but also try to create // the directory, if that succeeds, clear error. queue_adderr_dst(queue->items, line); debugf("QS|QID=%u|DSTMKD=%s\n", queue->id, queue->items->dst.dirname); // Try MKD, we fall-through down to trying // to send MKD. debugf("[handler] starting MKD with depth %d\n", queue->mkd_depth); session_cmdq_newf(session, 0, QUEUE_EVENT_PHASE_1_DST_MKD, "MKD %s\r\n", get_mkdname_by_depth(queue, 1)); } break; case QUEUE_EVENT_PHASE_1_DST_MKD: if ((reply >= 200) && (reply <= 299)) { // Success if (queue->num_users) { char *name; name = misc_url_encode(get_mkdname_by_depth(queue, 0)); for (i = 0; i < queue->num_users; i++) if (queue->users[i] && queue->users[i]->handle) lion_printf(queue->users[i]->handle, "QS|QID=%u|MKD=%s\r\n", queue->id, name); SAFE_FREE(name); } // Clear error. queue->items->dst_failure = 0; // Try CWD again. session_cwd(session, 0, QUEUE_EVENT_PHASE_1_DST_CWD2, get_mkdname_by_depth(queue, 0)); } else if ((reply >= 500)) { // Failed queue_adderr_dst(queue->items, line); } break; case QUEUE_EVENT_PHASE_1_DST_CWD2: if ((reply >= 200) && (reply <= 299)) { //if (reply == 250) { // Success debugf("[handler] 2ND mkd of depth %d\n", queue->mkd_depth); if (queue->mkd_depth > 0) { session_cmdq_newf(session, 0, QUEUE_EVENT_PHASE_1_DST_MKD, "MKD %s\r\n", get_mkdname_by_depth(queue, 1)); break; } } else if ((reply >= 500)) { // Failure queue_adderr_dst(queue->items, line); } break; case QUEUE_EVENT_PHASE_2_SRC_SECURE: if ((reply >= 200) && (reply <= 299)) { //if (reply == 200) { // Success queue->secure_data = 1; } else { // Failure queue_adderr_src(queue->items, line); } break; case QUEUE_EVENT_PHASE_2_DST_SECURE: if ((reply >= 200) && (reply <= 299)) { //if (reply == 200) { // Success queue->secure_data = 1; } else { // Failure queue_adderr_dst(queue->items, line); } break; case QUEUE_EVENT_PHASE_2_DISABLE: // Do we care if we failed here? Disabling // CCSN/SSCN should never fail to disable. // We would need to disconnect session instead. // TODO break; case QUEUE_EVENT_PHASE_3_SRC_PROT: if ((reply >= 200) && (reply <= 299)) { //if (reply == 200) { // Success } else { // Failure queue_adderr_src(queue->items, line); } break; case QUEUE_EVENT_PHASE_3_DST_PROT: if ((reply >= 200) && (reply <= 299)) { //if (reply == 200) { // Success } else { // Failure queue_adderr_dst(queue->items, line); } break; case QUEUE_EVENT_PHASE_4_TYPE: break; case QUEUE_EVENT_PHASE_5_SRC_SIZE: if (reply == 213) { lion64_t newsize = 0; if (line && sscanf((char *)line, "213 %"PRIu64, &newsize) == 1) { if (newsize != queue->items->src.size) { debugf("[handler] Updating src.size to %"PRIu64"\n", newsize); queue->items->src.size = newsize; } } // scanf } // 213 break; case QUEUE_EVENT_PHASE_5_DST_SIZE: if (reply == 213) { lion64_t newsize = 0; if (line && sscanf((char *)line, "213 %"PRIu64, &newsize) == 1) { if (newsize != queue->items->dst.size) { debugf("[handler] Updating dst.size to %"PRIu64"\n", newsize); queue->items->dst.size = newsize; } } // scanf } // 213 break; case QUEUE_EVENT_PHASE_6_PRET: break; case QUEUE_EVENT_PHASE_7_PASV: if (reply == 227) { // 227 Entering Passive Mode (127,0,0,1,226,180) // 229 Entering Extended Passive Mode (|||58028|) // Look for () and safe inbetween. If that failed, we fail. char *r; if ((r = strchr(line, '('))) { line = &r[1]; if ((r = strchr(line, ')'))) { *r = 0; SAFE_COPY(queue->pasv_line, line); return; } } } // Wrong reply, or couldn't parse, fail. if (queue->srcpasv) queue_adderr_src(queue->items, line); else queue_adderr_dst(queue->items, line); break; case QUEUE_EVENT_PHASE_8_PORT: if (reply == 200) break; if (!queue->srcpasv) queue_adderr_src(queue->items, line); else queue_adderr_dst(queue->items, line); break; case QUEUE_EVENT_PHASE_9_SRC_REST: if (reply == 350) { // REST ok } else { queue_adderr_src(queue->items, line); } break; case QUEUE_EVENT_PHASE_9_DST_REST: if (reply == 350) { // REST ok } else { queue_adderr_dst(queue->items, line); } break; case QUEUE_EVENT_PHASE_9_SRC_REST2: case QUEUE_EVENT_PHASE_9_DST_REST2: break; case QUEUE_EVENT_PHASE_10_STOR: if (reply == -1) { // LOG reply, in case we are looking for X-DUPE if (session->status & STATUS_ON_XDUPE) { // Look for X-DUPE lines, remember these are url // encoded. if (!strncasecmp("226-+X-DUPE%3A+", line, 15)) queue_xdupe_item(queue, &line[15]); } break; } if ((reply == 150) || // Unix (reply == 125)) { // Windows queue->items->src_transfer++; break; } queue_adderr_dst(queue->items, line); break; case QUEUE_EVENT_PHASE_11_RETR: if ((reply == 150) || // Unix (reply == 125)) { // Windows queue->items->dst_transfer++; gettimeofday(&queue->xfr_start, NULL); break; } queue_adderr_src(queue->items, line); break; case QUEUE_EVENT_PHASE_11_ABOR: break; case QUEUE_EVENT_PHASE_12_SRC_226: if (queue->items) queue->items->src_transfer++; if (reply == 226) break; queue_adderr_src(queue->items, line); break; case QUEUE_EVENT_PHASE_12_DST_226: if (queue->items) queue->items->dst_transfer++; if (reply == 226) break; queue_adderr_dst(queue->items, line); break; case QUEUE_EVENT_PHASE_12_NOOP: break; case QUEUE_EVENT_DIRECTORY_PHASE_1_SRC_CWD: if ((reply >= 200) && (reply <= 299)) { //if (reply == 250) { // Success if (!strstr(line, "cached")) if (queue->num_users) { char *name; name = misc_url_encode(queue->items->src.fullpath); for (i = 0; i < queue->num_users; i++) if (queue->users[i] && queue->users[i]->handle) lion_printf(queue->users[i]->handle, "QS|QID=%u|SRCCWD=%s\r\n", queue->id, name); SAFE_FREE(name); } } else { // Initiate failure. queue_adderr_src(queue->items, line); } break; case QUEUE_EVENT_DIRECTORY_PHASE_1_DST_CWD: if ((reply >= 200) && (reply <= 299)) { //if (reply == 250) { // Success debugf("[handler] CLEARing depth**********\n"); queue->mkd_depth = 0; if (!strstr(line, "cached")) if (queue->num_users) { char *name; name = misc_url_encode(queue->items->dst.fullpath); for (i = 0; i < queue->num_users; i++) if (queue->users[i] && queue->users[i]->handle) lion_printf(queue->users[i]->handle, "QS|QID=%u|DSTCWD=%s\r\n", queue->id, name); SAFE_FREE(name); } } else { // Initiate failure. queue_adderr_dst(queue->items, line); // Increase the depth that we've failed at, for MKDs. queue->mkd_depth++; debugf("[handler] INCreasing depth %d\n",queue->mkd_depth); } break; case QUEUE_EVENT_DIRECTORY_PHASE_2_SRC_DIRLIST: if (!line || !reply) { // No files. Empty dir. We have no FAILURE event in dirlist!! // FIXME!! } queue->items->src_transfer = 1; break; case QUEUE_EVENT_DIRECTORY_PHASE_2_DST_DIRLIST: if (!line || !reply) { // No files. Empty dir. We have no FAILURE event in dirlist!! // FIXME!! } queue->items->dst_transfer = 1; break; case QUEUE_EVENT_DIRECTORY_PHASE_2_DST_MKD: if ((reply >= 200) && (reply <= 299)) { // Success if (queue->num_users) { char *name; name = misc_url_encode(get_mkdname_by_depth(queue, 0)); for (i = 0; i < queue->num_users; i++) if (queue->users[i] && queue->users[i]->handle) lion_printf(queue->users[i]->handle, "QS|QID=%u|MKD=%s\r\n", queue->id, name); SAFE_FREE(name); } // Clear error. queue->items->dst_failure = 0; } else if ((reply >= 500)) { // Failed queue_adderr_dst(queue->items, line); } break; } // switch EVENT_CMD (inner switch) break; } }
static int root_request_handler(lion_t *handle, void *user_data, int status, int size, char *line) { request_t *node = (request_t *) user_data; // If node isn't set, it's b0rken. if (!node) return 0; switch(status) { case LION_CONNECTION_CONNECTED: debugf("[root] connected to remote http, issuing GET\n"); lion_printf(handle, "GET /%s HTTP/1.1\r\n" "Host: %s\r\n", root_array[node->root_index].http_file, root_array[node->root_index].http_host); lion_printf(handle, "Connection: close\r\n"); // End of header. lion_printf(handle, "\r\n"); break; case LION_CONNECTION_LOST: case LION_CONNECTION_CLOSED: node->roothandle = NULL; request_finishdir(node); break; case LION_INPUT: // FIXME, we just look for urls here.. Don't even care if we are in header or // body. //debugf("[root] request '%s'\n", line); if (line && *line) { char str[] = "-rwxr-xr-x 1 u g 0 Dec 15 21:44 "; char *part, *ar, *url, *entry; char *next; next = line; while((part = strstr(next, "\"http://"))) { ar = part; if ((url = misc_digtoken(&ar, "\"\r\n"))) { entry = misc_strjoin(str, url); if (entry) { debugf("[root] adding url '%s'\n", url); skin_write_type(node, entry); } SAFE_FREE(entry); } // if good url // Ok, skip this http://, look for more. next = ar; } // while strstr } // line break; } return 0; }