Changeset ad5e070 in rtems


Ignore:
Timestamp:
Nov 21, 2012, 2:47:46 PM (7 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
fe0f24e
Parents:
be6f505
git-author:
Sebastian Huber <sebastian.huber@…> (11/21/12 14:47:46)
git-committer:
Sebastian Huber <sebastian.huber@…> (11/21/12 15:38:34)
Message:

ftpfs: Open control connection during path eval

File:
1 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libnetworking/lib/ftpfs.c

    rbe6f505 rad5e070  
    7070  int ctrl_socket;
    7171
     72  uint32_t client_address;
     73
    7274  /**
    7375   * Data transfer socket.
     
    9496   */
    9597  bool eof;
     98
     99  bool write;
     100
     101  ino_t ino;
     102
     103  const char *user;
     104
     105  const char *password;
     106
     107  const char *hostname;
     108
     109  const char *filename;
     110
     111  char buffer [];
    96112} rtems_ftpfs_entry;
    97113
     
    109125   */
    110126  struct timeval timeout;
     127
     128  /**
     129   * Inode counter.
     130   */
     131  ino_t ino;
    111132} rtems_ftpfs_mount_entry;
    112133
     
    429450} split_state;
    430451
    431 static bool rtems_ftpfs_split_names (
     452static int rtems_ftpfs_split_names (
    432453  char *s,
    433454  const char **user,
     
    442463
    443464  *user = s;
    444   *password = NULL;
    445   *hostname = NULL;
    446   *path = NULL;
    447465
    448466  for (i = 0; i < len; ++i) {
     
    520538  }
    521539
    522   return state == STATE_DONE;
     540  return state == STATE_DONE ? 0 : ENOENT;
    523541}
    524542
     
    539557}
    540558
    541 static int rtems_ftpfs_terminate(rtems_libio_t *iop, bool error)
     559static int rtems_ftpfs_close_data_connection(
     560  rtems_ftpfs_entry *e,
     561  bool verbose,
     562  bool error
     563)
    542564{
    543565  int eno = 0;
    544   int rv = 0;
    545   rtems_ftpfs_entry *e = iop->data1;
    546   rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
    547   bool verbose = me->verbose;
    548   rtems_ftpfs_reply reply = RTEMS_FTPFS_REPLY_ERROR;
    549 
    550   if (e != NULL) {
    551     /* Close data connection if necessary */
    552     if (e->data_socket >= 0) {
    553       rv = close(e->data_socket);
    554       if (rv != 0) {
    555         eno = EIO;
    556       }
    557 
    558       /* For write connections we have to obtain the transfer reply  */
    559       if (
    560         e->ctrl_socket >= 0
    561           && (iop->flags & LIBIO_FLAGS_WRITE) != 0
    562           && !error
    563       ) {
    564         reply = rtems_ftpfs_get_reply(e, NULL, NULL, verbose);
    565         if (reply != RTEMS_FTPFS_REPLY_2) {
    566           eno = EIO;
    567         }
    568       }
    569     }
    570 
    571     /* Close control connection if necessary */
    572     if (e->ctrl_socket >= 0) {
    573       reply = rtems_ftpfs_send_command(e, "QUIT", NULL, verbose);
     566
     567  /* Close data connection if necessary */
     568  if (e->data_socket >= 0) {
     569    int rv = close(e->data_socket);
     570
     571    e->data_socket = -1;
     572    if (rv != 0) {
     573      eno = EIO;
     574    }
     575
     576    /* For write connections we have to obtain the transfer reply  */
     577    if (e->write && !error) {
     578      rtems_ftpfs_reply reply =
     579        rtems_ftpfs_get_reply(e, NULL, NULL, verbose);
     580
    574581      if (reply != RTEMS_FTPFS_REPLY_2) {
    575582        eno = EIO;
    576583      }
    577 
    578       rv = close(e->ctrl_socket);
    579       if (rv != 0) {
    580         eno = EIO;
    581       }
    582     }
    583 
    584     /* Free connection entry */
    585     free(e);
    586   }
    587 
    588   /* Invalidate IO entry */
    589   iop->data1 = NULL;
     584    }
     585  }
    590586
    591587  return eno;
     
    594590static int rtems_ftpfs_open_ctrl_connection(
    595591  rtems_ftpfs_entry *e,
    596   const char *user,
    597   const char *password,
    598   const char *hostname,
    599   uint32_t *client_address,
    600592  bool verbose,
    601593  const struct timeval *timeout
     
    616608
    617609  /* Set up the server address from the hostname */
    618   if (inet_aton(hostname, &address) == 0) {
     610  if (inet_aton(e->hostname, &address) == 0) {
    619611    /* Try to get the address by name */
    620     struct hostent *he = gethostbyname(hostname);
     612    struct hostent *he = gethostbyname(e->hostname);
    621613
    622614    if (he != NULL) {
     
    655647    return ENOMEM;
    656648  }
    657   *client_address = ntohl(sa.sin_addr.s_addr);
     649  e->client_address = ntohl(sa.sin_addr.s_addr);
    658650  DEBUG_PRINTF("client = %s\n", inet_ntoa(sa.sin_addr));
    659651
     
    665657
    666658  /* Send USER command */
    667   reply = rtems_ftpfs_send_command(e, "USER ", user, verbose);
     659  reply = rtems_ftpfs_send_command(e, "USER ", e->user, verbose);
    668660  if (reply == RTEMS_FTPFS_REPLY_3) {
    669661    /* Send PASS command */
    670     reply = rtems_ftpfs_send_command(e, "PASS ", password, verbose);
     662    reply = rtems_ftpfs_send_command(e, "PASS ", e->password, verbose);
    671663    if (reply != RTEMS_FTPFS_REPLY_2) {
    672664      return EACCES;
     
    689681static int rtems_ftpfs_open_data_connection_active(
    690682  rtems_ftpfs_entry *e,
    691   uint32_t client_address,
    692683  const char *file_command,
    693   const char *filename,
    694684  bool verbose,
    695685  const struct timeval *timeout
     
    742732    sizeof(port_command),
    743733    "PORT %lu,%lu,%lu,%lu,%lu,%lu",
    744     (client_address >> 24) & 0xffUL,
    745     (client_address >> 16) & 0xffUL,
    746     (client_address >> 8) & 0xffUL,
    747     (client_address >> 0) & 0xffUL,
     734    (e->client_address >> 24) & 0xffUL,
     735    (e->client_address >> 16) & 0xffUL,
     736    (e->client_address >> 8) & 0xffUL,
     737    (e->client_address >> 0) & 0xffUL,
    748738    (data_port >> 8) & 0xffUL,
    749739    (data_port >> 0) & 0xffUL
     
    763753
    764754  /* Send RETR or STOR command with filename */
    765   reply = rtems_ftpfs_send_command(e, file_command, filename, verbose);
     755  reply = rtems_ftpfs_send_command(e, file_command, e->filename, verbose);
    766756  if (reply != RTEMS_FTPFS_REPLY_1) {
    767757    eno = EIO;
     
    870860static int rtems_ftpfs_open_data_connection_passive(
    871861  rtems_ftpfs_entry *e,
    872   uint32_t client_address,
    873862  const char *file_command,
    874   const char *filename,
    875863  bool verbose,
    876864  const struct timeval *timeout
     
    927915
    928916  /* Send RETR or STOR command with filename */
    929   reply = rtems_ftpfs_send_command(e, file_command, filename, verbose);
     917  reply = rtems_ftpfs_send_command(e, file_command, e->filename, verbose);
    930918  if (reply != RTEMS_FTPFS_REPLY_1) {
    931919    return EIO;
     
    943931{
    944932  int eno = 0;
    945   bool ok = false;
    946   rtems_ftpfs_entry *e = NULL;
     933  rtems_ftpfs_entry *e = iop->pathinfo.node_access;
    947934  rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
    948935  bool verbose = me->verbose;
    949936  const struct timeval *timeout = &me->timeout;
    950   const char *user = NULL;
    951   const char *password = NULL;
    952   const char *hostname = NULL;
    953   const char *filename = NULL;
    954   const char *file_command = (iop->flags & LIBIO_FLAGS_WRITE) != 0
    955     ? "STOR "
    956     : "RETR ";
    957   uint32_t client_address = 0;
    958   char *location = iop->pathinfo.node_access;
    959 
    960   /* Invalidate data handle */
    961   iop->data1 = NULL;
    962 
    963   /* Split location into parts */
    964   ok = rtems_ftpfs_split_names(
    965       location,
    966       &user,
    967       &password,
    968       &hostname,
    969       &filename
    970   );
    971   if (!ok) {
    972     rtems_set_errno_and_return_minus_one(ENOENT);
    973   }
    974   DEBUG_PRINTF(
    975     "user = '%s', password = '%s', filename = '%s'\n",
    976     user,
    977     password,
    978     filename
    979   );
     937
     938  e->write = (iop->flags & LIBIO_FLAGS_WRITE) != 0;
    980939
    981940  /* Check for either read-only or write-only flags */
     
    984943      && (iop->flags & LIBIO_FLAGS_READ) != 0
    985944  ) {
    986     rtems_set_errno_and_return_minus_one(ENOTSUP);
    987   }
    988 
    989   /* Allocate connection entry */
    990   e = calloc(1, sizeof(*e));
    991   if (e == NULL) {
    992     rtems_set_errno_and_return_minus_one(ENOMEM);
    993   }
    994 
    995   /* Initialize connection entry */
    996   e->ctrl_socket = -1;
    997   e->data_socket = -1;
    998 
    999   /* Save connection state */
    1000   iop->data1 = e;
    1001 
    1002   /* Open control connection */
    1003   eno = rtems_ftpfs_open_ctrl_connection(
    1004     e,
    1005     user,
    1006     password,
    1007     hostname,
    1008     &client_address,
    1009     verbose,
    1010     timeout
    1011   );
    1012   if (eno != 0) {
    1013     goto cleanup;
    1014   }
    1015 
    1016   /* Open passive data connection */
    1017   eno = rtems_ftpfs_open_data_connection_passive(
    1018     e,
    1019     client_address,
    1020     file_command,
    1021     filename,
    1022     verbose,
    1023     timeout
    1024   );
    1025   if (eno == ENOTSUP) {
    1026     /* Open active data connection */
    1027     eno = rtems_ftpfs_open_data_connection_active(
     945    eno = ENOTSUP;
     946  }
     947
     948  if (eno == 0) {
     949    const char *file_command = e->write ? "STOR " : "RETR ";
     950
     951    /* Open passive data connection */
     952    eno = rtems_ftpfs_open_data_connection_passive(
    1028953      e,
    1029       client_address,
    1030954      file_command,
    1031       filename,
    1032955      verbose,
    1033956      timeout
    1034957    );
    1035   }
    1036   if (eno != 0) {
    1037     goto cleanup;
     958    if (eno == ENOTSUP) {
     959      /* Open active data connection */
     960      eno = rtems_ftpfs_open_data_connection_active(
     961        e,
     962        file_command,
     963        verbose,
     964        timeout
     965      );
     966    }
    1038967  }
    1039968
    1040969  /* Set data connection timeout */
    1041   eno = rtems_ftpfs_set_connection_timeout(e->data_socket, timeout);
    1042 
    1043 cleanup:
     970  if (eno == 0) {
     971    eno = rtems_ftpfs_set_connection_timeout(e->data_socket, timeout);
     972  }
    1044973
    1045974  if (eno == 0) {
    1046975    return 0;
    1047976  } else {
    1048     /* Free all resources if an error occured */
    1049     rtems_ftpfs_terminate(iop, true);
     977    rtems_ftpfs_close_data_connection(e, verbose, true);
    1050978
    1051979    rtems_set_errno_and_return_minus_one(eno);
     
    1059987)
    1060988{
    1061   rtems_ftpfs_entry *e = iop->data1;
    1062   rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
     989  rtems_ftpfs_entry *e = iop->pathinfo.node_access;
     990  const rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
    1063991  bool verbose = me->verbose;
    1064992  char *in = buffer;
     
    10991027)
    11001028{
    1101   rtems_ftpfs_entry *e = iop->data1;
     1029  rtems_ftpfs_entry *e = iop->pathinfo.node_access;
    11021030  const char *out = buffer;
    11031031  size_t todo = count;
     
    11231051static int rtems_ftpfs_close(rtems_libio_t *iop)
    11241052{
    1125   int eno = rtems_ftpfs_terminate(iop, false);
     1053  rtems_ftpfs_entry *e = iop->pathinfo.node_access;
     1054  const rtems_ftpfs_mount_entry *me = iop->pathinfo.mt_entry->fs_info;
     1055  int eno = rtems_ftpfs_close_data_connection(e, me->verbose, false);
    11261056
    11271057  if (eno == 0) {
     
    11421072)
    11431073{
     1074  int eno = 0;
     1075
    11441076  rtems_filesystem_eval_path_eat_delimiter(self);
    11451077
     
    11471079    const char *path = rtems_filesystem_eval_path_get_path(self);
    11481080    size_t pathlen = rtems_filesystem_eval_path_get_pathlen(self);
    1149     char *pathdup = malloc(pathlen + 1);
     1081    rtems_ftpfs_entry *e = calloc(1, sizeof(*e) + pathlen + 1);
    11501082
    11511083    rtems_filesystem_eval_path_clear_path(self);
    11521084
    1153     if (pathdup != NULL) {
    1154       rtems_filesystem_location_info_t *currentloc =
    1155         rtems_filesystem_eval_path_get_currentloc(self);
    1156 
    1157       memcpy(pathdup, path, pathlen);
    1158       pathdup [pathlen] = '\0';
    1159       currentloc->node_access = pathdup;
    1160       currentloc->handlers = &rtems_ftpfs_handlers;
     1085    if (e != NULL) {
     1086      memcpy(e->buffer, path, pathlen);
     1087
     1088      eno = rtems_ftpfs_split_names(
     1089          e->buffer,
     1090          &e->user,
     1091          &e->password,
     1092          &e->hostname,
     1093          &e->filename
     1094      );
     1095
     1096      DEBUG_PRINTF(
     1097        "user = '%s', password = '%s', filename = '%s'\n",
     1098        e->user,
     1099        e->password,
     1100        e->filename
     1101      );
     1102
     1103      if (eno == 0) {
     1104        rtems_filesystem_location_info_t *currentloc =
     1105          rtems_filesystem_eval_path_get_currentloc(self);
     1106        rtems_ftpfs_mount_entry *me = currentloc->mt_entry->fs_info;
     1107
     1108        rtems_libio_lock();
     1109        ++me->ino;
     1110        e->ino = me->ino;
     1111        rtems_libio_unlock();
     1112
     1113        e->ctrl_socket = -1;
     1114
     1115        eno = rtems_ftpfs_open_ctrl_connection(
     1116          e,
     1117          me->verbose,
     1118          &me->timeout
     1119        );
     1120        if (eno == 0) {
     1121          currentloc->node_access = e;
     1122          currentloc->handlers = &rtems_ftpfs_handlers;
     1123        }
     1124      }
     1125
     1126      if (eno != 0) {
     1127        free(e);
     1128      }
    11611129    } else {
    1162       rtems_filesystem_eval_path_error(self, ENOMEM);
    1163     }
     1130      eno = ENOMEM;
     1131    }
     1132  }
     1133
     1134  if (eno != 0) {
     1135    rtems_filesystem_eval_path_error(self, eno);
    11641136  }
    11651137}
     
    11671139static void rtems_ftpfs_free_node(const rtems_filesystem_location_info_t *loc)
    11681140{
    1169   free(loc->node_access);
     1141  rtems_ftpfs_entry *e = loc->node_access;
     1142  const rtems_ftpfs_mount_entry *me = loc->mt_entry->fs_info;
     1143
     1144  /* Close control connection if necessary */
     1145  if (e->ctrl_socket >= 0) {
     1146    rtems_ftpfs_send_command(e, "QUIT", NULL, me->verbose);
     1147
     1148    close(e->ctrl_socket);
     1149  }
     1150
     1151  free(e);
    11701152}
    11711153
     
    11821164)
    11831165{
    1184   rtems_ftpfs_mount_entry *me = malloc(sizeof(rtems_ftpfs_mount_entry));
     1166  rtems_ftpfs_mount_entry *me = calloc(1, sizeof(*me));
    11851167
    11861168  /* Mount entry for FTP file system instance */
     
    12551237)
    12561238{
    1257   static unsigned ino = 0;
     1239  rtems_ftpfs_entry *e = loc->node_access;
    12581240
    12591241  /* FIXME */
    1260   st->st_ino = ++ino;
     1242  st->st_ino = e->ino;
    12611243  st->st_dev = rtems_filesystem_make_dev_t(0xcc494cd6U, 0x1d970b4dU);
    12621244
     
    12661248}
    12671249
     1250static void rtems_ftpfs_lock_or_unlock(
     1251  const rtems_filesystem_mount_table_entry_t *mt_entry
     1252)
     1253{
     1254  /* Do nothing */
     1255}
     1256
    12681257static const rtems_filesystem_operations_table rtems_ftpfs_ops = {
    1269   .lock_h = rtems_filesystem_default_lock,
    1270   .unlock_h = rtems_filesystem_default_unlock,
     1258  .lock_h = rtems_ftpfs_lock_or_unlock,
     1259  .unlock_h = rtems_ftpfs_lock_or_unlock,
    12711260  .eval_path_h = rtems_ftpfs_eval_path,
    12721261  .link_h = rtems_filesystem_default_link,
Note: See TracChangeset for help on using the changeset viewer.