/*** nht_internal_ErrorHandler - handle the printing of notice and error *** messages to the error stream for the client, if the client has such *** an error stream (which is how this is called). ***/ int nht_internal_ErrorHandler(pNhtSessionData nsess, pFile net_conn) { pXString errmsg; char sbuf[256]; /** Wait on the errors semaphore **/ syGetSem(nsess->Errors, 1, 0); /** Grab one error **/ errmsg = (pXString)(nsess->ErrorList.Items[0]); xaRemoveItem(&nsess->ErrorList, 0); /** Format the error and print it as HTML. **/ sprintf(sbuf,"HTTP/1.0 200 OK\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<HTML><BODY><PRE>"); fdWrite(net_conn,sbuf,strlen(sbuf),0,0); fdWrite(net_conn,errmsg->String,strlen(errmsg->String),0,0); sprintf(sbuf,"</PRE></BODY></HTML>\r\n"); fdWrite(net_conn,sbuf,strlen(sbuf),0,0); /** Discard the string **/ xsDeInit(errmsg); nmFree(errmsg,sizeof(XString)); return 0; }
/*** mssPrintError - prints the current error stack out to the given file *** descriptor. ***/ int mssPrintError(pFile fd) { int i; pMtSession s; char sbuf[200]; /** Get session. **/ s = (pMtSession)thGetParam(NULL,"mss"); if (!s) return -1; /** Print the error stack. **/ snprintf(sbuf,200,"ERROR - Session By Username [%s]\r\n",s->UserName); fdWrite(fd,sbuf,strlen(sbuf),0,0); for(i=s->ErrList.nItems-1;i>=0;i--) { snprintf(sbuf,200,"--- %s\r\n",(char*)(s->ErrList.Items[i])); fdWrite(fd,sbuf,strlen(sbuf),0,0); } return 0; }
/*** shlWrite - Write data to the shell's stdin ***/ int shlWrite(void* inf_v, char* buffer, int cnt, int offset, int flags, pObjTrxTree* oxt) { pShlData inf = SHL(inf_v); int i=-1; int waitret; int retval; if(SHELL_DEBUG & SHELL_DEBUG_IO) printf("%s -- %p, %p, %i, %i, %i, %p\n",__FUNCTION__,inf_v,buffer,cnt,offset,flags,oxt); /** launch the program if it's not running already **/ if(inf->shell_pid == -1) if(shl_internal_Launch(inf) < 0) return -1; /** seek is _not_ allowed (obviously) **/ if(flags & FD_U_SEEK && offset!=inf->curWrite) return -1; /** can't write to a dead child :) **/ if(!inf->shell_pid) return -1; while(i < 0) { i=fdWrite(inf->shell_fd,buffer,cnt,0,flags & ~FD_U_SEEK); if(i < 0) { /** user doesn;t want us to block **/ if(flags & FD_U_NOBLOCK) return -1; /** check and make sure the child process is still alive... **/ shl_internal_UpdateStatus(inf); if(inf->shell_pid>0) { /** child is alive, it just isn't ready for data yet -- wait a bit **/ thSleep(200); } else if(inf->shell_pid==0) { /** child died :( **/ return -1; } } } inf->curWrite+=i; return i; }
static CFIndex fileWrite(CFWriteStreamRef stream, const UInt8 *buffer, CFIndex bufferLength, CFStreamError *errorCode, void *info) { _CFFileStreamContext *fileStream = ((_CFFileStreamContext *)info); CFIndex result = fdWrite(fileStream->fd, buffer, bufferLength, errorCode); #ifdef REAL_FILE_SCHEDULING if (__CFBitIsSet(fileStream->flags, SCHEDULE_AFTER_WRITE)) { __CFBitClear(fileStream->flags, SCHEDULE_AFTER_WRITE); if (fileStream->rlInfo.cffd) { CFFileDescriptorEnableCallBacks(fileStream->rlInfo.cffd, kCFFileDescriptorWriteCallBack); } } #else if (fileStream->scheduled > 0) { CFWriteStreamSignalEvent(stream, kCFStreamEventCanAcceptBytes, NULL); } #endif return result; }
struct gretTap *gretTapConnect(char *addr, int position, unsigned int typeMask) { struct sockaddr_in adr_srvr; /* AF_INET */ struct hostent *hp; struct gretTap *retval; int numrec, firstret[2]; unsigned int outbuf[2]; int numsent; gretTapClientError = GTC_NOERROR; retval = (struct gretTap *) calloc(1, sizeof(struct gretTap)); retval->connectionMutex = epicsMutexCreate(); if (!retval->connectionMutex) { gretTapClientError = GTC_M_CREATE; free(retval); return 0; } memset(&adr_srvr,0,sizeof adr_srvr); adr_srvr.sin_family = AF_INET; adr_srvr.sin_port = htons(GRETTAP_PORT); hp = gethostbyname(addr); if (!hp) { gretTapClientError = GTC_HOSTNAME; free(retval); return 0; } adr_srvr.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *) (hp->h_addr_list[0])))); if ( adr_srvr.sin_addr.s_addr == INADDR_NONE ) { gretTapClientError = GTC_INADDR; free(retval); return 0; } retval->inSock = socket(AF_INET, SOCK_STREAM, 0); if (retval->inSock == -1) { gretTapClientError = GTC_INSOCK; free(retval); return 0; } if (connect(retval->inSock, (struct sockaddr *)&adr_srvr, sizeof(adr_srvr)) < 0) { gretTapClientError = GTC_TAPCONN; close(retval->inSock); free(retval); return 0; } /* send two ints: type and position */ outbuf[0] = typeMask; outbuf[1] = position; numsent = fdWrite(retval->inSock, outbuf, 2 * sizeof(unsigned int)); if (numsent != 2 * sizeof(unsigned int)){ gretTapClientError = GTC_INITWRITE; close(retval->inSock); free(retval); return 0; } numrec = fdRead(retval->inSock, firstret, TAP_HEADER_LEN); if (numrec != TAP_HEADER_LEN) { gretTapClientError = GTC_INITREAD; close(retval->inSock); free(retval); return 0; } if (firstret[0] != TAP_ACK) { switch (firstret[0]) { case TAP_NOT_FOUND: gretTapClientError = GTC_NOT_FOUND; break; case TAP_NOT_RUNNING: gretTapClientError = GTC_NOT_RUNNING; break; default: gretTapClientError = GTC_UNKNOWN; } close(retval->inSock); free(retval); return 0; } return (retval); }
struct GEBData *gretTapData(struct gretTap *tap, int nreq, float timeout) { int numrec, i; int outbuf[2]; int firstret[2] = {0,0}; struct GEBData *retval=0, *inbuf = 0; gretTapClientError = GTC_NOERROR; if (tap->inSock == 0) { gretTapClientError = GTC_CLOSED; return 0; } outbuf[0] = nreq; if (timeout < 0) { outbuf[1] = 0; } else { outbuf[1] = (int)(timeout * 1000.0); } if (fdWrite(tap->inSock, outbuf, TAP_HEADER_LEN) != TAP_HEADER_LEN) { gretTapClientError = GTC_HEADER_WRITE; close(tap->inSock); tap->inSock = 0; return 0; } numrec = fdRead(tap->inSock, firstret, TAP_HEADER_LEN); if (numrec != TAP_HEADER_LEN) { if (numrec) { gretTapClientError = GTC_HEADER_READ; } else { gretTapClientError = GTC_CLOSED; } close(tap->inSock); tap->inSock = 0; return 0; } if (firstret[0] == TAP_TIMEOUT) { gretTapClientError = GTC_TIMEOUT; } if (firstret[0] == TAP_NOT_RUNNING) { gretTapClientError = GTC_NOT_RUNNING; } if (firstret[1] == 0) { return 0; } for (i = 0; i < firstret[1]; i++) { if (!retval) { inbuf = (struct GEBData *) calloc(1, sizeof(struct GEBData)); retval = inbuf; } else { inbuf->next = (struct GEBData *) calloc(1, sizeof(struct GEBData)); inbuf = inbuf->next; } numrec = fdRead(tap->inSock, inbuf, GEB_HEADER_BYTES); if (numrec != GEB_HEADER_BYTES) { gretTapClientError = GTC_GEB_HEADER; gretTapDataFree(retval); close(tap->inSock); tap->inSock = 0; } #if(1) if (inbuf == NULL) { printf("inbuf=0x%p, return GTC_LEN_0\n",inbuf); fflush(stdout); gretTapClientError = GTC_LEN_0; inbuf->next = (struct GEBData *) calloc(1, sizeof(struct GEBData)); inbuf = inbuf->next; continue; } #endif if (inbuf->length == 0) { gretTapClientError = GTC_LEN_0; inbuf->next = (struct GEBData *) calloc(1, sizeof(struct GEBData)); inbuf = inbuf->next; continue; } inbuf->payload = calloc(1, inbuf->length); if (!inbuf->payload) { /* if length rediculous this could happen ? */ gretTapClientError = GTC_LEN_HUGE; inbuf->next = (struct GEBData *) calloc(1, sizeof(struct GEBData)); inbuf = inbuf->next; continue; } numrec = fdRead(tap->inSock, inbuf->payload, inbuf->length); if (numrec != inbuf->length) { gretTapClientError = GTC_DATA_READ; gretTapDataFree(retval); close(tap->inSock); tap->inSock = 0; } } return retval; }
/*** nht_internal_ConnHandler - manages a single incoming HTTP connection *** and processes the connection's request. ***/ void nht_internal_ConnHandler(void* conn_v) { pFile conn = (pFile)conn_v; pLxSession s; int toktype; char method[16]; char url[256]; char sbuf[160]; char auth[160] = ""; char cookie[160] = ""; char dest[256] = ""; char hdr[64]; char* msg; char* ptr; Exception e; char* usrname; char* passwd; pNhtSessionData nsess = NULL; void* mts; int cnt; pStruct url_inf,find_inf; int size=-1; /*printf("ConnHandler called, stack ptr = %8.8X\n",&s);*/ /** Set the thread's name **/ thSetName(NULL,"HTTP Connection Handler"); /** Handle parsing exceptions... **/ Catch(e) { mlxCloseSession(s); mssError(1,"NHT","Failed to parse HTTP request, exiting thread."); sprintf(sbuf,"HTTP/1.0 400 Request Error\n\n%s\n",msg); fdWrite(conn,sbuf,strlen(sbuf),0,0); netCloseTCP(conn,1000,0); thExit(); } /** Initialize a lexical analyzer session... **/ s = mlxOpenSession(conn, MLX_F_NODISCARD | MLX_F_DASHKW | MLX_F_ICASE | MLX_F_EOL | MLX_F_EOF); /** Read in the main request header. **/ if (mlxNextToken(s) != MLX_TOK_KEYWORD) msg="Invalid method syntax",Throw(e); mlxCopyToken(s,method,16); mlxSetOptions(s,MLX_F_IFSONLY); if (mlxNextToken(s) != MLX_TOK_STRING) msg="Invalid url syntax",Throw(e); strcpy(url,mlxStringVal(s,NULL)); mlxNextToken(s); if (mlxNextToken(s) != MLX_TOK_EOL) msg="Expected EOL after version",Throw(e); mlxUnsetOptions(s,MLX_F_IFSONLY); /** Read in the various header parameters. **/ while((toktype = mlxNextToken(s)) != MLX_TOK_EOL) { if (toktype == MLX_TOK_EOF) break; if (toktype != MLX_TOK_KEYWORD) msg="Expected HTTP header item",Throw(e); /*ptr = mlxStringVal(s,NULL);*/ mlxCopyToken(s,hdr,64); if (mlxNextToken(s) != MLX_TOK_COLON) msg="Expected : after HTTP header",Throw(e); /** Got a header item. Pick an appropriate type. **/ if (!strcmp(hdr,"destination")) { /** Copy next IFS-only token to destination value **/ mlxSetOptions(s,MLX_F_IFSONLY); if (mlxNextToken(s) != MLX_TOK_STRING) msg="Expected filename after dest.",Throw(e); mlxCopyToken(s,dest,256); mlxUnsetOptions(s,MLX_F_IFSONLY); if (mlxNextToken(s) != MLX_TOK_EOF) msg="Expected EOL after filename",Throw(e); } else if (!strcmp(hdr,"authorization")) { /** Get 'Basic' then the auth string in base64 **/ mlxSetOptions(s,MLX_F_IFSONLY); if (mlxNextToken(s) != MLX_TOK_STRING) msg="Expected auth type",Throw(e); ptr = mlxStringVal(s,NULL); if (strcasecmp(ptr,"basic")) msg="Can only handle BASIC auth",Throw(e); if (mlxNextToken(s) != MLX_TOK_STRING) msg="Expected auth after Basic",Throw(e); nht_internal_Decode64(auth,mlxStringVal(s,NULL),160); mlxUnsetOptions(s,MLX_F_IFSONLY); if (mlxNextToken(s) != MLX_TOK_EOL) msg="Expected EOL after auth",Throw(e); } else if (!strcmp(hdr,"cookie")) { /** Copy whole thing. **/ mlxSetOptions(s,MLX_F_IFSONLY); if (mlxNextToken(s) != MLX_TOK_STRING) msg="Expected str after Cookie:",Throw(e); strcpy(cookie, mlxStringVal(s,NULL)); while(toktype = mlxNextToken(s)) { if (toktype == MLX_TOK_EOL || toktype == MLX_TOK_ERROR) break; } mlxUnsetOptions(s,MLX_F_IFSONLY); } else if (!strcmp(hdr,"content-length")) { /** Get the integer. **/ if (mlxNextToken(s) != MLX_TOK_INTEGER) msg="Expected content-length",Throw(e); size = mlxIntVal(s); if (mlxNextToken(s) != MLX_TOK_EOL) msg="Expected EOL after length",Throw(e); } else { /** Don't know what it is. Just skip to end-of-line. **/ mlxSetOptions(s,MLX_F_IFSONLY); while(toktype = mlxNextToken(s)) { if (toktype == MLX_TOK_EOL || toktype == MLX_TOK_ERROR) break; } mlxUnsetOptions(s,MLX_F_IFSONLY); } } /** Ok, done parsing. Close the lexer session. **/ mlxCloseSession(s); /** Did client send authentication? **/ if (!*auth) { sprintf(sbuf,"HTTP/1.0 401 Unauthorized\r\n" "Server: Centrallix/1.0\r\n" "WWW-Authenticate: Basic realm=\"Centrallix\"\r\n" "\r\n" "<H1>Unauthorized</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); netCloseTCP(conn,1000,0); thExit(); } /** Got authentication. Parse the auth string. **/ usrname = strtok(auth,":"); if (usrname) passwd = strtok(NULL,"\r\n"); if (!usrname || !passwd) { sprintf(sbuf,"HTTP/1.0 400 Bad Request\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>400 Bad Request</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); netCloseTCP(conn,1000,0); thExit(); } /** Check for a cookie -- if one, try to resume a session. **/ if (*cookie) { nsess = (pNhtSessionData)xhLookup(&(NHT.CookieSessions), cookie); if (nsess) { if (strcmp(nsess->Username,usrname) || strcmp(passwd,nsess->Password)) { sprintf(sbuf,"HTTP/1.0 401 Unauthorized\r\n" "Server: Centrallix/1.0\r\n" "WWW-Authenticate: Basic realm=\"Centrallix\"\r\n" "\r\n" "<H1>Unauthorized</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); netCloseTCP(conn,1000,0); thExit(); } thSetParam(NULL,"mss",nsess->Session); thSetUserID(NULL,((pMtSession)(nsess->Session))->UserID); } } /** No cookie or no session for the given cookie? **/ if (!nsess) { if (mssAuthenticate(usrname, passwd) < 0) { sprintf(sbuf,"HTTP/1.0 401 Unauthorized\r\n" "Server: Centrallix/1.0\r\n" "WWW-Authenticate: Basic realm=\"Centrallix\"\r\n" "\r\n" "<H1>Unauthorized</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); netCloseTCP(conn,1000,0); thExit(); } nsess = (pNhtSessionData)nmSysMalloc(sizeof(NhtSessionData)); strcpy(nsess->Username, mssUserName()); strcpy(nsess->Password, mssPassword()); nsess->Session = thGetParam(NULL,"mss"); nsess->IsNewCookie = 1; nsess->ObjSess = objOpenSession("/"); nsess->Errors = syCreateSem(0,0); xaInit(&nsess->ErrorList,16); nht_internal_CreateCookie(nsess->Cookie); xhAdd(&(NHT.CookieSessions), nsess->Cookie, (void*)nsess); xaAddItem(&(NHT.Sessions), (void*)nsess); } /** Parse out the requested url **/ url_inf = nht_internal_ParseURL(url); if (!url_inf) { sprintf(sbuf,"HTTP/1.0 500 Internal Server Error\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>500 Internal Server Error</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); netCloseTCP(conn,1000,0); } /** If the method was GET and an ls__method was specified, use that method **/ if (!strcmp(method,"get") && (find_inf=stLookup_ne(url_inf,"ls__method"))) { if (!strcasecmp(find_inf->StrVal,"get")) { nht_internal_GET(nsess,conn,url_inf); } else if (!strcasecmp(find_inf->StrVal,"copy")) { find_inf = stLookup_ne(url_inf,"ls__destination"); if (!find_inf || !(find_inf->StrVal)) { sprintf(sbuf,"HTTP/1.0 400 Method Error\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>400 Method Error - include ls__destination for copy</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); } else { ptr = find_inf->StrVal; nht_internal_COPY(nsess,conn,url_inf, ptr); } } else if (!strcasecmp(find_inf->StrVal,"put")) { find_inf = stLookup_ne(url_inf,"ls__content"); if (!find_inf || !(find_inf->StrVal)) { sprintf(sbuf,"HTTP/1.0 400 Method Error\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>400 Method Error - include ls__content for put</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); } else { ptr = find_inf->StrVal; size = strlen(ptr); nht_internal_PUT(nsess,conn,url_inf,size,ptr); } } } else { /** Which method was used? **/ if (!strcmp(method,"get")) { nht_internal_GET(nsess,conn,url_inf); } else if (!strcmp(method,"put")) { nht_internal_PUT(nsess,conn,url_inf,size,NULL); } else if (!strcmp(method,"copy")) { nht_internal_COPY(nsess,conn,url_inf,dest); } else { sprintf(sbuf,"HTTP/1.0 501 Not Implemented\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>501 Method Not Implemented</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); /*netCloseTCP(conn,1000,0);*/ } } /** Close and exit. **/ if (url_inf) stFreeInf(url_inf); netCloseTCP(conn,1000,0); thExit(); return; }
/*** nht_internal_COPY - implements the COPY centrallix-http method. ***/ int nht_internal_COPY(pNhtSessionData nsess, pFile conn, pStruct url_inf, char* dest) { pObject source_obj,target_obj; int size; int already_exist = 0; char sbuf[256]; int cnt,rcnt,wcnt; /** Ok, open the source object here. **/ source_obj = objOpen(nsess->ObjSess, url_inf->StrVal, O_RDONLY, 0600, "text/html"); if (!source_obj) { sprintf(sbuf,"HTTP/1.0 404 Not Found\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>404 Source Not Found</H1><HR><PRE>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); mssPrintError(conn); netCloseTCP(conn,1000,0); thExit(); } /** Do we need to set params as a part of the open? **/ nht_internal_CkParams(url_inf, target_obj); /** Get the size of the original object, if possible **/ if (objGetAttrValue(source_obj,"size",&size) != 0) size = -1; /** Try to open the new object read-only to see if it exists... **/ target_obj = objOpen(nsess->ObjSess, dest, O_RDONLY, 0600, "text/html"); if (target_obj) { objClose(target_obj); already_exist = 1; } /** Ok, open the target object for keeps now. **/ target_obj = objOpen(nsess->ObjSess, dest, O_WRONLY | O_TRUNC | O_CREAT, 0600, "text/html"); if (!target_obj) { sprintf(sbuf,"HTTP/1.0 404 Not Found\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>404 Target Not Found</H1>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); netCloseTCP(conn,1000,0); thExit(); } /** Set the size of the new document... **/ if (size >= 0) objSetAttrValue(target_obj, "size", &size); /** Do the copy operation. **/ while((rcnt = objRead(source_obj, sbuf, 256, 0,0)) > 0) { while(rcnt > 0) { wcnt = objWrite(target_obj, sbuf, rcnt, 0,0); if (wcnt <= 0) break; rcnt -= wcnt; } } /** Close the objects **/ objClose(source_obj); objClose(target_obj); /** Ok, issue the HTTP header for this one. **/ if (nsess->IsNewCookie) { if (already_exist) { sprintf(sbuf,"HTTP/1.0 200 OK\r\n" "Server: Centrallix/1.0\r\n" "Set-Cookie: %s\r\n" "\r\n" "%s\r\n", nsess->Cookie, dest); } else { sprintf(sbuf,"HTTP/1.0 201 Created\r\n" "Server: Centrallix/1.0\r\n" "Set-Cookie: %s\r\n" "\r\n" "%s\r\n", nsess->Cookie, dest); } nsess->IsNewCookie = 0; } else { if (already_exist) { sprintf(sbuf,"HTTP/1.0 200 OK\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "%s\r\n", dest); } else { sprintf(sbuf,"HTTP/1.0 201 Created\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "%s\r\n", dest); } } fdWrite(conn,sbuf,strlen(sbuf),0,0); return 0; }
/*** nht_internal_PUT - implements the PUT HTTP method. Set content_buf to *** data to write, otherwise it will be read from the connection if content_buf *** is NULL. ***/ int nht_internal_PUT(pNhtSessionData nsess, pFile conn, pStruct url_inf, int size, char* content_buf) { pObject target_obj; char sbuf[160]; int rcnt,wcnt; int type,i,v; pStruct sub_inf; int already_exist=0; /** See if the object already exists. **/ target_obj = objOpen(nsess->ObjSess, url_inf->StrVal, O_RDONLY, 0600, "text/html"); if (target_obj) { objClose(target_obj); already_exist = 1; } /** Ok, open the object here. **/ target_obj = objOpen(nsess->ObjSess, url_inf->StrVal, O_WRONLY | O_CREAT | O_TRUNC, 0600, "text/html"); if (!target_obj) { sprintf(sbuf,"HTTP/1.0 404 Not Found\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>404 Not Found</H1><HR><PRE>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); mssPrintError(conn); netCloseTCP(conn,1000,0); thExit(); } /** OK, we're ready. Send the 100 Continue message. **/ /*sprintf(sbuf,"HTTP/1.1 100 Continue\r\n" "Server: Centrallix/1.0\r\n" "\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0);*/ /** If size specified, set the size. **/ if (size != -1) objSetAttrValue(target_obj, "size", &size); /** Set any attributes specified in the url inf **/ for(i=0;i<url_inf->nSubInf;i++) { sub_inf = url_inf->SubInf[i]; type = objGetAttrType(target_obj, sub_inf->Name); if (type == DATA_T_INTEGER) { v = strtoi(sub_inf->StrVal,NULL,10); objSetAttrValue(target_obj, sub_inf->Name, &v); } else if (type == DATA_T_STRING) { objSetAttrValue(target_obj, sub_inf->Name, &(sub_inf->StrVal)); } } /** If content_buf, write that else write from the connection. **/ if (content_buf) { while(size != 0) { rcnt = (size>1024)?1024:size; objWrite(target_obj, content_buf, rcnt, 0,0); size -= rcnt; content_buf += rcnt; } } else { /** Ok, read from the connection, either until size bytes or until EOF. **/ while(size != 0 && (rcnt=fdRead(conn,sbuf,160,0,0)) > 0) { if (size > 0) { size -= rcnt; if (size < 0) { rcnt += size; size = 0; } } if (objWrite(target_obj, sbuf, rcnt, 0,0) < 0) break; } } /** Close the object. **/ objClose(target_obj); /** Ok, issue the HTTP header for this one. **/ if (nsess->IsNewCookie) { if (already_exist) { sprintf(sbuf,"HTTP/1.0 200 OK\r\n" "Server: Centrallix/1.0\r\n" "Set-Cookie: %s\r\n" "\r\n" "%s\r\n", nsess->Cookie, url_inf->StrVal); } else { sprintf(sbuf,"HTTP/1.0 201 Created\r\n" "Server: Centrallix/1.0\r\n" "Set-Cookie: %s\r\n" "\r\n" "%s\r\n", nsess->Cookie, url_inf->StrVal); } nsess->IsNewCookie = 0; } else { if (already_exist) { sprintf(sbuf,"HTTP/1.0 200 OK\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "%s\r\n", url_inf->StrVal); } else { sprintf(sbuf,"HTTP/1.0 201 Created\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "%s\r\n", url_inf->StrVal); } } fdWrite(conn,sbuf,strlen(sbuf),0,0); return 0; }
/*** nht_internal_GET - handle the HTTP GET method, reading a document or *** attribute list, etc. ***/ int nht_internal_GET(pNhtSessionData nsess, pFile conn, pStruct url_inf) { char sbuf[256]; int cnt; pStruct find_inf; pObjQuery query; char* dptr; char* ptr; char* aptr; pObject target_obj, sub_obj; char* bufptr; /*printf("GET called, stack ptr = %8.8X\n",&cnt);*/ /** If we're opening the "errorstream", pass of processing to err handler **/ if (!strncmp(url_inf->StrVal,"/errorstream",12)) { return nht_internal_ErrorHandler(nsess, conn); } /** Ok, open the object here. **/ target_obj = objOpen(nsess->ObjSess, url_inf->StrVal, O_RDONLY, 0600, "text/html"); if (!target_obj) { nht_internal_GenerateError(nsess); sprintf(sbuf,"HTTP/1.0 404 Not Found\r\n" "Server: Centrallix/1.0\r\n" "\r\n" "<H1>404 Not Found</H1><HR><PRE>\r\n"); fdWrite(conn,sbuf,strlen(sbuf),0,0); mssPrintError(conn); netCloseTCP(conn,1000,0); thExit(); } /** Do we need to set params as a part of the open? **/ nht_internal_CkParams(url_inf, target_obj); /** Ok, issue the HTTP header for this one. **/ if (nsess->IsNewCookie) { sprintf(sbuf,"HTTP/1.0 200 OK\r\n" "Server: Centrallix/1.0\r\n" "Set-Cookie: %s\r\n" "\r\n", nsess->Cookie); nsess->IsNewCookie = 0; } else { sprintf(sbuf,"HTTP/1.0 200 OK\r\n" "Server: Centrallix/1.0\r\n" "\r\n"); } fdWrite(conn,sbuf,strlen(sbuf),0,0); /** Check GET mode. **/ find_inf = stLookup_ne(url_inf,"ls__mode"); /** GET CONTENT mode. **/ if (!find_inf || !strcmp(find_inf->StrVal, "content")) { /** Check the object type. **/ objGetAttrValue(target_obj, "content_type", &ptr); if (!strcmp(ptr,"widget/page") || !strcmp(ptr,"widget/frameset")) { /*fdSetOptions(conn, FD_UF_WRBUF);*/ htrRender(conn, target_obj); } else { bufptr = (char*)nmMalloc(4096); while((cnt=objRead(target_obj,bufptr,4096,0,0)) > 0) { fdWrite(conn,bufptr,cnt,0,FD_U_PACKET); } if (cnt < 0) { mssError(0,"NHT","Incomplete read of object's content"); nht_internal_GenerateError(nsess); } nmFree(bufptr, 4096); } } /** GET DIRECTORY LISTING mode. **/ else if (!strcmp(find_inf->StrVal,"list")) { query = objOpenQuery(target_obj,"",NULL,NULL,NULL); if (query) { sprintf(sbuf,"<HTML><HEAD><META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\"></HEAD><BODY><TT><A HREF=%s/..>..</A><BR>\n",url_inf->StrVal); fdWrite(conn,sbuf,strlen(sbuf),0,0); dptr = url_inf->StrVal; while(*dptr && *dptr == '/' && dptr[1] == '/') dptr++; while(sub_obj = objQueryFetch(query,O_RDONLY)) { objGetAttrValue(sub_obj, "name", &ptr); objGetAttrValue(sub_obj, "annotation", &aptr); sprintf(sbuf,"<A HREF=%s%s%s TARGET='%s'>%s</A><BR>\n",dptr, (dptr[0]=='/' && dptr[1]=='\0')?"":"/",ptr,ptr,aptr); fdWrite(conn,sbuf,strlen(sbuf),0,0); objClose(sub_obj); } objQueryClose(query); } else { nht_internal_GenerateError(nsess); } } /** GET METHOD LIST mode. **/ else if (!strcmp(find_inf->StrVal,"methods")) { } /** GET ATTRIBUTE-VALUE LIST mode. **/ else if (!strcmp(find_inf->StrVal,"attr")) { } /** Close the objectsystem entry. **/ objClose(target_obj); return 0; }
/*** uxpWrite - write to a new print job. Each time this driver is opened *** and written to, it spools a new print job. ***/ int uxpWrite(void* inf_v, char* buffer, int cnt, int offset, int flags, pObjTrxTree* oxt) { pUxpData inf = UXP(inf_v); int rval; char* spooldir = NULL; char* type = NULL; struct stat fileinfo; int start_filter = 0; int saved_errno; /** Start the filter process? **/ if (!inf->SpoolFileFD && !inf->MasterFD) { start_filter = 1; } /** Ok, need to create a new print job? **/ if (inf->SpoolFileFD == NULL) { /** Get spool dir. **/ stAttrValue(stLookup(inf->Node->Data,"spool_directory"), NULL, &spooldir, 0); if (!spooldir) { mssError(1,"UXP","Spool directory not specified in node object"); return -1; } /** Generate a spool file name **/ TRY_SPOOL_AGAIN: do { sprintf(inf->SpoolPathname,"%s/%8.8d.job",spooldir,UXP_INF.SpoolCnt++); } while (lstat(inf->SpoolPathname, &fileinfo) == 0); /** Open the spool file **/ inf->SpoolFileFD = fdOpen(inf->SpoolPathname, O_WRONLY | O_CREAT | O_EXCL, 0600); if (!inf->SpoolFileFD) { /** oops - race condition, someone else got it, try again **/ saved_errno = errno; if (lstat(inf->SpoolPathname, &fileinfo) == 0) goto TRY_SPOOL_AGAIN; /** Oh well, can't open the thing. **/ /** Shouldn't be writing to errno, but mssErrorErrno wants it... sigh... **/ errno = saved_errno; mssErrorErrno(1,"UXP","Could not open spool file"); return -1; } } /** Ok, delayed start of filter process to wait until spoofile-fd is open **/ if (start_filter) { stAttrValue(stLookup(inf->Node->Data,"type"), NULL, &type, 0); if (type && strcmp(type, inf->ReqType) && !strcmp(inf->ReqType,"text/html")) { uxp_internal_StartFilter(inf); } } /** Need to filter the data? **/ if (inf->MasterFD) { rval = fdWrite(inf->MasterFD, buffer, cnt, offset, flags); } else { /** Write to the spool file. **/ rval = fdWrite(inf->SpoolFileFD, buffer, cnt, offset, flags); } return rval; }
void start(void* v) { char enc_pass[64]; char salt[MSS_SALT_SIZE + 1]; char passwd_line[128]; XString passwd_contents; pFile passwd_file; char buf[256]; int len; int offset; int pos; int uname_len; int found_user; size_t found_len; char* nlptr; char* ptr; cxssInitialize(); /** No file specified? **/ if (!CXPASSWD.PasswdFile[0]) { puts("no passwd file specified (use option -f)."); exit(1); } /** User asked us to read password from stdin? **/ if (CXPASSWD.ReadStdin) { fgets(CXPASSWD.Password, sizeof(CXPASSWD.Password), stdin); if (strchr(CXPASSWD.Password, '\n')) { *strchr(CXPASSWD.Password, '\n') = '\0'; } } /** Now get username and/or password if not supplied on command line **/ if (!CXPASSWD.UserName[0]) { ptr = readline("Username: "******"Password: "******"could not generate random bytes for password salt."); exit(1); } /** Generate encrypted credential **/ if (mssGenCred(salt, MSS_SALT_SIZE, CXPASSWD.Password, enc_pass, sizeof(enc_pass)) < 0) { puts("could not generate encrypted password."); exit(1); } /** Generate our password file line **/ snprintf(passwd_line, sizeof(passwd_line), "%s:%s\n", CXPASSWD.UserName, enc_pass); /** Open the password file **/ passwd_file = fdOpen(CXPASSWD.PasswdFile, O_RDWR | O_CREAT, 0600); if (!passwd_file) { puts("could not open passwd file."); exit(1); } /** Read it into the xstring **/ xsInit(&passwd_contents); while((len = fdRead(passwd_file, buf, sizeof(buf), 0, 0)) > 0) { xsConcatenate(&passwd_contents, buf, len); } fdClose(passwd_file, 0); /** Do we already have this user? **/ uname_len = strlen(CXPASSWD.UserName); offset = 0; found_user = -1; while((pos = xsFind(&passwd_contents, CXPASSWD.UserName, uname_len, offset)) >= 0) { if ((pos == 0 || xsString(&passwd_contents)[pos-1] == '\n') && xsString(&passwd_contents)[pos+uname_len] == ':') { /** Found it **/ found_user = pos; found_len = strlen(xsString(&passwd_contents)+pos); if ((nlptr = strchr(xsString(&passwd_contents)+pos, '\n')) != NULL) found_len = (nlptr - (xsString(&passwd_contents)+pos)) + 1; break; } offset = pos+1; } /** Replace if found, otherwise add the new user **/ if (found_user >= 0) xsSubst(&passwd_contents, found_user, found_len, passwd_line, strlen(passwd_line)); else xsConcatenate(&passwd_contents, passwd_line, strlen(passwd_line)); /** Rewrite the entire file **/ passwd_file = fdOpen(CXPASSWD.PasswdFile, O_RDWR | O_CREAT | O_TRUNC, 0600); if (!passwd_file) { puts("could not open password file to write to it."); exit(1); } if (fdWrite(passwd_file, xsString(&passwd_contents), strlen(xsString(&passwd_contents)), 0, FD_U_SEEK | FD_U_PACKET) != strlen(xsString(&passwd_contents))) { puts("could not re-write new password file."); exit(1); } /** Close the file **/ fdClose(passwd_file, 0); exit(0); }