static int tftp_fileop_open(void **ref,void *fsctx,char *filename,int mode) { tftp_info_t *info; char *host; char *file; int res; if ((mode != FILE_MODE_READ) && (mode != FILE_MODE_WRITE)) { /* must be either read or write, not both */ return CFE_ERR_UNSUPPORTED; } /* Allocate the tftp info structure */ info = KMALLOC(sizeof(tftp_info_t),0); if (!info) { return CFE_ERR_NOMEM; } info->tftp_filename = lib_strdup(filename); if (!info->tftp_filename) { KFREE(info); return CFE_ERR_NOMEM; } lib_chop_filename(info->tftp_filename,&host,&file); /* Open the file */ if (!*host && !*file) { /* TFTP server if hostname and filename are not specified */ #ifdef RESCUE_MODE xprintf("TFTP Server.\n"); #endif res = _tftpd_open(info,host,file,mode); } else { /* TFTP client otherwise */ #ifdef RESCUE_MODE xprintf("TFTP Client.\n"); #endif res = _tftp_open(info,host,file,mode); } if (res == 0) { info->tftp_blkoffset = 0; info->tftp_fileoffset = 0; *ref = info; } else { KFREE(info->tftp_filename); KFREE(info); *ref = NULL; } return res; }
static int http_fileop_open(void **ref,void *fsctx_arg,char *filename,int mode) { http_fsctx_t *fsctx; http_file_t *file; char temp[200]; char *hostname, *filen; int hlen; int termidx; int res; int err = 0; char *hptr; char *tok; uint8_t hostaddr[IP_ADDR_LEN]; uint8_t termstr[4]; uint8_t b; if (mode != FILE_MODE_READ) return CFE_ERR_UNSUPPORTED; fsctx = (http_fsctx_t *) fsctx_arg; file = KMALLOC(sizeof(http_file_t),0); if (!file) { return CFE_ERR_NOMEM; } file->http_filename = lib_strdup(filename); if (!file->http_filename) { KFREE(file); return CFE_ERR_NOMEM; } lib_chop_filename(file->http_filename,&hostname,&filen); /* * Look up remote host */ res = dns_lookup(hostname,hostaddr); if (res < 0) { KFREE(file); return res; } file->http_socket = tcp_socket(); if (file->http_socket < 0) { KFREE(file->http_filename); KFREE(file); return -1; } /* * Connect to remote host. */ tcp_setflags(file->http_socket,0); /* set socket to blocking */ res = tcp_connect(file->http_socket,hostaddr,80); if (res < 0) { tcp_close(file->http_socket); KFREE(file->http_filename); KFREE(file); return res; } /* * Send GET command. Supply the hostname (for HTTP 1.1 requirements) * and set the connection to close as soon as all the data is received. */ hlen = sprintf(temp,"GET /%s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",filen,hostname); res = tcp_send(file->http_socket,temp,hlen); if (res < 0) { tcp_close(file->http_socket); KFREE(file->http_filename); KFREE(file); return res; } /* * Read bytes until we either reach EOF or we see "\r\n\r\n" * This is the server's status string. */ termstr[0] = '\r'; termstr[1] = '\n'; termstr[2] = '\r'; termstr[3] = '\n'; termidx = 0; file->http_offset = 0; file->http_blen = 0; file->http_bptr = file->http_buffer; res = 0; for (;;) { res = tcp_recv(file->http_socket,&b,1); if (res < 0) break; if (b == termstr[termidx]) { termidx++; if (termidx == 4) break; } else { termidx = 0; } /* * Save the bytes from the header up to our buffer * size. It's okay if we don't save it all, * since all we want is the result code which comes * first. */ if (file->http_blen < (HTTP_BUFSIZE-1)) { *(file->http_bptr) = b; file->http_bptr++; file->http_blen++; } } /* * Premature EOFs are not good, bail now. */ if (res < 0) { err = CFE_ERR_EOF; goto protocolerr; } /* * Skip past the HTTP response header and grab the result code. * Sanity check it a little. */ *(file->http_bptr) = 0; hptr = file->http_buffer; tok = lib_gettoken(&hptr); if (!tok || (memcmp(tok,"HTTP",4) != 0)) { err = CFE_ERR_PROTOCOLERR; goto protocolerr; } tok = lib_gettoken(&hptr); if (!tok) { err = CFE_ERR_PROTOCOLERR; goto protocolerr; } switch (lib_atoi(tok)) { case 200: err = 0; break; case 404: err = CFE_ERR_FILENOTFOUND; break; } /* * If we get to here, the file is okay and we're about to receive data. */ if (err == 0) { *ref = file; return 0; } protocolerr: tcp_close(file->http_socket); KFREE(file->http_filename); KFREE(file); *ref = NULL; return err; }