Written by Urs-Jakob Rüetschi
as part of the pracc project.
The pracc API is a set of functions for interfacing pracc files. They are used by all pracc tools and by the pracc CUPS backend. To use any of these functions, include the pracc.h header.
Unless otherwise noted, all pracc API functions return 0 if successful and -1 on error (with errno set to an indicative error value).
Unless otherwise noted, each function x is contained in the x.c source file.
int praccCreate(const char *acctname, long balance, long limit, const char *comment, int overwrite); int praccDelete(const char *acctname); int praccAppend(const char *acctname, int type, long value, const char *username, const char *comment); int praccSum(const char *acctname, long *balance, long *limit, long *credits, long *debits, time_t *lastused); int praccSumRange(const char *acctname, time_t tmin, time_t tmax, long *balance, long *limit, long *credits, long *debits, time_t *lastused); int praccPurge(const char *acctname, struct tai *tx, int keepresets, int keeplimits, int keepnotes, int doit, const char *fntmp); int praccGrant(const char *acctname, const char *username);
Function praccCreate() creates a pracc file for acctname with initial balance balance and initial limit limit and the optional comment string comment. If overwrite is true, an existing pracc file will be overwritten; otherwise an existing pracc file of the same name remains unchanged and is flagged as EEXIST error.
Function praccDelete() deletes the pracc file for the account acctname.
Function praccAppend() adds a record to the pracc file for acctname. The record is of the given type (+ credit non-negative value, - debit non-negative value, = reset the account's balance to the given value, $ set the account's limit to value or minus infinity if value=UNLIMITED, ! add an error message, and # add a note) and includes the optional comment string. The username is mandatory and names the user that performed the action.
Function praccSum() reads the pracc file for acctname, sums up all records and stores account information into the locations provided. Returns 0 if successful and -1 on error with errno set.
Function praccSumRange() is like praccSum() but restricts summation to the given time range. The returned balance and limit are those at the end of the specified range and the returned credits and debits are the sums within the specified range.
Function praccGrant() checks if user username should be given access to account acctname. This function assumes that username has been authenticated! Return 0 if access should be granted, 1 if access should be denied, and -1 if there was an error (in this case, errno gives details about the error).
Function praccPurge() is not yet implemented.
The source file praccRead.c contains routines for reading sequentially through a pracc file, record-by-record. A pracc file entry is represented by a struct praccbuf (which also contains information about the connection to the pracc file):
int type; // debit, credit, limit, etc. long value; // associated value struct tai taistamp; // timestamp of record entry char username[MAXNAME]; // user who created the record char comment[MAXNAME]; // record's comment field long lineno; const char *fn; FILE *fp; /* private */
int praccOpen(const char *acctname, struct praccbuf *pracc); int praccRead(struct praccbuf *pracc); int praccClose(struct praccbuf *pracc);
Use praccOpen() to connect initialise a given struct praccbuf for subsequent record reading from a given pracc file. Then, use praccRead() to read one record per call into the given struct praccbuf. When done, use praccClose() to close the pracc file.
Note that praccRead() returns 1 if a record was successfully read, 0 if the end-of-file was encountered, and -1 on any other error.
All changes to pracc files, except those done by regular printing, should be noted in the common log file pracc.log using the praccLogup() function. It takes three arguments, the name of the user who did the change, the name of the account, upon which the change is done, and a description of the change. All three arguments are C strings.
int praccLogup(const char *username, const char *acctname, const char *info);
The source file praccLogRead.c contains routines for reading the common pracc log file record-by-record. The common pracc log records (time, user, account, action) tuples, stating which user acted at what time on which account. They are represented by a struct pracclog (which also represents the connection to the log file):
struct tai taistamp; char username[MAXNAME]; char acctname[MAXNAME]; char intostr[MAXNAME]; long lineno; FILE *fp; /* private */
int praccLogOpen(struct pracclog *logentry); int praccLogRead(struct pracclog *logentry); int praccLogClose(struct pracclog *logentry);
Use praccLogOpen() to prepare the struct pracclog for subsequent calls to praccLogRead(), which reads one record per call. When done, use praccLogClose() to close the pracc log file. After a call to praccLogRead(), use the fields in the pracclog structure to access the log record's components.
Note that praccLogRead() returns 1 if a record was successfully read, 0 if the end-of-file was encountered, and -1 on any other error.
char praccAccountInfo(const char *acctname, char *buf, int size);
Get information about the given account: its class and the owner's full name (taken from the gecos field). The account's class is returned as a single character: P personal account, G group account, D the default account (as defined by PRACCDEFLT in pracc.h), or z zombie account (no owner). If the named account does not exist or if there is an error, return \0 with details in errno.
int praccAssemble(char *buf, int type, long value, struct tai *taistamp, const char *username, const char *comment);
Assemble the individual fields of a pracc record as a pracc line into the given buffer. The buffer must provide space for at least MAXLINE characters. The taistamp and username arguments must not be NULL. Return the number of characters written to the buffer.
int praccFormatInfo(const char *info, char *buf, int size); int praccFormatName(const char *name, char *buf, int size);
Copy the given info string or user name into the given buffer buf[size]. Only copy up to size-1 characters or up to the first invalid character in the username. If the username is truncated because the buffer is not large enough, this is flagged with an exclamation mark. Return the number of characters written to buf.
int praccCheckName(const char *acctname);
Check if the given acctname is a valid pracc account name. Valid names consist of at most MAXNAME printable characters, excluding blanks, slashes, and backslashes. Return 0 if valid, -1 if invalid.
char *praccPath(const char *acctname);
Return a pointer to an malloc(3)ed string that contains the full path to the named account, or NULL if there is not enough memory to allocate the string. It is the caller's responsibility to free this memory.
char *praccTypeString(char type);
Return a constant string describing the given pracc record type: "debit" for -, "credit" for +, "reset" for =, "limit" for $, "error" for !, and "note" for #. For any other (unknown) type, NULL is returned.