1132 lines
49 KiB
C
1132 lines
49 KiB
C
#ifndef RCSAPI_H
|
|
#define RCSAPI_H
|
|
#include <sys/param.h> /* time_t, mode_t */
|
|
#include <sys/stat.h> /* struct stat */
|
|
|
|
typedef int bool;
|
|
|
|
typedef struct rcsTmp *RCSTMP;
|
|
typedef struct rcsArch *RCSARCH;
|
|
typedef struct rcsConn *RCSCONN;
|
|
typedef struct rcsStream RCSSTREAM;
|
|
|
|
#define ERR_OUT_OF_FILES -10 /* rsrc limit on simultaneous files */
|
|
#define ERR_BAD_HOST -11 /* bad name for server host */
|
|
#define ERR_BAD_SERVICE -12 /* bad name for server service */
|
|
#define ERR_CANT_OPEN_SOCKET -13 /* socket(2) failure */
|
|
#define ERR_CANT_CONNECT -14 /* connect(2) failure */
|
|
#define ERR_BAD_FILEOPEN -15 /* open(2) failure: internal error */
|
|
#define ERR_BAD_FILEWRITE -16 /* write(2) to file failed */
|
|
#define ERR_BAD_UTIME -17 /* utime(2) failed */
|
|
#define ERR_NO_MEMORY -18 /* out of memory (malloc failure) */
|
|
#define ERR_TOOMANY_CONNECTIONS -19 /* only one connection in linked mode */
|
|
#define ERR_NOHANDLES -20 /* too many tmp file handles in use */
|
|
#define ERR_OPEN_ARCH -21 /* cannot open archive file (eg perm)*/
|
|
#define ERR_ARCHIVE_INUSE -22 /* archive file locked by other proc */
|
|
#define ERR_NO_ARCHIVE -23 /* requested archive does not exist */
|
|
#define ERR_ARCHIVE_CHANGED -24 /* archive no longer a regular file,
|
|
* or contents changed when not allowed
|
|
*/
|
|
#define ERR_NAME_USED -151 /* -n<nameflag> w/ name already used */
|
|
#define ERR_REV_LOCKED -152 /* ci when other used locked revision */
|
|
/* co -u/-l when other holds lock */
|
|
#define ERR_READ_STREAM -190 /* error reading appl's read stream */
|
|
#define ERR_WRITE_STREAM -191 /* error writing appl's write stream */
|
|
#define ERR_BAD_HANDLE -192 /* handle arg bad (e.g. not alloc'd) */
|
|
#define ERR_BAD_OPENMODE -193 /* attempt to update arch opened r/o */
|
|
#define ERR_BAD_OLDREV -194 /* old rev is unknown or lex. bad */
|
|
#define ERR_BAD_NEWREV -195 /* new rev is unknown or lex. bad */
|
|
#define ERR_BAD_LOCK -196 /* ci w/unlocked file, or ambig. lock */
|
|
/* (co -u w/ambiguous lock) */
|
|
#define ERR_ARCHIVE_EXISTS -197 /* ci -i, when archive file exists */
|
|
#define ERR_APPL_ARGS -198 /* bad application argument values */
|
|
#define ERR_NO_PERM -199 /* no permission to open file */
|
|
#define ERR_NO_FILE -200 /* appl. specified nonexistent file */
|
|
#define ERR_NO_ACCESS -201 /* update w/user name not in ACL */
|
|
#define ERR_BAD_JOINREV -202 /* bad revision in join/merge request */
|
|
#define ERR_READONLY -203 /* attempt to set readonly value */
|
|
#define ERR_BAD_NAME -204 /* bad name of field */
|
|
#define ERR_BAD_VALUE -205 /* value outside of permitted range */
|
|
#define ERR_BAD_FCREATE -206 /* cannot create requested user file */
|
|
#define ERR_PARTIAL -250 /* some success; check subcodes */
|
|
#define ERR_INTERNAL -300 /* coding problem (internal bug) */
|
|
#define ERR_NETWORK_DOWN -301 /* read/write on socket failing.
|
|
* connection has been terminated
|
|
*/
|
|
#define ERR_FATAL -302 /* fatal err (internal, nonrecoverable)
|
|
* connection has been terminated
|
|
*/
|
|
#define ERR_SYSTEM -303 /* transient system error (e.g. space)*/
|
|
|
|
/* ============== API Option Structs and Initialization Routines =========== */
|
|
|
|
|
|
/* --------------------------- struct rcsConnOpts -------------------------- */
|
|
|
|
/* Type of connection to make (i.e. full network, or intramachine)
|
|
*/
|
|
enum rcsConnType {
|
|
RCS_CONN_DFLT = 0, /* default: fork w/intramachine messages, if possible */
|
|
RCS_CONN_NTWK /* force network socket connection */
|
|
};
|
|
|
|
/* Options describing per-connection behaviour. The first set of options
|
|
* pertain to the client/server connection (what might, in SQL, correspond to
|
|
* a SQL-connection); the latter set of options pertain to the behaviour
|
|
* of the server itself (what might, in SQL, correspond to a SQL-session).
|
|
*
|
|
* All options are evaluated when the connection is established.
|
|
*/
|
|
struct rcsConnOpts {
|
|
/* Server-oriented options */
|
|
bool Ttimeflag; /* -T flag to be used on all actions:
|
|
* adjust RCS archive file modification time,
|
|
* to input stream date (ci) or original
|
|
* time (if no substantial changes)
|
|
*/
|
|
bool noquietflag; /* Turn off quiet (default is -q; quiet "on" */
|
|
const char *suffixes; /* -x: default if ,v/, */
|
|
const char *debugout; /* name of server file for debug info */
|
|
|
|
|
|
/* Connection-oriented options */
|
|
enum rcsConnType ctype; /* Type of (network) connection */
|
|
void (*interrupt)(int sig); /* application interrupt handler - called
|
|
* after library does its own cleanup
|
|
* (SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
|
|
* SIGXCPU, SIGXFSZ)
|
|
*/
|
|
};
|
|
|
|
|
|
/* Initialize to defaults: no application interrupt handler */
|
|
int rcsInitConnOpts(struct rcsConnOpts *opts);
|
|
#define rcsInitConnOpts(opts) \
|
|
(memset(opts, '\0', sizeof(struct rcsConnOpts)), 0)
|
|
|
|
/* -------------------------- struct rcsStreamOpts ------------------------- */
|
|
|
|
/* Options for reading data streams. Only set these if you want
|
|
* other than default behaviour (see rcsReadInData()).
|
|
*
|
|
* The application create Output Method must also recognize these
|
|
* options. (How it makes use of these options is up to the application
|
|
* designer; the library-provided rcsFile stream routine will create
|
|
* a file of the given name, with the mode and modification time indicated.)
|
|
*/
|
|
struct rcsStreamOpts {
|
|
time_t mtime; /* modification time of stream
|
|
* default on input: "now" (zero means default)
|
|
* default on output: none (library always specifies)
|
|
*/
|
|
mode_t mode; /* mode of stream
|
|
* default on input: 0444 (zero means default)
|
|
* default on output: none (library always specifies)
|
|
*/
|
|
const char *fname; /* name of stream ("file")
|
|
* default on input: NULL
|
|
* *SEE rcsReadInData() FOR SEMANTICS IF YOU
|
|
* CHOOSE TO OVERRIDE*
|
|
*
|
|
* default on output: none (not used)
|
|
*/
|
|
};
|
|
|
|
int rcsInitStreamOpts(struct rcsStreamOpts *opts);
|
|
/* Initialize to defaults */
|
|
|
|
/* ------------------------ struct rcsCheckInOpts -------------------------- */
|
|
|
|
/* Options for checking in a stream (creating a new revision) */
|
|
struct rcsCheckInOpts { /* mostly ci(1)-like flags */
|
|
bool lockflag; /* -l (lock new revision) */
|
|
bool forceflag; /* -f (force delta even if no change) */
|
|
bool keywordflag; /* -k (use keyword values from inputstream) */
|
|
bool mustexist; /* -j (do not create file if it doesn't exist)*/
|
|
bool initflag; /* -i (initialize; file must not exist) */
|
|
/* Note: if both initflag and mustexist are
|
|
* set, rcsCheckIn() must return a failure.
|
|
*/
|
|
const char *msg; /* -mmessage (set revision message) */
|
|
char *nameflag; /* -nname[:[rev]] */
|
|
char *Nameflag; /* -Nname[:[rev]] */
|
|
char *stateflag; /* -s[state] */
|
|
const char *textflag; /* -t[textfile] (change file desc.) */
|
|
RCSTMP textfile; /* handle to file with desc. (-t<textfile>)*/
|
|
/* Note: use textflag or textfile; not both */
|
|
char *dateflag; /* -d[date] (checkin date) */
|
|
|
|
const char *oldrev; /* old revision at which new revision
|
|
* is to be checked in
|
|
*/
|
|
const char *newrev; /* new revision number */
|
|
|
|
|
|
RCSTMP *outHandle; /* if not null, then the revision is checked
|
|
* out, and a handle to the revision returned
|
|
* here.
|
|
*/
|
|
struct rcsStreamOpts *outOpts; /* Attributes of checked out file (if any)
|
|
* returned here (if not null).
|
|
*/
|
|
bool serverfile; /* Hint to server to keep output on same
|
|
* filesystem as archive file (for later rename)
|
|
*/
|
|
};
|
|
|
|
/* Initialize to defaults */
|
|
int rcsInitCheckInOpts(struct rcsCheckInOpts *opts);
|
|
#define rcsInitCheckInOpts(opts) \
|
|
(memset(opts, '\0', sizeof(struct rcsCheckInOpts)), 0)
|
|
|
|
|
|
/* ------------------------ struct rcsCheckOutOpts ------------------------- */
|
|
|
|
/* Options for checking out a stream (extracting an existing revision) */
|
|
struct rcsCheckOutOpts { /* mostly co(1)-like flags */
|
|
bool lockflag; /* -l (lock checked out revision) */
|
|
bool unlockflag; /* -u (unlock checked out revision) */
|
|
/* Don't specify both lockflag and unlockflag */
|
|
const char *rev; /* -r[rev] (revision to check out) */
|
|
const char *joinflag; /* -jjoinlist (revisions to merge) */
|
|
const char *stateflag; /* -s[state] */
|
|
const char *dateflag; /* -d[date] (checkin date) */
|
|
|
|
const char *keyexpand; /* -k[type]; keyword expansion: value is
|
|
* entire flag, starting with 'k'
|
|
*/
|
|
};
|
|
|
|
/* Initialize to defaults */
|
|
int rcsInitCheckoutOpts(struct rcsCheckOutOpts *opts);
|
|
#define rcsInitCheckOutOpts(opts) \
|
|
(memset(opts, '\0', sizeof(struct rcsCheckOutOpts)), 0)
|
|
|
|
/* ------------------------- struct rcs*HdrOpts ---------------------------- */
|
|
|
|
/* Name/Value pairs; name may be qualified by application name space, revno */
|
|
struct rcsNameVal {
|
|
const char *name; /* name of field in RCS file (e.g. locks) */
|
|
const char *revision; /* for fields contained in revisions, which
|
|
* revision to use in locating field.
|
|
* "" revision may mean "top" revision
|
|
* for some standard (public) fields, so
|
|
* use NULL for admin (file) header fields.
|
|
*/
|
|
const char *namespace; /* name for private namespace;
|
|
* NULL or "" means standard (public) fields
|
|
*/
|
|
const char *val; /* value of field; for fields with multiple
|
|
* values, layout depends upon whether value
|
|
* is being set or retrieved; see rcsChangeHdr,
|
|
* rcsGetHdr
|
|
*/
|
|
unsigned int flags; /* Modify action (for rcsChangeHdr, q.v.) */
|
|
#define rcsNameValUNIQUE 0x1 /* only set field if new (-n vs. -N)*/
|
|
#define rcsNameValDELETE 0x2 /* delete field or value, depending
|
|
* upon particular field
|
|
*/
|
|
#define rcsNameValFILE 0x4 /* value is name of file (-A) */
|
|
int errcode; /* field-specific error returned */
|
|
};
|
|
|
|
/* Options for changing field values in an RCS file */
|
|
struct rcsChangeHdrOpts {
|
|
bool initflag; /* create new RCS file (just header) */
|
|
bool nomail; /* -M - no mail when breaking a lock */
|
|
const char *mailtxt; /* message to mail owner of lock to break */
|
|
const char *obsRevisions; /* -o<range> - obsolete (delete) revisions */
|
|
|
|
};
|
|
|
|
/* Options for fetching field values in an RCS file */
|
|
struct rcsGetHdrOpts {
|
|
|
|
unsigned short hdrfields; /* which header fields to report (see below) */
|
|
|
|
#define RCS_HDR_BASIC 0x1 /* "basic" parts of header:
|
|
* rcs pathname,
|
|
* pathname of workfile (as if on server),
|
|
* head (top revision),
|
|
* default branch,
|
|
* locks,
|
|
* access list,
|
|
* comment leader,
|
|
* keyword substition string (e.g. "o", "v"),
|
|
* total revisions in file,
|
|
* revisions selected (unless RCS_REV_NONE set)
|
|
*/
|
|
#define RCS_HDR_TEXT 0x2 /* descriptive text */
|
|
#define RCS_HDR_SYMBOLS 0x4 /* symbolic names */
|
|
|
|
/* rlog -h = RCS_HDR_BASIC | RCS_HDR_SYMBOLS
|
|
* rlog -t = as above | RCS_HDR_TEXT
|
|
* rlog -N = ~RCS_HDR_SYMBOLS
|
|
*/
|
|
|
|
/* zero (no flags) = all header information */
|
|
|
|
bool nogetrev; /* if set, do not retrive any revision info
|
|
* rlog -t, rlog -h imply nogetrev set
|
|
*/
|
|
|
|
bool defaultbranch; /* include the default branch revisions
|
|
* as if selected with RCS_REV_REV
|
|
* (rcs -b)
|
|
*/
|
|
bool onlylocked; /* only report on files where locked revisions
|
|
* have been selected (rcs -L)
|
|
*/
|
|
bool onlyRCSname; /* only report RCSname field - overrides
|
|
* all formatting options, including
|
|
* hdrfields, revfields (implies RCS_REV_NONE).
|
|
* Does not write to output stream.
|
|
* (rcs -R)
|
|
*/
|
|
struct rcsNameVal *namesel; /* array of specific namespace/names to
|
|
* look up.
|
|
*/
|
|
int nameselnum; /* number of namespace values to look up */
|
|
|
|
const char *namespace; /* Look up all values in this namespace.
|
|
* "*" means all namespaces.
|
|
* Null means do not look up namespaces
|
|
* (except possibly specifice entries, in
|
|
* namesel).
|
|
*/
|
|
|
|
struct rcsNameVal *revsel; /* revision selection criteria :
|
|
* name: "revision" (rlog -r)
|
|
* "state" (rlog -s)
|
|
* "locker" (rlog -l)
|
|
* "date" (rlog -d)
|
|
* "writer" (rlog -w)
|
|
* (Only the first character is significant,
|
|
* e.g. "dxx" means the same as "date")
|
|
*
|
|
* value: as described in rlog, though
|
|
* each value/range to match may be specified
|
|
* in a separate name/value entry, rather than
|
|
* as part of a comma-separated list
|
|
*/
|
|
int revselnum; /* number of revision selection criteria */
|
|
|
|
};
|
|
|
|
/* Returned field values */
|
|
struct rcsGetHdrFields {
|
|
const char *rcspath; /* RCS file pathname */
|
|
const char *workpath; /* pathname (derived) of workfile */
|
|
const char *head; /* head revision number */
|
|
const char *branch; /* default branch */
|
|
int strict; /* boolean: strict locks? */
|
|
|
|
const struct rcsNameVal **locks;
|
|
/* null-term array of lock name/revno ptrs */
|
|
const char **access; /* null-terminated array of access list names */
|
|
const struct rcsNameVal **symbols;
|
|
/* null-term array of symbol/revno ptrs */
|
|
|
|
const char *comment; /* comment string */
|
|
const char *keysub; /* keyword substitution string */
|
|
int totalrev; /* total revisions in file */
|
|
int selectrev; /* number of selected revisions */
|
|
const char *description; /* descriptive text */
|
|
|
|
const struct rcsNameVal **names;
|
|
/* null-terminated array of namespace name/val
|
|
* ptrs
|
|
*/
|
|
|
|
/* First selected revision info is returned here: */
|
|
const char *revision; /* first revision number selected */
|
|
const char *locker; /* locked by (if any) */
|
|
const char *date; /* date of revision */
|
|
const char *author; /* author of revision */
|
|
const char *state; /* state of revision */
|
|
int inserted; /* lines inserted */
|
|
int deleted; /* lines deleted */
|
|
const char **branches; /* null-terminated array of branches */
|
|
const char *nextrev; /* next revision */
|
|
};
|
|
|
|
|
|
/* Initialize to defaults */
|
|
int rcsInitChangeHdrOpts(struct rcsChangeHdrOpts *opts);
|
|
#define rcsInitChangeHdrOpts(opts) \
|
|
(memset(opts, '\0', sizeof(struct rcsChangeHdrOpts)), 0)
|
|
|
|
int rcsInitGetHdrOpts(struct rcsGetHdrOpts *opts);
|
|
#define rcsInitGetHdrOpts(opts) \
|
|
(memset(opts, '\0', sizeof(struct rcsGetHdrOpts)), 0)
|
|
|
|
/* ========================== Other API Structs ============================ */
|
|
|
|
|
|
/* ============================== API Declarations ========================= */
|
|
|
|
/* ----------------------------- rcsOpenConnection() ---------------------- */
|
|
|
|
int rcsOpenConnection(
|
|
const char *host, /* name of server machine (gethostbyname()) */
|
|
struct rcsConnOpts *opts, /* see below for meaning of all options */
|
|
RCSCONN *conn /* connection handle returned to caller */
|
|
);
|
|
|
|
/* Establish a connection between a client and a server. Returns
|
|
* a handle for the connection in *conn. Returns zero on success,
|
|
* negative error code on failure.
|
|
*
|
|
* host - hostname of server machine. NULL (or "") implies
|
|
* same machine as client.
|
|
* opts -
|
|
* service - name of service requested (NULL means "rcssrv")
|
|
* interrupt - application signal handler to be called while
|
|
* connection is active
|
|
* Ttimeflag - -T flag applied on operations that affect RCS
|
|
* archive file. That is, the archive modification
|
|
* time is set to match the input stream time
|
|
* (for operations using an input stream, i.e. ci),
|
|
* or the archive modification time is unchanged
|
|
* (if no substantial changes made to archive)
|
|
* noquietflag - do not apply -q flag (normally run "quiet").
|
|
* Only meaningful if debugout is not NULL.
|
|
* auth - author (-w); defaults to login of user
|
|
* suffixes - archive location/suffixes (-x flag)
|
|
* debugout - name of server file to use for debug messages.
|
|
* When used with noquietflag, more messages printed.
|
|
* File is truncated when connection is established.
|
|
* conntype - RCS_CONN_DFLT: default - fork if server and client
|
|
* on same host, else network connection
|
|
* RCS_CONN_NTWK: use network conn, even if same host
|
|
* conn - returned handle for new connection (input to other APIs)
|
|
*/
|
|
|
|
int rcsCloseConnection(
|
|
RCSCONN conn /* connection to close */
|
|
);
|
|
|
|
/* Close a connection; invalidates all handles associated with the
|
|
* connection.
|
|
*
|
|
* Returns: 0 (success), ERR_APPL_ARGS (invalid connection)
|
|
*/
|
|
|
|
/* ------------------------------- rcsReadInData() ------------------------ */
|
|
|
|
int rcsReadInData(
|
|
int (*readMethod)(RCSSTREAM *inputStream, void **ptr, size_t nbytes),
|
|
RCSSTREAM *inputStream,
|
|
RCSCONN conn,
|
|
struct rcsStreamOpts *opts,
|
|
RCSTMP *hdl_ptr
|
|
);
|
|
|
|
/* Read in a complete data stream (usually representing data to
|
|
* be used to create one or more new revisions).
|
|
*
|
|
* Returns: handle to the data, to identify the data to subsequent
|
|
* function calls (typically, rcsCheckin()).
|
|
*
|
|
* return value is zero (success) or negative error code.
|
|
*
|
|
* Parameters:
|
|
* readMethod() - a function pointer that this routine may
|
|
* call in order to read the data from the stream.
|
|
* This function executes a blocking (synchronous) read.
|
|
*
|
|
* Returns: number of bytes read (0 == EOF, -1 == error).
|
|
*
|
|
* Its parameters are:
|
|
* inputStream - same as inputStream parameter to
|
|
* rcsReadInData(). It is a pointer
|
|
* to whatever context is required by
|
|
* the implementation to make the fcn
|
|
* work.
|
|
* ptr - the address of the data read is returned as *ptr.
|
|
* nbytes - maximum number of bytes desired.
|
|
*
|
|
* This method may be invoked multiple times by rcsReadInData(),
|
|
* but will not be invoked by the library once readMethod()
|
|
* returns an error or EOF, or after rcsReadInData() returns.
|
|
*
|
|
* inputStream - a context passed to readMethod(), to allow the
|
|
* readMethod() implementation to work. The context could,
|
|
* e.g., contain a FILE * pointer (if the implementation were
|
|
* built upon stdio), or a file descriptor to a socket
|
|
* (if the application were connected to another process
|
|
* generating the input stream), or any other data necessary
|
|
* to provide an input stream.
|
|
*
|
|
* conn - an opaque handle representing a previously established
|
|
* connection with the server. Each read in data stream is
|
|
* associated with a particular connection, and remains valid
|
|
* no longer than the duration of that connection.
|
|
*
|
|
* opts -
|
|
* mtime - the modification time of the stream. This may
|
|
* represent the time that the stream data were
|
|
* created/changed, or the current time. A value
|
|
* of zero is interpreted as the current time.
|
|
* For a file, this would be (in struct stat) st_mtime.
|
|
*
|
|
* This time may be used for such tasks as setting
|
|
* the time of a revision created from the input stream,
|
|
* and setting the time of the RCS archive file
|
|
* (if so desired, and indicated using appropriate
|
|
* option flags).
|
|
*
|
|
* mode - the mode of the stream. RCS uses the mode to set
|
|
* the mode of a newly created archive file (only the
|
|
* read and execute bits are used). Shell scripts
|
|
* should have the execute bit(s) on, so that the
|
|
* scripts checked out from the archive also have execute
|
|
* bit(s) on.
|
|
*
|
|
* A value of zero is interpreted as 0444 (r--r--r--).
|
|
* This is the default. For a file, mode would be
|
|
* (in struct stat) st_mode.
|
|
*
|
|
* fname - Typically NULL (default). Setting this to provide
|
|
* an input file name changes the semantics of
|
|
* rcsReadInData(), and should be used sparingly.
|
|
*
|
|
* If fname is specified (and is not ""), then the
|
|
* input stream is coming from a file. The library
|
|
* will attempt to use the named file on the server,
|
|
* which will probably not make sense if the caller
|
|
* is linked with library stubs (and the server is
|
|
* a different machine).
|
|
*
|
|
* The value of this option is that it may save one
|
|
* act of copying the input stream. (It is somewhat
|
|
* analagous to lp -c, in reverse; the default for
|
|
* RCS is to make copies, while the default for lp
|
|
* is not to.)
|
|
*
|
|
* The same problems that lp encounters when it does
|
|
* not copy a file may be encountered here. Notably,
|
|
* that the file changes while the operation takes
|
|
* place. (As with lp, merely calling rcsReadInData()
|
|
* does not guarantee that the file is read immediately,
|
|
* if fname is specified.) RCS attempts to mitigate
|
|
* these problems by checking that the file does not
|
|
* change in the middle of any action (like rcsCheckin()),
|
|
* but does not protect against the file changing
|
|
* between two operations. So, one could ReadIn a
|
|
* file, change the file, then invoke rcsCheckin(), and
|
|
* RCS would be quite happy, using the newer version
|
|
* of the file.
|
|
*
|
|
* Since RCS will read in the file as needed (and not
|
|
* start until rcsCheckIn() is called), the application
|
|
* must take particular care that the file not change.
|
|
* Otherwise, results may be unpredictable, depending
|
|
* upon when the file were to change.
|
|
*/
|
|
|
|
|
|
/* ------------------------------ rcsReadOutData() ------------------------ */
|
|
|
|
int rcsReadOutData(
|
|
int (*writeMethod)
|
|
(RCSSTREAM *outputStream, const void *ptr, size_t nbytes),
|
|
RCSSTREAM *outputStream,
|
|
RCSCONN conn,
|
|
RCSTMP datahandle
|
|
);
|
|
|
|
/* Read out a complete data stream (usually representing data output
|
|
* from a previous checkout).
|
|
*
|
|
* Returns: 0 (success)
|
|
* ERR_APPL_ARGS: bad arguments (e.g. null pointers, invalid
|
|
* handle)
|
|
* ERR_WRITE_STREAM: call to writeMethod() failed
|
|
* ERR_NETWORK_DOWN: unable to transmit entire data stream
|
|
*
|
|
* Parameters:
|
|
* writeMethod() - a function pointer that this routine may
|
|
* call in order to write the data from the library.
|
|
* This function executes a blocking (synchronous) write.
|
|
*
|
|
* Returns: number of bytes written (<= 0 means error;
|
|
* it is not required to write the full amount
|
|
* requested on each call, but it must write some
|
|
* non-negative number of bytes on each call.
|
|
*
|
|
* Its parameters are:
|
|
* outputStream - same as outputStream parameter to
|
|
* rcsReadOutData(). It is a pointer
|
|
* to whatever context is required by
|
|
* the implementation to make the fcn
|
|
* work.
|
|
* ptr - the address of the data to be written.
|
|
* nbytes - number of bytes to be written.
|
|
*
|
|
* This method may be invoked multiple times by rcsReadOutData(),
|
|
* but will not be invoked by the library once writeMethod()
|
|
* fails, or after rcsReadOutData() returns.
|
|
*
|
|
* outputStream - a context passed to writeMethod(), to allow the
|
|
* writeMethod() implementation to work. The context could,
|
|
* e.g., contain a FILE * pointer (if the implementation were
|
|
* built upon stdio), or a file descriptor to a socket
|
|
* (if the application were connected to another process
|
|
* generating the input stream), or any other data necessary
|
|
* to provide an input stream.
|
|
*
|
|
* conn - the connection through which the data stream may be retrieved
|
|
*
|
|
* datahandle - an opaque handle representing a previously established
|
|
* set of data, usually from rcsCheckOut() (or from
|
|
* rcsCheckIn() if an output stream is requested).
|
|
*/
|
|
|
|
|
|
/* ------------------------------- rcsCheckIn() --------------------------- */
|
|
|
|
int rcsCheckIn(
|
|
RCSCONN conn, /* Connection to server */
|
|
RCSTMP inputhandle, /* "handle" to previously ReadIn stream,
|
|
* used as data for new revision
|
|
*/
|
|
const char *rcspath, /* full pathname (on server) of archive file */
|
|
struct rcsCheckInOpts *opts /* a subset of the ci(1) flags; those
|
|
* flags that affect the arcive file directly
|
|
* (see struct RcsCheckInOpts, above)
|
|
*/
|
|
);
|
|
|
|
/* Check in a new revision of the archive.
|
|
* opts -
|
|
* lockflag: if set, lock the newly created revision (ci -l)
|
|
* forceflag: if set, allow new revisions which are unchanged
|
|
* from old revisions. If not set, and the new revision
|
|
* represents no change, the lock on the old revision
|
|
* (if any) is removed, and the nameflag and stateflag
|
|
* options (if any) are applied to the old revision.
|
|
* In that case, this function returns 1, rather than zero.
|
|
* (ci -f).
|
|
* keywordflag: use keyword values from input stream, rather than
|
|
* other options here, to determine new revision number,
|
|
* creation date, state, and author. If these options
|
|
* are also set (e.g. stateflag), they take precidence.
|
|
* (ci -k)
|
|
* nameflag: set the name of the checked in revision to this value.
|
|
* The checkin fails if <nameflag> is already used;
|
|
* ERR_NAME_USED is returned. (ci -n<nameflag>)
|
|
* Nameflag: set the name of the checked in revision; overrides
|
|
* preexisting use of <Nameflag>. (ci -N<Nameflag>)
|
|
* stateflag: set the state of this revision (ci -s). The default
|
|
* state is Exp.
|
|
* textflag: override the existing text (archive description)
|
|
* with the value of this flag (ci -t-<textflag>).
|
|
* In order to effect ci -t<file>, the application must
|
|
* convert the file contents to a string.
|
|
* [NOTE: an alternative would be to require the application
|
|
* to ReadIn the text stream, and then textflag would be
|
|
* an RCSTMP handle; only one of these mechanisms will be
|
|
* used, though.]
|
|
* dateflag: set the time/date of the revision to the value of
|
|
* this flag (ci -d).
|
|
*
|
|
* oldrev - a revision number (e.g. 1.3.2.1) to be used as the
|
|
* old revision, from which a new revision is made.
|
|
* If this is not specified (NULL), it is inferred using
|
|
* the usual ci rules (looking for locked revision by the
|
|
* user, using the new revision number, etc.).
|
|
* If this is specified, it must be a specific revision
|
|
* and not a branch; i.e. it must contain an even number of
|
|
* components, and not be something like 1.31.2.
|
|
* The effect of specifying oldrev is as if the old revision
|
|
* had been locked by this user, and ci located the old
|
|
* revision using its usual rules for finding locked files.
|
|
* Note that you cannot check in using an oldrev which has
|
|
* been locked by another user. ERR_REV_LOCKED is returned.
|
|
*
|
|
* newrev - this is equivalent to the <rev> value that the ci(1) command
|
|
* takes on flags like -l<rev>, -u<rev>, etc. If not specified,
|
|
* the usual rules for computing the new revision number apply.
|
|
*
|
|
* As usual, it is impermissible to specify a newrev which is
|
|
* not higher than the oldrev (whether the oldrev is stated
|
|
* explicitly, or inferred by RCS).
|
|
*
|
|
* outHandle - If not null, provide a handle to the newly checked in
|
|
* revision (which may be retrieved with rcsReadOutData()).
|
|
* This allows implementation of ci -u (or ci -l if lockflag
|
|
* is set). The handle to the revision is returned as *outHandle.
|
|
*
|
|
* outOpts - the modification time and mode attributes of the output stream.
|
|
* If this is null, but outHandle is not, the output stream is
|
|
* still produced, but the attribute information is not returned.
|
|
*
|
|
* serverfile - if true, the library is alerted to the possibility that
|
|
* the output data may ultimately be deposited in a server file
|
|
* on the same filesystem as the archive file. (A performance
|
|
* matter only.)
|
|
*
|
|
* Once a revision is checked in, the application must close the archive,
|
|
* and reopen it to perform additional actions (implementation limitation).
|
|
* Thus, outHandle (along with outOpts) is particularly useful.
|
|
*
|
|
* Returns: 0 - success
|
|
* 1 - success, but no checkin (no revision change; see -f)
|
|
* negative error codes - failures
|
|
*/
|
|
|
|
|
|
/* ------------------------------ rcsCheckOut() -------------------------- */
|
|
|
|
int rcsCheckOut(
|
|
RCSCONN conn, /* connection to server */
|
|
const char *rcspath, /* full pathname (on server) of archive file */
|
|
RCSTMP *outhandle, /* "handle" for output data */
|
|
struct rcsStreamOpts *outopts, /* place to rcv attributes of output data*/
|
|
struct rcsCheckOutOpts *opts /* checkout options (see below) */
|
|
);
|
|
|
|
/* Check out a revision of the archive file.
|
|
*
|
|
* The caller is returned a handle (outhandle) to the data, which may
|
|
* then be used to retrieve the data via rcsReadOutData(). If outopts
|
|
* is not null, the modification time and "file" permission mode of
|
|
* the output data is returned. The modification time is the time
|
|
* of the revision checked out (if any), or "now" (zero) if the
|
|
* check out was of an empty archive, or included a join.
|
|
*
|
|
* The mode of the "file" has the same read/execute bit settings as
|
|
* the archive file. The owner write bit is turned on if:
|
|
* -kv was not specified AND
|
|
* lockflag (-l) was specified OR there is not strict locking
|
|
* or if the archive was empty AND lockflag (-l) was specified..
|
|
*
|
|
* opts -
|
|
* rev: specifies the revision to check out (exactly the same as co -r)
|
|
* This may be NULL or "" (which is equivalent), in which case
|
|
* the top revision is retrieved.
|
|
* lockflag: if set, lock the revision checked out (co -l).
|
|
* unlockflag: if set, unlock the revision checked out (co -u). Lockflag
|
|
* takes precidence if both lockflag and unlockflag set.
|
|
* joinflag: a list of revisions to merge (co -j)
|
|
* stateflag: alter the algorithm to find the highest revision with
|
|
* the specified state to check out (co -s).
|
|
* dateflag: retrieve the latest revision on the selected branch whose
|
|
* timestamp is not later than dateflag (co -d).
|
|
* keyexpand: -k suite of flags (co -k?) that control keyword expansion.
|
|
* The entire flag (beginning with 'k') must be specified.
|
|
*/
|
|
|
|
/* ------------------------------ rcsChangeHdr() -------------------------- */
|
|
|
|
int rcsChangeHdr(
|
|
RCSCONN conn, /* connection to server */
|
|
const char *rcspath, /* full pathname (on server) of archive file */
|
|
struct rcsNameVal *nameval, /* array of name/value pairs to set */
|
|
int namevalNum, /* number of elements in array, above */
|
|
struct rcsChangeHdrOpts *opts /* header field options (see below) */
|
|
);
|
|
|
|
/* Change the value(s) of specified fields in the RCS file header,
|
|
* or in the fields associated with revisions within the RCS file.
|
|
* Examples of the former are symbols, locks; examples of the latter
|
|
* are state, date. RCS file header fields are referred to by
|
|
* specifying a NULL revision in the rcsNameVal struct; an empty
|
|
* string ("") implies the top revision on the trunk or default branch.
|
|
*
|
|
* If multiple entries change the same field value, the last change
|
|
* takes precidence. If one clears all values, and then others add
|
|
* values (e.g. to the access list), then both have effect. Basically,
|
|
* all changes are applied in order, whatever that means to the
|
|
* field in question. (An exception is for "strict"; see below.)
|
|
*
|
|
* If some fields cannot be changed (e.g. attempting to change a
|
|
* READONLY field), but the operation is generally successful,
|
|
* then ERR_PARTIAL is returned, and the caller must look in
|
|
* nameval[i].errorcode to see which fields could not be set, and why.
|
|
* If namevalNum is 1, the particular error code is also returned,
|
|
* rather than ERR_PARTIAL. Only errors that are independent of the
|
|
* RCS file's content are flagged this way. It is not an error,
|
|
* for example, to remove a nonexistent lock (the revision simply
|
|
* remains unlocked).
|
|
* Other return codes indicate complete failure, or complete success (0).
|
|
*
|
|
* Standard fields include:
|
|
* "head" - read only
|
|
* "branch" - default branch; if value is NULL or "", branch is
|
|
* reset to the (dynamically) highest branch on trunk
|
|
* (rcs -b[value])
|
|
, "access" - appends the login name to the accessor list.
|
|
* Value may be a single login, or a comma-separated
|
|
* list of logins. Multiple "access" entries may
|
|
* appear in nameval[]. (rcs -a<value>)
|
|
* If rcsNameValFILE is set, then the value is actually
|
|
* a path to another RCS archive file, from whence
|
|
* an access list to append is to be obtained
|
|
* (rcs -A<value>).
|
|
* If rcsNameValDELETE is set, then the login is to
|
|
* be deleted from the accessor list. If the value
|
|
* (login name) is NULL or "", then the entire accessor
|
|
* list is deleted. (rcs -e<value>).
|
|
* "symbols" - associate a symbolic name with a branch or revision.
|
|
* Value is of the form <symbolic name>[:[<rev>]]
|
|
* If ':' is omitted, or rcsNameValDELETE flag is set,
|
|
* then <symbolic name> is deleted from the list of symbols.
|
|
* If <rev> is omitted, then the latest revision on
|
|
* the current branch is used.
|
|
* <rev> may be symbolic; it is converted into a numeric
|
|
* revision number before being added to the list of symbols.
|
|
* If rcsNameValUNIQUE flag is set, then the <symbolic name>
|
|
* must not already appear in the list of symbols.
|
|
* Multiple "symbols" entries may appear in nameval[].
|
|
* (rcs -n and rcs -N).
|
|
* "locks" - lock the revision specified by the value (which
|
|
* may be a symbolic revision). This creates an entry
|
|
* of the form <login>:<numeric revision>. The
|
|
* numeric revision is derived from the symbolic
|
|
* revision specified. If the revision is omitted,
|
|
* the latest revision on the default branch is locked.
|
|
* If rcsNameValDELETE is set, then the indicated
|
|
* revision is unlocked (the lock is deleted), following
|
|
* the usual RCS rules for mapping the value (revision)
|
|
* to the lock to be removed.
|
|
* If the lock is owned by someone else, the unlock
|
|
* fails unless nomail is set, or mailtxt is set
|
|
* (providing the mail message to send the owner of
|
|
* the lock to be broken).
|
|
* As a convenience, the user may specify a value
|
|
* in the form <login>:<rev> (instead of simply <rev>).
|
|
* However, if <login> does not match the author specified
|
|
* or inferred for the connection, an addition of a
|
|
* will fail. The <login> is ignored when deleting
|
|
* a lock (only a single user may own a lock on a given
|
|
* revision; no checking whether <login> matches the
|
|
* lock owner is performed).
|
|
* Multiple "locks" entries may appear in nameval[].
|
|
* (rcs -l, rcs -u -M).
|
|
* "strict" - Value is ignored. If rcsNameValDELETE is set, this
|
|
* field is removed from the archive; else it is added
|
|
* (if not already there). (rcs -L, rcs -U). If "strict"
|
|
* is set by any rcsNameVal entry, it will be set even if
|
|
* a later entry unsets it. rcs -L takes precidence over
|
|
* rcs -U.
|
|
* "comment"- this field represents the string used to prefix every
|
|
* line when expanding the Log keyword during checkout (rcs -c).
|
|
* "expand" - sets the default keyword substitution to <value>.
|
|
* Value must be one of: "k", "o", "v", "kvl". If "kv"
|
|
* is used, the "expand" field is removed from the header.
|
|
* It is also removed if rcsNameValDELETE is set (and then
|
|
* value is ignored). If value is any other string, it is
|
|
* ignored (but ERR_BAD_VALUE is set). (rcs -k<val>).
|
|
* "desc" - sets the descriptive text of the file. Only the
|
|
* most current descriptive text (top of trunk or default
|
|
* but otherwise is ignored. (rcs -t-<value>).
|
|
*
|
|
* Standard revision fields include:
|
|
* "date" - currently read only (could be changed in the future).
|
|
* "author" - currently read only (could be changed in the future).
|
|
* "state" - a free form string; semantics defined by application.
|
|
* (rcs -s).
|
|
* "branches" - read only.
|
|
* "next" - read only.
|
|
* "log" - the log message for the revision. (rcs -m).
|
|
* "text" - use rcsCheckIn to change!
|
|
*
|
|
* Application fields have no semantics, and are defined by the
|
|
* user. If rcsNameValDELETE is set, the specified field is deleted;
|
|
* otherwise its value is replaced by the specified value, or if the
|
|
* field does not already exist, it is created. Likewise, if the
|
|
* application namespace does not already exist, it is created.
|
|
* (An application namespace is never deleted, though it may have no
|
|
* members.)
|
|
*
|
|
* Other options:
|
|
* initflag - Create and initialize a new RCS file (which must not
|
|
* already exist). Sets a default descriptive text message
|
|
* if no value provided for "desc" (see above). (rcs -i).
|
|
* nomail - do not send mail to owner of lock broken. See "locks",
|
|
* above. (rcs -M).
|
|
* mailtxt - the mail message to be sent if a lock is broken. If
|
|
* nomail is not set, and mailtxt is NULL, then the unlock
|
|
* fails (but the rest of the operation may still succeed).
|
|
* obsRevisions - what revisions to remove (rcs -o).
|
|
*/
|
|
|
|
/* ------------------------------- rcsGetHdr() ---------------------------- */
|
|
|
|
int rcsGetHdr(
|
|
RCSCONN conn, /* connection to server */
|
|
const char *rcspath, /* full pathname (on server) of archive file */
|
|
struct rcsGetHdrOpts *opts, /* header field options (see below) */
|
|
|
|
struct rcsGetHdrFields *ret,/* returned field values */
|
|
|
|
/* stream for receiving revision data */
|
|
int (*writeMethod)
|
|
(RCSSTREAM *outputStream, const void *ptr, size_t nbytes),
|
|
RCSSTREAM *outputStream /* context for stream */
|
|
);
|
|
|
|
/* Retrieve the value(s) of specified fields in the RCS file
|
|
* (excluding the actual delta text, which is extracted via
|
|
* rcsCheckOut()).
|
|
*
|
|
* The caller uses various options (opts) to indicate which fields are
|
|
* to be returned, and which revisions are to be reported.
|
|
* The file header fields are returned, parsed, in the rcsGetHdrFields
|
|
* struct, while the revision data are written into the caller-provided
|
|
* stream, in rlog(1) format.
|
|
*
|
|
* The memory used parsed fields is not guaranteed to persist past
|
|
* the next RCS API call, so needed information should be copied into
|
|
* the caller's memory. Only those fields which are requested are
|
|
* filled in.
|
|
*
|
|
* In essence, this function performs a select and a project on a
|
|
* table (the RCS file). The projection is described by specifying
|
|
* the particular fields to be retrieved. The selection is described
|
|
* by specifying particular revisions of interest.
|
|
*
|
|
* If no revision selection criteria are specified, all revisions
|
|
* are reported. Otherwise, any revision reported must satsify the
|
|
* "state" (rlog -s), "date" (rlog -d), AND "locker" (rlog -l) criteria,
|
|
* if specified. In addition, if "revision" (rlog -r) or
|
|
* opts->defaultbranch (rcs -b) is specified, then the revision is
|
|
* restricted to matching the "revision" criteria (if specified) OR
|
|
* to being on the main branch (if defaultbranch is set).
|
|
*
|
|
* One exception to this model is opts->onlylocked. If this is set,
|
|
* NO data for the RCS file will be reported, unless there is a locked
|
|
* revision (or if "locker" is specified, there is a locked revision
|
|
* matching this ONE criterion).
|
|
*
|
|
* Returns: 0, or negative value in case of error.
|
|
*
|
|
* opts - flags and strings describing selections and projections.
|
|
* hdrfields - which file header fields are to be returned.
|
|
* By default, all fields are reported (zero == default).
|
|
* These flags are "or'd" together:
|
|
* RCS_HDR_BASIC: basic fields, includiing RCS pathname,
|
|
* workfile pathname, head, locks, access list,
|
|
* comment leader, keyword substitution string,
|
|
* total number of revisions, and number of
|
|
* revisions selected (unless nogetrev set)
|
|
* (rlog -h)
|
|
* RCS_HDR_TEXT: descriptive text (rlog -t)
|
|
* RCS_HDR_SYMBOLS: symbols (turned off by rlog -N)
|
|
*
|
|
* nogetrev - boolean indicating that revisions not to be retrieved.
|
|
* (Implied by rlog -t, rlog -h, rlog -R)
|
|
*
|
|
* defaultbranch - include all default branch revisions in the list
|
|
* of revisions to be used as candidates for
|
|
* matching the selection criteria. (rlog -b)
|
|
*
|
|
* onlylocked - only report information for the file if there is
|
|
* a locked revision matching "locker" (if specified)
|
|
* or some locked revision (if "locker" not specified).
|
|
* (rlog -L). If there are no matches, return
|
|
* ERR_BAD_LOCK.
|
|
*
|
|
* Note that even if no locked revision is selected,
|
|
* file information may still be reported, since
|
|
* some other revision may be locked. For example,
|
|
* if only revision 1.15 is locked, then a call with
|
|
* "onlylocked" and "revision" == "1.16" specified
|
|
* (rlog -L -r1.16) is successful, even though
|
|
* revision 1.16 is not locked.
|
|
*
|
|
* onlyRCSname - boolean indicating that only the RCS pathname is
|
|
* to be returned (and not written to output stream).
|
|
* Overrides all other field options (but selection
|
|
* options onlylocked, "locker", still apply).
|
|
*
|
|
* namesel - array of struct rcsNameVal namespace identifiers.
|
|
* Values of identifiers are to be looked up and
|
|
* returned. If namespaces are in revisions, and
|
|
* nogetrev is specified, these identifiers are not
|
|
* looked up. It is not an error to reqest an
|
|
* identifier which is not in the RCS file. It is
|
|
* simply omitted from the return list.
|
|
*
|
|
* nameselnum - the number of entries in namesel.
|
|
*
|
|
* namespace - a string specifying the namespace whose identifiers
|
|
* are to be listed in the output stream (and returned)
|
|
* for the file header and revision listings. A "*"
|
|
* means all namespaces. A NULL means no namespaces.
|
|
*
|
|
* revsel - array of revision selection criteria
|
|
* The name indicates which criterion is specified,
|
|
* the value indicates what to match.
|
|
*
|
|
* name - (only the first character is significant)
|
|
* "locker": match locker (rlog -l)
|
|
* "state": match state (rlog -s)
|
|
* "date": match date range (rlog -d)
|
|
* "revision":match set of revisions (rlog -r)
|
|
* "writer": match writer (rlog -w)
|
|
*
|
|
* val - The values which must be matched. All may be
|
|
* lists of values (though the date value is a
|
|
* semi-colon separated list; the others are comma-
|
|
* separated). Alternatively, each value may be
|
|
* specified as a different entry in the revsel array.
|
|
*
|
|
* Dates are free-form (see ci(1)).
|
|
*
|
|
* Revisions are specified as [rev][:][rev]. If
|
|
* no revision is given in the string, then the top
|
|
* revision is inferred. (rlog -r).
|
|
*
|
|
* revselnum - the number of revision selection entries in revsel.
|
|
*
|
|
*
|
|
* The revision selection rule is:
|
|
* match any locker (satisfied if no lockers specified) AND
|
|
* match any date (satisfied if no date or range specified) AND
|
|
* match any state (satisfied if no date or range specified) AND
|
|
* be a qualified revision.
|
|
*
|
|
* A qualified revision is any revision if "defaultbranch"
|
|
* is not set, and no "revision" is specified.
|
|
* Otherwise, a qualified revision must meet the "revision"
|
|
* specification (if any) OR be on the main branch (if
|
|
* "defaultbranch" is set).
|
|
*
|
|
* ret - returned header field values. Only those fields requested
|
|
* in opts are returned. They are returned here, even if they
|
|
* are also sent to the application stream.
|
|
*
|
|
* rcspath - the pathname to the RCS file (including ,v).
|
|
*
|
|
* workpath - the filename of the workfile (clear text file).
|
|
* If the caller provided the "rcspath" as a clear
|
|
* text file (as opposed to a ,v file), then this
|
|
* is just the filename component of that value.
|
|
*
|
|
* head - the top (head) revision in the file (string value).
|
|
*
|
|
* branch - the default branch (string value).
|
|
*
|
|
* locks - a list of locks, represented as
|
|
* a null-terminated array of pointers to rcsNameVal
|
|
* name/value pairs. The name is the login owner
|
|
* of a lock. The value is the revision locked.
|
|
* Example: *locks[0] == {"wft", "1.2"}, locks[1] == 0
|
|
* means the file has a single lock, which is on
|
|
* revision 1.2, owned by wft.
|
|
*
|
|
* strict - boolean; true if strict locking is set in file.
|
|
*
|
|
* access - a null-terminated array of access list names (rcs -a)
|
|
*
|
|
* symbols - a list of tags (rcs -n) represented as
|
|
* a null-terminated array of pointers to rcsNameVal
|
|
* name/value pairs. The name is the symbol (tag),
|
|
* and the value is the associated id. See locks, above.
|
|
*
|
|
* keysub - a string representing the expansion to be performed
|
|
* on keywords upon checkout. (See co -k).
|
|
*
|
|
* totalrev - the total number of revisions in the file.
|
|
*
|
|
* selectrev - the number of revisions selected.
|
|
*
|
|
* description - the descriptive text (rcs -t).
|
|
*
|
|
* names - an array of pointers to namespace name/val pairs.
|
|
* *names[0] is the first name/val pair, *names[1]
|
|
* is the second, until names[i] is NULL.
|
|
*
|
|
* writeMethod - an application stream into which to write the
|
|
* revision data (and header data, if "printall"
|
|
* is set). This pointer may be NULL, in which
|
|
* case no revision information is returned.
|
|
* See rcsReadOutData for the full description of
|
|
* a writeMethod stream.
|
|
*
|
|
* outputStream - the context required by writeMethod, q.v.
|
|
*/
|
|
|
|
/* ============================= File Streams ============================== */
|
|
/* Generic routines for handling files; these manipulate file streams,
|
|
* much as stdio manipulates FILE * "streams".
|
|
*
|
|
* These are basic wrappers for the stdio routines, provided as a convenience.
|
|
* The RCS library calls for functions with slightly different signatures
|
|
* than the stdio functions, thus the wrappers. For instance, the read method
|
|
* returns a pointer to the data read, rather than copying the data to the
|
|
* caller-supplied location. This improves performance, especially in the
|
|
* case where the input stream is a memory-mapped file.
|
|
*/
|
|
|
|
/* ---------------------------- rcsFileOpen() ------------------------------ */
|
|
|
|
int rcsFileOpen(
|
|
const char *fname, /* name of file to open */
|
|
const char *mode, /* open mode (like fopen) */
|
|
RCSSTREAM **context /* place in which to return stream */
|
|
);
|
|
|
|
/* Open a file, and return a pointer to an RCSSTREAM. The return
|
|
* value is zero, or a negative number in case of an error
|
|
* (e.g. the named file does not exist, or the process does not
|
|
* have permission to access the file).
|
|
*/
|
|
|
|
|
|
/* --------------------------- rcsFileRead() ------------------------------- */
|
|
int rcsFileRead(
|
|
RCSSTREAM *inputStream, /* input stream (like FILE *) */
|
|
void **ptr, /* returns pointer to data buffer */
|
|
size_t nbytes /* max number of bytes to read */
|
|
);
|
|
|
|
/* The generic file reading stream.
|
|
* Applications may use a pointer to this function when asked for
|
|
* a read method on a stream.
|
|
*/
|
|
|
|
|
|
/* --------------------------- rcsFileClose() ------------------------------ */
|
|
int rcsFileClose(
|
|
RCSSTREAM *inputStream /* input stream (like FILE *) */
|
|
);
|
|
|
|
/* Close a file stream; returns zero on success, negative number on error */
|
|
|
|
|
|
/* -------------------------- rcsFileWrite() ------------------------------ */
|
|
int rcsFileWrite(
|
|
RCSSTREAM *outputStream, /* result of rcsFileCreateOutStream()*/
|
|
const void *data, /* data to be written */
|
|
size_t nbytes /* number of bytes to write */
|
|
);
|
|
|
|
/* Write nbytes into the stream (file) created by rcsFileCreateOutStream().
|
|
* Returns the number of bytes written (zero or negative error code on
|
|
* error).
|
|
*
|
|
* This is provided as a convenience to be used with rcsReadOutData().
|
|
* It is a trivial wrapper for fwrite(); if its address were not required,
|
|
* the entire implementation would be:
|
|
*
|
|
* #define rcsFileWrite(outStream, data, nbytes) \
|
|
* fwrite(data, 1, nbytes, (FILE *)outStream)
|
|
*
|
|
* Do not intermix rcsFileWrite with any of the other rcsFile* routines
|
|
* here.
|
|
*/
|
|
|
|
|
|
/* --------------------------- rcsFileStat() ------------------------------- */
|
|
int rcsFileStat(
|
|
RCSSTREAM *inputStream, /* input stream (like FILE *) */
|
|
struct stat *statbuf /* buffer in which to return stat(2) */
|
|
);
|
|
/* Perform an fstat(2), using RCSSTREAM * as input */
|
|
|
|
#endif /* RCSAPI_H */
|