Files
pcas/src/as/asDbLib.c
Andrew Johnson 1ac8ff6378 as: Make asSetFilename() warn on relative paths
Tell the user if they try this.  They'll get an error from
asInit() later, but it gets lost easily in other noise.
2012-08-28 16:35:52 -05:00

334 lines
8.0 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*************************************************************************\
* Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* Author: Marty Kraimer Date: 02-11-94*/
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "epicsStdioRedirect.h"
#include "dbDefs.h"
#include "cantProceed.h"
#include "epicsThread.h"
#include "errlog.h"
#include "taskwd.h"
#include "alarm.h"
#include "caeventmask.h"
#include "callback.h"
#include "dbStaticLib.h"
#include "dbAddr.h"
#include "dbAccess.h"
#include "db_field_log.h"
#include "dbEvent.h"
#include "dbCommon.h"
#include "recSup.h"
#define epicsExportSharedSymbols
#include "asLib.h"
#include "asCa.h"
#include "asDbLib.h"
static char *pacf=NULL;
static char *psubstitutions=NULL;
static epicsThreadId asInitTheadId=0;
static int firstTime = TRUE;
static long asDbAddRecords(void)
{
DBENTRY dbentry;
DBENTRY *pdbentry=&dbentry;
long status;
dbCommon *precord;
dbInitEntry(pdbbase,pdbentry);
status = dbFirstRecordType(pdbentry);
while(!status) {
status = dbFirstRecord(pdbentry);
while(!status) {
precord = pdbentry->precnode->precord;
if(!precord->asp) {
status = asAddMember(&precord->asp, precord->asg);
if(status) errMessage(status,"asDbAddRecords:asAddMember");
asPutMemberPvt(precord->asp,precord);
}
status = dbNextRecord(pdbentry);
}
status = dbNextRecordType(pdbentry);
}
dbFinishEntry(pdbentry);
return(0);
}
int epicsShareAPI asSetFilename(const char *acf)
{
if (pacf)
free (pacf);
if (acf) {
pacf = calloc(1, strlen(acf)+1);
if (!pacf) {
errMessage(0, "asSetFilename calloc failure");
} else {
strcpy(pacf, acf);
if (*pacf != '/' && !strchr(pacf, ':')) {
printf("asSetFilename: Warning - relative paths won't usually "
"work\n");
}
}
} else {
pacf = NULL;
}
return 0;
}
int epicsShareAPI asSetSubstitutions(const char *substitutions)
{
if(psubstitutions) free ((void *)psubstitutions);
if(substitutions) {
psubstitutions = calloc(1,strlen(substitutions)+1);
if(!psubstitutions) {
errMessage(0,"asSetSubstitutions calloc failure");
} else {
strcpy(psubstitutions,substitutions);
}
} else {
psubstitutions = NULL;
}
return(0);
}
static void asSpcAsCallback(struct dbCommon *precord)
{
asChangeGroup(&precord->asp, precord->asg);
}
static void asInitCommonOnce(void *arg)
{
int *firstTime = (int *)arg;
*firstTime = FALSE;
}
static long asInitCommon(void)
{
long status;
int asWasActive = asActive;
int wasFirstTime = firstTime;
static epicsThreadOnceId asInitCommonOnceFlag = EPICS_THREAD_ONCE_INIT;
epicsThreadOnce(&asInitCommonOnceFlag,asInitCommonOnce,(void *)&firstTime);
if(wasFirstTime) {
if(!pacf) return(0); /*access security will NEVER be turned on*/
} else {
if(!asActive) {
printf("Access security is NOT enabled."
" Was asSetFilename specified before iocInit?\n");
return(S_asLib_asNotActive);
}
if(pacf) {
asCaStop();
} else { /*Just leave everything as is */
return(S_asLib_badConfig);
}
}
status = asInitFile(pacf,psubstitutions);
if(asActive) {
if(!asWasActive) {
dbSpcAsRegisterCallback(asSpcAsCallback);
asDbAddRecords();
}
asCaStart();
}
return(status);
}
int epicsShareAPI asInit(void)
{
return(asInitCommon());
}
static void wdCallback(void *arg)
{
ASDBCALLBACK *pcallback = (ASDBCALLBACK *)arg;
pcallback->status = S_asLib_InitFailed;
callbackRequest(&pcallback->callback);
}
static void asInitTask(ASDBCALLBACK *pcallback)
{
long status;
taskwdInsert(epicsThreadGetIdSelf(), wdCallback, (void *)pcallback);
status = asInitCommon();
taskwdRemove(epicsThreadGetIdSelf());
asInitTheadId = 0;
if(pcallback) {
pcallback->status = status;
callbackRequest(&pcallback->callback);
}
}
int epicsShareAPI asInitAsyn(ASDBCALLBACK *pcallback)
{
if(!pacf) return(0);
if(asInitTheadId) {
errMessage(-1,"asInit: asInitTask already active");
if(pcallback) {
pcallback->status = S_asLib_InitFailed;
callbackRequest(&pcallback->callback);
}
return(-1);
}
asInitTheadId = epicsThreadCreate("asInitTask",
(epicsThreadPriorityCAServerHigh + 1),
epicsThreadGetStackSize(epicsThreadStackBig),
(EPICSTHREADFUNC)asInitTask,(void *)pcallback);
if(asInitTheadId==0) {
errMessage(0,"asInit: epicsThreadCreate Error");
if(pcallback) {
pcallback->status = S_asLib_InitFailed;
callbackRequest(&pcallback->callback);
}
asInitTheadId = 0;
}
return(0);
}
int epicsShareAPI asDbGetAsl(void *paddress)
{
DBADDR *paddr = paddress;
dbFldDes *pflddes;
pflddes = paddr->pfldDes;
return((int)pflddes->as_level);
}
void * epicsShareAPI asDbGetMemberPvt(void *paddress)
{
DBADDR *paddr = paddress;
dbCommon *precord;
precord = paddr->precord;
return((void *)precord->asp);
}
static void astacCallback(ASCLIENTPVT clientPvt,asClientStatus status)
{
char *recordname;
recordname = (char *)asGetClientPvt(clientPvt);
printf("astac callback %s: status=%d",recordname,status);
printf(" get %s put %s\n",(asCheckGet(clientPvt) ? "Yes" : "No"),
(asCheckPut(clientPvt) ? "Yes" : "No"));
}
int epicsShareAPI astac(const char *pname,const char *user,const char *location)
{
DBADDR *paddr;
long status;
ASCLIENTPVT *pasclientpvt=NULL;
dbCommon *precord;
dbFldDes *pflddes;
char *puser;
char *plocation;
paddr = dbCalloc(1,sizeof(DBADDR) + sizeof(ASCLIENTPVT));
pasclientpvt = (ASCLIENTPVT *)(paddr + 1);
status=dbNameToAddr(pname,paddr);
if(status) {
errMessage(status,"dbNameToAddr error");
return(1);
}
precord = paddr->precord;
pflddes = paddr->pfldDes;
puser = asCalloc(1,strlen(user)+1);
strcpy(puser,user);
plocation = asCalloc(1,strlen(location)+1);
strcpy(plocation,location);
status = asAddClient(pasclientpvt,precord->asp,
(int)pflddes->as_level,puser,plocation);
if(status) {
errMessage(status,"asAddClient error");
return(1);
} else {
asPutClientPvt(*pasclientpvt,(void *)precord->name);
asRegisterClientCallback(*pasclientpvt,astacCallback);
}
return(0);
}
static void myMemberCallback(ASMEMBERPVT memPvt,FILE *fp)
{
dbCommon *precord;
precord = asGetMemberPvt(memPvt);
if(precord) fprintf(fp," Record:%s",precord->name);
}
int epicsShareAPI asdbdump(void)
{
asDumpFP(stdout,myMemberCallback,NULL,1);
return(0);
}
int epicsShareAPI asdbdumpFP(FILE *fp)
{
asDumpFP(fp,myMemberCallback,NULL,1);
return(0);
}
int epicsShareAPI aspuag(const char *uagname)
{
asDumpUagFP(stdout,uagname);
return(0);
}
int epicsShareAPI aspuagFP(FILE *fp,const char *uagname)
{
asDumpUagFP(fp,uagname);
return(0);
}
int epicsShareAPI asphag(const char *hagname)
{
asDumpHagFP(stdout,hagname);
return(0);
}
int epicsShareAPI asphagFP(FILE *fp,const char *hagname)
{
asDumpHagFP(fp,hagname);
return(0);
}
int epicsShareAPI asprules(const char *asgname)
{
asDumpRulesFP(stdout,asgname);
return(0);
}
int epicsShareAPI asprulesFP(FILE *fp,const char *asgname)
{
asDumpRulesFP(fp,asgname);
return(0);
}
int epicsShareAPI aspmem(const char *asgname,int clients)
{
asDumpMemFP(stdout,asgname,myMemberCallback,clients);
return(0);
}
int epicsShareAPI aspmemFP(FILE *fp,const char *asgname,int clients)
{
asDumpMemFP(fp,asgname,myMemberCallback,clients);
return(0);
}