#include #include #include #include #include #include #include "devfsd.h" /* The following header is for struct devfsd_notify_struct */ #include static int realsymlink(char *arg1, char *arg2) { char src[MAXPATHLEN + 1], dst[MAXPATHLEN + 1]; struct stat buf; snprintf(src, sizeof(src), "/dev/%s", arg2); src[MAXPATHLEN] = '\0'; snprintf(dst, sizeof(dst), "/dev/%s", arg1); dst[MAXPATHLEN] = '\0'; if(lstat(dst, &buf)) { SYSLOG(LOG_ERR, "Link destination \"%s\" doesn't exist.", dst); return -1; } if(symlink(dst, src)) { SYSLOG(LOG_ERR, "Link \"%s\" to \"%s\" gives error %m.", src, dst); return -1; } SYSLOG(LOG_INFO, "Link \"%s\" to \"%s\" success!", src, dst); return 0; } int mysymlink(int argc, char **argv) { if(argc != 3) { SYSLOG(LOG_ERR, "Need two params for link not %d.", argc); return -1; } return realsymlink(argv[1], argv[2]); } static int realunlink(const char *arg) { struct stat buf; char name[MAXPATHLEN + 1]; snprintf(name, sizeof(name), "/dev/%s", arg); name[MAXPATHLEN] = '\0'; if(lstat(name, &buf)) { SYSLOG(LOG_ERR, "Can't stat \"%s\" for unlink.", name); return -1; } if(!S_ISLNK(buf.st_mode)) { SYSLOG(LOG_ERR, "Trying to unlink non-link \"%s\".", name); return -1; } if(unlink(name)) { SYSLOG(LOG_ERR, "Unlink of \"%s\" gives error %m.", name); return -1; } SYSLOG(LOG_INFO, "Unlink of \"%s\" success!", name); return 0; } int myunlink(int argc, char **argv) { if(argc != 2) { SYSLOG(LOG_ERR, "Need one param for unlink not %d.", argc); return -1; } return realunlink(argv[1]); } int mfunctest(int argc, char **argv) { char buf[1024]; int i; if(argv[1]) strcpy(buf, argv[1]); for(i = 2; argv[i]; i++) { strcat(buf, ":"); strcat(buf, argv[i]); } SYSLOG(LOG_ERR, "mfunctest:%s", buf); return 0; } static int isevent(void *arg) { struct devfsd_notify_struct *e; if(!arg) return 0; e = arg; if(e->type > DEVFSD_NOTIFY_MAX || e->type < 0 || e->namelen >= DEVFS_PATHLEN || e->namelen <= 0) { /* Must be a string not an event */ return 0; } return 1; } int cfdolink(void *arg1, void *arg2, void *arg3, void *arg4, void *arg5) { char src[MAXPATHLEN + 1], dst[MAXPATHLEN + 1]; struct stat buf; struct devfsd_notify_struct *e; char *args[4]; int num_args, rc = 0; if(!isevent(arg1)) { SYSLOG(LOG_ERR, "cfdolink() first param must be event."); return -1; } e = arg1; args[0] = arg2; args[1] = arg3; args[2] = arg4; args[3] = arg5; for(num_args = 0; num_args < 4 && args[num_args]; num_args++) { if(isevent(args[num_args])) { SYSLOG(LOG_ERR, "Only the first cfdolink() param should be an event."); return -1; } } if(num_args == 0) { SYSLOG(LOG_ERR, "Must specify at least one link name for cfdolink()."); return -1; } switch(e->type) { case DEVFSD_NOTIFY_REGISTERED: for(num_args--; num_args >= 0; num_args--) rc |= realsymlink(e->devname, args[num_args]); break; case DEVFSD_NOTIFY_UNREGISTERED: for(num_args--; num_args >= 0; num_args--) rc |= realunlink(args[num_args]); break; default: break; } return rc; } static void log_event(void *arg, char *name) { const char *tname; struct devfsd_notify_struct *e; if(!isevent(arg)) { /* Must be a string not an event */ SYSLOG(LOG_INFO, "event %s, val:%s", name, arg); return; } e = arg; switch(e->type) { case DEVFSD_NOTIFY_REGISTERED: tname = "registered"; break; case DEVFSD_NOTIFY_UNREGISTERED: tname = "unregistered"; break; case DEVFSD_NOTIFY_ASYNC_OPEN: tname = "async_open"; break; case DEVFSD_NOTIFY_CLOSE: tname = "close"; break; case DEVFSD_NOTIFY_LOOKUP: tname = "lookup"; break; case DEVFSD_NOTIFY_CHANGE: tname = "change"; break; case DEVFSD_NOTIFY_CREATE: tname = "create"; break; default: tname = "unknown"; } if(e->overrun_count) SYSLOG(LOG_INFO, "devfsd lost %d events", e->overrun_count); SYSLOG(LOG_INFO , "event %s, type:%s, mode:%o, maj/min:%d:%d, uid:%d, gid:%d, name:%s" , name, tname, e->mode, e->major, e->minor, e->uid, e->gid, e->devname); } int cfunctest(void *arg1, void *arg2, void *arg3, void *arg4, void *arg5) { if(arg1) { log_event(arg1, "arg1"); if(arg2) { log_event(arg2, "arg2"); if(arg3) { log_event(arg3, "arg3"); if(arg4) { log_event(arg4, "arg4"); if(arg5) log_event(arg5, "arg5"); } } } } return 0; }