// (POSIX thread function) // Handles a client until done with it. // needs pointer to woolnet_clnt_t void *client_handle(void *arg) { woolnet_clnt_t *self = (woolnet_clnt_t*)arg; self->termn = -1; self->username = NULL; printf("[wool client_handle(..)] CALL\n"); unsigned char *buf = new unsigned char[woolnet::prot_maxlen()]; size_t len; len = woolnet::wrap_crecv(self, buf, woolnet::pack_clogin(NULL, 0, 0)); if (len<=0) { printf("[wool client_handle(..) '%s' %02i] Failed to receive CLOGIN pack\n", self->username, self->termn); return (void*)ERRNCARE; } if (buf[0] != PACK_CLOGIN) { printf("[wool client_handle(..) '%s' %02i] Received unexpected non-CLOGIN packet\n", self->username, self->termn); return (void*)ERRNCARE; } char *username = new char[32]; char *password = new char[32]; woolnet::pack_unclogin(buf, username, password); printf("[wool client_handle(..) '%s' %02i] Client '%s' with password '%s'...\n", self->username, self->termn, username, password); // now talk to user module std::string stuffpath = std::string("::home::") + username; ppackage userfs = kap.knock(ppfuncs((char*)stuffpath.c_str()), NULL); if (userfs.type != 'd') { printf("[wool client_handle(..) '%s' %02i] failed to obtain functions (via knocking)\n", self->username, self->termn); len = woolnet::pack_slogin(buf, PRET_NOUSER, 0); // termn 0 doesnt exist btw. woolnet::wrap_csend(self, buf, len); // tell client authentication failed return (void*)ERR; } int (*user_term_new)(char *) = (int(*)(char*)) fsget((mfunc_t*)userfs.d.data, "term_new"); if (!user_term_new) { printf("[wool client_handle(..) '%s' %02i] 'term_new' function not found in this user\n", self->username, self->termn); len = woolnet::pack_slogin(buf, PRET_INTERN, 0); // i should have used ERRIMADERP here. woolnet::wrap_csend(self, buf, len); return (void*)ERR; } self->termn = user_term_new(self->passwd); printf("[wool client_handle(..) '%s' %02i] termn = %02i\n", self->username, self->termn, self->termn); len = woolnet::pack_slogin(buf, PRET_OKAY, self->termn); woolnet::wrap_csend(self, buf, len); // we have now a terminal and can start transferring keys/bytes while (1) { len = woolnet::wrap_crecv(self, buf, 1); if (len <= 0) { printf("[wool client_handle(..) '%s' %02i] failed to recv first typebyte of packge\n", self->username, self->termn); return (void*)ERRNCARE; } switch (buf[0]) { case PACK_KEY: len = woolnet::wrap_crecv(self, buf+1, woolnet::pack_key(NULL, 0, 0)-1); break; case PACK_CLOSE: len = woolnet::wrap_crecv(self, buf+1, woolnet::pack_key(NULL, 0, 0)-1); break; default: printf("[wool client_handle(..) '%s' %02i] Unknown packtype recievied(0x%02x). Quit.\n", self->username, self->termn, buf[0]); return (void*)ERRNIMPL; } if (len<=0) { printf("[wool client_handle(..) '%s' %02i] Failed to receive rest of package\n", self->username, self->termn); return (void*)ERRNCARE; } switch (buf[0]) { case PACK_KEY: { int special, key; woolnet::pack_unkey(buf, &special, &key); if (special != 0) { printf("[wool client_handle(..) '%s' %02i << PACK_KEY] special!=0 not supprted\n", self->username, self->termn); continue; } //printf("key: (0x%02x) %c\n", key, key); printf("[wool main(..) '%s' %02i << PACK_KEY] 0x%02x key\n", self->username, self->termn, key); ppackage key_p; key_p.type = 'D'; key_p.reci = (char*)stuffpath.c_str(); struct { int datachannel, key, special; } packet; packet.datachannel = self->termn; packet.key = key; packet.special = special; key_p.d.data = &packet; key_p.d.len = sizeof(packet); // three integers kap.knock(key_p, NULL); //putchar(key); continue; } case PACK_CLOSE: { char *reason = new char[128]; woolnet::pack_unclose(buf, reason); printf("[wool main(..) '%s' %02i << PACK_CLOSE] reason: %s\n", self->username, self->termn, reason); return (void*)OKAY; } // default: // cannot get till here else it'd quit in the previous switch } } return (void*)OKAY;//hax }
extern "C" int keh_init(kap_t k, ppackage aux) { kap = k; kauxhdl = kaux_newhandle(k); kaux_setfuncs(kauxhdl, (mfunc_t*)funcs); kaux_setobj(kauxhdl, NULL); kaux_settyp(kauxhdl, NULL); ppackage woolfs = kap.knock(ppfuncs("::woolnet"), NULL); if (woolfs.type != 'd') return ERRNCARE; woolnet::serv_accept = (int (*)(woolnet_serv_t *, woolnet_clnt_t *, unsigned int *))(fsget((mfunc_t*)woolfs.d.data, "serv_accept")); woolnet::serv_listen = (woolnet_serv_t *(*)(int port)) fsget((mfunc_t*)woolfs.d.data, "serv_listen"); woolnet::serv_fd = (int (*)(woolnet_serv_t*)) fsget((mfunc_t*)woolfs.d.data, "serv_fd"); woolnet::serv_shut = (int (*)(woolnet_serv_t*)) fsget((mfunc_t*)woolfs.d.data, "serv_shut"); woolnet::clnt_connect = (woolnet_clnt_t *(*)(char*, int, char*, char*)) fsget((mfunc_t*)woolfs.d.data, "clnt_connect"); woolnet::clnt_fd = (int (*)(woolnet_clnt_t*)) fsget((mfunc_t*)woolfs.d.data, "clnt_fd"); woolnet::clnt_shut = (int (*)(woolnet_clnt_t*)) fsget((mfunc_t*)woolfs.d.data, "clnt_shut"); woolnet::prot_maxlen = (int(*)()) fsget((mfunc_t*)woolfs.d.data, "prot_maxlen"); woolnet::pack_clogin = (int(*)(unsigned char*, char[32], char[32])) fsget((mfunc_t*)woolfs.d.data, "pack_clogin"); woolnet::pack_close = (int(*)(unsigned char*, char[128])) fsget((mfunc_t*)woolfs.d.data, "pack_close"); woolnet::pack_key = (int(*)(unsigned char*, int, int)) fsget((mfunc_t*)woolfs.d.data, "pack_key"); woolnet::pack_slogin = (int(*)(unsigned char*, int, int)) fsget((mfunc_t*)woolfs.d.data, "pack_slogin"); woolnet::pack_unclogin = (int(*)(unsigned char*, char*, char*)) fsget((mfunc_t*)woolfs.d.data, "pack_unclogin"); woolnet::pack_unclose = (int(*)(unsigned char*, char*)) fsget((mfunc_t*)woolfs.d.data, "pack_unclose"); woolnet::pack_unkey = (int(*)(unsigned char*, int*, int*)) fsget((mfunc_t*)woolfs.d.data, "pack_unkey"); woolnet::pack_unslogin = (int(*)(unsigned char*, int*, int*)) fsget((mfunc_t*)woolfs.d.data, "pack_unslogin"); woolnet::wrap_cclose = (int(*)(woolnet_clnt_t*)) fsget((mfunc_t*)woolfs.d.data, "wrap_cclose"); woolnet::wrap_crecv = (int(*)(woolnet_clnt_t*, void*, size_t)) fsget((mfunc_t*)woolfs.d.data, "wrap_crecv"); woolnet::wrap_csend = (int(*)(woolnet_clnt_t*, void*, size_t)) fsget((mfunc_t*)woolfs.d.data, "wrap_csend"); woolnet::wrap_sclose = (int(*)(woolnet_serv_t*)) fsget((mfunc_t*)woolfs.d.data, "wrap_close"); woolnet::wrap_srecv = (int(*)(woolnet_serv_t*, void*, size_t)) fsget((mfunc_t*)woolfs.d.data, "wrap_srecv"); woolnet::wrap_ssend = (int(*)(woolnet_serv_t*, void*, size_t)) fsget((mfunc_t*)woolfs.d.data, "wrap_ssend"); ppackage nstuff_p = ppnstuff(NULL, "home", kaux_knockaux, kaux_newhandle(k)); k.knock(nstuff_p, NULL); return OKAY; }
/* Fillstyle interpreter- generates/refreshes a gropnode list */ g_error exec_fillstyle_inner(struct gropctxt *ctx,u16 state, u16 property) { g_error e; u32 fssize; /* Fillstyle size */ unsigned char *fs; /* Pointer to the actual fillstyle data */ unsigned char *p,*plimit; unsigned char op; int r,g,b; /* For color arithmetic */ struct widget *w; int stackframe = fsstkpos-4; /* Look up the fillstyle */ e = rdhandle((void**)&fs,PG_TYPE_FILLSTYLE,-1,theme_lookup(state,property)); errorcheck; if (!fs) { /* When our best just isn't good enough... */ if (property == PGTH_P_BACKDROP || property == PGTH_P_BORDER_FILL) return success; /* The default fillstyle, if no theme is loaded or no theme has defined the property*/ addgrop(ctx,PG_GROP_SETCOLOR); ctx->current->param[0] = VID(color_pgtohwr) (0x000000); switch (state) { case PGTH_O_BUTTON_ON: /* 2 borders */ addgropsz(ctx,PG_GROP_FRAME,ctx->r.x,ctx->r.y,ctx->r.w,ctx->r.h); ctx->r.x += 1; ctx->r.y += 1; ctx->r.w -= 2; ctx->r.h -= 2; default: /* 1 border */ addgropsz(ctx,PG_GROP_FRAME,ctx->r.x,ctx->r.y,ctx->r.w,ctx->r.h); ctx->r.x += 1; ctx->r.y += 1; ctx->r.w -= 2; ctx->r.h -= 2; case PGTH_O_LABEL_SCROLL: /* No border */ addgrop(ctx,PG_GROP_SETCOLOR); ctx->current->param[0] = VID(color_pgtohwr) (theme_lookup(state,PGTH_P_BGCOLOR)); addgropsz(ctx,PG_GROP_RECT,ctx->r.x,ctx->r.y,ctx->r.w,ctx->r.h); } return success; } /* Process the opcodes */ fssize = *(((u32 *)fs)++); p = fs; plimit = fs+fssize; while (p<plimit) { op = *(p++); /* These must occur in MSB to LSB order! (see constants.h) */ if (op & PGTH_OPSIMPLE_GROP) { /* 1-byte gropnode */ e = fsgrop(ctx,op & (PGTH_OPSIMPLE_GROP-1)); errorcheck; } else if (op & PGTH_OPSIMPLE_LITERAL) { /* 1-byte literal */ fsstack[fsstkpos++] = op & (PGTH_OPSIMPLE_LITERAL-1); } else if (op & PGTH_OPSIMPLE_CMDCODE) { /* Command code */ switch (op) { case PGTH_OPCMD_LONGLITERAL: if ((plimit-p)<4) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsstack[fsstkpos++] = NEXTLONG; p += 4; break; case PGTH_OPCMD_LONGGROP: if ((plimit-p)<2) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ e = fsgrop(ctx,NEXTSHORT); p += 2; errorcheck; break; case PGTH_OPCMD_LONGGET: if (plimit<=p) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ e = fsget(*(p++)+stackframe); errorcheck; break; case PGTH_OPCMD_LONGSET: if (plimit<=p) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ e = fsset(*(p++)+stackframe); errorcheck; break; case PGTH_OPCMD_PROPERTY: if ((plimit-p)<4) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsa = NEXTSHORT; p += 2; fsb = NEXTSHORT; p += 2; fsstack[fsstkpos++] = theme_lookup(fsa,fsb); #ifdef CONFIG_ANIMATION /* If it depends on time or randomness, turn on the animated flag in the divnode */ if ((fsb==PGTH_P_TICKS || fsb==PGTH_P_RANDOM) && ctx->owner) ctx->owner->flags |= DIVNODE_ANIMATED; #endif break; case PGTH_OPCMD_LOCALPROP: if ((plimit-p)<2) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsa = NEXTSHORT; p += 2; #ifdef DEBUG_THEME printf("Local theme lookup, property %d\n",(int)fsa); #endif fsstack[fsstkpos++] = theme_lookup(state,fsa); #ifdef CONFIG_ANIMATION /* If it depends on time or randomness, turn on the animated flag in the divnode */ if ((fsa==PGTH_P_TICKS || fsa==PGTH_P_RANDOM) && ctx->owner) ctx->owner->flags |= DIVNODE_ANIMATED; #endif break; case PGTH_OPCMD_PLUS: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa + fsb; break; case PGTH_OPCMD_MINUS: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa - fsb; break; case PGTH_OPCMD_MULTIPLY: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa * fsb; break; case PGTH_OPCMD_SHIFTL: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa << fsb; break; case PGTH_OPCMD_SHIFTR: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa >> fsb; break; case PGTH_OPCMD_OR: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa | fsb; break; case PGTH_OPCMD_AND: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa & fsb; break; case PGTH_OPCMD_EQ: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa == fsb; break; case PGTH_OPCMD_LT: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa < fsb; break; case PGTH_OPCMD_GT: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa > fsb; break; case PGTH_OPCMD_LOGICAL_OR: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa || fsb; break; case PGTH_OPCMD_LOGICAL_AND: e = fspopargs(); errorcheck; fsstack[fsstkpos++] = fsa && fsb; break; case PGTH_OPCMD_LOGICAL_NOT: fsstack[fsstkpos-1] = !fsstack[fsstkpos-1]; break; case PGTH_OPCMD_DIVIDE: e = fspopargs(); errorcheck; if (fsb) fsstack[fsstkpos++] = fsa / fsb; else fsstack[fsstkpos++] = 0xFFFFFFFF; /* limit of fsa/fsb as fsb approaches 0 */ break; case PGTH_OPCMD_COLORADD: e = fspopargs(); errorcheck; r = getred(fsa); g = getgreen(fsa); b = getblue(fsa); r += getred(fsb); g += getgreen(fsb); b += getblue(fsb); if (r>255) r = 255; if (g>255) g = 255; if (b>255) b = 255; fsstack[fsstkpos++] = mkcolor(r,g,b); break; case PGTH_OPCMD_COLORSUB: e = fspopargs(); errorcheck; r = getred(fsa); g = getgreen(fsa); b = getblue(fsa); r -= getred(fsb); g -= getgreen(fsb); b -= getblue(fsb); if (r<0) r = 0; if (g<0) g = 0; if (b<0) b = 0; fsstack[fsstkpos++] = mkcolor(r,g,b); break; case PGTH_OPCMD_COLORDIV: e = fspopargs(); errorcheck; r = getred(fsa); g = getgreen(fsa); b = getblue(fsa); r = getred(fsb) ? (r/getred(fsb)) : 0xFF; /* Avoid divide by zero */ g = getgreen(fsb) ? (g/getgreen(fsb)) : 0xFF; b = getred(fsb) ? (b/getblue(fsb)) : 0xFF; fsstack[fsstkpos++] = mkcolor(r,g,b); break; case PGTH_OPCMD_COLORMULT: e = fspopargs(); errorcheck; r = getred(fsa); g = getgreen(fsa); b = getblue(fsa); r *= getred(fsb); g *= getgreen(fsb); b *= getblue(fsb); if (r>255) r = 255; if (g>255) g = 255; if (b>255) b = 255; fsstack[fsstkpos++] = mkcolor(r,g,b); break; case PGTH_OPCMD_QUESTIONCOLON: if (fsstkpos<3) return mkerror(PG_ERRT_BADPARAM,88); /* Stack underflow */ fsstkpos -= 2; fsstack[fsstkpos-1] = fsstack[fsstkpos+1] ? fsstack[fsstkpos] : fsstack[fsstkpos-1]; break; case PGTH_OPCMD_WIDGET: if (ctx->owner && ctx->owner->owner) fsstack[fsstkpos++] = hlookup(ctx->owner->owner,NULL); else fsstack[fsstkpos++] = 0; break; case PGTH_OPCMD_TRAVERSEWGT: if (fsstkpos<3) return mkerror(PG_ERRT_BADPARAM,88); /* Stack underflow */ fsstkpos -= 2; e = rdhandle((void**)&w, PG_TYPE_WIDGET, -1, fsstack[fsstkpos+1]); errorcheck; if (w) fsstack[fsstkpos-1] = hlookup(widget_traverse(w,fsstack[fsstkpos],fsstack[fsstkpos-1]),NULL); else fsstack[fsstkpos-1] = 0; break; case PGTH_OPCMD_GETWIDGET: e = fspopargs(); errorcheck; e = rdhandle((void**)&w, PG_TYPE_WIDGET, -1, fsa); errorcheck; if (w) fsstack[fsstkpos++] = widget_get(w,fsb); else fsstack[fsstkpos++] = 0; break; case PGTH_OPCMD_CALL: if ((plimit-p)<4) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsa = NEXTSHORT; p += 2; fsb = NEXTSHORT; p += 2; e = exec_fillstyle_inner(ctx,fsa,fsb); errorcheck; break; case PGTH_OPCMD_LOCALCALL: if ((plimit-p)<2) return mkerror(PG_ERRT_BADPARAM,91); /* Truncated opcode */ fsb = NEXTSHORT; p += 2; e = exec_fillstyle_inner(ctx,state,fsb); errorcheck; break; case PGTH_OPCMD_EXTENDED: /* extended command */ op = *(p++); switch (op) { case PGTH_EXCMD_SKIP_IF: if (!fsstack[--fsstkpos]) { --fsstkpos; break; } /* else proceed to EXCMD_SKIP */ case PGTH_EXCMD_SKIP: p += (s32)fsstack[--fsstkpos]; break; } break; } } else if (op & PGTH_OPSIMPLE_GET) { /* 1-byte get */ e = fsget((op & (PGTH_OPSIMPLE_GET-1)) + stackframe); errorcheck; } else { /* 1-byte set */ e = fsset(op + stackframe); errorcheck; } #ifdef DEBUG_THEME /* trace */ printf("FILLSTYLE --- Op: 0x%02X Stk:",op); for (fsa=0;fsa<fsstkpos;fsa++) printf(" %d",(int)fsstack[fsa]); printf("\n"); #endif /* check for stack over/underflow */ if (fsstkpos<0) return mkerror(PG_ERRT_BADPARAM,88); /* Stack underflow */ if (fsstkpos>=FSSTACKSIZE) return mkerror(PG_ERRT_BADPARAM,89); /* Stack overflow */ }