34 #define LOCK epicsMutexMustLock(asLock) 35 #define UNLOCK epicsMutexUnlock(asLock) 42 static void *freeListPvt =
NULL;
45 #define DEFAULT "DEFAULT" 51 static long asAddMemberPvt(
ASMEMBERPVT *pasMemberPvt,
const char *asgName);
52 static long asComputeAllAsgPvt(
void);
53 static long asComputeAsgPvt(
ASG *pasg);
55 static UAG *asUagAdd(
const char *uagName);
56 static long asUagAddUser(
UAG *puag,
const char *user);
57 static HAG *asHagAdd(
const char *hagName);
58 static long asHagAddHost(
HAG *phag,
const char *host);
59 static ASG *asAsgAdd(
const char *asgName);
60 static long asAsgAddInp(
ASG *pasg,
const char *inp,
int inpIndex);
62 static long asAsgAddRuleOptions(
ASGRULE *pasgrule,
int trapMask);
63 static long asAsgRuleUagAdd(
ASGRULE *pasgrule,
const char *name);
64 static long asAsgRuleHagAdd(
ASGRULE *pasgrule,
const char *name);
65 static long asAsgRuleCalc(
ASGRULE *pasgrule,
const char *calc);
79 static void asInitializeOnce(
void *arg)
104 status = myParse(inputfunction);
144 pasbaseold = (
ASBASE *)pasbase;
145 pasbase = (
ASBASE volatile *)pasbasenew;
157 status = asAddMemberPvt(&poldmem,poldmem->
asgName);
158 poldmem = pnextoldmem;
169 long epicsStdCall
asInitFile(
const char *filename,
const char *substitutions)
174 fp = fopen(filename,
"r");
176 errlogPrintf(
"asInitFile: Can't open file '%s'\n", filename);
179 status =
asInitFP(fp,substitutions);
180 if(fclose(fp)==EOF) {
188 static char *my_buffer;
189 static char *my_buffer_ptr;
191 static char *mac_input_buffer=
NULL;
194 static int myInputFunction(
char *buf,
int max_size)
199 if(*my_buffer_ptr==0) {
201 fgetsRtn = fgets(mac_input_buffer,
BUF_SIZE,stream);
206 errlogPrintf(
"access security: macExpandString failed\n" 207 "input line: %s\n",mac_input_buffer);
212 fgetsRtn = fgets(my_buffer,
BUF_SIZE,stream);
214 if(fgetsRtn==
NULL)
return(0);
215 my_buffer_ptr = my_buffer;
217 l = strlen(my_buffer_ptr);
218 n = (l<=max_size ? l : max_size);
219 memcpy(buf,my_buffer_ptr,n);
224 long epicsStdCall
asInitFP(FILE *fp,
const char *substitutions)
233 my_buffer_ptr = my_buffer;
237 errMessage(status,
"asInitFP: macCreateHandle error");
241 if(macPairs ==
NULL) {
247 mac_input_buffer = mac_buffer;
258 static const char* membuf;
260 static int memInputFunction(
char *buf,
int max_size)
263 if(!membuf)
return ret;
265 while(max_size && *membuf) {
274 long epicsStdCall
asInitMem(
const char *acf,
const char *substitutions)
292 status = asAddMemberPvt(pasMemberPvt,asgName);
302 pasgmember = *asMemberPvt;
309 if(pasgmember->
pasg) {
312 errMessage(-1,
"Logic error in asRemoveMember");
328 pasgmember = *asMemberPvt;
331 if(pasgmember->
pasg) {
334 errMessage(-1,
"Logic error in asChangeGroup");
338 status = asAddMemberPvt(asMemberPvt,newAsgName);
348 if(!pasgmember)
return(
NULL);
357 if(!pasgmember)
return;
363 int asl,
const char *user,
char *host)
375 for (i = 0; i < len; i++) {
376 host[
i] = (char)tolower((
int)host[
i]);
378 *pasClientPvt = pasgclient;
380 pasgclient->
level = asl;
381 pasgclient->
user = user;
382 pasgclient->
host = host;
385 status = asComputePvt(pasgclient);
391 ASCLIENTPVT asClientPvt,
int asl,
const char *user,
char *host)
400 for (i = 0; i < len; i++) {
401 host[
i] = (char)tolower((
int)host[
i]);
404 pasgclient->
level = asl;
405 pasgclient->
user = user;
406 pasgclient->
host = host;
407 status = asComputePvt(pasgclient);
422 errMessage(-1,
"asRemoveClient: No ASGMEMBER");
452 if(!pasgclient)
return(
NULL);
460 if(!pasgclient)
return;
472 status = asComputeAllAsgPvt();
483 status = asComputeAsgPvt(pasg);
494 status = asComputePvt(asClientPvt);
501 static const char *asAccessName[] = {
"NONE",
"READ",
"WRITE"};
502 static const char *asTrapOption[] = {
"NOTRAPWRITE",
"TRAPWRITE"};
503 static const char *asLevelName[] = {
"ASL0",
"ASL1"};
505 void (*memcallback)(
struct asgMember *,FILE *),
506 void (*clientcallback)(
struct asgClient *,FILE *),
514 void (*memcallback)(
struct asgMember *,FILE *),
515 void (*clientcallback)(
struct asgClient *,FILE *),
532 if(!puag) fprintf(fp,
"No UAGs\n");
534 fprintf(fp,
"UAG(%s)",puag->
name);
536 if(puagname) fprintf(fp,
" {");
else fprintf(fp,
"\n");
538 fprintf(fp,
"%s",puagname->
user);
540 if(puagname) fprintf(fp,
",");
else fprintf(fp,
"}\n");
545 if(!phag) fprintf(fp,
"No HAGs\n");
547 fprintf(fp,
"HAG(%s)",phag->
name);
549 if(phagname) fprintf(fp,
" {");
else fprintf(fp,
"\n");
551 fprintf(fp,
"%s",phagname->
host);
553 if(phagname) fprintf(fp,
",");
else fprintf(fp,
"}\n");
558 if(!pasg) fprintf(fp,
"No ASGs\n");
562 fprintf(fp,
"ASG(%s)",pasg->
name);
565 if(pasginp || pasgrule) {
567 print_end_brace =
TRUE;
570 print_end_brace =
FALSE;
574 fprintf(fp,
"\tINP%c(%s)",(pasginp->
inpIndex +
'A'),pasginp->
inp);
577 fprintf(fp,
" INVALID");
579 fprintf(fp,
" VALID");
588 fprintf(fp,
"\tRULE(%d,%s,%s)",
593 if(pasguag || pasghag || pasgrule->
calc) {
595 print_end_brace =
TRUE;
598 print_end_brace =
FALSE;
600 if(pasguag) fprintf(fp,
"\t\tUAG(");
602 fprintf(fp,
"%s",pasguag->
puag->
name);
604 if(pasguag) fprintf(fp,
",");
else fprintf(fp,
")\n");
607 if(pasghag) fprintf(fp,
"\t\tHAG(");
609 fprintf(fp,
"%s",pasghag->
phag->
name);
611 if(pasghag) fprintf(fp,
",");
else fprintf(fp,
")\n");
614 fprintf(fp,
"\t\tCALC(\"%s\")",pasgrule->
calc);
616 fprintf(fp,
" result=%s",(pasgrule->
result==1 ?
"TRUE" :
"FALSE"));
619 if(print_end_brace) fprintf(fp,
"\t}\n");
623 if(!verbose) pasgmember =
NULL;
624 if(pasgmember) fprintf(fp,
"\tMEMBERLIST\n");
626 if(strlen(pasgmember->
asgName)==0)
627 fprintf(fp,
"\t\t<null>");
629 fprintf(fp,
"\t\t%s",pasgmember->
asgName);
630 if(memcallback) memcallback(pasgmember,fp);
634 fprintf(fp,
"\t\t\t %s %s",pasgclient->
user,pasgclient->
host);
635 if(pasgclient->
level>=0 && pasgclient->
level<=1)
636 fprintf(fp,
" %s",asLevelName[pasgclient->
level]);
638 fprintf(fp,
" Illegal Level %d",pasgclient->
level);
641 asAccessName[pasgclient->
access],
642 asTrapOption[pasgclient->
trapMask]);
644 fprintf(fp,
" Illegal Access %d",pasgclient->
access);
645 if(clientcallback) clientcallback(pasgclient,fp);
651 if(print_end_brace) fprintf(fp,
"}\n");
669 if(!puag) fprintf(fp,
"No UAGs\n");
671 if(uagname && strcmp(uagname,puag->
name)!=0) {
675 fprintf(fp,
"UAG(%s)",puag->
name);
677 if(puagname) fprintf(fp,
" {");
else fprintf(fp,
"\n");
679 fprintf(fp,
"%s",puagname->
user);
681 if(puagname) fprintf(fp,
",");
else fprintf(fp,
"}\n");
700 if(!phag) fprintf(fp,
"No HAGs\n");
702 if(hagname && strcmp(hagname,phag->
name)!=0) {
706 fprintf(fp,
"HAG(%s)",phag->
name);
708 if(phagname) fprintf(fp,
" {");
else fprintf(fp,
"\n");
710 fprintf(fp,
"%s",phagname->
host);
712 if(phagname) fprintf(fp,
",");
else fprintf(fp,
"}\n");
734 if(!pasg) fprintf(fp,
"No ASGs\n");
738 if(asgname && strcmp(asgname,pasg->
name)!=0) {
742 fprintf(fp,
"ASG(%s)",pasg->
name);
745 if(pasginp || pasgrule) {
747 print_end_brace =
TRUE;
750 print_end_brace =
FALSE;
754 fprintf(fp,
"\tINP%c(%s)",(pasginp->
inpIndex +
'A'),pasginp->
inp);
756 fprintf(fp,
" INVALID");
764 fprintf(fp,
"\tRULE(%d,%s,%s)",
769 if(pasguag || pasghag || pasgrule->
calc) {
771 print_end_brace =
TRUE;
774 print_end_brace =
FALSE;
776 if(pasguag) fprintf(fp,
"\t\tUAG(");
778 fprintf(fp,
"%s",pasguag->
puag->
name);
780 if(pasguag) fprintf(fp,
",");
else fprintf(fp,
")\n");
783 if(pasghag) fprintf(fp,
"\t\tHAG(");
785 fprintf(fp,
"%s",pasghag->
phag->
name);
787 if(pasghag) fprintf(fp,
",");
else fprintf(fp,
")\n");
790 fprintf(fp,
"\t\tCALC(\"%s\")",pasgrule->
calc);
791 fprintf(fp,
" result=%s",(pasgrule->
result==1 ?
"TRUE" :
"FALSE"));
794 if(print_end_brace) fprintf(fp,
"\t}\n");
797 if(print_end_brace) fprintf(fp,
"}\n");
818 if(!pasg) fprintf(fp,
"No ASGs\n");
821 if(asgname && strcmp(asgname,pasg->
name)!=0) {
825 fprintf(fp,
"ASG(%s)\n",pasg->
name);
827 if(pasgmember) fprintf(fp,
"\tMEMBERLIST\n");
829 if(strlen(pasgmember->
asgName)==0)
830 fprintf(fp,
"\t\t<null>");
832 fprintf(fp,
"\t\t%s",pasgmember->
asgName);
833 if(memcallback) memcallback(pasgmember,fp);
836 if(!clients) pasgclient =
NULL;
838 fprintf(fp,
"\t\t\t %s %s",
840 if(pasgclient->
level>=0 && pasgclient->
level<=1)
841 fprintf(fp,
" %s",asLevelName[pasgclient->
level]);
843 fprintf(fp,
" Illegal Level %d",pasgclient->
level);
846 asAccessName[pasgclient->
access],
847 asTrapOption[pasgclient->
trapMask]);
849 fprintf(fp,
" Illegal Access %d",pasgclient->
access);
874 LIBCOM_API
void * epicsStdCall
asCalloc(
size_t nobj,
size_t size)
883 size_t len = strlen((
char *) str);
885 strcpy(buf, (
char *) str);
889 static long asAddMemberPvt(
ASMEMBERPVT *pasMemberPvt,
const char *asgName)
896 pasgmember = *pasMemberPvt;
900 *pasMemberPvt = pasgmember;
905 if(strcmp(pgroup->
name,pasgmember->
asgName)==0)
goto got_it;
917 pasgmember->
pasg = pgroup;
927 static long asComputeAllAsgPvt(
void)
934 asComputeAsgPvt(pasg);
940 static long asComputeAsgPvt(
ASG *pasg)
958 pasgrule->
result = ((result>.99) && (result<1.01)) ? 1 : 0;
991 pasg = pasgMember->
pasg;
993 oldaccess=pasgclient->
access;
997 if(access>=pasgrule->
access)
goto next_rule;
998 if(pasgclient->
level > pasgrule->
level)
goto next_rule;
1006 if((puag = pasguag->
puag)) {
1008 if(pgphentry)
goto check_hag;
1022 if((phag = pasghag->
phag)) {
1024 if(pgphentry)
goto check_calc;
1033 access = pasgrule->
access;
1039 pasgclient->
access = access;
1041 if(pasgclient->
pcallback && oldaccess!=access) {
1100 free(pasgrule->
calc);
1101 free(pasgrule->
rpcl);
1131 static UAG *asUagAdd(
const char *uagName)
1142 cmpvalue = strcmp(uagName,pnext->
name);
1143 if(cmpvalue < 0)
break;
1145 errlogPrintf(
"Duplicate User Access Group named '%s'\n", uagName);
1152 puag->
name = (
char *)(puag+1);
1153 strcpy(puag->
name,uagName);
1163 static long asUagAddUser(
UAG *puag,
const char *user)
1167 if(!puag)
return(0);
1169 puagname->
user = (
char *)(puagname+1);
1170 strcpy(puagname->
user,user);
1175 static HAG *asHagAdd(
const char *hagName)
1186 cmpvalue = strcmp(hagName,pnext->
name);
1187 if(cmpvalue < 0)
break;
1189 errlogPrintf(
"Duplicate Host Access Group named '%s'\n", hagName);
1196 phag->
name = (
char *)(phag+1);
1197 strcpy(phag->
name,hagName);
1207 static long asHagAddHost(
HAG *phag,
const char *host)
1211 if (!phag)
return 0;
1213 size_t i, len = strlen(host);
1214 phagname =
asCalloc(1,
sizeof(*phagname) + len);
1215 for (i = 0; i < len; i++) {
1216 phagname->
host[
i] = (char)tolower((
int)host[
i]);
1220 struct sockaddr_in addr;
1224 static const char unresolved[] =
"unresolved:";
1226 errlogPrintf(
"ACF: Unable to resolve host '%s'\n", host);
1228 phagname =
asCalloc(1,
sizeof(*phagname) +
sizeof(unresolved)-1+strlen(host));
1229 strcpy(phagname->
host, unresolved);
1230 strcat(phagname->
host, host);
1233 ip = ntohl(addr.sin_addr.s_addr);
1234 phagname =
asCalloc(1,
sizeof(*phagname) + 24);
1247 static ASG *asAsgAdd(
const char *asgName)
1258 cmpvalue = strcmp(asgName,pnext->
name);
1259 if(cmpvalue < 0)
break;
1266 errlogPrintf(
"Duplicate Access Security Group named '%s'\n", asgName);
1275 pasg->
name = (
char *)(pasg+1);
1276 strcpy(pasg->
name,asgName);
1286 static long asAsgAddInp(
ASG *pasg,
const char *inp,
int inpIndex)
1290 if(!pasg)
return(0);
1292 pasginp->
inp = (
char *)(pasginp+1);
1293 strcpy(pasginp->
inp,inp);
1294 pasginp->
pasg = pasg;
1304 if(!pasg)
return(0);
1306 pasgrule->
access = access;
1308 pasgrule->
level = level;
1315 static long asAsgAddRuleOptions(
ASGRULE *pasgrule,
int trapMask)
1317 if(!pasgrule)
return(0);
1322 static long asAsgRuleUagAdd(
ASGRULE *pasgrule,
const char *name)
1333 if (strcmp(puag->
name, name)==0)
1338 errlogPrintf(
"No User Access Group named '%s' defined\n", name);
1343 pasguag->
puag = puag;
1348 static long asAsgRuleHagAdd(
ASGRULE *pasgrule,
const char *name)
1359 if (strcmp(phag->
name, name)==0)
1364 errlogPrintf(
"No Host Access Group named '%s' defined\n", name);
1369 pasghag->
phag = phag;
1374 static long asAsgRuleCalc(
ASGRULE *pasgrule,
const char *calc)
1379 unsigned long stores;
1381 if (!pasgrule)
return 0;
1382 insize = strlen(calc) + 1;
1384 strcpy(pasgrule->
calc, calc);
1388 free(pasgrule->
calc);
1389 free(pasgrule->
rpcl);
1399 free(pasgrule->
calc);
1400 free(pasgrule->
rpcl);
1404 errlogPrintf(
"Assignment operator used in CALC expression '%s'\n",
void *epicsStdCall asGetMemberPvt(ASMEMBERPVT asMemberPvt)
int epicsStdCall asDumpRules(const char *asgname)
LIBCOM_API void *epicsStdCall freeListCalloc(void *pvt)
LIBCOM_API const char * calcErrorStr(short error)
Convert an error code to a string.
LIBCOM_API int epicsStdCall aToIPAddr(const char *pAddrString, unsigned short defaultPort, struct sockaddr_in *pIP)
LIBCOM_API long epicsStdCall macParseDefns(MAC_HANDLE *handle, const char *defns, char **pairs[])
Parse macro definitions into an array of {name, value} pairs.
void *epicsStdCall asGetClientPvt(ASCLIENTPVT asClientPvt)
#define S_asLib_badMember
#define ellCount(PLIST)
Report the number of nodes in a list.
int epicsStdCall asDumpUag(const char *uagname)
long epicsStdCall asInitialize(ASINPUTFUNCPTR inputfunction)
int epicsStdCall asDumpMemFP(FILE *fp, const char *asgname, void(*memcallback)(ASMEMBERPVT, FILE *), int clients)
The API for the EPICS Calculation Engine.
long epicsStdCall asRegisterClientCallback(ASCLIENTPVT asClientPvt, ASCLIENTCALLBACK pcallback)
long epicsStdCall asChangeGroup(ASMEMBERPVT *asMemberPvt, const char *newAsgName)
int epicsStdCall asDumpHagFP(FILE *fp, const char *hagname)
#define epicsMutexMustCreate()
Create an epicsMutex semaphore for use from C code.
int epicsStdCall asDump(void(*memcallback)(struct asgMember *, FILE *), void(*clientcallback)(struct asgClient *, FILE *), int verbose)
#define errMessage(S, PM)
LIBCOM_API void epicsStdCall freeListInitPvt(void **ppvt, int size, int nmalloc)
long epicsStdCall asComputeAllAsg(void)
long epicsStdCall asCompute(ASCLIENTPVT asClientPvt)
#define CALCPERFORM_NARGS
Number of input arguments to a calc expression (A-L)
Miscellaneous macro definitions.
#define ellPrevious(PNODE)
Find the previous node in list.
long epicsStdCall macExpandString(MAC_HANDLE *handle, const char *src, char *dest, long capacity)
Expand a string which may contain macro references.
ASCLIENTCALLBACK pcallback
LIBCOM_API void epicsStdCall gphInitPvt(struct gphPvt **ppvt, int tableSize)
#define S_asLib_InitFailed
int epicsStdCall asDumpHag(const char *hagname)
long epicsStdCall asInitFP(FILE *fp, const char *substitutions)
void ellAdd(ELLLIST *pList, ELLNODE *pNode)
Adds a node to the end of a list.
LIBCOM_API GPHENTRY *epicsStdCall gphFind(struct gphPvt *pvt, const char *name, void *pvtid)
#define ellNext(PNODE)
Find the next node in list.
#define EPICS_THREAD_ONCE_INIT
#define S_asLib_clientsExist
void epicsStdCall asPutMemberPvt(ASMEMBERPVT asMemberPvt, void *userPvt)
Macro substitution context, for use by macLib routines only.
APIs for the epicsMutex mutual exclusion semaphore.
LIBCOM_API void epicsStdCall epicsThreadOnce(epicsThreadOnceId *id, EPICSTHREADFUNC, void *arg)
long epicsStdCall asRemoveMember(ASMEMBERPVT *asMemberPvt)
LIBCOM_API void epicsStdCall freeListFree(void *pvt, void *pmem)
LIBCOM_API void *epicsStdCall asCalloc(size_t nobj, size_t size)
ChannelProviderRegistry::shared_pointer clients
long epicsStdCall asAddMember(ASMEMBERPVT *pasMemberPvt, const char *asgName)
int epicsStdCall asDumpFP(FILE *fp, void(*memcallback)(struct asgMember *, FILE *), void(*clientcallback)(struct asgClient *, FILE *), int verbose)
LIBCOM_API void epicsStdCall gphDumpFP(FILE *fp, struct gphPvt *pvt)
long epicsStdCall asInitFile(const char *filename, const char *substitutions)
ASBASE volatile * pasbase
void epicsStdCall asPutClientPvt(ASCLIENTPVT asClientPvt, void *userPvt)
LIBCOM_API int epicsStdCall asDumpHash(void)
LIBCOM_API void * callocMustSucceed(size_t count, size_t size, const char *msg)
A calloc() that never returns NULL.
int epicsStdCall asDumpMem(const char *asgname, void(*memcallback)(ASMEMBERPVT, FILE *), int clients)
LIBCOM_API void epicsStdCall gphFreeMem(struct gphPvt *pvt)
int errlogPrintf(const char *pFormat,...)
int(* ASINPUTFUNCPTR)(char *buf, int max_size)
LIBCOM_API int epicsStdCall asDumpHashFP(FILE *fp)
long epicsStdCall macDeleteHandle(MAC_HANDLE *handle)
Marks a handle invalid, and frees all storage associated with it.
long epicsStdCall asComputeAsg(ASG *pasg)
void asFreeAll(ASBASE *pasbase)
long epicsStdCall macCreateHandle(MAC_HANDLE **pHandle, const char *pairs[])
Creates a new macro substitution context.
#define S_asLib_badClient
#define ellInit(PLIST)
Initialize a list type.
int epicsStdCall asDumpUagFP(FILE *fp, const char *uagname)
void ellInsert(ELLLIST *plist, ELLNODE *pPrev, ELLNODE *pNode)
Inserts a node into a list immediately after a specific node.
Text macro substitution routines.
int epicsStdCall asDumpRulesFP(FILE *fp, const char *asgname)
Routines for code that can't continue or return after an error.
void(* ASCLIENTCALLBACK)(ASCLIENTPVT, asClientStatus)
long epicsStdCall asRemoveClient(ASCLIENTPVT *asClientPvt)
LIBCOM_API long postfix(const char *psrc, char *pout, short *perror)
Compile an infix expression into postfix byte-code.
long epicsStdCall asAddClient(ASCLIENTPVT *pasClientPvt, ASMEMBERPVT asMemberPvt, int asl, const char *user, char *host)
long epicsStdCall asInitMem(const char *acf, const char *substitutions)
C++ and C descriptions for a thread.
LIBCOM_API long epicsStdCall macInstallMacros(MAC_HANDLE *handle, char *pairs[])
Install set of {name, value} pairs as definitions.
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
#define INFIX_TO_POSTFIX_SIZE(n)
Calculate required size of postfix buffer from infix.
LIBCOM_API char *epicsStdCall asStrdup(unsigned char *str)
#define S_asLib_asNotActive
LIBCOM_API int epicsStdCall epicsSnprintf(char *str, size_t size, const char *format,...) EPICS_PRINTF_STYLE(3
long epicsStdCall asChangeClient(ASCLIENTPVT asClientPvt, int asl, const char *user, char *host)
LIBCOM_API GPHENTRY *epicsStdCall gphAdd(struct gphPvt *pvt, const char *name, void *pvtid)
#define ellFirst(PLIST)
Find the first node in list.
#define S_asLib_badConfig