diff options
Diffstat (limited to 'perl-install/c')
-rw-r--r-- | perl-install/c/smp.c | 201 | ||||
-rw-r--r-- | perl-install/c/stuff.xs.pl | 61 |
2 files changed, 213 insertions, 49 deletions
diff --git a/perl-install/c/smp.c b/perl-install/c/smp.c index 2438418bb..9cc75978d 100644 --- a/perl-install/c/smp.c +++ b/perl-install/c/smp.c @@ -64,30 +64,132 @@ int sparcDetectSMP(void) } #endif /* __sparc__ */ -/* just a placeholder for now - don't have an SMP machine - need something in place to build - s.benedict */ - #ifdef __powerpc__ +/* minifind.c -- simple find library + * + * Copyright (c) 2002 Terra Soft Solutions, Inc. + * Written by Dan Burcaw <dburcaw@terrasoftsolutions.com> + * + * This software may be freely redistributed under the terms of the GNU + * library public license. + * + * You should have received a copy of the GNU Library Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <string.h> +#include <dirent.h> +#include <malloc.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> + +struct pathNode +{ + char *path; + struct pathNode *next; +}; + +struct findNode +{ + struct pathNode *result; + struct pathNode *exclude; +}; + +// insert a node at head of linked-list +static void insert_node(struct pathNode *n, char *path) +{ + struct pathNode *new = (struct pathNode *) malloc(sizeof(struct pathNode)); + new->path = path; + new->next = n->next; + n->next = new; +} + +// return input strip less last character +static char *stripLastChar(char *in) +{ + char *out = malloc(sizeof(char)*strlen(in)); + snprintf(out, strlen(in) - 1, "%s", in); + return out; +} + +// do the work +static char *minifind(char *dir, char *search, struct findNode *list) +{ + char *d = NULL; + int n; + struct dirent **namelist; + struct stat buf; + + if (dir[strlen(dir)-1] == '/') + dir = stripLastChar(dir); + + // check is there is an exact filematch to dir + // when search is not specified + if (search == NULL) + { + if (lstat(dir, &buf) == 0) + insert_node(list->result, dir); + return 0; + } + + n = scandir(dir, &namelist, 0, alphasort); + if (n >= 0) + { + while (n--) + { + d = malloc(sizeof(char) * (strlen(dir) \ + + strlen(namelist[n]->d_name)+1)); + sprintf(d, "%s/%s", dir, namelist[n]->d_name); + if (strstr(namelist[n]->d_name, search)) + insert_node(list->result, d); + + if ((lstat(d, &buf) == 0) && S_ISDIR(buf.st_mode)) + { + if (strcmp(namelist[n]->d_name, ".") && + strcmp(namelist[n]->d_name, "..")) + d = minifind(d, search, list); + } + free(namelist[n]); + } + free(namelist); + return d; + } + return 0; +} + int ppcDetectSMP(void) { - int issmp = 0; + int issmp = -1; FILE *f; - - f = fopen("/proc/cpuinfo", "r"); - if (f) { - char buff[1024]; + struct findNode *list = (struct findNode *) malloc(sizeof(struct findNode)); + struct pathNode *n; - while (fgets (buff, 1024, f) != NULL) { - if (!strncmp (buff, "ncpus active\t: ", 15)) { - if (strtoul (buff + 15, NULL, 0) > 1) - issmp = 1; - break; + list->result = (struct pathNode *) malloc(sizeof(struct pathNode)); + list->result->path = NULL; + list->result->next = list->result; + + minifind("/proc/device-tree/cpus", "device_type", list); + + for (n = list->result->next; n != list->result; n = n->next) + { + f = fopen(n->path, "r"); + if (f) { + char buff[1024]; + while (fgets (buff, 1024, f) != NULL) { + if (!strncmp (buff, "cpu", 3)) + { + issmp++; + break; + } + } + fclose(f); } } - fclose(f); - } else - return -1; - + return issmp; } #endif /* __powerpc__ */ @@ -152,6 +254,11 @@ typedef unsigned int vm_offset_t; #include <machine/types.h> #endif +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; +typedef vm_offset_t addr_t; + /* EBDA is @ 40:0e in real-mode terms */ #define EBDA_POINTER 0x040e /* location of EBDA pointer */ @@ -172,43 +279,43 @@ typedef unsigned int vm_offset_t; /* MP Floating Pointer Structure */ typedef struct MPFPS { char signature[ 4 ]; - void* pap; - u_char length; - u_char spec_rev; - u_char checksum; - u_char mpfb1; - u_char mpfb2; - u_char mpfb3; - u_char mpfb4; - u_char mpfb5; + addr_t pap; + u8 length; + u8 spec_rev; + u8 checksum; + u8 mpfb1; + u8 mpfb2; + u8 mpfb3; + u8 mpfb4; + u8 mpfb5; } mpfps_t; /* MP Configuration Table Header */ typedef struct MPCTH { char signature[ 4 ]; - u_short base_table_length; - u_char spec_rev; - u_char checksum; - u_char oem_id[ 8 ]; - u_char product_id[ 12 ]; - void* oem_table_pointer; - u_short oem_table_size; - u_short entry_count; - void* apic_address; - u_short extended_table_length; - u_char extended_table_checksum; - u_char reserved; + u16 base_table_length; + u8 spec_rev; + u8 checksum; + u8 oem_id[ 8 ]; + u8 product_id[ 12 ]; + addr_t oem_table_pointer; + u16 oem_table_size; + u16 entry_count; + addr_t apic_address; + u16 extended_table_length; + u8 extended_table_checksum; + u8 reserved; } mpcth_t; typedef struct PROCENTRY { - u_char type; - u_char apicID; - u_char apicVersion; - u_char cpuFlags; - u_long cpuSignature; - u_long featureFlags; - u_long reserved1; - u_long reserved2; + u8 type; + u8 apicID; + u8 apicVersion; + u8 cpuFlags; + u32 cpuSignature; + u32 featureFlags; + u32 reserved1; + u32 reserved2; } ProcEntry; #define PROCENTRY_FLAG_EN 0x01 @@ -274,7 +381,7 @@ static int intelDetectSMP_mptable(void) mpcth_t cth; int count, i; - paddr = (vm_offset_t) mpfps.pap; + paddr = mpfps.pap; seekEntry( paddr ); readEntry( &cth, sizeof( cth ) ); /* if we don't have any entries, the kernel sure diff --git a/perl-install/c/stuff.xs.pl b/perl-install/c/stuff.xs.pl index 26e6ce413..07249d66b 100644 --- a/perl-install/c/stuff.xs.pl +++ b/perl-install/c/stuff.xs.pl @@ -23,6 +23,8 @@ print ' #include <sys/stat.h> #include <sys/utsname.h> #include <sys/mount.h> +#undef __USE_MISC +#include <linux/wireless.h> #include <linux/keyboard.h> #include <linux/kd.h> #include <linux/hdreg.h> @@ -398,13 +400,68 @@ hasNetDevice(device) int s = socket(AF_INET, SOCK_DGRAM, 0); if (s == -1) { RETVAL = 0; return; } - strcpy(req.ifr_name, device); + strncpy(req.ifr_name, device, IFNAMSIZ); RETVAL = ioctl(s, SIOCGIFFLAGS, &req) == 0; close(s); OUTPUT: RETVAL + +int +isNetDeviceWirelessAware(device) + char * device + CODE: + struct iwreq ifr; + + int s = socket(AF_INET, SOCK_DGRAM, 0); + + memset(&ifr, 0, sizeof(ifr)); + strncpy(ifr.ifr_name, device, IFNAMSIZ); + RETVAL = ioctl(s, SIOCGIWNAME, &ifr) != -1; + close(s); + OUTPUT: + RETVAL + + +void +get_netdevices() + PPCODE: + struct ifconf ifc; + struct ifreq *ifr; + int i; + int numreqs = 10; + + int s = socket(AF_INET, SOCK_DGRAM, 0); + + ifc.ifc_buf = NULL; + for (;;) { + ifc.ifc_len = sizeof(struct ifreq) * numreqs; + ifc.ifc_buf = realloc(ifc.ifc_buf, ifc.ifc_len); + + if (ioctl(s, SIOCGIFCONF, &ifc) < 0) { + perror("SIOCGIFCONF"); + return; + } + if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) { + /* assume it overflowed and try again */ + numreqs += 10; + continue; + } + break; + } + if (ifc.ifc_len) { + ifr = ifc.ifc_req; + EXTEND(sp, ifc.ifc_len); + for (i=0; i < ifc.ifc_len; i+= sizeof(struct ifreq)) { + PUSHs(sv_2mortal(newSVpv(ifr->ifr_name, 0))); + ifr++; + } + } + + close(s); + + char* getNetDriver(char* device) ALIAS: @@ -415,7 +472,7 @@ getNetDriver(char* device) int s = socket(AF_INET, SOCK_DGRAM, 0); memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)-1); + strncpy(ifr.ifr_name, device, IFNAMSIZ); drvinfo.cmd = ETHTOOL_GDRVINFO; ifr.ifr_data = (caddr_t) &drvinfo; |