Пример #1
0
LOCAL int queueRecord (const char *precName)
{
    DBENTRY	dbentry;
    DBENTRY	*pdbentry=&dbentry;
    dbCommon	*pdbc;
    msg_t	msg;

    dbInitEntry (pdbbase, pdbentry);
    if (dbFindRecord (pdbentry, precName) != 0) {
	dbFinishEntry (pdbentry);
	return ERROR;
    }
    pdbc = dbentry.precnode->precord;
    dbFinishEntry (pdbentry);

    DEBUG2(4,"queueRecord: Name: %s ptr: 0x%x\n",precName,(unsigned)pdbc)
    msg.pdbc = pdbc;
    msg.osevr = pdbc->sevr;
    msg.ostat = pdbc->stat;
    msg.nsevr = pdbc->sevr;
    msg.nstat = pdbc->stat;
    tsLocalTime (&msg.stamp);
    msg.msgType = mt_Status;

    ringInsert (&msg);

    return OK;
}
Пример #2
0
long epicsShareAPI dbla(const char *pmask)
{
    DBENTRY dbentry;
    DBENTRY *pdbentry = &dbentry;
    long status;

    if (!pdbbase) {
        printf("No database loaded\n");
        return 0;
    }

    dbInitEntry(pdbbase, pdbentry);
    status = dbFirstRecordType(pdbentry);
    while (!status) {
        for (status = dbFirstRecord(pdbentry); !status;
             status = dbNextRecord(pdbentry)) {
            char *palias;

            if (!dbIsAlias(pdbentry))
                continue;

            palias = dbGetRecordName(pdbentry);
            if (pmask && *pmask && !epicsStrGlobMatch(palias, pmask))
                continue;
            dbFindField(pdbentry, "NAME");
            printf("%s -> %s\n", palias, dbGetString(pdbentry));
        }
        status = dbNextRecordType(pdbentry);
    }

    dbFinishEntry(pdbentry);
    return 0;
}
Пример #3
0
long epicsShareAPI dbgrep(const char *pmask)
{
    DBENTRY dbentry;
    DBENTRY *pdbentry = &dbentry;
    long status;

    if (!pmask || !*pmask) {
        printf("Usage: dbgrep \"pattern\"\n");
        return 1;
    }

    if (!pdbbase) {
        printf("No database loaded\n");
        return 0;
    }

    dbInitEntry(pdbbase, pdbentry);
    status = dbFirstRecordType(pdbentry);
    while (!status) {
        status = dbFirstRecord(pdbentry);
        while (!status) {
            char *pname = dbGetRecordName(pdbentry);
            if (epicsStrGlobMatch(pname, pmask))
                puts(pname);
            status = dbNextRecord(pdbentry);
        }
        status = dbNextRecordType(pdbentry);
    }

    dbFinishEntry(pdbentry);
    return 0;
}
Пример #4
0
ChannelFind::shared_pointer DbPvProvider::channelList(
    ChannelListRequester::shared_pointer const & channelListRequester)
{
    PVStringArray::svector channelNames;

    DBENTRY dbentry;
    DBENTRY *pdbentry=&dbentry;

    if (pdbbase) {
        dbInitEntry(pdbbase, pdbentry);
        long status = dbFirstRecordType(pdbentry);
        if (!status) {
            while (!status) {
                status = dbFirstRecord(pdbentry);
                while (!status) {
                    channelNames.push_back(dbGetRecordName(pdbentry));
                    status = dbNextRecord(pdbentry);
                }
                status = dbNextRecordType(pdbentry);
            }
        }
        dbFinishEntry(pdbentry);
    }

    ChannelFind::shared_pointer nullChannelFind;
    channelListRequester->channelListResult(Status::Ok, nullChannelFind, freeze(channelNames), false);
    return nullChannelFind;
}
Пример #5
0
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);
}
Пример #6
0
LOCAL void queueAllRecords ()
{
    DBENTRY     dbentry;
    DBENTRY     *pdbentry=&dbentry;
    dbCommon	*pdbc;
    long        status;

    dbInitEntry(pdbbase,pdbentry);
    status = dbFirstRecordType(pdbentry);
    while(!status) {
	status = dbFirstRecord(pdbentry);
	while(!status) {
	    msg_t msg;

	    pdbc = pdbentry->precnode->precord;
	    DEBUG2(4,"queueAllRecords:Name: %s ptr: 0x%x\n",
	      dbGetRecordName(pdbentry),(unsigned)pdbc)
	    msg.pdbc = pdbc;
	    msg.osevr = pdbc->sevr;
	    msg.ostat = pdbc->stat;
	    msg.nsevr = pdbc->sevr;
	    msg.nstat = pdbc->stat;
	    tsLocalTime (&msg.stamp);
	    msg.msgType = mt_Status;

	    ringInsert (&msg);

	    status = dbNextRecord(pdbentry);
	}
	status = dbNextRecordType(pdbentry);
    }
    dbFinishEntry(pdbentry);
}
Пример #7
0
long epicsShareAPI dbGetField(DBADDR *paddr,short dbrType,
    void *pbuffer, long *options, long *nRequest, void *pflin)
{
    short dbfType = paddr->field_type;
    dbCommon *precord = paddr->precord;
    long status = 0;

    dbScanLock(precord);
    if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
        DBENTRY dbEntry;
        dbFldDes *pfldDes = paddr->pfldDes;
        char *rtnString;
        char *pbuf = (char *)pbuffer;
        int maxlen;

        if (options && (*options))
            getOptions(paddr, &pbuf, options, pflin);
        if (nRequest && *nRequest == 0) goto done;

        switch (dbrType) {
        case DBR_STRING:
            maxlen = MAX_STRING_SIZE - 1;
            if (nRequest && *nRequest > 1) *nRequest = 1;
            break;

        case DBR_CHAR:
        case DBR_UCHAR:
            if (nRequest && *nRequest > 0) {
                maxlen = *nRequest - 1;
                break;
            }
            /* else fall through ... */
        default:
            status = S_db_badDbrtype;
            goto done;
        }

        dbInitEntry(pdbbase, &dbEntry);
        status = dbFindRecord(&dbEntry, precord->name);
        if (!status) status = dbFindField(&dbEntry, pfldDes->name);
        if (!status) {
            rtnString = dbGetString(&dbEntry);
            strncpy(pbuf, rtnString, maxlen);
            pbuf[maxlen] = 0;
        }
        dbFinishEntry(&dbEntry);
    } else {
        status = dbGet(paddr, dbrType, pbuffer, options, nRequest, pflin);
    }
done:
    dbScanUnlock(precord);
    return status;
}
Пример #8
0
LOCAL int connect(void **pab1771IXPvt,DBLINK *plink,boolean *isEng)
{
    DBENTRY       dbEntry;
    DBENTRY       *pdbEntry = &dbEntry;
    DBADDR        dbAddr;
    deviceData	  *pdeviceData;
    ab1771IXRecord *precord;
    recordPvt	  *precordPvt;
    long	  status;
    char          buffer[MAX_BUFFER];
    char          *recordname = &buffer[0];
    char          *pstring;
    unsigned short signal;
    char          *pLeftbracket;
    char          *pRightbracket;

    if(plink->type!=INST_IO) return(ab1771IXFatalError);
    pstring = plink->value.instio.string;
    if(strlen(pstring)>=MAX_BUFFER) return(ab1771IXFatalError);
    strcpy(buffer,pstring);
    pLeftbracket = strchr(buffer,'['); pRightbracket = strchr(buffer,']');
    if(!pLeftbracket || !pRightbracket) {
	errlogPrintf("link was not of the form record[signal]\n");
	return(ab1771IXFatalError);
    }
    *pLeftbracket++ = '\0'; *pRightbracket = '\0';
    sscanf(pLeftbracket,"%hu",&signal);
    dbInitEntry(pdbbase,pdbEntry);
    status = dbFindRecord(pdbEntry,recordname);
    if(status) return(ab1771IXNoRecord);
    if(strcmp(dbGetRecordTypeName(pdbEntry),"ab1771IX")!=0)
	return(ab1771IXIllegalRecordType);
    dbFinishEntry(pdbEntry);
    status = dbNameToAddr(recordname,&dbAddr);
    if(status) return(ab1771IXNoRecord);
    precord = (ab1771IXRecord *)dbAddr.precord;
    if(!(precordPvt = (recordPvt *)precord->dpvt)) {
	printf("%s precordPvt is NULL ?\n",precord->name);
	return(ab1771IXFatalError);
    }
    if(signal>=NUM_CHANS) return(ab1771IXIllegalType);
    if(signal<=3) {
	*isEng = ((precord->typa==ab1771IX_TYPE_MV)?FALSE:TRUE);
    } else {
	*isEng = ((precord->typb==ab1771IX_TYPE_MV)?FALSE:TRUE);
    }
    pdeviceData = dbCalloc(1,sizeof(deviceData));
    pdeviceData->precord = precord;
    pdeviceData->signal = signal;
    *pab1771IXPvt = (void *)pdeviceData;
    return(ab1771IXOK);
}
Пример #9
0
long dbChannelTest(const char *name)
{
    DBENTRY dbEntry;
    long status;

    if (!name || !*name || !pdbbase)
        return S_db_notFound;

    status = pvNameLookup(&dbEntry, &name);

    dbFinishEntry(&dbEntry);
    return status;
}
Пример #10
0
/*utility routine to dump raw messages*/
int ab1771IXpm(char *recordname)
{
    DBENTRY       dbEntry;
    DBENTRY       *pdbEntry = &dbEntry;
    DBADDR        dbAddr;
    ab1771IXRecord *precord;
    recordPvt	  *precordPvt;
    long	  status;
    short	  *pdata;
    int           i;

    dbInitEntry(pdbbase,pdbEntry);
    status = dbFindRecord(pdbEntry,recordname);
    if(status) {
	printf("Cant find %s\n",recordname);
	return(0);
    }
    if(strcmp(dbGetRecordTypeName(pdbEntry),"ab1771IX")!=0) {
	printf("Not a ab1771IXRecord\n");
	return(0);
    }
    dbFinishEntry(pdbEntry);
    status = dbNameToAddr(recordname,&dbAddr);
    if(status) {
	printf("Cant find %s\n",recordname);
	return(0);
    }
    precord = (ab1771IXRecord *)dbAddr.precord;
    if(!(precordPvt = (recordPvt *)precord->dpvt)) {
	printf("dpvt is NULL\n");
	return(0);
    }
    printf("output message");
    pdata = precord->outm;
    for(i=0; i< NUM_WORDS_OUT; i++) {
	if(i%10 == 0) printf("\n");
	printf(" %4hx",*pdata);
	pdata++;
    }
    printf("\ninput message");
    pdata = precord->inpm;
    for(i=0; i< NUM_WORDS_IN; i++) {
	if(i%10 == 0) printf("\n");
	printf(" %4hx",*pdata);
	pdata++;
    }
    printf("\n");
    return(0);
}
Пример #11
0
long dbPutAttribute(
    const char *recordTypename,const char *name,const char*value)
{
	DBENTRY		dbEntry;
	DBENTRY		*pdbEntry = &dbEntry;
	long		status=0;

        if(!pdbbase) return(S_db_notFound);
	dbInitEntry(pdbbase,pdbEntry);
	status = dbFindRecordType(pdbEntry,recordTypename);
	if(!status) status = dbPutRecordAttribute(pdbEntry,name,value);
	dbFinishEntry(pdbEntry);
	if(status) errMessage(status,"dbPutAttribute failure");
	return(status);
}
Пример #12
0
static int countCvtRecords(void)
{
    DBENTRY dbentry;
    extern DBBASE *pdbbase;
    int result = 0;
    long status;

    dbInitEntry(pdbbase, &dbentry);
    status = dbFindRecordType(&dbentry,"cvt");
    if (!status) {
        result = dbGetNRecords(&dbentry);
    }
    dbFinishEntry(&dbentry);
    return result;
}
Пример #13
0
static long ai_init(int pass)
{
    long i;

    if (pass) return 0;

    /* Create timers */
    for (i = 0; i < TOTAL_TYPES; i++) {
        scanIoInit(&scan[i].ioscan);
        scan[i].wd = wdogCreate(scan_time, i);
        scan[i].total = 0;
        scan[i].on = 0;
        scan[i].rate_sec = parmTypes[i].scan_rate;
    }

    /* Init OSD stuff */
    scan_mutex = epicsMutexMustCreate();
    devIocStatsInitCpuUsage();
    devIocStatsInitCpuUtilization(&loadinfo);
    devIocStatsInitFDUsage();
    devIocStatsInitMemUsage();
    devIocStatsInitWorkspaceUsage();
    devIocStatsInitSuspTasks();
    devIocStatsInitIFErrors();
    /* Get initial values of a few things that don't change much */
    devIocStatsGetClusterInfo(SYS_POOL, &clustinfo[SYS_POOL]);
    devIocStatsGetClusterInfo(DATA_POOL, &clustinfo[DATA_POOL]);
    devIocStatsGetClusterUsage(SYS_POOL, &mbufnumber[SYS_POOL]);
    devIocStatsGetClusterUsage(DATA_POOL, &mbufnumber[DATA_POOL]);
    devIocStatsGetCpuUtilization(&loadinfo);
    devIocStatsGetIFErrors(&iferrors);
    devIocStatsGetFDUsage(&fdusage);

    /* Count EPICS records */
    if (pdbbase) {
        DBENTRY dbentry;
        long	  status;
        dbInitEntry(pdbbase,&dbentry);
        status = dbFirstRecordType(&dbentry);
        while (!status) {
            recordnumber += dbGetNRecords(&dbentry);
            status = dbNextRecordType(&dbentry);
        }
        dbFinishEntry(&dbentry);
    }
    return 0;
}
Пример #14
0
static void dbAlias(char *name, char *alias)
{
    DBENTRY	dbEntry;
    DBENTRY	*pdbEntry = &dbEntry;

    dbInitEntry(pdbbase, pdbEntry);
    if (dbFindRecord(pdbEntry, name)) {
        epicsPrintf("Alias \"%s\" refers to unknown record \"%s\"\n",
                    alias, name);
        yyerror(NULL);
    } else if (dbCreateAlias(pdbEntry, alias)) {
        epicsPrintf("Can't create alias \"%s\" referring to \"%s\"\n",
                    alias, name);
        yyerror(NULL);
    }
    dbFinishEntry(pdbEntry);
}
Пример #15
0
void dbcaStats(int *pchans, int *pdiscon)
{
    DBENTRY     dbentry;
    DBENTRY     *pdbentry = &dbentry;
    long        status;
    DBLINK      *plink;
    long        ncalinks = 0;
    long        nconnected = 0;

    dbInitEntry(pdbbase,pdbentry);
    status = dbFirstRecordType(pdbentry);
    while (!status) {
        dbRecordType *pdbRecordType = pdbentry->precordType;

        status = dbFirstRecord(pdbentry);
        while (!status) {
            dbCommon *precord = (dbCommon *)pdbentry->precnode->precord;
            int j;

            if (!dbIsAlias(pdbentry)) {
                for (j=0; j<pdbRecordType->no_links; j++) {
                    int i = pdbRecordType->link_ind[j];

                    dbFldDes *pdbFldDes = pdbRecordType->papFldDes[i];
                    plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
                    if (plink->type == CA_LINK) {
                        caLink *pca = (caLink *)plink->value.pv_link.pvt;

                        ncalinks++;
                        if (pca && ca_state(pca->chid) == cs_conn) {
                            nconnected++;
                        }
                    }
                }
            }
            status = dbNextRecord(pdbentry);
        }
        status = dbNextRecordType(pdbentry);
    }
    dbFinishEntry(pdbentry);
    if (pchans)  *pchans  = ncalinks;
    if (pdiscon) *pdiscon = ncalinks - nconnected;
}
Пример #16
0
static long getLinkValue(DBADDR *paddr, short dbrType,
    char *pbuf, long *nRequest)
{
    dbCommon *precord = paddr->precord;
    dbFldDes *pfldDes = paddr->pfldDes;
    int maxlen;
    DBENTRY dbEntry;
    long status;

    switch (dbrType) {
    case DBR_STRING:
        maxlen = MAX_STRING_SIZE - 1;
        if (nRequest && *nRequest > 1) *nRequest = 1;
        break;

    case DBR_DOUBLE:    /* Needed for dbCa links */
        if (nRequest && *nRequest) *nRequest = 1;
        *(double *)pbuf = epicsNAN;
        return 0;

    case DBR_CHAR:
    case DBR_UCHAR:
            if (nRequest && *nRequest > 0) {
            maxlen = *nRequest - 1;
            break;
        }
        /* else fall through ... */
    default:
        return S_db_badDbrtype;
    }

    dbInitEntry(pdbbase, &dbEntry);
    status = dbFindRecord(&dbEntry, precord->name);
    if (!status) status = dbFindField(&dbEntry, pfldDes->name);
    if (!status) {
        char *rtnString = dbGetString(&dbEntry);

        strncpy(pbuf, rtnString, --maxlen);
        pbuf[maxlen] = 0;
    }
    dbFinishEntry(&dbEntry);
    return status;
}
static long ai_init(int pass)
{
    long i;

    if (pass) return 0;

    /* Create timers */
    for (i = 0; i < TOTAL_TYPES; i++) {
        scanIoInit(&scan[i].ioscan);
        scan[i].wd = wdogCreate(scan_time, i);
        scan[i].total = 0;
        scan[i].on = 0;
        scan[i].rate_sec = scan_rate_sec[i];
        scan[i].last_read_sec = 1000000;
    }

    /* Init OSD stuff */
    devIocStatsInitCpuUsage();
    devIocStatsInitCpuUtilization(&loadinfo);
    devIocStatsInitFDUsage();
    devIocStatsInitMemUsage();
    devIocStatsInitWorkspaceUsage();
    devIocStatsInitSuspTasks();
    devIocStatsInitIFErrors();

    /* Count EPICS records */
    if (pdbbase) {
        DBENTRY dbentry;
        long	  status;
        dbInitEntry(pdbbase,&dbentry);
        status = dbFirstRecordType(&dbentry);
        while (!status) {
            recordnumber += dbGetNRecords(&dbentry);
            status = dbNextRecordType(&dbentry);
        }
        dbFinishEntry(&dbentry);
    }
    return 0;
}
Пример #18
0
static void hookPass1(initHookState state)
{
    DBENTRY entry;
    DBADDR  addr;
    if(state!=initHookAfterInitDatabase)
        return;
    testDiag("initHookAfterInitDatabase");

    dbInitEntry(pdbbase, &entry);

    if(dbFindRecord(&entry, "rec0.VAL")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk(prec->val==3, "VAL %d==3 (init_record value)", (int)prec->val);
        testOk1(dbPutString(&entry, "4")==0);
        testOk(prec->val==4, "VAL %d==4", (int)prec->val);
    } else{
        testFail("Missing rec0");
        testSkip(1, "missing record");
    }

    /* Can't restore links in pass 1 */

    if(dbNameToAddr("rec1.VAL", &addr)) {
        testFail("missing rec1");
        testSkip(3, "missing record");
    } else {
        struct rset *prset = dbGetRset(&addr);
        dbfType ftype = addr.field_type;
        long count=-1, offset=-1, maxcount = addr.no_elements;
        testOk1(prset && prset->get_array_info && prset->put_array_info);
        testOk1((*prset->get_array_info)(&addr, &count, &offset)==0);
        /* count is ignored */
        testOk1((*dbPutConvertRoutine[DBF_DOUBLE][ftype])(&addr, values, NELEMENTS(values), maxcount,offset)==0);
        testOk1((*prset->put_array_info)(&addr, NELEMENTS(values))==0);
    }

    dbFinishEntry(&entry);
}
Пример #19
0
long epicsShareAPI dbnr(int verbose)
{
    DBENTRY dbentry;
    DBENTRY *pdbentry=&dbentry;
    long status;
    int nrecords;
    int naliases;
    int trecords = 0;
    int taliases = 0;

    if (!pdbbase) {
        printf("No database loaded\n");
        return 0;
    }

    dbInitEntry(pdbbase, pdbentry);
    status = dbFirstRecordType(pdbentry);
    if (status) {
        printf("No record types loaded\n");
        return 0;
    }

    printf("Records  Aliases  Record Type\n");
    while (!status) {
        naliases = dbGetNAliases(pdbentry);
        taliases += naliases;
        nrecords = dbGetNRecords(pdbentry) - naliases;
        trecords += nrecords;
        if (verbose || nrecords)
            printf(" %5d    %5d    %s\n",
                nrecords, naliases, dbGetRecordTypeName(pdbentry));
        status = dbNextRecordType(pdbentry);
    }

    dbFinishEntry(pdbentry);
    printf("Total %d records, %d aliases\n", trecords, taliases);
    return 0;
}
Пример #20
0
int epicsShareAPI logAlarmsInit (
) {
    DBENTRY     dbentry;
    DBENTRY     *pdbentry=&dbentry;
    long        status;
    int		numRecords=0;
    int		tid[MSG_TASK_NUM], btid, ctid, rtid;
    int		normalRangeSize, overRangeSize;
    struct sockaddr_in	*psin;
    int		node;
    char	string[32];
    char	*pstring, *serverList, *ptok, *pheader;
    int		i;

    if (initialized) {
	errlogPrintf ("logAlarmsInit: already initialized\n");
	return ERROR;
    }

    clkRate = sysClkRateGet();

    tickInitWait = (unsigned long)(clkRate * INIT_DELAY_SEC + 0.5);

    tickMaxSilent = (unsigned long)(clkRate * BEACON_IDLE_SEC + 0.5);
    tickBeaconPeriod = (unsigned long)(clkRate * BEACON_PERIOD_SEC + 0.5);
    tickBeaconReplyTmo = (unsigned long)(clkRate * BEACON_REPLY_TMO_SEC + 0.5);
    tickMessageReplyTmo = (unsigned long)(clkRate * MESSAGE_REPLY_TMO_SEC + 0.5);
    /* wait time between retrying to send messages (>= 1 tick) */
    tickMsgRetryWait = (unsigned long)(clkRate * MESSAGE_RETRY_WAIT_SEC + 0.5);
    if (tickMsgRetryWait == 0UL) tickMsgRetryWait = 1UL;

    if(!pdbbase) {
	errlogPrintf ("logAlarmsInit: No database has been loaded\n");
        return ERROR;
    }

    serverList = getenv ("EPICS_ALARM_SERVER_INET");
    if (!serverList) {
	errlogPrintf ("logAlarmsInit: EPICS_ALARM_SERVER_INET env not defined\n");
	return ERROR;
    }

    pstring = getenv ("EPICS_ALARM_MESSAGE_PORT");
    if (!pstring)
	msg_port = DEFAULT_MSG_PORT;
    else {
	msg_port = (unsigned short) atoi (pstring);
	if (msg_port < 1024) {
	    msg_port = DEFAULT_MSG_PORT;
	    errlogPrintf ("Port number EPICS_ALARM_MESSAGE_PORT is wrong\n");
	}
    }

    pstring = getenv ("EPICS_ALARM_COMMAND_PORT");
    if (!pstring)
	cmd_port = DEFAULT_CMD_PORT;
    else {
	cmd_port = (unsigned short) atoi (pstring);
	if (cmd_port < 1024) {
	    cmd_port = DEFAULT_CMD_PORT;
	    errlogPrintf ("Port number EPICS_ALARM_COMMAND_PORT is wrong\n");
	}
    }

    /* if allAcceptOption is set, commands are accepted from all servers */
    pstring = getenv ("EPICS_ALARM_COMMAND_ACCEPT_ALL");
    if (strcmp (pstring, "YES") == 0)
	allAcceptOption = TRUE;

    psin = &msgServerAddr[0];
    node = 0;

    ptok = strtok_r (serverList, " ", &pstring);

    while (ptok && node < SERVERS_MAX && aToIPAddr (ptok, msg_port, psin) == 0) {
        node++;
        psin++;
	ptok = strtok_r (NULL, " ", &pstring);
    }
    numServersConfigured = node;

    if (numServersConfigured == 0) {
	errlogPrintf (
	  "logAlarmsInit: No server correctly defined in EPICS_ALARM_SERVER_INET\n");
    }

    wakeupSem = semBCreate (SEM_Q_FIFO, SEM_EMPTY);
    if (!wakeupSem) {
	errlogPrintf ("logAlarmsInit: Reader wakeup semaphore could not be created\n");
        return ERROR;
    }

    bucketSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
    if (!bucketSem) {
	errlogPrintf ("logAlarmsInit: Hash facility mutex could not be created\n");
	cleanup (1);
        return ERROR;
    }

    ringSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
    if (!ringSem) {
	errlogPrintf ("logAlarmsInit: Ring r/w mutex could not be created\n");
	cleanup (2);
        return ERROR;
    }

    ringWriteSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
    if (!ringWriteSem) {
	errlogPrintf ("logAlarmsInit: Ring (write) mutex could not be created\n");
	cleanup (3);
        return ERROR;
    }

    msgSockSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
    if (!msgSockSem) {
	errlogPrintf ("logAlarmsInit: MsgSocket mutex could not be created\n");
	cleanup (4);
        return ERROR;
    }

    dbInitEntry(pdbbase,pdbentry);

    status = dbFirstRecordType(pdbentry);
    while(!status) {
	int	numRecordsType;

	numRecordsType = dbGetNRecords(pdbentry);
	DEBUG2(4,"There are %d records of type %s\n",
	  numRecordsType, dbGetRecordTypeName(pdbentry))
	numRecords += numRecordsType;
	status = dbNextRecordType(pdbentry);
    }
    dbFinishEntry(pdbentry);

    normalRangeSize = (int)(numRecords * RING_NORMAL_MULTI) + 1;
    overRangeSize = numRecords + numRecords / RING_OVER_DIVI + 1;

    ringSize = normalRangeSize + overRangeSize;

    pRingBottom = (msgBuffer_t *)calloc (ringSize, sizeof(msgBuffer_t));
    if (!pRingBottom) {
	errlogPrintf ("logAlarmsInit: Ring buffer could not be created\n");
	cleanup (5);
	return ERROR;
    }
    pRingTop = pRingBottom + ringSize;
    DEBUG2(2,"pRingBottom:%lu  pRingTop:%lu\n",
      (unsigned long)pRingBottom, (unsigned long)pRingTop)

    ringHighWater = normalRangeSize;
    DEBUG2(2,"Ring buffer size:%d  highwater:%d\n",ringSize,ringHighWater)
    pRingRead = pRingBottom;
    pRingWrite = pRingBottom;
    msgLost = 0;

    pbuck = bucketCreate (numRecords);
    if (!pbuck) {
	errlogPrintf ("logAlarmsInit: Hash table could not be initalized\n");
	cleanup (6);
	return ERROR;
    }

    serverSelected = -1;
    serverSelectedLast = -1;

    queueAllRecords();

    /* spawn alarm beacon task */
    btid = taskSpawn ("Al'Beacon", BEACON_TASK_PRIO, BEACON_TASK_OPTIONS,
      BEACON_TASK_STACK, (FUNCPTR)alarmBeaconTask,0,0,0,0,0,0,0,0,0,0);

    if (!btid) {
	errlogPrintf ("logAlarmsInit: Beacon task could not be spawned\n");
	cleanup (7);
	return ERROR;
    }
    DEBUG1(1,"alarmBeaconTask started. Task-ID = 0x%x\n", btid);

    msg_soc = socket (AF_INET, SOCK_DGRAM, 0);
    if (msg_soc < 0) {
	errlogPrintf ("Message socket create failed\n");
	cleanup (7);
	return ERROR;
    }
    bzero ((char *) &msgReplyInAddr, sockAddrSize);
    msgReplyInAddr.sin_port = htons(msg_port);
    msgReplyInAddr.sin_family = AF_INET;
    msgReplyInAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind (msg_soc, (struct sockaddr*)&msgReplyInAddr, sockAddrSize) < 0 ) {
	errlogPrintf ("Message socket bind failed\n");
	cleanup (8);
	return ERROR;
    }

    cmd_soc = socket (AF_INET, SOCK_DGRAM, 0);
    if (cmd_soc < 0) {
	errlogPrintf ("Command socket create failed\n");
	cleanup (8);
	return ERROR;
    }
    bzero ((char *) &cmdServerAddr, sockAddrSize);
    cmdServerAddr.sin_port = htons(cmd_port);
    cmdServerAddr.sin_family = AF_INET;
    cmdServerAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    if (bind (cmd_soc, (struct sockaddr*)&cmdServerAddr, sockAddrSize) < 0 ) {
	errlogPrintf ("Command socket bind failed\n");
	cleanup (9);
	return ERROR;
    }

    /* spawn alarm message tasks */
    for (i=0; i<MSG_TASK_NUM; i++) {
	sprintf (string, "Al'Msg%d", i+1);
	tid[i] = taskSpawn (string, CLIENT_TASK_PRIO, CLIENT_TASK_OPTIONS,
	 CLIENT_TASK_STACK, (FUNCPTR)alarmMessageTask,i+1,0,0,0,0,0,0,0,0,0);

	if (!tid[i]) {
	    errlogPrintf (
	     "logAlarmsInit: Message task %d could not be spawned\n");
	    cleanup (9);
	    while (i > 0) taskDelete (tid[--i]);
	    taskDelete (btid);
	    return ERROR;
	}
    }

    /* spawn alarm log control (command receiver) server task */
    ctid = taskSpawn ("Al'Command", CONTROL_TASK_PRIO, CONTROL_TASK_OPTIONS,
      CONTROL_TASK_STACK, (FUNCPTR)alarmCommandTask,0,0,0,0,0,0,0,0,0,0);

    if (!ctid) {
	errlogPrintf ("logAlarmsInit: Control task could not be spawned\n");
	cleanup (9);
	taskDelete (btid);
	for (i=0; i<MSG_TASK_NUM; i++) taskDelete (tid[i]);
	return ERROR;
    }

    /* spawn message reply receiver task */
    rtid = taskSpawn ("Al'ReplyRx", REPLY_TASK_PRIO, REPLY_TASK_OPTIONS,
      REPLY_TASK_STACK, (FUNCPTR)replyReceiveTask,0,0,0,0,0,0,0,0,0,0);

    if (!rtid) {
	errlogPrintf ("logAlarmsInit: Reply receiver task could not be spawned\n");
	cleanup (9);
	taskDelete (btid);
	taskDelete (ctid);
	for (i=0; i<MSG_TASK_NUM; i++) taskDelete (tid[i]);
	return ERROR;
    }

    pheader = messageHeader;

    pstring = getenv ("EPICS_IOC_NAME");

    if (pstring)		/* given IOC name */
	pheader = messageHeader +
	  sprintf (messageHeader, "HOST=%s;", pstring);
    pheader +=
      sprintf (pheader, "HOST-PHYS=%s;APPLICATION=logAlarms;",
        gethostname (string, sizeof(string)) ? "TOO_LONG" : string);

    pstring = getenv ("EPICS_FACILITY");

    if (pstring)		/* name of application facility */
	pheader +=
	  sprintf (pheader, "FACILITY=%s;", pstring);

    /* calculate the remaining space in the message string */
    textMsgSize = MAX_MESSAGE_LENGTH - (pheader-messageHeader);

    epicsPrintf("logAlarms started\n");

    recGblAlarmHook = (RECGBL_ALARM_HOOK_ROUTINE)logEvent;
    DEBUG1(3,"recGblAlarmHook = 0x%lx\n",(unsigned long)recGblAlarmHook)

    initialized = TRUE;

    return OK;
}
Пример #21
0
long dbcar(char *precordname, int level)
{
    DBENTRY             dbentry;
    DBENTRY             *pdbentry=&dbentry;
    long                status;
    dbCommon            *precord;
    dbRecordType        *pdbRecordType;
    dbFldDes            *pdbFldDes;
    DBLINK              *plink;
    int                 ncalinks=0;
    int                 nconnected=0;
    int                 noReadAccess=0;
    int                 noWriteAccess=0;
    unsigned long       nDisconnect=0;
    unsigned long       nNoWrite=0;
    caLink              *pca;
    int                 j;

    if (!precordname || precordname[0] == '\0' || !strcmp(precordname, "*")) {
        precordname = NULL;
        printf("CA links in all records\n\n");
    } else {
        printf("CA links in record named '%s'\n\n", precordname);
    }
    dbInitEntry(pdbbase,pdbentry);
    status = dbFirstRecordType(pdbentry);
    while (!status) {
        status = dbFirstRecord(pdbentry);
        while (!status) {
            if (precordname ?
                !strcmp(precordname, dbGetRecordName(pdbentry)) :
                !dbIsAlias(pdbentry)) {
                pdbRecordType = pdbentry->precordType;
                precord = (dbCommon *)pdbentry->precnode->precord;
                for (j=0; j<pdbRecordType->no_links; j++) {
                    pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->link_ind[j]];
                    plink = (DBLINK *)((char *)precord + pdbFldDes->offset);
                    dbLockSetGblLock();
                    if (plink->type == CA_LINK) {
                        ncalinks++;
                        pca = (caLink *)plink->value.pv_link.pvt;
                        if (pca
                        && pca->chid
                        && (ca_field_type(pca->chid) != TYPENOTCONN)) {
                            nconnected++;
                            nDisconnect += pca->nDisconnect;
                            nNoWrite += pca->nNoWrite;
                            if (!ca_read_access(pca->chid)) noReadAccess++;
                            if (!ca_write_access(pca->chid)) noWriteAccess++;
                            if (level>1) {
                                int rw = ca_read_access(pca->chid) |
                                         ca_write_access(pca->chid) << 1;
                                static const char *rights[4] = {
                                    "No Access", "Read Only",
                                    "Write Only", "Read/Write"
                                };
                                int mask = plink->value.pv_link.pvlMask;
                                printf("%28s.%-4s ==> %-28s  (%lu, %lu)\n",
                                    precord->name,
                                    pdbFldDes->name,
                                    plink->value.pv_link.pvname,
                                    pca->nDisconnect,
                                    pca->nNoWrite);
                                printf("%21s [%s%s%s%s] host %s, %s\n", "",
                                    mask & pvlOptInpNative ? "IN" : "  ",
                                    mask & pvlOptInpString ? "IS" : "  ",
                                    mask & pvlOptOutNative ? "ON" : "  ",
                                    mask & pvlOptOutString ? "OS" : "  ",
                                    ca_host_name(pca->chid),
                                    rights[rw]);
                            }
                        } else {
                            if (level>0) {
                                printf("%28s.%-4s --> %-28s  (%lu, %lu)\n",
                                    precord->name,
                                    pdbFldDes->name,
                                    plink->value.pv_link.pvname,
                                    pca->nDisconnect,
                                    pca->nNoWrite);
                            }
                        }
                    }
                    dbLockSetGblUnlock();
                }
                if (precordname) goto done;
            }
            status = dbNextRecord(pdbentry);
        }
        status = dbNextRecordType(pdbentry);
    }
done:
    if ((level > 1 && nconnected > 0) ||
        (level > 0 && ncalinks != nconnected)) printf("\n");
    printf("Total %d CA link%s; ",
           ncalinks, (ncalinks != 1) ? "s" : "");
    printf("%d connected, %d not connected.\n",
           nconnected, (ncalinks - nconnected));
    printf("    %d can't read, %d can't write.",
           noReadAccess, noWriteAccess);
    printf("  (%lu disconnects, %lu writes prohibited)\n\n",
           nDisconnect, nNoWrite);
    dbFinishEntry(pdbentry);
    
    if ( level > 2  && dbCaClientContext != 0 ) {
        ca_context_status ( dbCaClientContext, level - 2 );
    }

    return(0);
}
Пример #22
0
static void hookPass0(initHookState state)
{
    DBENTRY entry;
    if(state!=initHookAfterInitDevSup)
        return;
    testDiag("initHookAfterInitDevSup");

    dbInitEntry(pdbbase, &entry);

    testDiag("restore integer pass0");
    /* rec0.VAL is initially 1, set it to 2 */
    if(dbFindRecord(&entry, "rec0.VAL")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk(prec->val==1, "VAL %d==1 (initial value from .db)", (int)prec->val);
        checkGetString(&entry, "1");
        testOk1(dbPutString(&entry, "2")==0);
        testOk(prec->val==2, "VAL %d==2", (int)prec->val);
        checkGetString(&entry, "2");
    } else {
        testFail("Missing rec0");
        testSkip(4, "missing record");
    }

    testDiag("restore string pass0");
    if(dbFindRecord(&entry, "rec0.DESC")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk1(strcmp(prec->desc, "foobar")==0);
        checkGetString(&entry, "foobar");
        testOk1(dbPutString(&entry, "hello")==0);
        testOk1(strcmp(prec->desc, "hello")==0);
        checkGetString(&entry, "hello");
    } else {
        testFail("Missing rec0");
        testSkip(4, "missing record");
    }

    if(dbFindRecord(&entry, "rec1.DESC")==0) {
        aoRecord *prec = entry.precnode->precord;
        testOk1(strcmp(prec->desc, "")==0);
        checkGetString(&entry, "");
        testOk1(dbPutString(&entry, "world")==0);
        testOk1(strcmp(prec->desc, "world")==0);
        checkGetString(&entry, "world");
    } else {
        testFail("Missing rec1");
        testSkip(4, "missing record");
    }

    testDiag("restore link pass0");
    /* rec0.OUT is initially "rec0.DISV", set it to "rec0.SEVR" */
    if(dbFindRecord(&entry, "rec0.OUT")==0) {
        aoRecord *prec = entry.precnode->precord;
        if(prec->out.type==CONSTANT)
            testOk(strcmp(prec->out.text,"rec0.DISV")==0,
                   "%s==rec0.DISV (initial value from .db)",
                   prec->out.text);
        else
            testFail("Wrong link type: %d", (int)prec->out.type);

        /* note that dbGetString() reads an empty string before links are initialized
         * should probably be considered a bug, but has been the case for so long
         * we call it a 'feature'.
         */
        checkGetString(&entry, "");

        testOk1(dbPutString(&entry, "rec0.SEVR")==0);
    } else{
        testFail("Missing rec0");
        testSkip(1, "missing record");
    }

    /* rec0.SDIS is initially NULL, set it to "rec0.STAT" */
    if(dbFindRecord(&entry, "rec0.SDIS")==0) {
        aoRecord *prec = entry.precnode->precord;
        if(prec->sdis.type==CONSTANT)
            testOk1(prec->sdis.value.constantStr==NULL);
        else
            testFail("Wrong link type: %d", (int)prec->sdis.type);

        testOk1(dbPutString(&entry, "rec0.STAT")==0);
    } else{
        testFail("Missing rec0");
        testSkip(1, "missing record");
    }

    /* can't restore array field in pass0 */

    dbFinishEntry(&entry);
}
Пример #23
0
/* Performs the work of the public db_get_field API, but also returns the number
 * of elements actually copied to the buffer.  The caller is responsible for
 * zeroing the remaining part of the buffer. */
int dbChannel_get_count(
    struct dbChannel *chan, int buffer_type,
    void *pbuffer, long *nRequest, void *pfl)
{
    long status;
    long options;
    long i;
    long zero = 0;

   /* The order of the DBR* elements in the "newSt" structures below is
    * very important and must correspond to the order of processing
    * in the dbAccess.c dbGet() and getOptions() routines.
    */

    dbScanLock(dbChannelRecord(chan));

    switch(buffer_type) {
    case(oldDBR_STRING):
        status = dbChannelGet(chan, DBR_STRING, pbuffer, &zero, nRequest, pfl);
        break;
/*  case(oldDBR_INT): */
    case(oldDBR_SHORT):
        status = dbChannelGet(chan, DBR_SHORT, pbuffer, &zero, nRequest, pfl);
        break;
    case(oldDBR_FLOAT):
        status = dbChannelGet(chan, DBR_FLOAT, pbuffer, &zero, nRequest, pfl);
        break;
    case(oldDBR_ENUM):
        status = dbChannelGet(chan, DBR_ENUM, pbuffer, &zero, nRequest, pfl);
        break;
    case(oldDBR_CHAR):
        status = dbChannelGet(chan, DBR_CHAR, pbuffer, &zero, nRequest, pfl);
        break;
    case(oldDBR_LONG):
        status = dbChannelGet(chan, DBR_LONG, pbuffer, &zero, nRequest, pfl);
        break;
    case(oldDBR_DOUBLE):
        status = dbChannelGet(chan, DBR_DOUBLE, pbuffer, &zero, nRequest, pfl);
        break;

    case(oldDBR_STS_STRING):
    case(oldDBR_GR_STRING):
    case(oldDBR_CTRL_STRING):
        {
            struct dbr_sts_string *pold = (struct dbr_sts_string *)pbuffer;
            struct {
                DBRstatus
            } newSt;

            options = DBR_STATUS;
            status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            status = dbChannelGet(chan, DBR_STRING, pold->value, &zero,
                nRequest, pfl);
        }
        break;
/*  case(oldDBR_STS_INT): */
    case(oldDBR_STS_SHORT):
        {
            struct dbr_sts_int *pold = (struct dbr_sts_int *)pbuffer;
            struct {
                DBRstatus
            } newSt;

            options = DBR_STATUS;
            status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            status = dbChannelGet(chan, DBR_SHORT, &pold->value, &zero,
                nRequest, pfl);
        }
        break;
    case(oldDBR_STS_FLOAT):
        {
            struct dbr_sts_float *pold = (struct dbr_sts_float *)pbuffer;
            struct {
                DBRstatus
            } newSt;

            options = DBR_STATUS;
            status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &zero,
                nRequest, pfl);
        }
        break;
    case(oldDBR_STS_ENUM):
        {
            struct dbr_sts_enum *pold = (struct dbr_sts_enum *)pbuffer;
            struct {
                DBRstatus
            } newSt;

            options = DBR_STATUS;
            status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            status = dbChannelGet(chan, DBR_ENUM, &pold->value, &zero,
                nRequest, pfl);
        }
        break;
    case(oldDBR_STS_CHAR):
        {
            struct dbr_sts_char *pold = (struct dbr_sts_char *)pbuffer;
            struct {
                DBRstatus
            } newSt;

            options = DBR_STATUS;
            status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &zero,
                nRequest, pfl);
        }
        break;
    case(oldDBR_STS_LONG):
        {
            struct dbr_sts_long *pold = (struct dbr_sts_long *)pbuffer;
            struct {
                DBRstatus
            } newSt;

            options = DBR_STATUS;
            status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            status = dbChannelGet(chan, DBR_LONG, &pold->value, &zero,
                nRequest, pfl);
        }
        break;
    case(oldDBR_STS_DOUBLE):
        {
            struct dbr_sts_double *pold = (struct dbr_sts_double *)pbuffer;
            struct {
                DBRstatus
            } newSt;

            options = DBR_STATUS;
            status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            options = 0;
            status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options,
                nRequest, pfl);
        }
        break;

    case(oldDBR_TIME_STRING):
        {
            struct dbr_time_string *pold = (struct dbr_time_string *)pbuffer;
            struct {
                DBRstatus
                DBRtime
            } newSt;

            options = DBR_STATUS | DBR_TIME;
            status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->stamp = newSt.time;         /* structure copy */
            options = 0;
            status = dbChannelGet(chan, DBR_STRING, pold->value, &options,
                    nRequest, pfl);
        }
        break;
/*  case(oldDBR_TIME_INT): */
    case(oldDBR_TIME_SHORT):
        {
            struct dbr_time_short *pold = (struct dbr_time_short *)pbuffer;
            struct {
                DBRstatus
                DBRtime
            } newSt;

            options = DBR_STATUS | DBR_TIME;
            status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->stamp = newSt.time;         /* structure copy */
            options = 0;
            status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_TIME_FLOAT):
        {
            struct dbr_time_float *pold = (struct dbr_time_float *)pbuffer;
            struct {
                DBRstatus
                DBRtime
            } newSt;

            options = DBR_STATUS | DBR_TIME;
            status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->stamp = newSt.time;         /* structure copy */
            options = 0;
            status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_TIME_ENUM):
        {
            struct dbr_time_enum *pold = (struct dbr_time_enum *)pbuffer;
            struct {
                DBRstatus
                DBRtime
            } newSt;

            options = DBR_STATUS | DBR_TIME;
            status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->stamp = newSt.time;         /* structure copy */
            options = 0;
            status = dbChannelGet(chan, DBR_ENUM, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_TIME_CHAR):
        {
            struct dbr_time_char *pold = (struct dbr_time_char *)pbuffer;
            struct {
                DBRstatus
                DBRtime
            } newSt;

            options = DBR_STATUS | DBR_TIME;
            status = dbChannelGet(chan, DBR_CHAR, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->stamp = newSt.time;         /* structure copy */
            options = 0;
            status = dbChannelGet(chan, DBR_CHAR, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_TIME_LONG):
        {
            struct dbr_time_long *pold = (struct dbr_time_long *)pbuffer;
            struct {
                DBRstatus
                DBRtime
            } newSt;

            options = DBR_STATUS | DBR_TIME;
            status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->stamp = newSt.time;         /* structure copy */
            options = 0;
            status = dbChannelGet(chan, DBR_LONG, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_TIME_DOUBLE):
        {
            struct dbr_time_double *pold = (struct dbr_time_double *)pbuffer;
            struct {
                DBRstatus
                DBRtime
            } newSt;

            options = DBR_STATUS | DBR_TIME;
            status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->stamp = newSt.time;         /* structure copy */
            options = 0;
            status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options,
                nRequest, pfl);
        }
        break;

/*  case(oldDBR_GR_STRING): NOT IMPLEMENTED - use DBR_STS_STRING */
/*  case(oldDBR_GR_INT): */
    case(oldDBR_GR_SHORT):
        {
            struct dbr_gr_int *pold = (struct dbr_gr_int *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRgrLong
                DBRalLong
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
            status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = newSt.upper_disp_limit;
            pold->lower_disp_limit = newSt.lower_disp_limit;
            pold->upper_alarm_limit = newSt.upper_alarm_limit;
            pold->upper_warning_limit = newSt.upper_warning_limit;
            pold->lower_warning_limit = newSt.lower_warning_limit;
            pold->lower_alarm_limit = newSt.lower_alarm_limit;
            options = 0;
            status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_GR_FLOAT):
        {
            struct dbr_gr_float *pold = (struct dbr_gr_float *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRprecision
                DBRgrDouble
                DBRalDouble
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
                DBR_AL_DOUBLE;
            status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->precision = (dbr_short_t) newSt.precision.dp;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = epicsConvertDoubleToFloat(newSt.upper_disp_limit);
            pold->lower_disp_limit = epicsConvertDoubleToFloat(newSt.lower_disp_limit);
            pold->upper_alarm_limit = epicsConvertDoubleToFloat(newSt.upper_alarm_limit);
            pold->lower_alarm_limit = epicsConvertDoubleToFloat(newSt.lower_alarm_limit);
            pold->upper_warning_limit = epicsConvertDoubleToFloat(newSt.upper_warning_limit);
            pold->lower_warning_limit = epicsConvertDoubleToFloat(newSt.lower_warning_limit);
            options = 0;
            status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options,
                nRequest, pfl);
        }
        break;
/*  case(oldDBR_GR_ENUM): see oldDBR_CTRL_ENUM */
    case(oldDBR_GR_CHAR):
        {
            struct dbr_gr_char *pold = (struct dbr_gr_char *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRgrLong
                DBRalLong
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
            status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = newSt.upper_disp_limit;
            pold->lower_disp_limit = newSt.lower_disp_limit;
            pold->upper_alarm_limit = newSt.upper_alarm_limit;
            pold->upper_warning_limit = newSt.upper_warning_limit;
            pold->lower_warning_limit = newSt.lower_warning_limit;
            pold->lower_alarm_limit = newSt.lower_alarm_limit;
            options = 0;
            status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_GR_LONG):
        {
            struct dbr_gr_long *pold = (struct dbr_gr_long *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRgrLong
                DBRalLong
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_AL_LONG;
            status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = newSt.upper_disp_limit;
            pold->lower_disp_limit = newSt.lower_disp_limit;
            pold->upper_alarm_limit = newSt.upper_alarm_limit;
            pold->upper_warning_limit = newSt.upper_warning_limit;
            pold->lower_warning_limit = newSt.lower_warning_limit;
            pold->lower_alarm_limit = newSt.lower_alarm_limit;
            options = 0;
            status = dbChannelGet(chan, DBR_LONG, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_GR_DOUBLE):
        {
            struct dbr_gr_double *pold = (struct dbr_gr_double *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRprecision
                DBRgrDouble
                DBRalDouble
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
                DBR_AL_DOUBLE;
            status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->precision = (dbr_short_t) newSt.precision.dp;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = newSt.upper_disp_limit;
            pold->lower_disp_limit = newSt.lower_disp_limit;
            pold->upper_alarm_limit = newSt.upper_alarm_limit;
            pold->upper_warning_limit = newSt.upper_warning_limit;
            pold->lower_warning_limit = newSt.lower_warning_limit;
            pold->lower_alarm_limit = newSt.lower_alarm_limit;
            options = 0;
            status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options,
                nRequest, pfl);
        }
        break;

/*  case(oldDBR_CTRL_INT): */
    case(oldDBR_CTRL_SHORT):
        {
            struct dbr_ctrl_int *pold = (struct dbr_ctrl_int *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRgrLong
                DBRctrlLong
                DBRalLong
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
                DBR_AL_LONG;
            status = dbChannelGet(chan, DBR_SHORT, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = newSt.upper_disp_limit;
            pold->lower_disp_limit = newSt.lower_disp_limit;
            pold->upper_alarm_limit = newSt.upper_alarm_limit;
            pold->upper_warning_limit = newSt.upper_warning_limit;
            pold->lower_warning_limit = newSt.lower_warning_limit;
            pold->lower_alarm_limit = newSt.lower_alarm_limit;
            pold->upper_ctrl_limit = newSt.upper_ctrl_limit;
            pold->lower_ctrl_limit = newSt.lower_ctrl_limit;
            options = 0;
            status = dbChannelGet(chan, DBR_SHORT, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_CTRL_FLOAT):
        {
            struct dbr_ctrl_float *pold = (struct dbr_ctrl_float *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRprecision
                DBRgrDouble
                DBRctrlDouble
                DBRalDouble
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
                DBR_CTRL_DOUBLE | DBR_AL_DOUBLE;
            status = dbChannelGet(chan, DBR_FLOAT, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->precision = (dbr_short_t) newSt.precision.dp;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = epicsConvertDoubleToFloat(newSt.upper_disp_limit);
            pold->lower_disp_limit = epicsConvertDoubleToFloat(newSt.lower_disp_limit);
            pold->upper_alarm_limit = epicsConvertDoubleToFloat(newSt.upper_alarm_limit);
            pold->lower_alarm_limit = epicsConvertDoubleToFloat(newSt.lower_alarm_limit);
            pold->upper_warning_limit = epicsConvertDoubleToFloat(newSt.upper_warning_limit);
            pold->lower_warning_limit = epicsConvertDoubleToFloat(newSt.lower_warning_limit);
            pold->upper_ctrl_limit = epicsConvertDoubleToFloat(newSt.upper_ctrl_limit);
            pold->lower_ctrl_limit = epicsConvertDoubleToFloat(newSt.lower_ctrl_limit);
            options = 0;
            status = dbChannelGet(chan, DBR_FLOAT, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_GR_ENUM):
    case(oldDBR_CTRL_ENUM):
        {
            struct dbr_ctrl_enum *pold = (struct dbr_ctrl_enum *)pbuffer;
            struct {
                DBRstatus
                DBRenumStrs
            } newSt;
            short no_str;

            memset(pold, '\0', sizeof(struct dbr_ctrl_enum));
            /* first get status and severity */
            options = DBR_STATUS | DBR_ENUM_STRS;
            status = dbChannelGet(chan, DBR_ENUM, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            no_str = newSt.no_str;
            if (no_str>16) no_str=16;
            pold->no_str = no_str;
            for (i = 0; i < no_str; i++)
                strncpy(pold->strs[i], newSt.strs[i], sizeof(pold->strs[i]));
            /*now get values*/
            options = 0;
            status = dbChannelGet(chan, DBR_ENUM, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_CTRL_CHAR):
        {
            struct dbr_ctrl_char *pold = (struct dbr_ctrl_char *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRgrLong
                DBRctrlLong
                DBRalLong
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
                DBR_AL_LONG;
            status = dbChannelGet(chan, DBR_UCHAR, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = newSt.upper_disp_limit;
            pold->lower_disp_limit = newSt.lower_disp_limit;
            pold->upper_alarm_limit = newSt.upper_alarm_limit;
            pold->upper_warning_limit = newSt.upper_warning_limit;
            pold->lower_warning_limit = newSt.lower_warning_limit;
            pold->lower_alarm_limit = newSt.lower_alarm_limit;
            pold->upper_ctrl_limit = newSt.upper_ctrl_limit;
            pold->lower_ctrl_limit = newSt.lower_ctrl_limit;
            options = 0;
            status = dbChannelGet(chan, DBR_UCHAR, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_CTRL_LONG):
        {
            struct dbr_ctrl_long *pold = (struct dbr_ctrl_long *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRgrLong
                DBRctrlLong
                DBRalLong
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_GR_LONG | DBR_CTRL_LONG |
                DBR_AL_LONG;
            status = dbChannelGet(chan, DBR_LONG, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = newSt.upper_disp_limit;
            pold->lower_disp_limit = newSt.lower_disp_limit;
            pold->upper_alarm_limit = newSt.upper_alarm_limit;
            pold->upper_warning_limit = newSt.upper_warning_limit;
            pold->lower_warning_limit = newSt.lower_warning_limit;
            pold->lower_alarm_limit = newSt.lower_alarm_limit;
            pold->upper_ctrl_limit = newSt.upper_ctrl_limit;
            pold->lower_ctrl_limit = newSt.lower_ctrl_limit;
            options = 0;
            status = dbChannelGet(chan, DBR_LONG, &pold->value, &options,
                nRequest, pfl);
        }
        break;
    case(oldDBR_CTRL_DOUBLE):
        {
            struct dbr_ctrl_double *pold = (struct dbr_ctrl_double *)pbuffer;
            struct {
                DBRstatus
                DBRunits
                DBRprecision
                DBRgrDouble
                DBRctrlDouble
                DBRalDouble
            } newSt;

            options = DBR_STATUS | DBR_UNITS | DBR_PRECISION | DBR_GR_DOUBLE |
                DBR_CTRL_DOUBLE | DBR_AL_DOUBLE;
            status = dbChannelGet(chan, DBR_DOUBLE, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->precision = (dbr_short_t) newSt.precision.dp;
            strncpy(pold->units, newSt.units, MAX_UNITS_SIZE);
            pold->units[MAX_UNITS_SIZE-1] = '\0';
            pold->upper_disp_limit = newSt.upper_disp_limit;
            pold->lower_disp_limit = newSt.lower_disp_limit;
            pold->upper_alarm_limit = newSt.upper_alarm_limit;
            pold->upper_warning_limit = newSt.upper_warning_limit;
            pold->lower_warning_limit = newSt.lower_warning_limit;
            pold->lower_alarm_limit = newSt.lower_alarm_limit;
            pold->upper_ctrl_limit = newSt.upper_ctrl_limit;
            pold->lower_ctrl_limit = newSt.lower_ctrl_limit;
            options = 0;
            status = dbChannelGet(chan, DBR_DOUBLE, &pold->value, &options,
                nRequest, pfl);
        }
        break;

    case(oldDBR_STSACK_STRING):
        {
            struct dbr_stsack_string *pold = (struct dbr_stsack_string *)pbuffer;
            struct {
                DBRstatus
            } newSt;

            options = DBR_STATUS;
            status = dbChannelGet(chan, DBR_STRING, &newSt, &options, &zero, pfl);
            pold->status = newSt.status;
            pold->severity = newSt.severity;
            pold->ackt = newSt.ackt;
            pold->acks = newSt.acks;
            options = 0;
            status = dbChannelGet(chan, DBR_STRING, pold->value,
                &options, nRequest, pfl);
        }
        break;

    case(oldDBR_CLASS_NAME):
        {
            DBENTRY dbEntry;
            char *name = 0;
            char *pto = (char *)pbuffer;

            if (!pdbbase) {
                status = S_db_notFound;
                break;
            }
            dbInitEntry(pdbbase, &dbEntry);
            status = dbFindRecord(&dbEntry, dbChannelRecord(chan)->name);
            if (!status) name = dbGetRecordTypeName(&dbEntry);
            dbFinishEntry(&dbEntry);
            if (status) break;
            if (!name) {
                status = S_dbLib_recordTypeNotFound;
                break;
            }
            pto[MAX_STRING_SIZE-1] = 0;
            strncpy(pto, name, MAX_STRING_SIZE-1);
        }
        break;
    default:
        status = -1;
        break;
    }

    dbScanUnlock(dbChannelRecord(chan));

    if (status) return -1;
    return 0;
}
Пример #24
0
static long dbReadCOM(DBBASE **ppdbbase,const char *filename, FILE *fp,
	const char *path,const char *substitutions)
{
    long	status;
    inputFile	*pinputFile = NULL;
    char	*penv;
    char	**macPairs;
    
    if(*ppdbbase == 0) *ppdbbase = dbAllocBase();
    pdbbase = *ppdbbase;
    if(path && strlen(path)>0) {
	dbPath(pdbbase,path);
    } else {
	penv = getenv("EPICS_DB_INCLUDE_PATH");
	if(penv) {
	    dbPath(pdbbase,penv);
	} else {
	    dbPath(pdbbase,".");
	}
    }
    my_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
    freeListInitPvt(&freeListPvt,sizeof(tempListNode),100);
    if(substitutions) {
	if(macCreateHandle(&macHandle,NULL)) {
	    epicsPrintf("macCreateHandle error\n");
            status = -1;
	    goto cleanup;
	}
	macParseDefns(macHandle,(char *)substitutions,&macPairs);
	if(macPairs ==NULL) {
	    macDeleteHandle(macHandle);
	    macHandle = NULL;
	} else {
	    macInstallMacros(macHandle,macPairs);
	    free((void *)macPairs);
	    mac_input_buffer = dbCalloc(MY_BUFFER_SIZE,sizeof(char));
	}
    }
    pinputFile = dbCalloc(1,sizeof(inputFile));
    if(filename) {
	pinputFile->filename = macEnvExpand(filename);
    }
    if(!fp) {
	FILE	*fp1;

	if(pinputFile->filename) pinputFile->path = dbOpenFile(pdbbase,pinputFile->filename,&fp1);
	if(!pinputFile->filename || !fp1) {
	    errPrintf(0,__FILE__, __LINE__,
		"dbRead opening file %s",pinputFile->filename);
	    free((void *)pinputFile->filename);
	    free((void *)pinputFile);
            status = -1;
            goto cleanup;
	}
	pinputFile->fp = fp1;
    } else {
	pinputFile->fp = fp;
    }
    pinputFile->line_num = 0;
    pinputFileNow = pinputFile;
    my_buffer[0] = '\0';
    my_buffer_ptr = my_buffer;
    ellAdd(&inputFileList,&pinputFile->node);
    status = pvt_yy_parse();
    dbFreePath(pdbbase);
    if(!status) { /*add RTYP and VERS as an attribute */
	DBENTRY	dbEntry;
	DBENTRY	*pdbEntry = &dbEntry;
	long	localStatus;

	dbInitEntry(pdbbase,pdbEntry);
	localStatus = dbFirstRecordType(pdbEntry);
	while(!localStatus) {
	    localStatus = dbPutRecordAttribute(pdbEntry,"RTYP",
		dbGetRecordTypeName(pdbEntry));
	    if(!localStatus)  {
		localStatus = dbPutRecordAttribute(pdbEntry,"VERS",
		    "none specified");
	    }
	    if(localStatus) {
		fprintf(stderr,"dbPutRecordAttribute status %ld\n",status);
	    } else {
	        localStatus = dbNextRecordType(pdbEntry);
	    }
	}
	dbFinishEntry(pdbEntry);
    }
cleanup:
    if(macHandle) macDeleteHandle(macHandle);
    macHandle = NULL;
    if(mac_input_buffer) free((void *)mac_input_buffer);
    mac_input_buffer = NULL;
    if(freeListPvt) freeListCleanup(freeListPvt);
    freeListPvt = NULL;
    if(my_buffer) free((void *)my_buffer);
    my_buffer = NULL;
    freeInputFileList();
    return(status);
}
Пример #25
0
dbChannel * dbChannelCreate(const char *name)
{
    const char *pname = name;
    DBENTRY dbEntry;
    dbChannel *chan = NULL;
    char *cname;
    dbAddr *paddr;
    dbFldDes *pflddes;
    long status;
    short dbfType;

    if (!name || !*name || !pdbbase)
        return NULL;

    status = pvNameLookup(&dbEntry, &pname);
    if (status)
        goto finish;

    chan = freeListCalloc(dbChannelFreeList);
    if (!chan)
        goto finish;
    cname = malloc(strlen(name) + 1);
    if (!cname)
        goto finish;

    strcpy(cname, name);
    chan->name = cname;
    ellInit(&chan->filters);
    ellInit(&chan->pre_chain);
    ellInit(&chan->post_chain);

    paddr = &chan->addr;
    pflddes = dbEntry.pflddes;
    dbfType = pflddes->field_type;

    paddr->precord = dbEntry.precnode->precord;
    paddr->pfield = dbEntry.pfield;
    paddr->pfldDes = pflddes;
    paddr->no_elements = 1;
    paddr->field_type = dbfType;
    paddr->field_size = pflddes->size;
    paddr->special = pflddes->special;
    paddr->dbr_field_type = mapDBFToDBR[dbfType];

    if (paddr->special == SPC_DBADDR) {
        struct rset *prset = dbGetRset(paddr);

        /* Let record type modify paddr */
        if (prset && prset->cvt_dbaddr) {
            status = prset->cvt_dbaddr(paddr);
            if (status)
                goto finish;
            dbfType = paddr->field_type;
        }
    }

    /* Handle field modifiers */
    if (*pname) {
        if (*pname == '$') {
            /* Some field types can be accessed as char arrays */
            if (dbfType == DBF_STRING) {
                paddr->no_elements = paddr->field_size;
                paddr->field_type = DBF_CHAR;
                paddr->field_size = 1;
                paddr->dbr_field_type = DBR_CHAR;
            } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
                /* Clients see a char array, but keep original dbfType */
                paddr->no_elements = PVNAME_STRINGSZ + 12;
                paddr->field_size = 1;
                paddr->dbr_field_type = DBR_CHAR;
            } else {
                status = S_dbLib_fieldNotFound;
                goto finish;
            }
            pname++;
        }

        if (*pname == '[') {
            status = parseArrayRange(chan, pname, &pname);
            if (status) goto finish;
        }

        /* JSON may follow */
        if (*pname == '{') {
            status = chf_parse(chan, &pname);
            if (status) goto finish;
        }

        /* Make sure there's nothing else */
        if (*pname) {
            status = S_dbLib_fieldNotFound;
            goto finish;
        }
    }

finish:
    if (status && chan) {
        dbChannelDelete(chan);
        chan = NULL;
    }
    dbFinishEntry(&dbEntry);
    return chan;
}
Пример #26
0
/*
 *  Fill out a database structure (*paddr) for
 *    a record given by the name "pname."
 *
 *    Returns error codes from StaticLib module, not
 *        from dbAccess.
 */
long epicsShareAPI dbNameToAddr(const char *pname, DBADDR *paddr)
{
    DBENTRY dbEntry;
    dbFldDes *pflddes;
    struct rset *prset;
    long status = 0;
    long no_elements = 1;
    short dbfType, dbrType, field_size;

    if (!pname || !*pname || !pdbbase)
        return S_db_notFound;

    dbInitEntry(pdbbase, &dbEntry);
    status = dbFindRecordPart(&dbEntry, &pname);
    if (status) goto finish;

    if (*pname == '.') ++pname;
    status = dbFindFieldPart(&dbEntry, &pname);
    if (status == S_dbLib_fieldNotFound)
        status = dbGetAttributePart(&dbEntry, &pname);
    if (status) goto finish;

    paddr->precord = dbEntry.precnode->precord;
    paddr->pfield = dbEntry.pfield;
    pflddes = dbEntry.pflddes;

    dbfType = pflddes->field_type;
    dbrType = mapDBFToDBR[dbfType];
    field_size = pflddes->size;

    if (*pname++ == '$') {
        /* Some field types can be accessed as char arrays */
        if (dbfType == DBF_STRING) {
            dbfType     = DBF_CHAR;
            dbrType     = DBR_CHAR;
            no_elements = field_size;
            field_size  = 1;
        } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
            /* Clients see a char array, but keep original dbfType */
            dbrType     = DBR_CHAR;
            no_elements = PVNAME_STRINGSZ + 12;
            field_size = 1;
        } else {
            status = S_dbLib_fieldNotFound;
            goto finish;
        }
    }

    paddr->pfldDes     = pflddes;
    paddr->field_type  = dbfType;
    paddr->dbr_field_type = dbrType;
    paddr->field_size  = field_size;
    paddr->special     = pflddes->special;
    paddr->no_elements = no_elements;

    if ((paddr->special == SPC_DBADDR) &&
        (prset = dbGetRset(paddr)) &&
        prset->cvt_dbaddr)
        /* cvt_dbaddr routine may change any of these elements of paddr:
         *     pfield, no_elements, element_offset, field_type,
         *     dbr_field_type, field_size, and/or special.
         */
        status = prset->cvt_dbaddr(paddr);

finish:
    dbFinishEntry(&dbEntry);
    return status;
}
Пример #27
0
/*
 *  Fill out a database structure (*paddr) for
 *    a record given by the name "pname."
 *
 *    Returns error codes from StaticLib module, not
 *        from dbAccess.
 */
long dbNameToAddr(const char *pname, DBADDR *paddr)
{
    DBENTRY dbEntry;
    dbFldDes *pflddes;
    long status = 0;
    short dbfType;

    if (!pname || !*pname || !pdbbase)
        return S_db_notFound;

    dbInitEntry(pdbbase, &dbEntry);
    status = dbFindRecordPart(&dbEntry, &pname);
    if (status) goto finish;

    if (*pname == '.') ++pname;
    status = dbFindFieldPart(&dbEntry, &pname);
    if (status == S_dbLib_fieldNotFound)
        status = dbGetAttributePart(&dbEntry, &pname);
    if (status) goto finish;

    pflddes = dbEntry.pflddes;
    dbfType = pflddes->field_type;

    paddr->precord = dbEntry.precnode->precord;
    paddr->pfield = dbEntry.pfield;
    paddr->pfldDes = pflddes;
    paddr->no_elements = 1;
    paddr->field_type  = dbfType;
    paddr->field_size  = pflddes->size;
    paddr->special     = pflddes->special;
    paddr->dbr_field_type = mapDBFToDBR[dbfType];

    if (paddr->special == SPC_DBADDR) {
        struct rset *prset = dbGetRset(paddr);

        /* Let record type modify paddr */
        if (prset && prset->cvt_dbaddr) {
            status = prset->cvt_dbaddr(paddr);
            if (status)
                goto finish;
            dbfType = paddr->field_type;
        }
    }

    /* Handle field modifiers */
    if (*pname++ == '$') {
        /* Some field types can be accessed as char arrays */
        if (dbfType == DBF_STRING) {
            paddr->no_elements = paddr->field_size;
            paddr->field_type = DBF_CHAR;
            paddr->field_size = 1;
            paddr->dbr_field_type = DBR_CHAR;
        } else if (dbfType >= DBF_INLINK && dbfType <= DBF_FWDLINK) {
            /* Clients see a char array, but keep original dbfType */
            paddr->no_elements = PVNAME_STRINGSZ + 12;
            paddr->field_size = 1;
            paddr->dbr_field_type = DBR_CHAR;
        } else {
            status = S_dbLib_fieldNotFound;
            goto finish;
        }
    }

finish:
    dbFinishEntry(&dbEntry);
    return status;
}
Пример #28
0
long epicsShareAPI dbl(const char *precordTypename, const char *fields)
{
    DBENTRY dbentry;
    DBENTRY *pdbentry=&dbentry;
    long status;
    int nfields = 0;
    int ifield;
    char *fieldnames = 0;
    char **papfields = 0;

    if (!pdbbase) {
        printf("No database loaded\n");
        return 0;
    }

    if (precordTypename &&
        ((*precordTypename == '\0') || !strcmp(precordTypename,"*")))
        precordTypename = NULL;
    if (fields && (*fields == '\0'))
        fields = NULL;
    if (fields) {
        char *pnext;

        fieldnames = epicsStrDup(fields);
        nfields = 1;
        pnext = fieldnames;
        while (*pnext && (pnext = strchr(pnext,' '))) {
            nfields++;
            while (*pnext == ' ') pnext++;
        }
        papfields = dbCalloc(nfields,sizeof(char *));
        pnext = fieldnames;
        for (ifield = 0; ifield < nfields; ifield++) {
            papfields[ifield] = pnext;
            if (ifield < nfields - 1) {
                pnext = strchr(pnext, ' ');
                *pnext++ = 0;
                while (*pnext == ' ') pnext++;
            }
        }
    }
    dbInitEntry(pdbbase, pdbentry);
    if (!precordTypename)
        status = dbFirstRecordType(pdbentry);
    else
        status = dbFindRecordType(pdbentry,precordTypename);
    if (status) {
        printf("No record type\n");
    }

    while (!status) {
        status = dbFirstRecord(pdbentry);
        while (!status) {
            printf("%s", dbGetRecordName(pdbentry));
            for (ifield = 0; ifield < nfields; ifield++) {
                char *pvalue;
                status = dbFindField(pdbentry, papfields[ifield]);
                if (status) {
                    if (!strcmp(papfields[ifield], "recordType")) {
                        pvalue = dbGetRecordTypeName(pdbentry);
                    }
                    else {
                        printf(", ");
                        continue;
                    }
                }
                else {
                    pvalue = dbGetString(pdbentry);
                }
                printf(", \"%s\"", pvalue ? pvalue : "");
            }
            printf("\n");
            status = dbNextRecord(pdbentry);
        }
        if (precordTypename)
            break;

        status = dbNextRecordType(pdbentry);
    }
    if (nfields > 0) {
        free((void *)papfields);
        free((void *)fieldnames);
    }
    dbFinishEntry(pdbentry);
    return 0;
}
Пример #29
0
static int dbpr_report(
    const char *pname, DBADDR *paddr, int interest_level,
    TAB_BUFFER *pMsgBuff, int tab_size)
{
    char        *pmsg;
    dbFldDes    *pdbFldDes = paddr->pfldDes;
    dbRecordType *pdbRecordType = pdbFldDes->pdbRecordType;
    short       n2;
    void        *pfield;
    char        *pfield_name;
    char        *pfield_value;
    DBENTRY     dbentry;
    DBENTRY     *pdbentry = &dbentry;
    long        status;

    dbInitEntry(pdbbase,pdbentry);
    status = dbFindRecord(pdbentry,pname);
    if (status) {
        errMessage(status,pname);
        return -1;
    }

    pmsg = pMsgBuff->message;
    for (n2 = 0; n2 <= pdbRecordType->no_fields - 1; n2++) {
        pdbFldDes = pdbRecordType->papFldDes[pdbRecordType->sortFldInd[n2]];
        pfield_name = pdbFldDes->name;
        pfield = ((char *)paddr->precord) + pdbFldDes->offset;
        if (pdbFldDes->interest > interest_level )
            continue;

        switch (pdbFldDes->field_type) {
        case DBF_STRING:
        case DBF_USHORT:
        case DBF_ENUM:
        case DBF_FLOAT:
        case DBF_CHAR:
        case DBF_UCHAR:
        case DBF_SHORT:
        case DBF_LONG:
        case DBF_ULONG:
        case DBF_DOUBLE:
        case DBF_MENU:
        case DBF_DEVICE:
            status = dbFindField(pdbentry,pfield_name);
            pfield_value = dbGetString(pdbentry);
            sprintf(pmsg, "%s: %s", pfield_name,
                (pfield_value ? pfield_value : "<nil>"));
            dbpr_msgOut(pMsgBuff, tab_size);
            break;

        case DBF_INLINK:
        case DBF_OUTLINK:
        case DBF_FWDLINK: {
                DBLINK  *plink = (DBLINK *)pfield;
                int     ind;

                status = dbFindField(pdbentry,pfield_name);
                for (ind=0; ind<LINK_NTYPES; ind++) {
                    if (pamaplinkType[ind].value == plink->type)
                        break;
                }
                if (ind>=LINK_NTYPES) {
                    sprintf(pmsg,"%s: Illegal Link Type", pfield_name);
                }
                else {
                    sprintf(pmsg,"%s:%s %s", pfield_name,
                        pamaplinkType[ind].strvalue,dbGetString(pdbentry));
                }
                dbpr_msgOut(pMsgBuff, tab_size);
            }
            break;

        case DBF_NOACCESS:
            if (pfield == (void *)&paddr->precord->time) {
                /* Special for the TIME field, make it human-readable */
                char time_buf[40];
                epicsTimeToStrftime(time_buf, 40, "%Y-%m-%d %H:%M:%S.%09f",
                    &paddr->precord->time);
                sprintf(pmsg, "%s: %s", pfield_name, time_buf);
                dbpr_msgOut(pMsgBuff, tab_size);
            }
            else if (pdbFldDes->size == sizeof(void *) &&
                strchr(pdbFldDes->extra, '*')) {
                /* Special for pointers, needed on little-endian CPUs */
                sprintf(pmsg, "%s: %p", pfield_name, *(void **)pfield);
                dbpr_msgOut(pMsgBuff, tab_size);
            }
            else { /* just print field as hex bytes */
                unsigned char *pchar = (unsigned char *)pfield;
                char   temp_buf[61];
                char *ptemp_buf = &temp_buf[0];
                short n = pdbFldDes->size;
                short i;
                unsigned int value;

                if (n > sizeof(temp_buf)/3) n = sizeof(temp_buf)/3;
                for (i=0; i<n; i++, ptemp_buf += 3, pchar++) {
                        value = (unsigned int)*pchar;
                        sprintf(ptemp_buf, "%02x ", value);
                }
                sprintf(pmsg, "%s: %s", pfield_name,temp_buf);
                dbpr_msgOut(pMsgBuff, tab_size);
            }
            break;

        default:
            sprintf(pmsg, "%s: dbpr: Unknown field_type", pfield_name);
            dbpr_msgOut(pMsgBuff, tab_size);
            break;
        }
    }
    pmsg[0] = '\0';
    dbpr_msgOut(pMsgBuff, tab_size);
    dbFinishEntry(pdbentry);
    return (0);
}
Пример #30
0
static long dbPutFieldLink(DBADDR *paddr,
    short dbrType, const void *pbuffer, long nRequest)
{
    dbCommon    *precord = paddr->precord;
    dbFldDes    *pfldDes = paddr->pfldDes;
    long        special = paddr->special;
    DBLINK      *plink = (DBLINK *)paddr->pfield;
    const char  *pstring = (const char *)pbuffer;
    DBENTRY     dbEntry;
    DBADDR      dbaddr;
    struct dsxt *old_dsxt = NULL;
    struct dset *new_dset = NULL;
    struct dsxt *new_dsxt = NULL;
    long        status;
    int         isDevLink;
    short       scan;

    switch (dbrType) {
    case DBR_CHAR:
    case DBR_UCHAR:
        if (pstring[nRequest - 1] != '\0')
            return S_db_badDbrtype;
        break;

    case DBR_STRING:
        break;

    default:
        return S_db_badDbrtype;
    }

    dbInitEntry(pdbbase, &dbEntry);
    status = dbFindRecord(&dbEntry, precord->name);
    if (!status) status = dbFindField(&dbEntry, pfldDes->name);
    if (status) goto finish;

    isDevLink = ellCount(&precord->rdes->devList) > 0 &&
                (strcmp(pfldDes->name, "INP") == 0 ||
                 strcmp(pfldDes->name, "OUT") == 0);

    dbLockSetGblLock();
    dbLockSetRecordLock(precord);

    scan = precord->scan;

    if (isDevLink) {
        devSup *pdevSup = dbDTYPtoDevSup(precord->rdes, precord->dtyp);
        if (pdevSup) {
            new_dset = pdevSup->pdset;
            new_dsxt = pdevSup->pdsxt;
        }

        if (precord->dset) {
            pdevSup = dbDSETtoDevSup(precord->rdes, precord->dset);
            if (pdevSup)
                old_dsxt = pdevSup->pdsxt;
        }

        if (new_dsxt == NULL ||
            new_dsxt->add_record == NULL ||
            (precord->dset && old_dsxt == NULL) ||
            (old_dsxt && old_dsxt->del_record == NULL)) {
            status = S_db_noSupport;
            goto unlock;
        }

        if (scan == menuScanI_O_Intr) {
            scanDelete(precord);
            precord->scan = menuScanPassive;
        }

        if (old_dsxt) {
            status = old_dsxt->del_record(precord);
            if (status)
                goto restoreScan;
        }
    }

    switch (plink->type) { /* Old link type */
    case DB_LINK:
        free(plink->value.pv_link.pvt);
        plink->value.pv_link.pvt = 0;
        plink->type = PV_LINK;
        plink->value.pv_link.getCvt = 0;
        plink->value.pv_link.pvlMask = 0;
        plink->value.pv_link.lastGetdbrType = 0;
        dbLockSetSplit(precord);
        break;

    case CA_LINK:
        dbCaRemoveLink(plink);
        plink->type = PV_LINK;
        plink->value.pv_link.getCvt = 0;
        plink->value.pv_link.pvlMask = 0;
        plink->value.pv_link.lastGetdbrType = 0;
        break;

    case CONSTANT:
        break;  /* do nothing */

    case PV_LINK:
    case MACRO_LINK:
        break;  /* should never get here */

    default: /* Hardware address */
        if (!isDevLink) {
            status = S_db_badHWaddr;
            goto restoreScan;
        }
        break;
    }

    if (special) status = dbPutSpecial(paddr, 0);

    if (!status) status = dbPutString(&dbEntry, pstring);

    if (!status && special) status = dbPutSpecial(paddr, 1);

    if (status) {
        if (isDevLink) {
            precord->dset = NULL;
            precord->pact = TRUE;
        }
        goto postScanEvent;
    }

    if (isDevLink) {
        precord->dpvt = NULL;
        precord->dset = new_dset;
        precord->pact = FALSE;

        status = new_dsxt->add_record(precord);
        if (status) {
            precord->dset = NULL;
            precord->pact = TRUE;
            goto postScanEvent;
        }
    }

    switch (plink->type) { /* New link type */
    case PV_LINK:
        if (plink == &precord->tsel)
            recGblTSELwasModified(plink);
        plink->value.pv_link.precord = precord;

        if (!(plink->value.pv_link.pvlMask & (pvlOptCA|pvlOptCP|pvlOptCPP)) &&
            (dbNameToAddr(plink->value.pv_link.pvname, &dbaddr) == 0)) {
            /* It's a DB link */
            DBADDR      *pdbAddr;

            plink->type = DB_LINK;
            pdbAddr = dbMalloc(sizeof(struct dbAddr));
            *pdbAddr = dbaddr; /* NB: structure copy */;
            plink->value.pv_link.pvt = pdbAddr;
            dbLockSetRecordLock(pdbAddr->precord);
            dbLockSetMerge(precord, pdbAddr->precord);
        } else { /* Make it a CA link */
            char        *pperiod;

            plink->type = CA_LINK;
            if (pfldDes->field_type == DBF_INLINK) {
                plink->value.pv_link.pvlMask |= pvlOptInpNative;
            }
            dbCaAddLink(plink);
            if (pfldDes->field_type == DBF_FWDLINK) {
                pperiod = strrchr(plink->value.pv_link.pvname, '.');
                if (pperiod && strstr(pperiod, "PROC"))
                    plink->value.pv_link.pvlMask |= pvlOptFWD;
            }
        }
        break;

    case CONSTANT:
        break;

    case DB_LINK:
    case CA_LINK:
    case MACRO_LINK:
        break;  /* should never get here */

    default: /* Hardware address */
        if (!isDevLink) {
            status = S_db_badHWaddr;
            goto postScanEvent;
        }
        break;
    }
    db_post_events(precord, plink, DBE_VALUE | DBE_LOG);

restoreScan:
    if (isDevLink &&
        scan == menuScanI_O_Intr) { /* undo scanDelete() */
        precord->scan = scan;
        scanAdd(precord);
    }
postScanEvent:
    if (scan != precord->scan)
        db_post_events(precord, &precord->scan, DBE_VALUE|DBE_LOG);
unlock:
    dbLockSetGblUnlock();
finish:
    dbFinishEntry(&dbEntry);
    return status;
}