// Netlink.cpp #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define NETLINK_KOBJECT_UEVENT 15 /* Kernel messages to userspace */ struct sDevice { std::string strName; bool bActive; bool bMedia; int fd; }; std::vector vDevices; int main(int argc, char** argv) { char buffer[1024]; struct sDevice sDev; std::vector::iterator it; for (char c = 'a'; c <= 'h'; ++c) { sDev.strName = "/dev/sd"; sDev.strName += c; sDev.bActive = false; sDev.bMedia = false; sDev.fd = -1; vDevices.push_back(sDev); } // Open netlink socket int fd; fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); if (fd < 0) { printf ("Cannot create netlink socket\n"); return -1; } // Bind netlink socket struct sockaddr_nl addr; memset(&addr, 0, sizeof(addr)); addr.nl_family = AF_NETLINK; addr.nl_pid = getpid(); addr.nl_groups = 1; if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("Cannot bind netlink socket\n"); return -1; } // Listen netlink socket fd_set fds; struct timeval tv; for (;;) { FD_ZERO (&fds); FD_SET (fd, &fds); tv.tv_sec = 0; tv.tv_usec = 100000; while ((select(FD_SETSIZE, &fds, NULL, NULL, &tv)) > 0) { int status = read(fd, buffer, sizeof(buffer)-1); if (status > 0) { buffer[status] = 0; // null terminate std::string sMessage; sMessage = buffer; if ((sMessage.substr(0, 4) == "add@") && (sMessage.size() == 14)) { for (it = vDevices.begin(); it != vDevices.end(); ++it) { // Add device if (sMessage.substr(11, 3) == (*it).strName.substr(5, 3)) { printf ("%s added\n", (*it).strName.c_str()); (*it).bActive = true; (*it).bMedia = false; printf ("opening\n");; (*it).fd = open((*it).strName.c_str(), O_RDONLY | O_NONBLOCK); printf ("opened %d\n", (*it).fd); } } } else if ((sMessage.substr(0, 7) == "remove@") && (sMessage.size() == 17)) { for (it = vDevices.begin(); it != vDevices.end(); ++it) { // Remove device if (sMessage.substr(14, 3) == (*it).strName.substr(5, 3)) { printf ("%s removed\n", (*it).strName.c_str()); (*it).bActive = false; (*it).bMedia = false; printf ("closing %d\n", (*it).fd); close ((*it).fd); printf ("closed\n"); } } } } } } }