Changeset 4bcbd8d6 in rtems


Ignore:
Timestamp:
Jul 26, 2015, 11:57:27 AM (4 years ago)
Author:
Michael Davidsaver <mdavidsaver@…>
Branches:
4.10
Children:
05d8495
Parents:
e2f7059
git-author:
Michael Davidsaver <mdavidsaver@…> (07/26/15 11:57:27)
git-committer:
Sebastian Huber <sebastian.huber@…> (01/26/17 06:41:24)
Message:

tftpDriver: apply changes through master

from 4.10.2-15-g5b21eb6
to eb7753437ff858ebe34a08baef7dfdb45eb0f018

Update #2375.

File:
1 edited

Legend:

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

    re2f7059 r4bcbd8d6  
    1010 * eric@skatter.usask.ca
    1111 *
    12  *  $Id$
     12 * Modifications to support reference counting in the file system are
     13 * Copyright (c) 2012 embedded brains GmbH.
    1314 *
    1415 */
     
    2627#include <fcntl.h>
    2728#include <rtems.h>
    28 #include <rtems/libio.h>
    2929#include <rtems/libio_.h>
    3030#include <rtems/seterr.h>
    3131#include <rtems/rtems_bsdnet.h>
     32#include <rtems/tftp.h>
    3233#include <sys/types.h>
    3334#include <sys/socket.h>
     
    147148
    148149/*
    149  * Root node_access value
    150  * By using the address of the file system
    151  * we ensure a unique value for this identifier.
    152  */
    153 #define ROOT_NODE_ACCESS(_fs) (_fs)
    154 
    155 /*
    156150 * TFTP File system info.
    157151 */
     
    171165 */
    172166
    173 typedef const char *tftp_node;
    174167static const rtems_filesystem_operations_table  rtems_tftp_ops;
    175168static const rtems_filesystem_file_handlers_r   rtems_tftp_handlers;
     169
     170static bool rtems_tftp_is_directory(
     171    const char *path,
     172    size_t pathlen
     173)
     174{
     175    return path [pathlen - 1] == '/';
     176}
    176177
    177178int rtems_tftpfs_initialize(
     
    180181)
    181182{
    182   tftpfs_info_t     *fs;
    183183  rtems_status_code  sc;
    184 
    185   mt_entry->mt_fs_root.handlers = &rtems_tftp_handlers;
    186   mt_entry->mt_fs_root.ops      = &rtems_tftp_ops;
    187 
    188   /*
    189    *   We have no tftp filesystem specific data to maintain.  This
    190    *   filesystem may only be mounted ONCE.
    191    *
    192    *   And we maintain no real filesystem nodes, so there is no real root.
    193    */
    194 
    195   fs = malloc (sizeof (tftpfs_info_t));
    196   if (!fs)
    197       rtems_set_errno_and_return_minus_one (ENOMEM);
     184  const char *device = mt_entry->dev;
     185  size_t devicelen = strlen (device);
     186  tftpfs_info_t *fs;
     187  char *root_path;
     188
     189  if (devicelen == 0)
     190      rtems_set_errno_and_return_minus_one (ENXIO);
     191
     192  fs = malloc (sizeof (*fs));
     193  root_path = malloc (devicelen + 2);
     194  if (root_path == NULL || fs == NULL)
     195      goto error;
     196
     197  root_path = memcpy (root_path, device, devicelen);
     198  root_path [devicelen] = '/';
     199  root_path [devicelen + 1] = '\0';
    198200
    199201  fs->flags = 0;
     
    201203  fs->tftpStreams = 0;
    202204 
    203   mt_entry->fs_info                  = fs;
    204   mt_entry->mt_fs_root.node_access   = ROOT_NODE_ACCESS (fs);
    205   mt_entry->mt_fs_root.node_access_2 = NULL;
     205  mt_entry->fs_info = fs;
     206  mt_entry->mt_fs_root->location.node_access = root_path;
     207  mt_entry->mt_fs_root->location.handlers = &rtems_tftp_handlers;
     208  mt_entry->ops = &rtems_tftp_ops;
    206209 
    207210  /*
     
    224227
    225228  if (sc != RTEMS_SUCCESSFUL)
    226       rtems_set_errno_and_return_minus_one (ENOMEM);
     229      goto error;
    227230
    228231  if (data) {
     
    239242 
    240243  return 0;
     244
     245error:
     246
     247  free (fs);
     248  free (root_path);
     249
     250  rtems_set_errno_and_return_minus_one (ENOMEM);
    241251}
    242252
     
    255265}
    256266
    257 static int
     267static void
    258268rtems_tftpfs_shutdown (rtems_filesystem_mount_table_entry_t* mt_entry)
    259269{
     
    264274  rtems_semaphore_delete (fs->tftp_mutex);
    265275  free (fs);
    266   return 0;
     276  free (mt_entry->mt_fs_root->location.node_access);
    267277}
    268278
     
    417427        return errno;
    418428    return 0;
    419 }
    420 
    421 static int rtems_tftp_evaluate_for_make(
    422    const char                         *path __attribute__((unused)),       /* IN     */
    423    rtems_filesystem_location_info_t   *pathloc,    /* IN/OUT */
    424    const char                        **name __attribute__((unused))        /* OUT    */
    425 )
    426 {
    427   pathloc->node_access = NULL;
    428   pathloc->node_access_2 = NULL;
    429   rtems_set_errno_and_return_minus_one (EIO);
    430429}
    431430
     
    484483}
    485484
    486 static int rtems_tftp_eval_path(
    487   const char                        *pathname,     /* IN     */
    488   size_t                             pathnamelen,  /* IN     */         
    489   int                                flags,        /* IN     */
    490   rtems_filesystem_location_info_t  *pathloc       /* IN/OUT */
    491 )
    492 {
    493     tftpfs_info_t *fs;
    494     char          *cp;
    495 
    496     /*
    497      * Get the file system info.
    498      */
    499     fs = tftpfs_info_pathloc (pathloc);
    500 
    501     pathloc->handlers = &rtems_tftp_handlers;
    502 
    503     /*
    504      * Hack to provide the illusion of directories inside the TFTP file system.
    505      * Paths ending in a / are assumed to be directories.
    506      */
    507     if (pathname[strlen(pathname)-1] == '/') {
    508         int nal = 0;
    509         if (pathloc->node_access != ROOT_NODE_ACCESS (fs))
    510             nal = strlen(pathloc->node_access);
    511         cp = malloc(nal + pathnamelen + 1);
    512         if (cp == NULL)
    513             rtems_set_errno_and_return_minus_one(ENOMEM);
    514         if (nal)
    515             memcpy (cp, pathloc->node_access, nal);
    516         memcpy(cp + nal, pathname, pathnamelen);
    517         cp[nal + pathnamelen] = '\0';
    518         fixPath (cp);
    519         pathloc->node_access = cp;
    520     }
    521     else {
    522         if (pathnamelen) {
    523             /*
    524              * Reject it if it's not read-only or write-only.
    525              */
    526             flags &= RTEMS_LIBIO_PERMS_READ | RTEMS_LIBIO_PERMS_WRITE;
    527             if ((flags != RTEMS_LIBIO_PERMS_READ)   \
    528                 && (flags != RTEMS_LIBIO_PERMS_WRITE))
    529                 rtems_set_errno_and_return_minus_one(EINVAL);
    530 
    531             cp = malloc(pathnamelen + 1);
    532             if (cp == NULL)
    533                 rtems_set_errno_and_return_minus_one(ENOMEM);
    534             memcpy(cp, pathname, pathnamelen);
    535             cp[pathnamelen] = '\0';
    536             fixPath (cp);
    537             pathloc->node_access_2 = cp;
    538         }
    539     }
    540 
    541     return 0;
     485static void rtems_tftp_eval_path(rtems_filesystem_eval_path_context_t *self)
     486{
     487    int eval_flags = rtems_filesystem_eval_path_get_flags (self);
     488
     489    if ((eval_flags & RTEMS_FS_MAKE) == 0) {
     490        int rw = RTEMS_FS_PERMS_READ | RTEMS_FS_PERMS_WRITE;
     491
     492        if ((eval_flags & rw) != rw) {
     493            rtems_filesystem_location_info_t *currentloc =
     494                rtems_filesystem_eval_path_get_currentloc (self);
     495            char *current = currentloc->node_access;
     496            size_t currentlen = strlen (current);
     497            const char *path = rtems_filesystem_eval_path_get_path (self);
     498            size_t pathlen = rtems_filesystem_eval_path_get_pathlen (self);
     499            size_t len = currentlen + pathlen;
     500
     501            rtems_filesystem_eval_path_clear_path (self);
     502
     503            current = realloc (current, len + 1);
     504            if (current != NULL) {
     505                memcpy (current + currentlen, path, pathlen);
     506                current [len] = '\0';
     507                if (!rtems_tftp_is_directory (current, len)) {
     508                    fixPath (current);
     509                }
     510                currentloc->node_access = current;
     511            } else {
     512                rtems_filesystem_eval_path_error (self, ENOMEM);
     513            }
     514        } else {
     515            rtems_filesystem_eval_path_error (self, EINVAL);
     516        }
     517    } else {
     518        rtems_filesystem_eval_path_error (self, EIO);
     519    }
    542520}
    543521
     
    548526    rtems_libio_t *iop,
    549527    char          *full_path_name,
    550     uint32_t       flags,
    551     uint32_t       mode __attribute__((unused))
     528    int            oflag
    552529)
    553530{
     
    676653    tp->farAddress.sin_port = htons (69);
    677654
     655    if (fs->flags & TFTPFS_VERBOSE) {
     656        printf("TFTPFS: %d %s %s from %08lx\n", flags,
     657               ((flags & O_ACCMODE) == O_RDONLY)?"read":"write",
     658               remoteFilename, ntohl(farAddress.s_addr));
     659    }
    678660    /*
    679661     * Start the transfer
     
    685667         * Create the request
    686668         */
    687         if ((flags & O_ACCMODE) == O_RDONLY) {
     669        if ((oflag & O_ACCMODE) == O_RDONLY) {
    688670            tp->writing = 0;
    689671            tp->pkbuf.tftpRWRQ.opcode = htons (TFTP_OPCODE_RRQ);
     
    756738}
    757739
    758 /*
    759  * The IMFS open handler
    760  */
    761740static int rtems_tftp_open(
    762741    rtems_libio_t *iop,
    763742    const char    *new_name,
    764     uint32_t       flags,
    765     uint32_t       mode
     743    int            oflag,
     744    mode_t         mode
    766745)
    767746{
    768747    tftpfs_info_t *fs;
    769     const char    *device;
    770748    char          *full_path_name;
    771     char          *na;
    772     char          *na2;
    773     int           dlen;
    774     int           nalen;
    775     int           na2len;
    776     int           sep1;
    777749    int           err;
    778750
     751    full_path_name = iop->pathinfo.node_access;
     752
     753    if (rtems_tftp_is_directory (full_path_name, strlen (full_path_name))) {
     754        rtems_set_errno_and_return_minus_one (ENOTSUP);
     755    }
     756
    779757    /*
    780758     * Get the file system info.
    781759     */
    782760    fs = tftpfs_info_iop (iop);
    783    
    784     /*
    785      * Tack the prefix directory if one exists from the device name.
    786      */
    787     device =
    788       rtems_filesystem_mount_device (rtems_filesystem_location_mount (&iop->pathinfo));
    789     dlen = device ? strlen(device) : 0;
    790 
    791     if (iop->pathinfo.node_access == NULL || iop->pathinfo.node_access_2 == NULL)
    792         rtems_set_errno_and_return_minus_one (ENOENT);
    793 
    794     if (iop->pathinfo.node_access != ROOT_NODE_ACCESS (fs)) {
    795         na = iop->pathinfo.node_access;
    796         nalen = strlen (na);
    797     }     
    798     else {
    799         na = NULL;
    800         nalen = 0;
    801     }
    802 
    803     na2 = iop->pathinfo.node_access_2;
    804    
    805     na2len = strlen (na2);
    806 
    807     if (nalen) {
    808       sep1 = 1;
    809         if (na[nalen] == '/') {
    810             sep1 = 0;
    811             if (na2[0] == '/')
    812                 ++na2;
    813         }
    814         else {
    815             if (na2[0] == '/')
    816                 sep1 = 0;
    817             else
    818                 sep1 = 1;
    819         }
    820     }
    821     else
    822       sep1 = 0;
    823 
    824     full_path_name = malloc (dlen + nalen + sep1 + na2len + 1);
    825     if (full_path_name == NULL)
    826         rtems_set_errno_and_return_minus_one(ENOMEM);
    827     if (dlen)
    828         strcpy (full_path_name, device);
    829     else
    830         strcpy (full_path_name, "");
    831     if (nalen)
    832       strcat (full_path_name, na);
    833     if (sep1)
    834         strcat (full_path_name, "/");
    835     strcat (full_path_name, na2);
    836     fixPath (full_path_name);
    837761
    838762    if (fs->flags & TFTPFS_VERBOSE)
    839       printf ("TFTPFS: %s %s %s -> %s\n", device, na, na2, full_path_name);
    840 
    841     err = rtems_tftp_open_worker (iop, full_path_name, flags, mode);
    842     free (full_path_name);
    843     rtems_set_errno_and_return_minus_one(err);
     763      printf ("TFTPFS: %s\n", full_path_name);
     764
     765    err = rtems_tftp_open_worker (iop, full_path_name, oflag);
     766    if (err != 0) {
     767       rtems_set_errno_and_return_minus_one (err);
     768    }
     769
     770    return 0;
    844771}
    845772
     
    1052979static int rtems_tftp_ftruncate(
    1053980    rtems_libio_t   *iop __attribute__((unused)),
    1054     rtems_off64_t    count __attribute__((unused))
     981    off_t            count __attribute__((unused))
    1055982)
    1056983{
     
    1058985}
    1059986
    1060 static rtems_filesystem_node_types_t rtems_tftp_node_type(
    1061      rtems_filesystem_location_info_t        *pathloc                 /* IN */
    1062 )
    1063 {
    1064     tftpfs_info_t *fs = tftpfs_info_pathloc (pathloc);
    1065     if ((pathloc->node_access == NULL)
    1066      || (pathloc->node_access_2 != NULL)
    1067         || (pathloc->node_access == ROOT_NODE_ACCESS (fs)))
    1068         return RTEMS_FILESYSTEM_MEMORY_FILE;
    1069     return RTEMS_FILESYSTEM_DIRECTORY;
    1070 }
    1071 
    1072 static int rtems_tftp_free_node_info(
    1073      rtems_filesystem_location_info_t        *pathloc                 /* IN */
    1074 )
    1075 {
    1076     tftpfs_info_t *fs = tftpfs_info_pathloc (pathloc);
    1077     if (pathloc->node_access && \
    1078         (pathloc->node_access != ROOT_NODE_ACCESS (fs))) {
    1079         free (pathloc->node_access);
    1080         pathloc->node_access = NULL;
    1081     }
    1082     if (pathloc->node_access_2) {
    1083         free (pathloc->node_access_2);
    1084         pathloc->node_access_2 = NULL;
    1085     }
     987static int rtems_tftp_fstat(
     988    const rtems_filesystem_location_info_t *loc,
     989    struct stat                            *buf
     990)
     991{
     992    const char *path = loc->node_access;
     993    size_t pathlen = strlen (path);
     994
     995    buf->st_mode = S_IRWXU | S_IRWXG | S_IRWXO
     996        | (rtems_tftp_is_directory (path, pathlen) ? S_IFDIR : S_IFREG);
     997
    1086998    return 0;
    1087999}
    10881000
     1001static int rtems_tftp_clone(
     1002    rtems_filesystem_location_info_t *loc
     1003)
     1004{
     1005    int rv = 0;
     1006
     1007    loc->node_access = strdup (loc->node_access);
     1008
     1009    if (loc->node_access == NULL) {
     1010        errno = ENOMEM;
     1011        rv = -1;
     1012    }
     1013
     1014    return rv;
     1015}
     1016
     1017static void rtems_tftp_free_node_info(
     1018    const rtems_filesystem_location_info_t *loc
     1019)
     1020{
     1021    free (loc->node_access);
     1022}
     1023
     1024static bool rtems_tftp_are_nodes_equal(
     1025  const rtems_filesystem_location_info_t *a,
     1026  const rtems_filesystem_location_info_t *b
     1027)
     1028{
     1029  return strcmp (a->node_access, b->node_access) == 0;
     1030}
    10891031
    10901032static const rtems_filesystem_operations_table  rtems_tftp_ops = {
    1091     rtems_tftp_eval_path,            /* eval_path */
    1092     rtems_tftp_evaluate_for_make,    /* evaluate_for_make */
    1093     NULL,                            /* link */
    1094     NULL,                            /* unlink */
    1095     rtems_tftp_node_type,            /* node_type */
    1096     NULL,                            /* mknod */
    1097     NULL,                            /* chown */
    1098     rtems_tftp_free_node_info,       /* freenodinfo */
    1099     NULL,                            /* mount */
    1100     rtems_tftpfs_initialize,         /* initialize */
    1101     NULL,                            /* unmount */
    1102     rtems_tftpfs_shutdown,           /* fsunmount */
    1103     NULL,                            /* utime, */
    1104     NULL,                            /* evaluate_link */
    1105     NULL,                            /* symlink */
    1106     NULL,                            /* readlin */
     1033    .lock_h = rtems_filesystem_default_lock,
     1034    .unlock_h = rtems_filesystem_default_unlock,
     1035    .eval_path_h = rtems_tftp_eval_path,
     1036    .link_h = rtems_filesystem_default_link,
     1037    .are_nodes_equal_h = rtems_tftp_are_nodes_equal,
     1038    .mknod_h = rtems_filesystem_default_mknod,
     1039    .rmnod_h = rtems_filesystem_default_rmnod,
     1040    .fchmod_h = rtems_filesystem_default_fchmod,
     1041    .chown_h = rtems_filesystem_default_chown,
     1042    .clonenod_h = rtems_tftp_clone,
     1043    .freenod_h = rtems_tftp_free_node_info,
     1044    .mount_h = rtems_filesystem_default_mount,
     1045    .unmount_h = rtems_filesystem_default_unmount,
     1046    .fsunmount_me_h = rtems_tftpfs_shutdown,
     1047    .utime_h = rtems_filesystem_default_utime,
     1048    .symlink_h = rtems_filesystem_default_symlink,
     1049    .readlink_h = rtems_filesystem_default_readlink,
     1050    .rename_h = rtems_filesystem_default_rename,
     1051    .statvfs_h = rtems_filesystem_default_statvfs
    11071052};
    11081053
    11091054static const rtems_filesystem_file_handlers_r rtems_tftp_handlers = {
    1110     rtems_tftp_open,      /* open */
    1111     rtems_tftp_close,     /* close */
    1112     rtems_tftp_read,      /* read */
    1113     rtems_tftp_write,     /* write */
    1114     NULL,                 /* ioctl */
    1115     NULL,                 /* lseek */
    1116     NULL,                 /* fstat */
    1117     NULL,                 /* fchmod */
    1118     rtems_tftp_ftruncate, /* ftruncate */
    1119     NULL,                 /* fpathconf */
    1120     NULL,                 /* fsync */
    1121     NULL,                 /* fdatasync */
    1122     NULL,                 /* fcntl */
    1123     NULL                  /* rmnod */
     1055   .open_h = rtems_tftp_open,
     1056   .close_h = rtems_tftp_close,
     1057   .read_h = rtems_tftp_read,
     1058   .write_h = rtems_tftp_write,
     1059   .ioctl_h = rtems_filesystem_default_ioctl,
     1060   .lseek_h = rtems_filesystem_default_lseek,
     1061   .fstat_h = rtems_tftp_fstat,
     1062   .ftruncate_h = rtems_tftp_ftruncate,
     1063   .fsync_h = rtems_filesystem_default_fsync_or_fdatasync,
     1064   .fdatasync_h = rtems_filesystem_default_fsync_or_fdatasync,
     1065   .fcntl_h = rtems_filesystem_default_fcntl,
     1066   .kqfilter_h = rtems_filesystem_default_kqfilter,
     1067   .poll_h = rtems_filesystem_default_poll,
     1068   .readv_h = rtems_filesystem_default_readv,
     1069   .writev_h = rtems_filesystem_default_writev
    11241070};
Note: See TracChangeset for help on using the changeset viewer.