⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpfs.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    if (s == nStreams) {      /*       * Reallocate stream pointers       * Guard against the case where realloc() returns NULL.       */      struct ftpStream **np;            np = realloc (ftpStreams, ++nStreams * sizeof *ftpStreams);      if (np == NULL) {	eno = ENOMEM;      }      else {	ftpStreams = np;      }    }  }  if (eno == 0) {    fsp = ftpStreams[s] = malloc (sizeof (struct ftpStream));    rtems_semaphore_release (ftp_mutex);    sema_obtained = FALSE;    if (fsp == NULL) {      eno = ENOMEM;    }    else {      iop->data0 = s;      iop->data1 = fsp;      fsp->ctrl_socket = -1; /* mark, that sockets not yet created */      fsp->port_socket = -1;      fsp->data_socket = -1;      fsp->eof_reached = FALSE;    }  }  if (eno == 0) {    /*   * Create the socket for control connection   */    if ((fsp->ctrl_socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {      eno = ENOMEM;    }  }  if (eno == 0) {    /*     * Set the destination to the FTP server     * port on the remote machine.     */    memset(&(fsp->farCtrlAddress),sizeof(fsp->farCtrlAddress),0);    fsp->farCtrlAddress.sin_family = AF_INET;    if (*hostname == '\0') {      fsp->farCtrlAddress.sin_addr.s_addr = rtems_bsdnet_bootp_server_address.s_addr;    }    else if (1 != inet_aton(hostname,&(fsp->farCtrlAddress.sin_addr))) {      struct hostent *hent;      struct hostent *gethostbyname(const char *name);            hent = gethostbyname(hostname);      if (hent != NULL) {	bcopy(hent->h_addr, 	      (char *)(&(fsp->farCtrlAddress.sin_addr)), 	      sizeof(fsp->farCtrlAddress.sin_addr));      }      else {	eno = ENOENT;      }    }    if (eno == 0) {      fsp->farCtrlAddress.sin_port = htons (FTP_PORT_NUM);        fsp->farCtrlAddress.sin_len  = sizeof(fsp->farCtrlAddress);          if (0 > connect(fsp->ctrl_socket,		      (struct sockaddr *)&(fsp->farCtrlAddress),		      sizeof(fsp->farCtrlAddress))) {	eno = ENOENT;      }    }    if (eno == 0) {      /*       * fetch IP address of interface used       */      memset(&(fsp->myCtrlAddress),sizeof(fsp->myCtrlAddress),0);      fsp->myCtrlAddress.sin_family = AF_INET;      fsp->myCtrlAddress.sin_addr.s_addr = INADDR_ANY;      fsp->myCtrlAddress.sin_port   = 0;       fsp->myCtrlAddress.sin_len  = sizeof(fsp->myDataAddress);      sockaddr_size = sizeof(fsp->myCtrlAddress);      if (0 > getsockname(fsp->ctrl_socket,			  (struct sockaddr *)&(fsp->myCtrlAddress),			  &sockaddr_size)) {	eno = ENOMEM;      }    }  }  if (eno == 0) {    /*     * now we should get a connect message from the FTP server     */    eno = rtems_ftp_get_message(fsp,&msg_tmp);    if ((eno == 0) &&	(msg_tmp != FTP_REPLY_CONNECT)) {      eno = ENOENT;    }  }  if (eno == 0) {    /*     * send user ID to server     * NOTE: the following lines will be executed in order     * and will be aborted whenever an error occures... (see your ANSI C book)     */    if ((0 > send(fsp->ctrl_socket,FTP_USER_CMD,strlen(FTP_USER_CMD),0)) ||	(0 > send(fsp->ctrl_socket,uname,       strlen(uname),       0)) ||	(0 > send(fsp->ctrl_socket,"\n",        1,                   0))) {      eno = EIO;    }  }  if (eno == 0) {    /*     * now we should get a request for the password or a login...     */    eno = rtems_ftp_get_message(fsp,&msg_tmp);    if (eno == 0) {      if (msg_tmp == FTP_REPLY_PASSREQ) {	/*	 * send password to server	 */#ifdef DEBUG_OUT	write(1,FTP_PASS_CMD,strlen(FTP_PASS_CMD));	write(1,upass,       strlen(upass)       );	write(1,"\n",        1                   );#endif    	if ((0 > send(fsp->ctrl_socket,FTP_PASS_CMD,strlen(FTP_PASS_CMD),0)) ||	    (0 > send(fsp->ctrl_socket,upass,       strlen(upass),       0)) ||	    (0 > send(fsp->ctrl_socket,"\n",        1,                   0))) {	  eno = EIO;	}	/*	 * at least now a login reply should come up...	 * this is checked some lines downwards the code	 */	if (eno == 0) {	  eno = rtems_ftp_get_message(fsp,&msg_tmp);	}      }    }  }  if (eno == 0) {    /*     * check for a login reply. this should be present now...     */    if (msg_tmp != FTP_REPLY_LOGIN) {      eno = EACCES; /* pseudo for wrong user/pass */    }  }  if (eno == 0) {    /*     * set binary mode for all transfers     */#ifdef DEBUG_OUT    write(1,FTP_BINARY_CMD,strlen(FTP_BINARY_CMD));    write(1,"\n",        1                   );#endif        if ((0 > send(fsp->ctrl_socket,FTP_BINARY_CMD,strlen(FTP_BINARY_CMD),0)) ||	(0 > send(fsp->ctrl_socket,"\n",          1,                     0))) {      eno = EIO;    }    else {      eno = rtems_ftp_get_message(fsp,&msg_tmp);    }  }  if (eno == 0) {    /*     * check for a "BINARY TYPE command successful" reply     */    if (msg_tmp != FTP_REPLY_SUCCESS) {      eno = EIO;    }  }  if (eno == 0) {    /*     * create and bind socket for data connection     */    if ((fsp->port_socket = socket (AF_INET, SOCK_STREAM, 0)) < 0) {      eno = ENOMEM;    }    else {      memset(&(fsp->myDataAddress),sizeof(fsp->myDataAddress),0);      fsp->myDataAddress.sin_family = AF_INET;      fsp->myDataAddress.sin_addr.s_addr = INADDR_ANY;      fsp->myDataAddress.sin_port   = 0; /* unique port will be assigned */      fsp->myDataAddress.sin_len  = sizeof(fsp->myDataAddress);      if (0 > bind(fsp->port_socket,		   (struct sockaddr *)&(fsp->myDataAddress),		   sizeof(fsp->myDataAddress))) {	eno = EBUSY;      }      else {	/*	 * fetch port number of data socket	 */	memset(&(fsp->myDataAddress),sizeof(fsp->myDataAddress),0);	fsp->myDataAddress.sin_family = AF_INET;	fsp->myDataAddress.sin_addr.s_addr = INADDR_ANY;	fsp->myDataAddress.sin_port   = 0; 	fsp->myDataAddress.sin_len  = sizeof(fsp->myDataAddress);	sockaddr_size = sizeof(fsp->myDataAddress);	if (0 > getsockname(fsp->port_socket,			    (struct sockaddr *)&(fsp->myDataAddress),			    &sockaddr_size)) {	  eno = ENOMEM;	}      }    }  }  if (eno == 0) {    /*     * propagate data connection port to server     */    my_ip   = ntohl(fsp->myCtrlAddress.sin_addr.s_addr);    my_port = ntohs(fsp->myDataAddress.sin_port);    sprintf(port_buffer,"%s%u,%u,%u,%u,%u,%u\n",	    FTP_PORT_CMD,	    (my_ip >> 24) & 0x00ff,	    (my_ip >> 16) & 0x00ff,	    (my_ip >>  8) & 0x00ff,	    (my_ip >>  0) & 0x00ff,	    (my_port>> 8) & 0x00ff,	    (my_port>> 0) & 0x00ff);#ifdef DEBUG_OUT    write(1,port_buffer,strlen(port_buffer));#endif    if (0 > send(fsp->ctrl_socket,port_buffer,strlen(port_buffer),0)) {      eno = EIO;    }        else {      eno = rtems_ftp_get_message(fsp,&msg_tmp);    }  }  if (eno == 0) {    /*     * check for a "PORT command successful" reply     */    if (msg_tmp != FTP_REPLY_SUCCESS) {      eno = EBUSY;    }  }  /*   * prepare port socket to listen for incoming connections    */  if (eno == 0) {    if (0 > listen(fsp->port_socket,1)) {      eno = EBUSY;    }  }  if (eno == 0) {    /*     * send retrive/store command with filename     */    if (is_write) {#ifdef DEBUG_OUT    write(1,FTP_STOR_CMD,strlen(FTP_STOR_CMD));    write(1,filename    ,strlen(filename)    );    write(1,"\n",1);#endif      if ((0 > send(fsp->ctrl_socket,FTP_STOR_CMD,strlen(FTP_STOR_CMD),0)) ||	  (0 > send(fsp->ctrl_socket,filename,    strlen(filename),    0)) ||	  (0 > send(fsp->ctrl_socket,"\n",        1,                   0))) {	eno = EIO;      }    }    else {#ifdef DEBUG_OUT    write(1,FTP_RETR_CMD,strlen(FTP_RETR_CMD));    write(1,filename    ,strlen(filename)    );    write(1,"\n",1);#endif      if ((0 > send(fsp->ctrl_socket,FTP_RETR_CMD,strlen(FTP_RETR_CMD),0)) ||	  (0 > send(fsp->ctrl_socket,filename,    strlen(filename),    0)) ||	  (0 > send(fsp->ctrl_socket,"\n",        1,                   0))) {	eno = EIO;      }    }        }#if 1  if (eno == 0) {    eno = rtems_ftp_get_message(fsp,&msg_tmp);  }  if (eno == 0) {    /*     * check for a "OPENING binary connection" reply     */    if (msg_tmp != FTP_REPLY_OPENCONN) {      eno = EACCES;    }  }#endif  /*   * wait for connect on data connection   * FIXME: this should become a select instead with a timeout   */  if (eno == 0) {    sockaddr_size = sizeof(fsp->farDataAddress);    fsp->data_socket = accept(fsp->port_socket,			      (struct sockaddr *)&(fsp->farDataAddress),			      &sockaddr_size);    if (0 > fsp->data_socket) {      eno = EIO;    }  }  /*   * FIXME: check, that fardataAddr is really from our ftp server   */    /*    * clean up temp strings...   */  if (uname != NULL) {    free(uname);    uname = NULL;  }  if (upass != NULL) {    free(upass);    upass = NULL;  }  if (hostname != NULL) {    free(hostname);    hostname = NULL;  }  if (filename != NULL) {    free(filename);    filename = NULL;  }  /*   * close part socket, no longer needed   */  if (fsp->port_socket != -1) {    close(fsp->port_socket);    fsp->port_socket = -1;  }  /*   * if error, clean up everything   */  if (eno != 0) {    if (fsp != NULL) {      /*       * check and close ctrl/data connection       */      if (fsp->data_socket != -1) {	close(fsp->data_socket);	fsp->data_socket = -1;      }      if (fsp->ctrl_socket != -1) {	close(fsp->ctrl_socket);	fsp->ctrl_socket = -1;      }      /*       * free ftpStream structure        */      ftpStreams[s] = NULL;      free(fsp);      fsp = NULL;    }  }  /*   * return sema, if still occupied   */  if (sema_obtained) {    rtems_semaphore_release (ftp_mutex);    sema_obtained = FALSE;  }#if 0  if (eno != 0) {    set_errno_and_return_minus_one(eno);  }  return 0;#else  return eno;#endif}/* * Read from a FTP stream */ssize_t rtems_ftp_read(  rtems_libio_t *iop,  void          *buffer,  unsigned32     count){  int eno = 0;  struct ftpStream *fsp;  size_t want_cnt;  ssize_t rd_cnt;  int msg_tmp;  fsp = iop->data1;  want_cnt = count;  /*   * check, that data connection present   */  if (eno == 0) {    if ((fsp == NULL) || 	(fsp->data_socket < 0)) {      eno = EBADF;    }  }       /*   * perform read from data socket   * read multiple junks, if smaller than wanted   */  while ((eno == 0) && 	 (want_cnt > 0) &&	 !(fsp->eof_reached) ) {    rd_cnt = read(fsp->data_socket,buffer,want_cnt);    if (rd_cnt > 0) {      buffer += rd_cnt;      want_cnt -= rd_cnt;    }    else {      eno = rtems_ftp_get_message(fsp,&msg_tmp);      fsp->eof_reached = TRUE;      if ((eno == 0) &&	  (msg_tmp != FTP_REPLY_TFERCMPL)) {	eno = EIO;      }      if (rd_cnt < 0) {	eno = EIO;      }    }  }  if (eno != 0) {    set_errno_and_return_minus_one(eno);  }  return count - want_cnt;}ssize_t rtems_ftp_write(  rtems_libio_t *iop,  const void    *buffer,  unsigned32     count){  int eno = EIO;  struct ftpStream *fsp;  size_t want_cnt;  ssize_t wr_cnt;  int msg_tmp;  fsp = iop->data1;  want_cnt = count;  /*   * check, that data connection present   */  if (eno == 0) {    if ((fsp == NULL) || 	(fsp->data_socket < 0)) {      eno = EBADF;    }  }       /*   * perform write to data socket   */  if (eno == 0) {    wr_cnt = write(fsp->data_socket,buffer,want_cnt);    if (wr_cnt > 0) {      buffer += wr_cnt;      want_cnt -= wr_cnt;    }    else {      eno = rtems_ftp_get_message(fsp,&msg_tmp);      if ((eno == 0) &&	  (msg_tmp != FTP_REPLY_TFERCMPL)) {	eno = EIO;      }      if (wr_cnt < 0) {	eno = EIO;      }    }  }  if (eno != 0) {    set_errno_and_return_minus_one(eno);  }  return count - want_cnt;}/* * Close a FTP stream */int rtems_ftp_close(  rtems_libio_t *iop){  int s = iop->data0;  struct ftpStream *fsp = iop->data1;  /*   * close ctrl/data connection, if needed   */  if (fsp->data_socket >= 0) {    close(fsp->data_socket);    fsp->data_socket = -1;  }  if (fsp->ctrl_socket >= 0) {    close(fsp->ctrl_socket);    fsp->ctrl_socket = -1;  }  /*   * free any used space...   */  rtems_semaphore_obtain (ftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);  free (ftpStreams[s]);  ftpStreams[s] = NULL;  rtems_semaphore_release (ftp_mutex);  return 0;}rtems_device_driver rtems_ftp_control(  rtems_device_major_number major,  rtems_device_minor_number minor,  void *pargp){  return RTEMS_NOT_CONFIGURED;}/* * Dummy version to let fopen(xxxx,"w") work properly. */static int rtems_ftp_ftruncate(    rtems_libio_t   *iop,    off_t           count){    return 0;}rtems_filesystem_node_types_t rtems_ftp_node_type(     rtems_filesystem_location_info_t        *pathloc                 /* IN */){    return RTEMS_FILESYSTEM_MEMORY_FILE;}rtems_filesystem_operations_table  rtems_ftp_ops = {    rtems_ftp_eval_path,             /* eval_path */    rtems_ftp_evaluate_for_make,     /* evaluate_for_make */    NULL,                            /* link */    NULL,                            /* unlink */    rtems_ftp_node_type,             /* node_type */    NULL,                            /* mknod */    NULL,                            /* chown */    NULL,                            /* freenodinfo */    NULL,                            /* mount */    rtems_ftp_mount_me,              /* initialize */    NULL,                            /* unmount */    NULL,                            /* fsunmount */    NULL,                            /* utime, */    NULL,                            /* evaluate_link */    NULL,                            /* symlink */    NULL,                            /* readlin */};  rtems_filesystem_file_handlers_r rtems_ftp_handlers = {    rtems_ftp_open,      /* open */         rtems_ftp_close,     /* close */        rtems_ftp_read,      /* read */         rtems_ftp_write,     /* write */        NULL,                /* ioctl */        NULL,                /* lseek */        NULL,                /* fstat */        NULL,                /* fchmod */       rtems_ftp_ftruncate, /* ftruncate */    NULL,                /* fpathconf */    NULL,                /* fsync */        NULL,                /* fdatasync */    NULL,                /* fcntl */    NULL                 /* rmnod */};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -