Projekt

Allgemein

Profil

Herunterladen (4,58 KB) Statistiken
| Zweig: | Markierung: | Revision:
/***************************************************************************
$RCSfile$
-------------------
cvs : $Id$
begin : Mon Mar 01 2004
copyright : (C) 2004 by Martin Preuss
email : martin@libchipcard.de

***************************************************************************
* Please see toplevel file COPYING for license details *
***************************************************************************/


#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "pcmciascanner_p.h"
#include <gwenhywfar/debug.h>
#include <gwenhywfar/misc.h>
#include <gwenhywfar/directory.h>
#include <gwenhywfar/buffer.h>


#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

#ifdef USE_PCMCIA
# include <pcmcia/version.h>
# include <pcmcia/cs_types.h>
# include <pcmcia/cs.h>
# include <pcmcia/cistpl.h>
# include <pcmcia/ds.h>
#endif


GWEN_INHERIT(LC_DEVSCANNER, LC_PCMCIA_SCANNER)



LC_DEVSCANNER *LC_PcmciaScanner_new() {
LC_DEVSCANNER *sc;
LC_PCMCIA_SCANNER *scp;

sc=LC_DevScanner_new();
GWEN_NEW_OBJECT(LC_PCMCIA_SCANNER, scp);
GWEN_INHERIT_SETDATA(LC_DEVSCANNER, LC_PCMCIA_SCANNER, sc, scp,
LC_PcmciaScanner_FreeData);
LC_DevScanner_SetReadDevsFn(sc, LC_PcmciaScanner_ReadDevs);
scp->devMajor=LC_PcmciaScanner_GetDevMajor();

return sc;
}



void LC_PcmciaScanner_FreeData(void *bp, void *p) {
LC_PCMCIA_SCANNER *scp;

scp=(LC_PCMCIA_SCANNER*)p;

GWEN_FREE_OBJECT(scp);
}



int LC_PcmciaScanner_GetDevMajor() {
FILE *f;
int devMajor;
char lineBuf[32], name[32];

f=fopen(LC_PCMCIA_PROC_FILE, "r");
if (!f) {
DBG_ERROR(0, "fopen(%s): %s", LC_PCMCIA_PROC_FILE,
strerror(errno));
return -1;
}

while(fgets(lineBuf, sizeof(lineBuf)-1, f) != NULL) {
lineBuf[sizeof(lineBuf)-1]=0;
if (2==sscanf(lineBuf, "%d %s", &devMajor, name)){
if (strcmp(name, "pcmcia")==0){
fclose(f);
return devMajor;
}
}
}
fclose(f);
return -1;
}



int LC_PcmciaScanner_OpenSocket(LC_DEVSCANNER *sc, int sk){
LC_PCMCIA_SCANNER *scp;
static char *paths[]={"/var/lib/pcmcia", "/var/run", "/tmp", 0};
int fd;
char **p;
char fpath[32];
dev_t d;

assert(sc);
scp=GWEN_INHERIT_GETDATA(LC_DEVSCANNER, LC_PCMCIA_SCANNER, sc);
assert(scp);

d=makedev(scp->devMajor, sk);

for (p = paths; *p; p++) {
snprintf(fpath, sizeof(fpath), "%s/cc-%d", *p, (int)getpid());
if (mknod(fpath, (S_IFCHR|S_IREAD|S_IWRITE), d)==0) {
fd=open(fpath, O_RDONLY);
unlink(fpath);
if (fd>=0)
return fd;
if (errno==ENODEV) {
DBG_INFO(0, "PCMCIA socket %d not available", sk);
break;
}
}
}
return -1;
}



int LC_PcmciaScanner_GetTuple(int fd, unsigned char code,
ds_ioctl_arg_t *arg) {
arg->tuple.DesiredTuple=code;
arg->tuple.Attributes=TUPLE_RETURN_COMMON;
arg->tuple.TupleOffset=0;
if ((ioctl(fd, DS_GET_FIRST_TUPLE, arg)==0) &&
(ioctl(fd, DS_GET_TUPLE_DATA, arg)==0) &&
(ioctl(fd, DS_PARSE_TUPLE, arg)==0))
return 0;
else
return -1;
}



int LC_PcmciaScanner_ReadDevs(LC_DEVSCANNER *sc, LC_DEVICE_LIST *dl) {
#ifndef USE_PCMCIA
return 1; /* no changes */
#else
LC_PCMCIA_SCANNER *scp;
int sknum;

assert(sc);
scp=GWEN_INHERIT_GETDATA(LC_DEVSCANNER, LC_PCMCIA_SCANNER, sc);
assert(scp);

if (scp->devMajor==-1) {
DBG_ERROR(0,
"Major device number for PCMCIA device not found. "
"Maybe kernel module not loaded?");
return -1;
}

for (sknum=0; sknum<LC_PCMCIA_MAX_SOCKETS; sknum++) {
int fd;

fd=LC_PcmciaScanner_OpenSocket(sc, sknum);
if (fd<0)
break;
else {
ds_ioctl_arg_t arg;

if (LC_PcmciaScanner_GetTuple(fd, CISTPL_MANFID, &arg)==0) {
GWEN_TYPE_UINT32 vendorId;
GWEN_TYPE_UINT32 productId;
LC_DEVICE *dev;

vendorId=arg.tuple_parse.parse.manfid.manf;
productId=arg.tuple_parse.parse.manfid.card;
dev=LC_Device_new(LC_Device_BusType_Pcmcia,
0, sknum, vendorId, productId);
LC_Device_SetDevicePos(dev, sknum);
LC_Device_List_Add(dev, dl);
}
else {
DBG_DEBUG(0,
"Could not get info for PCMCIA "
"device at socket %d (%s)",
sknum,
strerror(errno));
}
close(fd);
}
} /* for */
#endif

return 0;
}






(13-13/15)