Files
open-simh.simtools/extracters/ods2/vmsfile.c
Timothe Litt 66e00b9900 Backlog of work since 2016
Too much to list all, but includes (in no particular order):
 - Cleanup for 64-bit builds, MSVC warnings.
 - Structured help
 - Help file compiler.
 - Supports volsets, writes/create work.
 - Support for I18n in messages, help.
 - Makefiles.
 - Initialize volume/volset
 - Command line editing/history

Builds and works on Linux and Windows (VS).
Not recently built or tested on other platforms, but
not intentinonally broken.
2022-10-10 11:00:20 -04:00

179 lines
4.5 KiB
C

/* This is part of ODS2 written by Paul Nankervis,
* email address: Paulnank@au1.ibm.com
* ODS2 is distributed freely for all members of the
* VMS community to use. However all derived works
* must maintain comments in their source to acknowledge
* the contributions of the original author and
* subsequent contributors. This is free software; no
* warranty is offered, and while we believe it to be useful,
* you use it at your own risk.
*/
/* Copyright (C) 2016 Timothe Litt, litt at acm dot org.
*/
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <starlet.h>
#include <rms.h>
#include <ssdef.h>
#include <stsdef.h>
#include <descrip.h>
#include "vmsfile.h"
#ifndef $SUCCESSFUL
#define $SUCCESSFUL(cond) (((cond) & STS$M_SUCCESS))
#endif
typedef struct globlist_ {
struct globlist_ *next;
char path[1];
} globlist_;
/******************************************************************* addfile() */
static int addfile( int flags, glob_t *pglob, dsc$descriptor_d *path ) {
size_t n, ofs;
char ** nl;
globlist_ *fp;
ofs = pglob->gl_pathc;
if( flags & GLOB_DOOFFS )
ofs += pglob->gl_offs;
if( (nl = (char **)realloc( pglob->gl_pathv,
(ofs + 2) * sizeof( char **) )) == NULL ) {
return GLOB_NOSPACE;
}
pglob->gl_pathv = nl;
n = offsetof( globlist_, path ) + path->dsc$w_length;
if( (fp = malloc( n + 1 )) == NULL )
return GLOB_NOSPACE;
memcpy( fp->path, path->dsc$a_pointer, n - offsetof( globlist_, path ) );
fp->path[n] = '\0';
pglob->gl_pathv[ofs++] = fp->path;
pglob->gl_pathv[ofs] = NULL;
++pglob->gl_pathc;
fp->next = pglob->list_;
pglob->list_ = fp;
return 0;
}
/******************************************************************* globfree() */
void globfree( glob_t *pglob ) {
globlist_ *fp;
while( (fp = pglob->list_) != NULL ) {
pglob->list_ = fp->next;
free( fp );
}
free( pglob->gl_pathv );
pglob->gl_pathv = NULL;
pglob->gl_pathc = 0;
}
/******************************************************************* cmpglb() */
static int cmpglb( const void *p1, const void *p2 ) {
return _stricmp( *((const char *const *)p1),
*((const char *const *)p2) );
}
/******************************************************************* glob() */
int glob( const char *pattern, int flags,
int (*errfunc)( const char *epath, int eerrno ),
glob_t *pglob ) {
struct dsc$descriptor_d retdsc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_D, NULL };
unsigned long ctx = 0;
unsigned long status;
struct dsc$descriptor_s patdsc = { 0, DSC$K_TYPE_T, DSC$K_CLASS_S, NULL };
int err;
size_t found;
if( errfunc != NULL )
abort();
found =
err = 0;
if( !(flags & GLOB_APPEND) ) {
pglob->gl_pathc = 0;
pglob->list_ = NULL;
pglob->gl_pathv = NULL;
}
ctx = 0;
patdsc.dsc$a_pointer = pattern;
patdsc.dsc$w_length = strlen( pattern );
do {
if( $SUCCESSFUL(status = lib$find_file( &patdsc, &retdsc, &ctx,
NULL, NULL, NULL, 0 )) ) {
err = addfile( flags, pglob, &retdsc );
found++;
}
} while( !err && $SUCCESSFUL(status) );
lib$find_file_end( &ctx );
str$free1_dx(&retdsc );
if( !found )
err = GLOB_NOMATCH;
if( err ) {
globfree( pglob );
errno = err;
} else {
if( !(flags & GLOB_NOSORT) ) {
qsort( pglob->gl_pathv, pglob->gl_pathc,
sizeof( char **), cmpglb );
}
}
return err;
}
/******************************************************************* strlcpy() */
static size_t strlcpy( char *dst, const char *src, size_t size ) {
size_t srclen;
size--;
srclen = strlen( src );
if( srclen > size )
srclen = size;
memcpy( dst, src, srclen );
dst[srclen] = '\0';
return (srclen);
}
/******************************************************************* vmsbasename() */
char *vmsbasename( char *path ) {
static char buf[NAM$C_MAXRSS + 1];
char *p, *d;
if( path == NULL || !*path )
return ".";
strlcpy( buf, path, sizeof( buf ) );
if( (p = strrchr( buf, ']' )) != NULL )
return p+1;
if( (p = strrchr( buf, ':' )) != NULL )
return p+1;
return buf;
}