static int fnet_inet_pton_ip6( const char *str, fnet_ip6_addr_t *addr ) { const char xdigits_l[] = "0123456789abcdef"; const char xdigits_u[] = "0123456789ABCDEF"; unsigned char tmp[sizeof(*addr)]; unsigned char *tp; unsigned char *endp; unsigned char *colonp; const char *xdigits; int ch; int seen_xdigits; unsigned int val; fnet_memset_zero((tp = tmp), sizeof(*addr)); endp = tp + sizeof(*addr); colonp = FNET_NULL; /* Leading :: */ if (*str == ':') if (*++str != ':') goto ERROR; seen_xdigits = 0; val = 0; while (((ch = *str++) != '\0') && (ch != '%')) { const char *pch; if ((pch = fnet_strchr((xdigits = xdigits_l), ch)) == FNET_NULL) pch = fnet_strchr((xdigits = xdigits_u), ch); if (pch != FNET_NULL) { val <<= 4; val |= (pch - xdigits); if (++seen_xdigits > 4) goto ERROR; continue; } if (ch == ':') { if (!seen_xdigits) { if (colonp) goto ERROR; colonp = tp; continue; } else if (*str == '\0') { goto ERROR; } else {} if (tp + 2 > endp) goto ERROR; *tp++ = (unsigned char) ((val >> 8) & 0xff); *tp++ = (unsigned char) (val & 0xff); seen_xdigits = 0; val = 0; continue; } goto ERROR; } if (seen_xdigits) { if (tp + 2 > endp) goto ERROR; *tp++ = (unsigned char) ((val >> 8) & 0xff); *tp++ = (unsigned char) (val & 0xff); } if (colonp != FNET_NULL) { /* * Shift. */ const int n = tp - colonp; int i; if (tp == endp) goto ERROR; for (i = 1; i <= n; i++) { endp[- i] = colonp[n - i]; colonp[n - i] = 0; } tp = endp; } if (tp != endp) goto ERROR; fnet_memcpy(addr, tmp, sizeof(*addr)); return (FNET_OK); ERROR: return (FNET_ERR); }
/************************************************************************ * NAME: fnet_http_ssi_send * * DESCRIPTION: ************************************************************************/ static fnet_size_t fnet_http_ssi_send (struct fnet_http_if * http) { fnet_size_t result = 0u; fnet_size_t read_result = 0u; fnet_index_t ssi_head_index = 0u; fnet_index_t ssi_tail_index = 0u; struct fnet_http_session_if *session = http->session_active; fnet_uint8_t *buffer = session->buffer; fnet_bool_t next = FNET_FALSE; while ((result < sizeof(session->buffer)) && (next == FNET_FALSE)) { if((http->ssi.state != FNET_HTTP_SSI_INCLUDING) /* Read from file if not in including. */ &&((read_result = fnet_fs_fread(buffer, 1u, session->send_param.file_desc)) == 0u) ) { break; /*EOF*/ } switch (http->ssi.state) { case FNET_HTTP_SSI_WAIT_HEAD: if(*buffer == fnet_http_ssi_head[ssi_head_index]) { ssi_head_index++; if(ssi_head_index == sizeof(fnet_http_ssi_head)) { /* Head is found */ if(result >= sizeof(fnet_http_ssi_head)) { /* Found in the middle */ fnet_fs_fseek (session->send_param.file_desc, -((fnet_int32_t)sizeof(fnet_http_ssi_head)), FNET_FS_SEEK_CUR); next = FNET_TRUE; /* break */ result -= sizeof(fnet_http_ssi_head); /* Correct result */ } else { http->ssi.state = FNET_HTTP_SSI_WAIT_TAIL; } } } else { ssi_head_index = 0u; } break; case FNET_HTTP_SSI_WAIT_TAIL: if(*buffer == fnet_http_ssi_tail[ssi_tail_index]) { ssi_tail_index++; if(ssi_tail_index == sizeof(fnet_http_ssi_tail)) { /* Tail is found */ const struct fnet_http_ssi *ssi_ptr = 0; fnet_char_t *ssi_name = (fnet_char_t*)&session->buffer[sizeof(fnet_http_ssi_head)]; fnet_char_t *ssi_param; http->ssi.send = 0; session->buffer[buffer + 1 - session->buffer - sizeof(fnet_http_ssi_tail)] = '\0'; /* Mark end of the SSI. */ /* Find SSI parameters. */ if((ssi_param = fnet_strchr( (fnet_char_t*)session->buffer, ' ' )) !=0) { *ssi_param = '\0'; /* Mark end of the SSI name. */ ssi_param ++; /* Point to the begining of params. */ } if(http->ssi.ssi_table) /* SSI table is initialized.*/ { /* Find SSI handler */ for(ssi_ptr = http->ssi.ssi_table; (ssi_ptr->name) && (ssi_ptr->send); ssi_ptr++) { if (!fnet_strcmp( ssi_name, ssi_ptr->name)) { http->ssi.send = ssi_ptr->send; break; } } } read_result = 0u; /* Eliminate the include. */ if(http->ssi.send) { /* SSI Handler is found. */ if((ssi_ptr->handle == 0) || (ssi_ptr->handle(ssi_param, &session->response.cookie) == FNET_OK)) { buffer = session->buffer; /* Reset */ result = 0u; http->ssi.state = FNET_HTTP_SSI_INCLUDING; } else { http->ssi.state = FNET_HTTP_SSI_WAIT_HEAD; } } else { http->ssi.state = FNET_HTTP_SSI_WAIT_HEAD; } } } else { ssi_tail_index = 0u; } break; case FNET_HTTP_SSI_INCLUDING: { fnet_bool_t eof; read_result = http->ssi.send(session->buffer, sizeof(session->buffer), &eof, &session->response.cookie); if((read_result == 0u) || (eof == FNET_TRUE)) { http->ssi.state = FNET_HTTP_SSI_WAIT_HEAD; } next = FNET_TRUE; /* break */ } break; default: break; } buffer+=read_result; result+=read_result; } if(read_result && (next == FNET_FALSE) && ssi_head_index && (http->ssi.state == FNET_HTTP_SSI_WAIT_HEAD) ) { /* Potential SSI is splitted => parse in the next itteration */ result-=ssi_head_index; /* adjust result */ fnet_fs_fseek(session->send_param.file_desc, -(fnet_int32_t)ssi_head_index, FNET_FS_SEEK_CUR); } return result; }
/************************************************************************ * NAME: fnet_http_ssi_send * * DESCRIPTION: ************************************************************************/ static unsigned long fnet_http_ssi_send (struct fnet_http_if * http) { unsigned long result = 0; unsigned long read_result = 0; int ssi_head_index = 0; int ssi_tail_index = 0; char * buffer = http->buffer; int next = 0; while (result<sizeof(http->buffer) && (next == 0)) { if(http->ssi.state != FNET_HTTP_SSI_INCLUDING) /* Read from file if not in including. */ if((read_result = fnet_fs_fread(buffer, 1, http->send_param.file_desc)) == 0) break; /*EOF*/ switch (http->ssi.state) { case FNET_HTTP_SSI_WAIT_HEAD: if(*buffer == fnet_http_ssi_head[ssi_head_index]) { ssi_head_index++; if(ssi_head_index == sizeof(fnet_http_ssi_head)) { /* Head is found */ if(result >= sizeof(fnet_http_ssi_head)) { /* Found in the middle */ fnet_fs_fseek (http->send_param.file_desc, -sizeof(fnet_http_ssi_head), FNET_FS_SEEK_CUR); next = 1; /* break */ result -= sizeof(fnet_http_ssi_head); /* Correct result */ } else http->ssi.state = FNET_HTTP_SSI_WAIT_TAIL; } } else ssi_head_index = 0; break; case FNET_HTTP_SSI_WAIT_TAIL: if(*buffer == fnet_http_ssi_tail[ssi_tail_index]) { ssi_tail_index++; if(ssi_tail_index == sizeof(fnet_http_ssi_tail)) { /* Tail is found */ const struct fnet_http_ssi *ssi_ptr = 0; char * ssi_name = &http->buffer[sizeof(fnet_http_ssi_head)]; char * ssi_param; http->ssi.send = 0; http->buffer[buffer + 1 - http->buffer - sizeof(fnet_http_ssi_tail)] = '\0'; /* Mark end of the SSI. */ /* Find SSI parameters. */ if((ssi_param = fnet_strchr( http->buffer, ' ' )) !=0) { *ssi_param = '\0'; /* Mark end of the SSI name. */ ssi_param ++; /* Point to the begining of params. */ } if(http->ssi.ssi_table) /* SSI table is initialized.*/ { /* Find SSI handler */ for(ssi_ptr = http->ssi.ssi_table; ssi_ptr->name && ssi_ptr->send; ssi_ptr++) { if (!fnet_strcmp( ssi_name, ssi_ptr->name)) { http->ssi.send = ssi_ptr->send; break; } } } read_result = 0; /* Eliminate the include. */ if(http->ssi.send) { /* SSI Handler is found. */ if((ssi_ptr->handle == 0) || (ssi_ptr->handle(ssi_param, &http->response.cookie) == FNET_OK)) { buffer = http->buffer; /* Reset */ result = 0; http->ssi.state = FNET_HTTP_SSI_INCLUDING; } else http->ssi.state = FNET_HTTP_SSI_WAIT_HEAD; } else http->ssi.state = FNET_HTTP_SSI_WAIT_HEAD; } } else ssi_tail_index = 0; break; case FNET_HTTP_SSI_INCLUDING: { char eof; read_result = (unsigned long) http->ssi.send(http->buffer, sizeof(http->buffer), &eof, &http->response.cookie); if((read_result == 0) || (eof == 1)) http->ssi.state = FNET_HTTP_SSI_WAIT_HEAD; next = 1; /* break */ } break; } buffer+=read_result; result+=read_result; } if(read_result && (next == 0) && ssi_head_index && (http->ssi.state == FNET_HTTP_SSI_WAIT_HEAD) ) { /* Potential SSI is splitted => parse in the next itteration */ result-=ssi_head_index; /* adjust result */ fnet_fs_fseek (http->send_param.file_desc, -ssi_head_index, FNET_FS_SEEK_CUR); } return result; }