Update of /cvsroot/linux-decnet/dnprogs/dapfs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1416
Modified Files:
Makefile dapfs.c dapfs_dap.cc
Added Files:
filenames.c filenames.h
Log Message:
A bit more work. Seems basically functional now
--- NEW FILE: filenames.c ---
/******************************************************************************
(c) 2005 P.J. Caulfield pa...@ty...
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
******************************************************************************
*/
/* This code is lifted from FAL. */
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/mman.h>
#include <assert.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <syslog.h>
#include <pwd.h>
#include <grp.h>
#include <glob.h>
#include <regex.h>
#include <string.h>
#include <netdnet/dn.h>
#include <netdnet/dnetdb.h>
#include "filenames.h"
static int vms_format; // Do we use this ??
#define true 1
#define false 0
const char *sysdisk_name = "SYS$SYSDEVICE";
// A couple of general utility methods:
static void makelower(char *s)
{
unsigned int i;
for (i=0; i<strlen(s); i++) s[i] = tolower(s[i]);
}
static void makeupper(char *s)
{
unsigned int i;
for (i=0; i<strlen(s); i++) s[i] = toupper(s[i]);
}
// A test to see if the file is a VMS-type filespec or a Unix one
// Also sets the 'vms_format' flag
int is_vms_name(char *name)
{
if ( (strchr(name, '[') && strchr(name, ']')) ||
strchr(name, ';') || strchr(name, ':') )
return vms_format=true;
else
return vms_format=false;
}
// Splits a filename up into volume, directory and file parts.
// The volume and directory are just for display purposes (they get sent back
// to the client). file is the (possibly) wildcard filespec to use for
// searching for files.
//
// Unix filenames are just returned as-is.
//
// volume and directory are assumed to be long enough for PATH_MAX. file
// also contains the input filespec.
//
void split_filespec(char *volume, char *directory, char *file)
{
if (is_vms_name(file))
{
// This converts the VMS name to a Unix name and back again. This
// involves calling parse_vms_filespec twice and ourself once more.
// YES THIS IS RIGHT! We need to make sense of the input file name
// in our own terms and then send back our re-interpretation of
// the input filename. This is what any sensible operating
// system would do. (VMS certainly does!)
// Convert it to a Unix filespec
char unixname[PATH_MAX];
char vmsname[PATH_MAX];
make_unix_filespec(unixname, file);
// Parse that Unix name
strcpy(file, unixname);
split_filespec(volume, directory, file);
// Then convert it back to VMS
make_vms_filespec(unixname, vmsname, true);
// Split up the VMS spec for returning in bits
parse_vms_filespec(volume, directory, vmsname);
// Make sure we set this back to true after we called ourself with a
// Unix filespec
vms_format = true;
return;
}
// We don't fill in the volume for unix filespecs
volume[0] = '\0';
directory[0] = '\0';
}
// Convert a Unix-style filename to a VMS-style name
// No return code because this routine cannot fail :-)
void make_vms_filespec(const char *unixname, char *vmsname, int full)
{
char fullname[PATH_MAX];
int i;
char *lastslash;
struct stat st;
// Resolve all relative bits and symbolic links
realpath(unixname, fullname);
// Find the last slash in the name
lastslash = fullname + strlen(fullname);
while (*(--lastslash) != '/') ;
// If the filename has no extension then add one. VMS seems to
// expect one as does dapfs.
if (!strchr(lastslash, '.'))
strcat(fullname, ".");
// If it's a directory then add .DIR;1
if (lstat(unixname, &st)==0 && S_ISDIR(st.st_mode))
{
// Take care of dots embedded in directory names (/etc/rc.d)
if (fullname[strlen(fullname)-1] != '.')
strcat(fullname, ".");
strcat(fullname, "DIR;1"); // last dot has already been added
}
else // else just add a version number unless the file already has one
{
if (!strchr(fullname, ';'))
strcat(fullname, ";1");
}
// If we were only asked for the short name then return that bit now
if (!full)
{
i=strlen(fullname);
while (fullname[i--] != '/') ;
strcpy(vmsname, &fullname[i+2]);
// Make it all uppercase
makeupper(vmsname);
return;
}
// Count the slashes. If there is one slash we emit a filename like:
// SYSDISK:[000000]filename
// For two we use:
// SYSDISK:[DIR]filename
// for three or more we use:
// DIR:[DIR1]filename
// and so on...
int slashes = 0;
// Oh, also make it all upper case for VMS's benefit.
for (i=0; i<(int)strlen(fullname); i++)
{
if (islower(fullname[i])) fullname[i] = toupper(fullname[i]);
if (fullname[i] == '/')
{
slashes++;
}
}
// File is in the root directory
if (slashes == 1)
{
sprintf(vmsname, "%s:[000000]%s", sysdisk_name, fullname+1);
return;
}
// File is in a directory immediately below the root directory
if (slashes == 2)
{
char *second_slash = strchr(fullname+1, '/');
*second_slash = '\0';
strcpy(vmsname, sysdisk_name);
strcat(vmsname, ":[");
strcat(vmsname, fullname+1);
strcat(vmsname, "]");
strcat(vmsname, second_slash+1);
return;
}
// Most user filenames end up here
char *slash2 = strchr(fullname+1, '/');
*slash2 = '\0';
strcpy(vmsname, fullname+1);
strcat(vmsname, ":[");
// Do the directory depth
lastslash = slash2;
for (i=1; i<slashes-1; i++)
{
char *slash = strchr(lastslash+1, '/');
if (slash)
{
*slash = '\0';
strcat(vmsname, lastslash+1);
strcat(vmsname, ".");
lastslash = slash;
}
}
vmsname[strlen(vmsname)-1] = ']';
strcat(vmsname, lastslash+1);
}
// Split out the volume, directory and file portions of a VMS file spec
// We assume that the VMS name is (quite) well formed.
void parse_vms_filespec(char *volume, char *directory, char *file)
{
char *colon = strchr(file, ':');
char *ptr = file;
volume[0] = '\0';
directory[0] = '\0';
if (colon) // We have a volume name
{
char saved = *(colon+1);
*(colon+1) = '\0';
strcpy(volume, file);
ptr = colon+1;
*ptr = saved;
}
char *enddir = strchr(ptr, ']');
// Don't get caught out by concatenated filespecs
// like dua0:[home.patrick.][test]
if (enddir && enddir[1] == '[')
enddir=strchr(enddir+1, ']');
if (*ptr == '[' && enddir) // we have a directory
{
char saved = *(enddir+1);
*(enddir+1) = '\0';
strcpy(directory, ptr);
ptr = enddir+1;
*ptr = saved;
}
// Copy the rest of the filename using memmove 'cos it might overlap
if (ptr != file)
memmove(file, ptr, strlen(ptr)+1);
}
// Convert a VMS filespec into a Unix filespec
// volume names are turned into directories in the root directory
// (unless they are SYSDISK which is our pseudo name)
void make_unix_filespec(char *unixname, char *vmsname)
{
char volume[PATH_MAX];
char dir[PATH_MAX];
char file[PATH_MAX];
int ptr;
int i;
strcpy(file, vmsname);
// Remove the trailing version number
char *semi = strchr(file, ';');
if (semi) *semi = '\0';
// If the filename has a trailing dot them remove that too
if (file[strlen(file)-1] == '.')
file[strlen(file)-1] = '\0';
unixname[0] = '\0';
// Split it into its component parts
parse_vms_filespec(volume, dir, file);
// Remove the trailing colon from the volume name
if (volume[strlen(volume)-1] == ':')
volume[strlen(volume)-1] = '\0';
// If the filename has the dummy SYSDISK volume then start from the
// filesystem root
if (strcasecmp(volume, sysdisk_name) == 0)
{
strcpy(unixname, "/");
}
else
{
if (volume[0] != '\0')
{
strcpy(unixname, "/");
strcat(unixname, volume);
}
}
ptr = strlen(unixname);
// Copy the directory
for (i=0; i< (int)strlen(dir); i++)
{
// If the directory name starts [. then it is relative to the
// user's home directory and we lose the starting slash
// If there is also a volume name present then it all falls
// to bits but then it's pretty dodgy on VMS too.
if (dir[i] == '[' &&
dir[i+1] == '.')
{
i++;
ptr = 0;
continue;
}
if (dir[i] == '[' ||
dir[i] == ']' ||
dir[i] == '.')
{
unixname[ptr++] = '/';
}
else
{
// Skip root directory specs
if (dir[i] == '0' && (strncmp(&dir[i], "000000", 6) == 0))
{
i += 5;
continue;
}
if (dir[i] == '0' && (strncmp(&dir[i], "0,0", 3) == 0))
{
i += 2;
continue;
}
unixname[ptr++] = dir[i];
}
}
unixname[ptr++] = '\0'; // so that strcat will work properly
// A special case (ugh!), if VMS sent us '*.*' (maybe as part of *.*;*)
// then change it to just '*' so we get all the files.
if (strcmp(file, "*.*") == 0) strcpy(file, "*");
strcat(unixname, file);
// Finally convert it all to lower case. This is not the greatest way to
// cope with it but because VMS will upper-case everything anyway we
// can't really distinguish case. I know samba does fancy stuff with
// matching various combinations of case but I really can't be bothered.
makelower(unixname);
// If the name ends in .dir and there is a directory of that name without
// the .dir then remove it (the .dir, not the directory!)
if (strstr(unixname, ".dir") == unixname+strlen(unixname)-4)
{
char dirname[strlen(unixname)+1];
struct stat st;
strcpy(dirname, unixname);
char *ext = strstr(dirname, ".dir");
if (ext) *ext = '\0';
if (stat(dirname, &st) == 0 &&
S_ISDIR(st.st_mode))
{
char *ext = strstr(unixname, ".dir");
if (ext) *ext = '\0';
}
}
}
--- NEW FILE: filenames.h ---
/******************************************************************************
(c) 2005 P.J. Caulfield pa...@ty...
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
******************************************************************************
*/
/* filenames.c */
int is_vms_name(char *name);
void split_filespec(char *volume, char *directory, char *file);
void make_vms_filespec(const char *unixname, char *vmsname, int full);
void parse_vms_filespec(char *volume, char *directory, char *file);
void make_unix_filespec(char *unixname, char *vmsname);
Index: Makefile
===================================================================
RCS file: /cvsroot/linux-decnet/dnprogs/dapfs/Makefile,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** Makefile 7 Oct 2005 13:40:33 -0000 1.1
--- Makefile 12 Oct 2005 10:31:31 -0000 1.2
***************
*** 7,11 ****
MANPAGES=dapfs.1
! PROG1OBJS=dapfs.o dapfs_dap.o
all: $(PROG1)
--- 7,11 ----
MANPAGES=dapfs.1
! PROG1OBJS=dapfs.o dapfs_dap.o filenames.o
all: $(PROG1)
Index: dapfs.c
===================================================================
RCS file: /cvsroot/linux-decnet/dnprogs/dapfs/dapfs.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** dapfs.c 7 Oct 2005 13:40:33 -0000 1.1
--- dapfs.c 12 Oct 2005 10:31:31 -0000 1.2
***************
*** 24,28 ****
--- 24,34 ----
#include "rms.h"
#include "dapfs_dap.h"
+ #include "filenames.h"
+ struct dapfs_handle
+ {
+ RMSHANDLE rmsh;
+ off_t offset;
+ };
char prefix[1024];
***************
*** 61,85 ****
}
- static int dapfs_utime(const char *path, struct utimbuf *buf)
- {
- // TODO
- return -ENOSYS;
- }
-
-
static int dapfs_open(const char *path, struct fuse_file_info *fi)
{
! RMSHANDLE h;
char fullname[2048];
! // TODO: This WILL break on VMS - we need to nick the Unix->VMS path stuff from FAL
! sprintf(fullname, "%s%s", prefix, path);
syslog(1, "dapfs: filename: %s\n", fullname);
! h = rms_open(fullname, fi->flags, NULL);
syslog(1, "dapfs: rms_open %p, %d\n", h, errno);
! if (!h)
! return -errno;
fi->fh = (unsigned long)h;
return 0;
}
--- 67,93 ----
}
static int dapfs_open(const char *path, struct fuse_file_info *fi)
{
! struct dapfs_handle *h;
char fullname[2048];
+ char vmsname[2048];
+
+ h = malloc(sizeof(struct dapfs_handle));
+ if (!h)
+ return -ENOMEM;
! make_vms_filespec(path, vmsname, 0);
! sprintf(fullname, "%s%s", prefix, vmsname);
syslog(1, "dapfs: filename: %s\n", fullname);
! h->rmsh = rms_open(fullname, fi->flags, NULL);
syslog(1, "dapfs: rms_open %p, %d\n", h, errno);
! if (!h->rmsh) {
! int saved_errno = errno;
! free(h);
! return -saved_errno;
! }
fi->fh = (unsigned long)h;
+ h->offset = 0;
return 0;
}
***************
*** 91,109 ****
int got = 0;
struct RAB rab;
! RMSHANDLE h = (RMSHANDLE)fi->fh;
- // TODO Detect if offset hasn't changed...
memset(&rab, 0, sizeof(rab));
! if (offset) {
rab.rab$l_kbf = &offset;
rab.rab$b_rac = 2;//FB$RFA;
rab.rab$b_ksz = sizeof(offset);
}
do {
! res = rms_read(h, buf+got, size-got, &rab);
if (res)
got += res;
- syslog(1, "rms_read returned %d (errno=%d) size = %d\n", res, errno, size);
} while (res > 0);
if (res >= 0)
--- 99,118 ----
int got = 0;
struct RAB rab;
! struct dapfs_handle *h = (struct dapfs_handle *)fi->fh;
memset(&rab, 0, sizeof(rab));
! if (offset && offset != h->offset) {
rab.rab$l_kbf = &offset;
rab.rab$b_rac = 2;//FB$RFA;
rab.rab$b_ksz = sizeof(offset);
}
+
+ // TODO this can be quite slow, because it reads records. Maybe we
+ // should abandon librms and pull blocks down as per dncopy
do {
! res = rms_read(h->rmsh, buf+got, size-got, &rab);
if (res)
got += res;
} while (res > 0);
if (res >= 0)
***************
*** 113,116 ****
--- 122,126 ----
res = -errno;
+ h->offset += res;
return res;
}
***************
*** 119,129 ****
off_t offset, struct fuse_file_info *fi)
{
! // TODO
! return -ENOSYS;
}
static int dapfs_release(const char *path, struct fuse_file_info *fi)
{
! return rms_close((RMSHANDLE)fi->fh);
}
--- 129,169 ----
off_t offset, struct fuse_file_info *fi)
{
! int res;
! int got = 0;
! struct RAB rab;
! struct dapfs_handle *h = (struct dapfs_handle *)fi->fh;
!
! memset(&rab, 0, sizeof(rab));
! if (offset && offset != h->offset) {
! rab.rab$l_kbf = &offset;
! rab.rab$b_rac = 2;//FB$RFA;
! rab.rab$b_ksz = sizeof(offset);
! }
!
! do {
! res = rms_write(h->rmsh, (char *)buf+got, size-got, &rab);
! if (res)
! got += res;
!
! } while (res > 0);
! if (res >= 0)
! res = got;
!
! if (res == -1)
! res = -errno;
!
! h->offset += res;
! return res;
}
static int dapfs_release(const char *path, struct fuse_file_info *fi)
{
! struct dapfs_handle *h = (struct dapfs_handle *)fi->fh;
! int ret;
!
! ret = rms_close(h->rmsh);
! free(h);
!
! return ret;
}
***************
*** 132,141 ****
int res;
syslog(1, "dapfs - getattr on %s\n", path);
! if (strcmp(path, "/") == 0)
! {
res = stat("/", stbuf);
}
! else
! {
res = dapfs_getattr_dap(path, stbuf);
}
--- 172,179 ----
int res;
syslog(1, "dapfs - getattr on %s\n", path);
! if (strcmp(path, "/") == 0) {
res = stat("/", stbuf);
}
! else {
res = dapfs_getattr_dap(path, stbuf);
}
***************
*** 153,157 ****
.rmdir = dapfs_rmdir,
.rename = dapfs_rename,
- .utime = dapfs_utime,
.release = dapfs_release,
};
--- 191,194 ----
Index: dapfs_dap.cc
===================================================================
RCS file: /cvsroot/linux-decnet/dnprogs/dapfs/dapfs_dap.cc,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** dapfs_dap.cc 7 Oct 2005 13:40:33 -0000 1.1
--- dapfs_dap.cc 12 Oct 2005 10:31:31 -0000 1.2
***************
*** 16,28 ****
#include "protocol.h"
#include "dapfs_dap.h"
!
! int dapfs_getattr_dap(const char *path, struct stat *stbuf)
{
- dap_connection conn(0);
char dirname[256] = {'\0'};
- char name[80],cdt[25],owner[20],prot[22];
- int size;
-
if (!conn.connect(prefix, dap_connection::FAL_OBJECT, dirname))
{
--- 16,26 ----
#include "protocol.h"
#include "dapfs_dap.h"
+ extern "C" {
+ #include "filenames.h"
+ }
! static int dap_connect(dap_connection &conn)
{
char dirname[256] = {'\0'};
if (!conn.connect(prefix, dap_connection::FAL_OBJECT, dirname))
{
***************
*** 34,44 ****
{
fprintf(stderr, "Error in config: %s\n", conn.get_error());
! return -1;
}
dap_access_message acc;
acc.set_accfunc(dap_access_message::DIRECTORY);
acc.set_accopt(1);
! acc.set_filespec(path); // PJC TODO Translate to VMS format...
acc.set_display(dap_access_message::DISPLAY_MAIN_MASK |
dap_access_message::DISPLAY_DATE_MASK |
--- 32,109 ----
{
fprintf(stderr, "Error in config: %s\n", conn.get_error());
! return -ENOTCONN;
! }
! return 0;
! }
!
! static void add_to_stat(dap_message *m, struct stat *stbuf)
! {
! switch (m->get_type())
! {
! case dap_message::NAME:
! {
! dap_name_message *nm = (dap_name_message *)m;
!
! // If name ends in .DIR;1 then add directory attribute
! if (nm->get_nametype() == dap_name_message::FILENAME) {
! if (strstr(nm->get_namespec(), ".DIR;1")) {
! stbuf->st_mode |= S_IFDIR;
! syslog(1, "%s is a directory\n", nm->get_namespec());
! }
! else {
! stbuf->st_mode &= ~S_IFDIR;
! }
! }
}
+ break;
+
+ case dap_message::PROTECT:
+ {
+ dap_protect_message *pm = (dap_protect_message *)m;
+ stbuf->st_mode |= pm->get_mode();
+ stbuf->st_uid = 0;
+ stbuf->st_gid = 0;
+ }
+ break;
+
+ case dap_message::ATTRIB:
+ {
+ dap_attrib_message *am = (dap_attrib_message *)m;
+ stbuf->st_size = am->get_size();
+ stbuf->st_blksize = am->get_bsz();
+ stbuf->st_blocks = am->get_alq();
+ }
+ break;
+
+ case dap_message::DATE:
+ {
+ dap_date_message *dm = (dap_date_message *)m;
+ syslog(1, "got date message\n");
+ stbuf->st_atime = dm->get_rdt_time();
+ stbuf->st_ctime = dm->get_cdt_time();
+ stbuf->st_mtime = dm->get_cdt_time();
+ }
+ break;
+ }
+ }
+
+ int dapfs_getattr_dap(const char *path, struct stat *stbuf)
+ {
+ dap_connection conn(0);
+ char vmsname[1024];
+ char name[80];
+ int ret;
+ int size;
+
+ ret = dap_connect(conn);
+ if (ret)
+ return ret;
+
+ make_vms_filespec(path, vmsname, 0);
dap_access_message acc;
acc.set_accfunc(dap_access_message::DIRECTORY);
acc.set_accopt(1);
! acc.set_filespec(vmsname);
acc.set_display(dap_access_message::DISPLAY_MAIN_MASK |
dap_access_message::DISPLAY_DATE_MASK |
***************
*** 46,99 ****
acc.write(conn);
- bool name_pending = false;
dap_message *m;
- char volname[256];
// Loop through the files we find
while ( ((m=dap_message::read_message(conn, true) )) )
{
! switch (m->get_type())
! {
! case dap_message::NAME:
! break;
!
! case dap_message::PROTECT:
{
! dap_protect_message *pm = (dap_protect_message *)m;
! stbuf->st_mode = pm->get_mode();
! stbuf->st_uid = 0;
! stbuf->st_gid = 0;
}
- break;
-
- case dap_message::ATTRIB:
- {
- dap_attrib_message *am = (dap_attrib_message *)m;
- stbuf->st_size = am->get_size();
- stbuf->st_blksize = am->get_bsz();
- stbuf->st_blocks = am->get_alq();
- }
- break;
-
- case dap_message::DATE:
- {
- dap_date_message *dm = (dap_date_message *)m;
- stbuf->st_atime = dm->get_rdt_time();
- stbuf->st_ctime = dm->get_cdt_time();
- stbuf->st_mtime = dm->get_cdt_time();
- }
- break;
-
- case dap_message::ACK:
- break;
-
- case dap_message::STATUS:
- case dap_message::ACCOMP:
delete m;
- goto finished;
- }
}
- // TODO if name ends in .DIR;1 then add DIRECTORY to st_mode
- // TODO Errors;
finished:
conn.close();
--- 111,126 ----
acc.write(conn);
dap_message *m;
// Loop through the files we find
while ( ((m=dap_message::read_message(conn, true) )) )
{
! add_to_stat(m, stbuf);
! if (m->get_type() == dap_message::ACCOMP)
{
! goto finished;
}
delete m;
}
finished:
conn.close();
***************
*** 105,128 ****
{
dap_connection conn(0);
! char dirname[256] = {'\0'};
! char name[80],cdt[25],owner[20],prot[22];
int size;
! if (!conn.connect(prefix, dap_connection::FAL_OBJECT, dirname))
! {
! return -ENOTCONN;
! }
! // Exchange config messages
! if (!conn.exchange_config())
! {
! fprintf(stderr, "Error in config: %s\n", conn.get_error());
! return -1;
}
dap_access_message acc;
acc.set_accfunc(dap_access_message::DIRECTORY);
acc.set_accopt(1);
! acc.set_filespec(path); // PJC TODO Translate to VMS format...
acc.set_display(dap_access_message::DISPLAY_MAIN_MASK |
dap_access_message::DISPLAY_DATE_MASK |
--- 132,160 ----
{
dap_connection conn(0);
! char vmsname[1024];
! char wildname[strlen(path)+2];
! char name[80];
! struct stat stbuf;
int size;
+ int ret;
! memset(&stbuf, 0, sizeof(stbuf));
! ret = dap_connect(conn);
! if (ret)
! return ret;
! // Add wildcard to path
! if (path[strlen(path)-1] == '/') {
! sprintf(wildname, "%s*", path);
! path = wildname;
}
+ make_vms_filespec(path, vmsname, 0);
+ syslog(1, "readdir: dir = %s: %s\n", path, vmsname);
+
dap_access_message acc;
acc.set_accfunc(dap_access_message::DIRECTORY);
acc.set_accopt(1);
! acc.set_filespec(vmsname);
acc.set_display(dap_access_message::DISPLAY_MAIN_MASK |
dap_access_message::DISPLAY_DATE_MASK |
***************
*** 137,140 ****
--- 169,174 ----
while ( ((m=dap_message::read_message(conn, true) )) )
{
+ add_to_stat(m, &stbuf);
+
switch (m->get_type())
{
***************
*** 143,149 ****
if (name_pending)
{
name_pending = false;
! // TODO fill stat
! filler(buf, name, NULL, 0);
}
--- 177,185 ----
if (name_pending)
{
+ char unixname[1024];
name_pending = false;
! make_unix_filespec(unixname, name);
! filler(buf, unixname, &stbuf, 0);
! memset(&stbuf, 0, sizeof(stbuf));
}
***************
*** 163,193 ****
break;
- case dap_message::PROTECT:
- {
- dap_protect_message *pm = (dap_protect_message *)m;
- strcpy(owner, pm->get_owner());
- strcpy(prot, pm->get_protection());
- }
- break;
-
- case dap_message::ATTRIB:
- {
- dap_attrib_message *am = (dap_attrib_message *)m;
- size = am->get_size();
- }
- break;
-
- case dap_message::DATE:
- {
- dap_date_message *dm = (dap_date_message *)m;
- strcpy(cdt, dm->make_y2k(dm->get_cdt()));
- }
- break;
-
- case dap_message::ACK:
- {
- }
- break;
-
case dap_message::STATUS:
{
--- 199,202 ----
***************
*** 206,211 ****
else
{
! printf("Error opening %s: %s\n", dirname,
! sm->get_message());
name_pending = false;
goto flush;
--- 215,219 ----
else
{
! printf("Error opening %s: %s\n", vmsname, sm->get_message());
name_pending = false;
goto flush;
***************
*** 228,233 ****
if (name_pending)
{
! // TODO fill stat
! filler(buf, name, NULL, 0);
}
conn.close();
--- 236,242 ----
if (name_pending)
{
! char unixname[1024];
! make_unix_filespec(unixname, name);
! filler(buf, name, &stbuf, 0);
}
conn.close();
|