// 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); }
void sites_setkey(char *key) { if (key && !*key) key = NULL; SAFE_COPY(sites_key, key); }
// // Take src-file node AND // dst-file node, to populate the dst-file node with // appropriate information. // // If dst "fullpath" is set, we trust it. if not // copy over the "name" from source, and build from that. // void file_makedest(file_t *dst, file_t *src, char *cwd) { if (!dst->fullpath && !dst->name) SAFE_COPY(dst->name, src->name); file_makepath(dst, cwd); dst->directory = src->directory; dst->soft_link = src->soft_link; }
void file_dupe(file_t *dst, file_t *src) { SAFE_COPY(dst->name, src->name); SAFE_COPY(dst->fullpath, src->fullpath); SAFE_COPY(dst->dirname, src->dirname); SAFE_COPY(dst->user, src->user); SAFE_COPY(dst->group, src->group); SAFE_COPY(dst->raw, src->raw); memcpy(&dst->perm, src->perm, sizeof(dst->perm)); dst->date = src->date; dst->size = src->size; dst->rest = src->rest; dst->directory = src->directory; dst->soft_link = src->soft_link; }
// // If "fullpath" is set, then we trust it is correct and fill in the // "name" and "dirname" sections. // // If "fullpath" is not set, we combine "name" and "dirname" to be "fullpath". // void file_makepath(file_t *file, char *cwd) { char *r; if (file->fullpath) { // Create name and dirname. r = strrchr(file->fullpath, '/'); if (!r) { // Shouldn't happen as fullpath should be _full path_ SAFE_COPY(file->dirname, "/"); SAFE_COPY(file->name, file->fullpath); return; } *r = 0; if (*file->fullpath) { SAFE_COPY(file->dirname, file->fullpath); } else { SAFE_COPY(file->dirname, "/"); } SAFE_COPY(file->name, &r[1]); *r = '/'; return; } // fullpath not set. if (cwd && file->name) { SAFE_FREE(file->fullpath); file->fullpath = misc_strjoin(cwd, file->name); SAFE_COPY(file->dirname, cwd); } else if (file->dirname && file->name) { SAFE_FREE(file->fullpath); file->fullpath = misc_strjoin(file->dirname, file->name); } else { debugf("[file] can't file_makepath\n"); } }
void arguments(int argc, char **argv) { int opt; while ((opt=getopt(argc, argv, "hf:a:i:I:qnvdC:")) != -1) { switch(opt) { case 'h': options(argv[0]); break; case 'f': SAFE_COPY(conf_file_name, optarg); break; case 'a': default_age = strtoul(optarg, NULL, 10); break; case 'i': SAFE_COPY(conf_incpattern, optarg); break; case 'I': SAFE_COPY(conf_autoqpattern, optarg); break; case 'q': conf_do_autoq ^= 1; break; case 'n': conf_do_save ^= 1; break; case 'v': conf_do_verbose ^= 1; break; case 'd': debug_on ^= 1; break; case 'C': lion_ssl_ciphers(optarg); break; default: printf("Unknown option.\n"); break; } } argc -= optind; argv += optind; // argc and argv adjusted here. if (!conf_file_name) conf_file_name = strdup("clomps.conf"); }
//SITE|NAME=foo|DIR=/tv/|USESKIP=1|INCTEST=%s-INCOMPLETE|LAST_CHECK=123123123 //NUKETEST=!NUKED-%s void conf_site(char **keys, char **values, int items,void *optarg) { char *name, *dir, *useskip, *inctest, *nuketest, *last_check, *hide; site_t *site, **tmp; char **dtmp; char *strtmp; int i; name = parser_findkey(keys, values, items, "NAME"); useskip = parser_findkey(keys, values, items, "USESKIP"); inctest = parser_findkey(keys, values, items, "INCTEST"); nuketest = parser_findkey(keys, values, items, "NUKETEST"); hide = parser_findkey(keys, values, items, "HIDE"); last_check = parser_findkey(keys, values, items, "LAST_CHECK"); if (!name) { printf("SITE Entry in conf without NAME= field\n"); return; } // Attempt to find a site already defined by name, if found, allow // HIDE to be concatenated. for (i = 0; i < num_sites; i++) { if (sites[i] && !mystrccmp(name, sites[i]->name)) { if (hide) { if (!sites[i]->hide) { SAFE_COPY(sites[i]->hide, hide); } else { strtmp = sites[i]->hide; sites[i]->hide = misc_strjoin(strtmp?strtmp:"", hide); SAFE_FREE(strtmp); } } return; } } site = calloc(1, sizeof(*site)); if (!site) return; tmp = realloc(sites, sizeof(site_t *) * (num_sites + 1)); if (!tmp) return; sites = tmp; sites[num_sites] = site; num_sites++; SAFE_COPY(site->name, name); while ((dir = parser_findkey_once(keys, values, items, "DIR"))) { dtmp = (char **) realloc(site->dirs, sizeof(char *) * (site->num_dirs + 1)); if (!dtmp) break; site->dirs = dtmp; site->dirs[ site->num_dirs ] = strdup(dir); site->num_dirs++; } SAFE_COPY(site->inctest, inctest); SAFE_COPY(site->nuketest, nuketest); SAFE_COPY(site->hide, hide); if (useskip) site->use_lists = atoi(useskip); if (last_check) { site->last_check = strtoul(last_check, NULL, 10); site->last_check -= default_age; } else { site->last_check = lion_global_time; site->last_check -= default_age; } site->num_files = 0; }
static fz_error evalpostscriptfunc(pdf_function *func, psstack *st, int codeptr) { fz_error error; int i1, i2; float r1, r2; int b1, b2; while (1) { switch (func->u.p.code[codeptr].type) { case PSINT: SAFE_PUSHINT(st, func->u.p.code[codeptr++].u.i); break; case PSREAL: SAFE_PUSHREAL(st, func->u.p.code[codeptr++].u.f); break; case PSOPERATOR: switch (func->u.p.code[codeptr++].u.op) { case PSOABS: if (pstopisint(st)) { SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, abs(i1)); } else { SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, fabs(r1)); } break; case PSOADD: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, i1 + i2); } else { SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, r1 + r2); } break; case PSOAND: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, i1 & i2); } else { SAFE_POPBOOL(st, &b2); SAFE_POPBOOL(st, &b1); SAFE_PUSHBOOL(st, b1 && b2); } break; case PSOATAN: SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, atan2(r1, r2)*RADIAN); break; case PSOBITSHIFT: SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); if (i2 > 0) { SAFE_PUSHINT(st, i1 << i2); } else if (i2 < 0) { SAFE_PUSHINT(st, (int)((unsigned int)i1 >> i2)); } else { SAFE_PUSHINT(st, i1); } break; case PSOCEILING: if (!pstopisint(st)) { SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, ceil(r1)); } break; case PSOCOPY: SAFE_POPINT(st, &i1); SAFE_COPY(st, i1); break; case PSOCOS: SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, cos(r1/RADIAN)); break; case PSOCVI: if (!pstopisint(st)) { SAFE_POPNUM(st, &r1); SAFE_PUSHINT(st, (int)r1); } break; case PSOCVR: if (!pstopisreal(st)) { SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, r1); } break; case PSODIV: SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, r1 / r2); break; case PSODUP: SAFE_COPY(st, 1); break; case PSOEQ: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHBOOL(st, i1 == i2); } else if (pstoptwoarenums(st)) { SAFE_POPNUM(st, &r1); SAFE_POPNUM(st, &r1); SAFE_PUSHBOOL(st, r1 == r2); } else { SAFE_POPBOOL(st, &b2); SAFE_POPBOOL(st, &b2); SAFE_PUSHBOOL(st, b1 == b2); } break; case PSOEXCH: psroll(st, 2, 1); break; case PSOEXP: SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, pow(r1, r2)); break; case PSOFALSE: SAFE_PUSHBOOL(st, 0); break; case PSOFLOOR: if (!pstopisint(st)) { SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, floor(r1)); } break; case PSOGE: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHBOOL(st, i1 >= i2); } else { SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHBOOL(st, r1 >= r2); } break; case PSOGT: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHBOOL(st, i1 > i2); } else { SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHBOOL(st, r1 > r2); } break; case PSOIDIV: SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, i1 / i2); break; case PSOINDEX: SAFE_POPINT(st, &i1); SAFE_INDEX(st, i1); break; case PSOLE: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHBOOL(st, i1 <= i2); } else { SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHBOOL(st, r1 <= r2); } break; case PSOLN: SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, log(r1)); break; case PSOLOG: SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, log10(r1)); break; case PSOLT: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHBOOL(st, i1 < i2); } else { SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHBOOL(st, r1 < r2); } break; case PSOMOD: SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, i1 % i2); break; case PSOMUL: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); /* FIXME should check for out-of-range, and push a real instead */ SAFE_PUSHINT(st, i1 * i2); } else { SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, r1 * r2); } break; case PSONE: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHBOOL(st, i1 != i2); } else if (pstoptwoarenums(st)) { SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHBOOL(st, r1 != r2); } else { SAFE_POPBOOL(st, &b2); SAFE_POPBOOL(st, &b1); SAFE_PUSHBOOL(st, b1 != b2); } break; case PSONEG: if (pstopisint(st)) { SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, -i1); } else { SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, -r1); } break; case PSONOT: if (pstopisint(st)) { SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, ~i1); } else { SAFE_POPBOOL(st, &b1); SAFE_PUSHBOOL(st, !b1); } break; case PSOOR: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, i1 | i2); } else { SAFE_POPBOOL(st, &b2); SAFE_POPBOOL(st, &b1); SAFE_PUSHBOOL(st, b1 || b2); } break; case PSOPOP: SAFE_POP(st); break; case PSOROLL: SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); psroll(st, i1, i2); break; case PSOROUND: if (!pstopisint(st)) { SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, (r1 >= 0) ? floor(r1 + 0.5) : ceil(r1 - 0.5)); } break; case PSOSIN: SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, sin(r1/RADIAN)); break; case PSOSQRT: SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, sqrt(r1)); break; case PSOSUB: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, i1 - i2); } else { SAFE_POPNUM(st, &r2); SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, r1 - r2); } break; case PSOTRUE: SAFE_PUSHBOOL(st, 1); break; case PSOTRUNCATE: if (!pstopisint(st)) { SAFE_POPNUM(st, &r1); SAFE_PUSHREAL(st, (r1 >= 0) ? floor(r1) : ceil(r1)); } break; case PSOXOR: if (pstoptwoareints(st)) { SAFE_POPINT(st, &i2); SAFE_POPINT(st, &i1); SAFE_PUSHINT(st, i1 ^ i2); } else { SAFE_POPBOOL(st, &b2); SAFE_POPBOOL(st, &b1); SAFE_PUSHBOOL(st, b1 ^ b2); } break; case PSOIF: SAFE_POPBOOL(st, &b1); if (b1) { error = evalpostscriptfunc(func, st, codeptr + 2); if (error) return fz_rethrow(error, "runtime error in if-branch"); } codeptr = func->u.p.code[codeptr + 1].u.block; break; case PSOIFELSE: SAFE_POPBOOL(st, &b1); if (b1) { error = evalpostscriptfunc(func, st, codeptr + 2); if (error) return fz_rethrow(error, "runtime error in if-branch"); } else { error = evalpostscriptfunc(func, st, func->u.p.code[codeptr].u.block); if (error) return fz_rethrow(error, "runtime error in else-branch"); } codeptr = func->u.p.code[codeptr + 1].u.block; break; case PSORETURN: return fz_okay; default: return fz_throw("foreign operator in calculator function"); } break; default: return fz_throw("foreign object in calculator function"); }
void TCLinkSend(TCLinkHandle handle) { param *p, *next; char buf[TC_BUFF_MAX], destbuf[TC_LINE_MAX]; char buf2[1024]; int host_hash = 1; int retval = 0; TCLinkCon *c = (TCLinkCon *)handle; ClearRecvList(c); /* build most of the string we will send to the processor */ sprintf(buf, "BEGIN\nversion=%s\n", tclink_version); for (p = c->send_param_list; p; p = next) { next = p->next; SAFE_COPY(buf2, p->name); SAFE_APPEND(buf2, "="); SAFE_APPEND(buf2, p->value); SAFE_APPEND(buf2, "\n"); SAFE_APPEND(buf, buf2); if (!strcasecmp(p->name, "custid")) { host_hash = atoi(p->value); host_hash = (host_hash / 100) + (host_hash % 100); } free(p->name); free(p->value); free(p); } c->send_param_list = c->send_param_tail = NULL; /* try to make the connection */ if (!Connect(c, host_hash)) { Close(c); /* clean up any memory Connect() may have left lying around */ AddRecvParam(c, "status", "error"); AddRecvParam(c, "errortype", "cantconnect"); return; } /* append some data about the connection */ sprintf(buf+strlen(buf), "pass=%d\ntime=%ld\n", c->pass, time(0) - c->start_time); if (c->dns != 1) SAFE_APPEND(buf, "dns=n\n"); SAFE_APPEND(buf, "END\n"); /* send the data */ if (Send(c, buf)) { int state = 0; buf[0] = destbuf[0] = 0; /* recycle buf */ c->is_error = 0; while (1) { int len = ReadLine(c, buf, destbuf); if (len == 0) continue; if (len < 0) break; if (strcasecmp(destbuf, "BEGIN") == 0) { if (state != 0) { state = -1; break; } state = 1; } else if (strcasecmp(destbuf, "END") == 0) { if (state != 1) state = -1; else state = 2; break; } else { if (state != 1 || !AddRecvString(c, destbuf)) { state = -1; break; } } } if (state == 2) retval = 1; } Close(c); if (!retval) { ClearRecvList(c); AddRecvParam(c, "status", "error"); AddRecvParam(c, "errortype", "linkfailure"); } }
// // Take a argc/argv pair, parse out the required fields for a site // then save any optional fields for GUIs. // // Return standard error codes, or 0 for success. // int sites_parsekeys(char **keys, char **values, int items, sites_t *node) { int i, len; int xitems; unsigned long set = 0; // make sure we have seen all required fields. xitems = items; #ifdef DEBUG_VERBOSE debugf("[sites_parsekeys] parsing for %p\n", node); #endif for (i = 0; i < items; i++) { // Empty key, just loop if (!keys[i]) continue; len = strlen(keys[i]); #define tester(X) ((sizeof((X))-1 == len) && !strcasecmp(keys[i], (X))) // REQUIRED if (tester("name")) { if (!values[i]) return 1504; // Missing required field SAFE_COPY(node->name, values[i]); keys[i] = NULL; xitems--; set |= 1; } else if (tester("host")) { if (!values[i]) return 1504; SAFE_COPY(node->host, values[i]); keys[i] = NULL; xitems--; set |= 2; } else if (tester("user")) { if (!values[i]) return 1504; SAFE_COPY(node->user, values[i]); keys[i] = NULL; xitems--; set |= 4; } else if (tester("pass")) { if (!values[i]) return 1504; SAFE_COPY(node->pass, values[i]); keys[i] = NULL; xitems--; set |= 8; // OPTIONAL } else if (tester("port")) { if (!values[i]) continue; node->port = atoi(values[i]); keys[i] = NULL; xitems--; } else if (tester("passive")) { if (!values[i]) continue; node->passive = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("fxp_passive")) { if (!values[i]) continue; node->fxp_passive = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("control_TLS")) { if (!values[i]) continue; node->control_TLS = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("data_TLS")) { if (!values[i]) continue; node->data_TLS = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("iface")) { // FIXME!! Use char * if (!values[i]) continue; node->iface = lion_addr(values[i]); keys[i] = NULL; xitems--; } else if (tester("iport")) { if (!values[i]) continue; node->iport = atoi(values[i]); keys[i] = NULL; xitems--; } else if (tester("desired_type")) { if (!values[i]) continue; node->desired_type = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("resume")) { if (!values[i]) continue; node->resume = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("resume_last")) { if (!values[i]) continue; node->resume_last = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("pret")) { if (!values[i]) continue; node->pret = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("fskiplist")) { if (!values[i]) { SAFE_FREE(node->file_skiplist); continue; } SAFE_COPY(node->file_skiplist, values[i]); keys[i] = NULL; xitems--; } else if (tester("dskiplist")) { if (!values[i]) { SAFE_FREE(node->directory_skiplist); continue; } SAFE_COPY(node->directory_skiplist, values[i]); keys[i] = NULL; xitems--; } else if (tester("fpasslist")) { if (!values[i]) { SAFE_FREE(node->file_passlist); continue; } SAFE_COPY(node->file_passlist, values[i]); keys[i] = NULL; xitems--; } else if (tester("dpasslist")) { if (!values[i]) { SAFE_FREE(node->directory_passlist); continue; } SAFE_COPY(node->directory_passlist, values[i]); keys[i] = NULL; xitems--; } else if (tester("fskipempty")) { if (!values[i]) continue; node->file_skipempty = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("dskipempty")) { if (!values[i]) continue; node->directory_skipempty = str2yna(values[i]); keys[i] = NULL; xitems--; } else if (tester("fmovefirst")) { if (!values[i]) { SAFE_FREE(node->file_movefirst); continue; } SAFE_COPY(node->file_movefirst, values[i]); keys[i] = NULL; xitems--; } else if (tester("dmovefirst")) { if (!values[i]) { SAFE_FREE(node->directory_movefirst); continue; } SAFE_COPY(node->directory_movefirst, values[i]); keys[i] = NULL; xitems--; // Parser adds the "type" field to say what command we were // so we had better take it out. } else if (tester("type")) { keys[i] = NULL; xitems--; } else if (tester("SITEID")) { keys[i] = NULL; xitems--; } #undef tester } #ifdef DEBUG_VERBOSE debugf("[sites_parsekeys] saw fields %lu.\n", set); #endif // Check if we saw all required fields. // name, host, user and pass. // Save any left over fields // Subtract the number of matched fields, and allocate the arrays to // hold the remainding. if (xitems) { #ifdef DEBUG_VERBOSE debugf("[sites] %d items remaining..\r\n", xitems); #endif // We want to keep/copy the old key/pairs, and check against fields // given to remove some, or add new. // Find key/value to delete. if (node->items && node->keys) { for (i = 0; i < items; i++) { if (keys[i] && (!values[i] || !values[i][0])) { // Look for keys[i] in the site's keys. If it finds it // it sets it to NULL. (Delete). We also wipe it from // keys to not consider it as an addition. parser_findkey_once(node->keys, node->values, node->items, keys[i]); keys[i] = NULL; xitems--; } } } // All other remaining key/pairs are either changes, or, additions. // Do we need to allocate more space? if (xitems > node->items) { char **tmp; tmp = (char **) realloc(node->keys, sizeof(char *) * xitems); if (!tmp) return 401; // Out of memory node->keys = tmp; tmp = (char **) realloc(node->values, sizeof(char *) * xitems); if (!tmp) return 401; // Out of memory node->values = tmp; } //node->items = xitems; // Assign in... for (i = 0; i < items; i++) { int j, empty; if (keys[i] && values[i]) { // Still set, we should save it. // Attempt to find it, in node->keys for (j = 0, empty = -1; j < node->items; j++) { // If a key position is empty, remember it if (!node->keys[j]) { if (empty < 0) empty = j; continue; // It's empty, don't bother comparing below } if (!strcasecmp(keys[i], node->keys[j])) { // Key exists, just copy over the new value. SAFE_DUPE(node->values[j], values[i]); break; } } // Didn't find it? If so add it. if (j >= node->items) { // Did we not find an empty slot? if (empty == -1) { empty = node->items; // Add more space. node->items++; char **tmp; tmp = (char **) realloc(node->keys, sizeof(char *) * node->items); if (!tmp) return 401; // Out of memory node->keys = tmp; tmp = (char **) realloc(node->values, sizeof(char *) * node->items); if (!tmp) return 401; // Out of memory node->values = tmp; } // Ok, there is space. SAFE_DUPE(node->keys[empty], keys[i]); SAFE_DUPE(node->values[empty], values[i]); } // Added node } // both keys and values set. } // for all remaining items. // We could update node->items when there was deletion.. But they // should not be saved to disk if they are NULL, and so, next load // they are set correctly. // xitems should be 0 here, or something went wrong, but we // can just adjust out value and not panic about it. } // xitems // This check is only for siteadd, not sitemod if ((set & (15)) != 15) return 1504; return 0; }
// // 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; } }
//<< 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; } } }
// >> 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)); } } }
// // This takes the "virtual path" ->path sent over by the HTTP request, and // attempts to match it to one of the roots we have setup from conf file. // If there is a valid match, ->disk_path is assigned. // // Note that if "disk_path" is already set, we don't do anything, and assume // it is good. Only place that sets it apart from this function, is when we // copy over the temporary filename, which is strictly controlled in // request_action() // int root_setpath(request_t *node) { char *tmpname, *subdir, *skin_root = NULL; char *str; int i; // If disk_path is set, we need not do anything. if (node->disk_path && node->disk_path) { debugf("[root] trusting that '%s' is valid.\n", node->disk_path); // However, if the path is "/", or stat to a directory we // call dirlist. stat(node->disk_path, &node->stat); return 0; } // Reduce away any naughty "../../../" parts. root_undot(node->path); // If its "/" we just leave it as that. if (!mystrccmp("/", node->path)) { // Strictly not needed. We dont expand "/" to the real root as // we may have multiple real roots. So it is left as a secret // match strict which starts listing of all roots. SAFE_COPY(node->disk_path, node->path); return 0; } // Anything else, we need to find the "right" root, and // set full path. Any multiple hits are ignored as we just // settle for first come. // First we check if it is in the skin directory. if ((skin_root = skin_get_root(node->skin_type))) { tmpname = misc_strjoin(skin_root, node->path); debugf("[root] testing path '%s'\n", tmpname); // Windows does not like "directory/" in stat. misc_stripslash(tmpname); if (!stat(tmpname, &node->stat)) { // misc_strjoin allocates string, so we can just assign it. node->disk_path = tmpname; // Caveat, if the target is a directory, we have to ensure // it has a trailing "/" for dirlist's precat in ->path if (S_ISDIR(node->stat.st_mode) && node->path[ strlen(node->path) ] != '/') { tmpname = misc_strjoin(node->path, ""); SAFE_FREE(node->path); node->path = tmpname; } return 0; } SAFE_FREE(tmpname); } // skin #if 0 // The above (identical) code uses skin_get_root() which should return // the root of the current skin, which should be set to the upnp skin // in skin_set_skin(). // First we check if it is in the upnpskin directory. if (skin_upnp_root) { tmpname = misc_strjoin(skin_upnp_root, node->path); debugf("[root] testing path '%s'\n", tmpname); // Windows does not like "directory/" in stat. misc_stripslash(tmpname); if (!stat(tmpname, &node->stat)) { // misc_strjoin allocates string, so we can just assign it. node->disk_path = tmpname; // Caveat, if the target is a directory, we have to ensure // it has a trailing "/" for dirlist's precat in ->path if (S_ISDIR(node->stat.st_mode) && node->path[ strlen(node->path) ] != '/') { tmpname = misc_strjoin(node->path, ""); SAFE_FREE(node->path); node->path = tmpname; } return 0; } SAFE_FREE(tmpname); } //upnp skin #endif // Now try all the roots defined. for (i = 0; i < root_count; i++) { // Check for exact http ROOT matches if (root_array[i].http_host) { // If its a proxy request (file mode) if (node->cgi_host && node->cgi_file) { node->root_index = i; node->stat.st_mode = S_IFREG; node->disk_path = strdup("http-proxy"); return 0; } // it will start with a slash, so skip it str = node->path; while (*str == '/') str++; // Compare it if (!mystrccmp(root_array[i].path, str)) { debugf("[root] ROOT|http match '%s'\n", str); node->root_index = i; // Due to stat()s, we need to send a real dir here. // Don't worry, "/" means dirlist, not that it lists from root node->disk_path = strdup("http-listing"); //Fake a stat of a dirlist node->stat.st_mode = S_IFDIR; return 0; } } tmpname = misc_strjoin(root_array[i].path, node->path); misc_stripslash(tmpname); debugf("[root] testing path '%s'\n", tmpname); if (!stat(tmpname, &node->stat)) { // misc_strjoin allocates string, so we can just assign it. node->disk_path = tmpname; // Caveat, if the target is a directory, we have to ensure // it has a trailing "/" for dirlist's precat in ->path if (S_ISDIR(node->stat.st_mode) && node->path[ strlen(node->path) ] != '/') { tmpname = misc_strjoin(node->path, ""); SAFE_FREE(node->path); node->path = tmpname; } node->root_index = i; return 0; } SAFE_FREE(tmpname); } // This test destroys node->path, so it needs to be last debugf("[root] testing for SUBDIR type: '%s'\n", node->path); // it might be using a SUBDIR style syntax. str = node->path; while (*str == '/') str++; // Might be the root of SUBDIR, or deeper request. if ((subdir = strchr(str, '/'))) { *subdir = 0; subdir++; } else { subdir = ""; } debugf("[root] looking for '%s' rest '%s'\n", str, subdir); for (i = 0; i < root_count; i++) { if (root_array[i].subdir && !mystrccmp(root_array[i].subdir, str)) { node->disk_path = misc_strjoin(root_array[i].path, subdir); debugf("[root] testing subdir path '%s'\n", node->disk_path); misc_stripslash(node->disk_path); if (!stat(node->disk_path, &node->stat)) { // Caveat, if the target is a directory, we have to ensure // it has a trailing "/" for dirlist's precat in ->path // path = path + subdir tmpname = misc_strjoin(node->path, subdir); SAFE_FREE(node->path); node->path = tmpname; if (S_ISDIR(node->stat.st_mode) && node->path[ strlen(node->path) ] != '/') { tmpname = misc_strjoin(node->path, ""); SAFE_FREE(node->path); node->path = tmpname; } node->root_index = i; debugf("[root] returning subdir: '%s':%d\n", node->disk_path, node->root_index); return 0; } // stat } // mystrccmp } // for roots debugf("[root] giving up, path not valid.\n"); // we've trashed the path anyway? SAFE_FREE(node->path); // Invalid path. Do we ensure it will fail later here? Or just assume // that the stat will fail later on. return -1; }