From 6b97710009d2830fa2ca86438a8eb83e3abf5810 Mon Sep 17 00:00:00 2001 From: open-license-manager <rillf@maildrop.cc> Date: ćšć, 31 7æ 2014 16:33:19 +0800 Subject: [PATCH] valgrind & tests --- src/library/os/linux/os-linux.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 195 insertions(+), 18 deletions(-) diff --git a/src/library/os/linux/os-linux.c b/src/library/os/linux/os-linux.c index b316c17..f4f5d8c 100644 --- a/src/library/os/linux/os-linux.c +++ b/src/library/os/linux/os-linux.c @@ -4,12 +4,13 @@ #include <netdb.h> #include <ifaddrs.h> #include <stdio.h> +#include <ctype.h> #include <stdlib.h> #include <unistd.h> #include <linux/if_link.h> #include <sys/socket.h> #include <netpacket/packet.h> - +#include <valgrind/memcheck.h> #include <paths.h> #include <stdlib.h> @@ -25,6 +26,10 @@ #include <openssl/bio.h> #include <openssl/pem.h> #include <openssl/err.h> + +#include <mntent.h> +#include <dirent.h> +#include <stdio.h> static int ifname_position(char *ifnames, char * ifname, int ifnames_max) { int i, position; @@ -53,6 +58,11 @@ perror("getifaddrs"); return ERROR; } + + if (adapterInfos != NULL) { + memset(adapterInfos, 0, (*adapter_info_size) * sizeof(AdapterInfo)); + } + /* count the maximum number of interfaces */ for (ifa = ifaddr, if_max = 0; ifa != NULL; ifa = ifa->ifa_next, n++) { if (ifa->ifa_addr == NULL) { @@ -77,7 +87,7 @@ strncpy(&ifnames[if_num * NI_MAXHOST], ifa->ifa_name, NI_MAXHOST); if (adapterInfos != NULL && if_num < *adapter_info_size) { strncpy(adapterInfos[if_num].description, ifa->ifa_name, - NI_MAXHOST); + NI_MAXHOST); } if_name_position = if_num; if_num++; @@ -106,8 +116,8 @@ */ #ifdef _DEBUG s = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), host, - NI_MAXHOST, - NULL, 0, NI_NUMERICHOST); + NI_MAXHOST, + NULL, 0, NI_NUMERICHOST); if (s != 0) { printf("getnameinfo() failed: %s\n", gai_strerror(s)); } @@ -137,7 +147,7 @@ #endif } #ifdef _DEBUG - printf("\t %s\n", ifa->ifa_name); + printf("\t %s\n", ifa->ifa_name); #endif } @@ -151,29 +161,196 @@ f_return = BUFFER_TOO_SMALL; } freeifaddrs(ifaddr); + free(ifnames); return f_return; } +/** + *Usually uuid are hex number separated by "-". this method read up to 8 hex + *numbers skipping - characters. + *@param uuid uuid as read in /dev/disk/by-uuid + *@param buffer_out: unsigned char buffer[8] output buffer for result + */ +static void parseUUID(const char *uuid, unsigned char* buffer_out, + unsigned int out_size) { + size_t len; + unsigned int i, j; + char * hexuuid; + unsigned char cur_character; + //remove characters not in hex set + len = strlen(uuid); + hexuuid = (char *) malloc(sizeof(char) * strlen(uuid)); + memset(buffer_out, 0, out_size); + memset(hexuuid, 0, sizeof(char) * strlen(uuid)); + for (i = 0, j = 0; i < len; i++) { + if (isxdigit(uuid[i])) { + hexuuid[j] = uuid[i]; + j++; + } else { + //skip + continue; + } + } + if (j % 2 == 1) { + hexuuid[j++] = '0'; + } + hexuuid[j] = '\0'; + for (i = 0; i < j / 2; i++) { + sscanf(&hexuuid[i * 2], "%2hhx", &cur_character); + buffer_out[i % out_size] = buffer_out[i % out_size] ^ cur_character; + } + + free(hexuuid); +} + +#define MAX_UNITS 20 FUNCTION_RETURN getDiskInfos(DiskInfo * diskInfos, size_t * disk_info_size) { - struct stat filename_stat, mount_stat; - static char discard[1024]; - char device[64], name[64], type[64]; - FILE *mounts = fopen(_PATH_MOUNTED, "r"); - if (mounts == NULL) { + struct stat mount_stat, sym_stat; + /*static char discard[1024]; + char device[64], name[64], type[64]; + */ + char cur_dir[MAX_PATH]; + struct mntent *ent; + + int maxDrives, currentDrive, i, drive_found; + __ino64_t *statDrives; + DiskInfo *tmpDrives; + FILE *aFile; + DIR *disk_by_uuid_dir, *disk_by_label; + struct dirent *dir; + FUNCTION_RETURN result; + + if (diskInfos != NULL) { + maxDrives = *disk_info_size; + tmpDrives = diskInfos; + } else { + maxDrives = MAX_UNITS; + tmpDrives = (DiskInfo *) malloc(sizeof(DiskInfo) * maxDrives); + } + memset(tmpDrives, 0, sizeof(DiskInfo) * maxDrives); + statDrives = (__ino64_t *) malloc(maxDrives * sizeof(__ino64_t )); + memset(statDrives, 0, sizeof(__ino64_t ) * maxDrives); + ; + + aFile = setmntent("/proc/mounts", "r"); + if (aFile == NULL) { + /*proc not mounted*/ return ERROR; } - while (fscanf(mounts, "%64s %64s %64s %1024[^\n]", device, name, type, - discard) != EOF) { - if (stat(device, &mount_stat) != 0) - continue; - if (filename_stat.st_dev == mount_stat.st_rdev) { - fprintf(stderr, "device: %s; name: %s; type: %s\n", device, name, - type); + currentDrive = 0; + while (NULL != (ent = getmntent(aFile))) { + if ((strncmp(ent->mnt_type, "ext", 3) == 0 + || strncmp(ent->mnt_type, "vfat", 4) == 0 + || strncmp(ent->mnt_type, "ntfs", 4) == 0) + && ent->mnt_fsname != NULL + && strncmp(ent->mnt_fsname, "/dev/", 5) == 0) { + if (stat(ent->mnt_fsname, &mount_stat) == 0) { + drive_found = -1; + for (i = 0; i < currentDrive; i++) { + if (statDrives[i] == mount_stat.st_ino) { + drive_found = i; + } + } + if (drive_found == -1) { +#ifdef _DEBUG + printf("mntent: %s %s %d\n", ent->mnt_fsname, ent->mnt_dir, + mount_stat.st_ino); +#endif + strcpy(tmpDrives[currentDrive].device, ent->mnt_fsname); + statDrives[currentDrive] = mount_stat.st_ino; + drive_found = currentDrive; + currentDrive++; + } + if (strcmp(ent->mnt_dir, "/") == 0) { + strcpy(tmpDrives[drive_found].label, "root"); +#ifdef _DEBUG + printf("drive %s set to preferred\n", ent->mnt_fsname); +#endif + tmpDrives[drive_found].preferred = true; + } + } } } + endmntent(aFile); - return ERROR; + if (diskInfos == NULL) { + *disk_info_size = currentDrive; + free(tmpDrives); + result = OK; + } else if (*disk_info_size >= currentDrive) { + disk_by_uuid_dir = opendir("/dev/disk/by-uuid"); + if (disk_by_uuid_dir == NULL) { +#ifdef _DEBUG + printf("Open /dev/disk/by-uuid fail"); +#endif + free(statDrives); + return ERROR; + } + result = OK; + *disk_info_size = currentDrive; + while ((dir = readdir(disk_by_uuid_dir)) != NULL) { + strcpy(cur_dir, "/dev/disk/by-uuid/"); + strncat(cur_dir, dir->d_name, 200); + if (stat(cur_dir, &sym_stat) == 0) { + for (i = 0; i < currentDrive; i++) { + if (sym_stat.st_ino == statDrives[i]) { + parseUUID(dir->d_name, tmpDrives[i].disk_sn, + sizeof(tmpDrives[i].disk_sn)); +#ifdef _DEBUG + VALGRIND_CHECK_VALUE_IS_DEFINED(tmpDrives[i].device); + + printf("uuid %d %s %02x%02x%02x%02x\n", i, + tmpDrives[i].device, + tmpDrives[i].disk_sn[0], + tmpDrives[i].disk_sn[1], + tmpDrives[i].disk_sn[2], + tmpDrives[i].disk_sn[3]); +#endif + } + } + } + } + closedir(disk_by_uuid_dir); + + disk_by_label = opendir("/dev/disk/by-label"); + if (disk_by_label != NULL) { + while ((dir = readdir(disk_by_label)) != NULL) { + strcpy(cur_dir, "/dev/disk/by-label/"); + strcat(cur_dir, dir->d_name); + if (stat(cur_dir, &sym_stat) == 0) { + for (i = 0; i < currentDrive; i++) { + if (sym_stat.st_ino == statDrives[i]) { + strncpy(tmpDrives[i].label, dir->d_name, 255); + printf("label %d %s %s\n", i, tmpDrives[i].label, + tmpDrives[i].device); + } + } + } + } + closedir(disk_by_label); + } + } else { + result = BUFFER_TOO_SMALL; + } + /* + FILE *mounts = fopen(_PATH_MOUNTED, "r"); + if (mounts == NULL) { + return ERROR; + } + + while (fscanf(mounts, "%64s %64s %64s %1024[^\n]", device, name, type, + discard) != EOF) { + if (stat(device, &mount_stat) != 0) + continue; + if (filename_stat.st_dev == mount_stat.st_rdev) { + fprintf(stderr, "device: %s; name: %s; type: %s\n", device, name, + type); + } + } + */ + free(statDrives); + return result; } void os_initialize() { -- Gitblit v1.9.1