This is Unofficial EPICS BASE Doxygen Site
asDbLib.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2012 UChicago Argonne LLC, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * EPICS BASE is distributed subject to a Software License Agreement found
7 * in file LICENSE that is included with this distribution.
8 \*************************************************************************/
9 /* Author: Marty Kraimer Date: 02-11-94*/
10 
11 #include <stdlib.h>
12 #include <stddef.h>
13 #include <stdio.h>
14 #include <string.h>
15 
16 #include "alarm.h"
17 #include "asLib.h"
18 #include "cantProceed.h"
19 #include "dbDefs.h"
20 #include "epicsStdio.h"
21 #include "epicsThread.h"
22 #include "errlog.h"
23 #include "taskwd.h"
24 
25 #include "caeventmask.h"
26 
27 #define epicsExportSharedSymbols
28 #include "asCa.h"
29 #include "asDbLib.h"
30 #include "callback.h"
31 #include "dbAccess.h"
32 #include "dbChannel.h"
33 #include "dbCommon.h"
34 #include "dbEvent.h"
35 #include "db_field_log.h"
36 #include "dbStaticLib.h"
37 #include "recSup.h"
38 
39 static char *pacf=NULL;
40 static char *psubstitutions=NULL;
41 static epicsThreadId asInitTheadId=0;
42 static int firstTime = TRUE;
43 
44 static long asDbAddRecords(void)
45 {
46  DBENTRY dbentry;
47  DBENTRY *pdbentry=&dbentry;
48  long status;
49  dbCommon *precord;
50 
51  dbInitEntry(pdbbase,pdbentry);
52  status = dbFirstRecordType(pdbentry);
53  while(!status) {
54  status = dbFirstRecord(pdbentry);
55  while(!status) {
56  precord = pdbentry->precnode->precord;
57  if(!precord->asp) {
58  status = asAddMember(&precord->asp, precord->asg);
59  if(status) errMessage(status,"asDbAddRecords:asAddMember");
60  asPutMemberPvt(precord->asp,precord);
61  }
62  status = dbNextRecord(pdbentry);
63  }
64  status = dbNextRecordType(pdbentry);
65  }
66  dbFinishEntry(pdbentry);
67  return(0);
68 }
69 
70 int asSetFilename(const char *acf)
71 {
72  if (pacf)
73  free (pacf);
74  if (acf) {
75  pacf = calloc(1, strlen(acf)+1);
76  if (!pacf) {
77  errMessage(0, "asSetFilename calloc failure");
78  } else {
79  strcpy(pacf, acf);
80  if (*pacf != '/' && !strchr(pacf, ':')) {
81  printf("asSetFilename: Warning - relative paths won't usually "
82  "work\n");
83  }
84  }
85  } else {
86  pacf = NULL;
87  }
88  return 0;
89 }
90 
91 int asSetSubstitutions(const char *substitutions)
92 {
93  if(psubstitutions) free ((void *)psubstitutions);
94  if(substitutions) {
95  psubstitutions = calloc(1,strlen(substitutions)+1);
96  if(!psubstitutions) {
97  errMessage(0,"asSetSubstitutions calloc failure");
98  } else {
99  strcpy(psubstitutions,substitutions);
100  }
101  } else {
102  psubstitutions = NULL;
103  }
104  return(0);
105 }
106 
107 static void asSpcAsCallback(struct dbCommon *precord)
108 {
109  asChangeGroup(&precord->asp, precord->asg);
110 }
111 
112 static void asInitCommonOnce(void *arg)
113 {
114  int *firstTime = (int *)arg;
115  *firstTime = FALSE;
116 }
117 
118 static long asInitCommon(void)
119 {
120  long status;
121  int asWasActive = asActive;
122  int wasFirstTime = firstTime;
123  static epicsThreadOnceId asInitCommonOnceFlag = EPICS_THREAD_ONCE_INIT;
124 
125 
126  epicsThreadOnce(&asInitCommonOnceFlag,asInitCommonOnce,(void *)&firstTime);
127  if(wasFirstTime) {
128  if(!pacf) return(0); /*access security will NEVER be turned on*/
129  } else {
130  if(!asActive) {
131  printf("Access security is NOT enabled."
132  " Was asSetFilename specified before iocInit?\n");
133  return(S_asLib_asNotActive);
134  }
135  if(pacf) {
136  asCaStop();
137  } else { /*Just leave everything as is */
138  return(S_asLib_badConfig);
139  }
140  }
141  status = asInitFile(pacf,psubstitutions);
142  if(asActive) {
143  if(!asWasActive) {
144  dbSpcAsRegisterCallback(asSpcAsCallback);
145  asDbAddRecords();
146  }
147  asCaStart();
148  }
149  return(status);
150 }
151 
152 int asInit(void)
153 {
154  return(asInitCommon());
155 }
156 
157 int asShutdown(void) {
158  volatile ASBASE *pbase = pasbase;
159  pasbase = NULL;
160  firstTime = TRUE;
161  if(pbase)
162  asFreeAll((ASBASE*)pbase);
163  return 0;
164 }
165 
166 static void wdCallback(void *arg)
167 {
168  ASDBCALLBACK *pcallback = (ASDBCALLBACK *)arg;
169  pcallback->status = S_asLib_InitFailed;
170  callbackRequest(&pcallback->callback);
171 }
172 
173 static void asInitTask(ASDBCALLBACK *pcallback)
174 {
175  long status;
176 
177  taskwdInsert(epicsThreadGetIdSelf(), wdCallback, (void *)pcallback);
178  status = asInitCommon();
180  asInitTheadId = 0;
181  if(pcallback) {
182  pcallback->status = status;
183  callbackRequest(&pcallback->callback);
184  }
185 }
186 
187 int asInitAsyn(ASDBCALLBACK *pcallback)
188 {
189  if(!pacf) return(0);
190  if(asInitTheadId) {
191  errMessage(-1,"asInit: asInitTask already active");
192  if(pcallback) {
193  pcallback->status = S_asLib_InitFailed;
194  callbackRequest(&pcallback->callback);
195  }
196  return(-1);
197  }
198  asInitTheadId = epicsThreadCreate("asInitTask",
201  (EPICSTHREADFUNC)asInitTask,(void *)pcallback);
202  if(asInitTheadId==0) {
203  errMessage(0,"asInit: epicsThreadCreate Error");
204  if(pcallback) {
205  pcallback->status = S_asLib_InitFailed;
206  callbackRequest(&pcallback->callback);
207  }
208  asInitTheadId = 0;
209  }
210  return(0);
211 }
212 
213 int asDbGetAsl(struct dbChannel *chan)
214 {
215  return dbChannelFldDes(chan)->as_level;
216 }
217 
218 void * asDbGetMemberPvt(struct dbChannel *chan)
219 {
220  return dbChannelRecord(chan)->asp;
221 }
222 
223 static void astacCallback(ASCLIENTPVT clientPvt,asClientStatus status)
224 {
225  char *recordname;
226 
227  recordname = (char *)asGetClientPvt(clientPvt);
228  printf("astac callback %s: status=%d",recordname,status);
229  printf(" get %s put %s\n",(asCheckGet(clientPvt) ? "Yes" : "No"),
230  (asCheckPut(clientPvt) ? "Yes" : "No"));
231 }
232 
233 int astac(const char *pname,const char *user,const char *location)
234 {
235  DBADDR *paddr;
236  long status;
237  ASCLIENTPVT *pasclientpvt=NULL;
238  dbCommon *precord;
239  dbFldDes *pflddes;
240  char *puser;
241  char *plocation;
242 
243  if (!pname || !user || !location){
244  printf("Usage: astac \"record name\", \"user\", \"host\"\n");
245  return(1);
246  }
247  paddr = dbCalloc(1,sizeof(DBADDR) + sizeof(ASCLIENTPVT));
248  pasclientpvt = (ASCLIENTPVT *)(paddr + 1);
249  status=dbNameToAddr(pname,paddr);
250  if(status) {
251  errMessage(status,"dbNameToAddr error");
252  return(1);
253  }
254  precord = paddr->precord;
255  pflddes = paddr->pfldDes;
256  puser = asCalloc(1,strlen(user)+1);
257  strcpy(puser,user);
258  plocation = asCalloc(1,strlen(location)+1);
259  strcpy(plocation,location);
260 
261  status = asAddClient(pasclientpvt,precord->asp,
262  (int)pflddes->as_level,puser,plocation);
263  if(status) {
264  errMessage(status,"asAddClient error");
265  return(1);
266  } else {
267  asPutClientPvt(*pasclientpvt,(void *)precord->name);
268  asRegisterClientCallback(*pasclientpvt,astacCallback);
269  }
270  return(0);
271 }
272 
273 static void myMemberCallback(ASMEMBERPVT memPvt,FILE *fp)
274 {
275  dbCommon *precord;
276 
277  precord = asGetMemberPvt(memPvt);
278  if(precord) fprintf(fp," Record:%s",precord->name);
279 }
280 
281 int asdbdump(void)
282 {
283  asDumpFP(stdout,myMemberCallback,NULL,1);
284  return(0);
285 }
286 
287 int asdbdumpFP(FILE *fp)
288 {
289  asDumpFP(fp,myMemberCallback,NULL,1);
290  return(0);
291 }
292 
293 int aspuag(const char *uagname)
294 {
295  asDumpUagFP(stdout,uagname);
296  return(0);
297 }
298 
299 int aspuagFP(FILE *fp,const char *uagname)
300 {
301 
302  asDumpUagFP(fp,uagname);
303  return(0);
304 }
305 
306 int asphag(const char *hagname)
307 {
308  asDumpHagFP(stdout,hagname);
309  return(0);
310 }
311 
312 int asphagFP(FILE *fp,const char *hagname)
313 {
314  asDumpHagFP(fp,hagname);
315  return(0);
316 }
317 
318 int asprules(const char *asgname)
319 {
320  asDumpRulesFP(stdout,asgname);
321  return(0);
322 }
323 
324 int asprulesFP(FILE *fp,const char *asgname)
325 {
326  asDumpRulesFP(fp,asgname);
327  return(0);
328 }
329 
330 int aspmem(const char *asgname,int clients)
331 {
332  asDumpMemFP(stdout,asgname,myMemberCallback,clients);
333  return(0);
334 }
335 
336 int aspmemFP(FILE *fp,const char *asgname,int clients)
337 {
338  asDumpMemFP(fp,asgname,myMemberCallback,clients);
339  return(0);
340 }
void dbInitEntry(dbBase *pdbbase, DBENTRY *pdbentry)
Definition: dbStaticLib.c:626
long dbFirstRecordType(DBENTRY *pdbentry)
Definition: dbStaticLib.c:1198
void taskwdInsert(epicsThreadId tid, TASKWDFUNC callback, void *usr)
Definition: taskwd.c:176
void asCaStart(void)
Definition: asCa.c:230
LIBCOM_API long epicsStdCall asChangeGroup(ASMEMBERPVT *asMemberPvt, const char *newAsgName)
#define FALSE
Definition: dbDefs.h:32
int aspmem(const char *asgname, int clients)
Definition: asDbLib.c:330
LIBCOM_API long epicsStdCall asInitFile(const char *filename, const char *substitutions)
LIBCOM_API int epicsStdCall asDumpHagFP(FILE *fp, const char *hagname)
pvd::Status status
#define asCheckPut(asClientPvt)
Definition: asLib.h:45
#define asCheckGet(asClientPvt)
Definition: asLib.h:43
LIBCOM_API volatile ASBASE * pasbase
Definition: asLibRoutines.c:38
void * precord
Definition: dbBase.h:116
LIBCOM_API long epicsStdCall asAddClient(ASCLIENTPVT *asClientPvt, ASMEMBERPVT asMemberPvt, int asl, const char *user, char *host)
int asInitAsyn(ASDBCALLBACK *pcallback)
Definition: asDbLib.c:187
LIBCOM_API long epicsStdCall asRegisterClientCallback(ASCLIENTPVT asClientPvt, ASCLIENTCALLBACK pcallback)
#define printf
Definition: epicsStdio.h:41
void dbFinishEntry(DBENTRY *pdbentry)
Definition: dbStaticLib.c:632
int asphagFP(FILE *fp, const char *hagname)
Definition: asDbLib.c:312
LIBCOM_API void epicsStdCall asPutClientPvt(ASCLIENTPVT asClientPvt, void *userPvt)
#define NULL
Definition: catime.c:38
#define errMessage(S, PM)
Definition: errlog.h:48
void asCaStop(void)
Definition: asCa.c:254
int asphag(const char *hagname)
Definition: asDbLib.c:306
LIBCOM_API int epicsStdCall asDumpFP(FILE *fp, void(*memcallback)(ASMEMBERPVT, FILE *), void(*clientcallback)(ASCLIENTPVT, FILE *), int verbose)
Definition: asLib.h:152
long dbNextRecordType(DBENTRY *pdbentry)
Definition: dbStaticLib.c:1209
int asdbdumpFP(FILE *fp)
Definition: asDbLib.c:287
Miscellaneous macro definitions.
LIBCOM_API unsigned int epicsStdCall epicsThreadGetStackSize(epicsThreadStackSizeClass size)
Definition: osdThread.c:466
long dbNextRecord(DBENTRY *pdbentry)
Definition: dbStaticLib.c:1583
int asSetSubstitutions(const char *substitutions)
Definition: asDbLib.c:91
epicsThreadId epicsStdCall epicsThreadCreate(const char *name, unsigned int priority, unsigned int stackSize, EPICSTHREADFUNC funptr, void *parm)
Definition: epicsThread.cpp:33
int aspuag(const char *uagname)
Definition: asDbLib.c:293
#define S_asLib_InitFailed
Definition: asLib.h:136
epicsCallback callback
Definition: asDbLib.h:21
asClientStatus
Definition: asLib.h:32
LIBCOM_API void *epicsStdCall asGetMemberPvt(ASMEMBERPVT asMemberPvt)
#define EPICS_THREAD_ONCE_INIT
Definition: epicsThread.h:109
dbRecordNode * precnode
Definition: dbStaticLib.h:37
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
LIBCOM_API int epicsStdCall asDumpRulesFP(FILE *fp, const char *asgname)
ChannelProviderRegistry::shared_pointer clients
int asprules(const char *asgname)
Definition: asDbLib.c:318
LIBCOM_API void *epicsStdCall asGetClientPvt(ASCLIENTPVT asClientPvt)
LIBCOM_API int epicsStdCall asDumpMemFP(FILE *fp, const char *asgname, void(*memcallback)(ASMEMBERPVT, FILE *), int clients)
#define stdout
Definition: epicsStdio.h:30
int aspmemFP(FILE *fp, const char *asgname, int clients)
Definition: asDbLib.c:336
int astac(const char *pname, const char *user, const char *location)
Definition: asDbLib.c:233
#define epicsThreadPriorityCAServerHigh
Definition: epicsThread.h:81
asLevel as_level
Definition: dbBase.h:93
void taskwdRemove(epicsThreadId tid)
Definition: taskwd.c:206
long status
Definition: asDbLib.h:22
void * asDbGetMemberPvt(struct dbChannel *chan)
Definition: asDbLib.c:218
#define TRUE
Definition: dbDefs.h:27
#define dbCalloc(nobj, size)
Definition: dbStaticLib.h:228
int asDbGetAsl(struct dbChannel *chan)
Definition: asDbLib.c:213
int aspuagFP(FILE *fp, const char *uagname)
Definition: asDbLib.c:299
long dbFirstRecord(DBENTRY *pdbentry)
Definition: dbStaticLib.c:1569
LIBCOM_API long epicsStdCall asAddMember(ASMEMBERPVT *asMemberPvt, const char *asgName)
LIBCOM_API void *epicsStdCall asCalloc(size_t nobj, size_t size)
Routines for code that can&#39;t continue or return after an error.
const std::string pname
int asprulesFP(FILE *fp, const char *asgname)
Definition: asDbLib.c:324
C++ and C descriptions for a thread.
int asSetFilename(const char *acf)
Definition: asDbLib.c:70
int asInit(void)
Definition: asDbLib.c:152
LIBCOM_API void epicsStdCall asPutMemberPvt(ASMEMBERPVT asMemberPvt, void *userPvt)
int asShutdown(void)
Definition: asDbLib.c:157
LIBCOM_API int epicsStdCall asDumpUagFP(FILE *fp, const char *uagname)
LIBCOM_API int asActive
Definition: asLibRoutines.c:40
void(* EPICSTHREADFUNC)(void *parm)
Definition: epicsThread.h:66
#define S_asLib_asNotActive
Definition: asLib.h:137
int asdbdump(void)
Definition: asDbLib.c:281
LIBCOM_API void asFreeAll(ASBASE *pasbase)
LIBCOM_API epicsThreadId epicsStdCall epicsThreadGetIdSelf(void)
Definition: osdThread.c:810
#define S_asLib_badConfig
Definition: asLib.h:133