📄 cardctl.c
字号:
int i, ret; cs_status_t status; config_info_t config; ret = 0; switch (cmd) { case C_STATUS: for (i = 0; i < 4; i++) { status.Function = i; if (ioctl(fd, DS_GET_STATUS, &status) == 0) print_status(&status); else { if (i == 0) { if (errno == ENODEV) printf(" no card\n"); else perror("ioctl()"); } break; } } break; case C_CONFIG: for (i = 0; i < 4; i++) { config.Function = i; if (ioctl(fd, DS_GET_CONFIGURATION_INFO, &config) == 0) print_config(&config); else { if (i == 0) printf(" not configured\n"); break; } print_windows(fd); } break; case C_IDENT: print_ident(fd); break; case C_SUSPEND: ret = ioctl(fd, DS_SUSPEND_CARD); break; case C_RESUME: ret = ioctl(fd, DS_RESUME_CARD); break; case C_RESET: ret = ioctl(fd, DS_RESET_CARD); break; case C_EJECT: ret = ioctl(fd, DS_EJECT_CARD); break; case C_INSERT: ret = ioctl(fd, DS_INSERT_CARD); break; } return ret;}/*====================================================================== A utility function to scan /var/run/stab and apply a specified action to each device, in turn. If any command returns a non-zero exit code, execute() returns -1. ======================================================================*/typedef struct stab_t { int status; char class[33]; char dev[33];} stab_t;static stab_t stab[256];static int nstab;static int fetch_stab(void){ char s[133]; FILE *f; f = fopen(stabfile, "r"); if (f == NULL) return -1; for (nstab = 0; fgets(s, 132, f); ) { if (s[0] != 'S') { sscanf(s, "%*d\t%s\t%*s\t%*d\t%s", stab[nstab].class, stab[nstab].dev); stab[nstab].status = 0; nstab++; } } fclose(f); return 0;}static int execute(stab_t *s, char *action, char *scheme){ int ret; char cmd[133]; if (scheme) sprintf(cmd, "./%s %s %s %s", s->class, action, s->dev, scheme); else sprintf(cmd, "./%s %s %s", s->class, action, s->dev); ret = system(cmd); if (!WIFEXITED(ret) || WEXITSTATUS(ret)) return -1; return 0;}static int stop_scheme(char *new){ int i; fprintf(stderr, "checking:"); for (i = 0; i < nstab; i++) { fprintf(stderr, " %s", stab[i].dev); stab[i].status = execute(stab+i, "cksum", new); if (stab[i].status && (execute(stab+i, "check", NULL) != 0)) break; } fprintf(stderr, "\n"); if (i < nstab) { fprintf(stderr, "Device '%s' busy: scheme unchanged.\n", stab[i].dev); return -1; } for (i = 0; i < nstab; i++) if (stab[i].status) execute(stab+i, "stop", NULL); return 0;}static int start_scheme(void){ int i, j = 0; for (i = 0; i < nstab; i++) if (stab[i].status) j |= execute(stab+i, "start", NULL); return j;}/*====================================================================== do_scheme() is in charge of checking and updating the current PCMCIA configuration scheme. The current scheme is kept in a file, /var/run/pcmcia-scheme. When updating the scheme, we first stop all PCMCIA devices, then update the scheme, then restart. ======================================================================*/static int do_scheme(char *new){ FILE *f; char old[33]; int i; f = fopen(scheme, "r"); if (f && fgets(old, 32, f)) old[strlen(old)-1] = '\0'; else old[0] = '\0'; if (f) fclose(f); if (new) {#ifndef UNSAFE_TOOLS if (getuid() != 0) { fprintf(stderr, "Only root can select a new scheme.\n"); return -1; }#else setuid(geteuid());#endif /* Sanity checks... */ for (i = 0; i < strlen(new); i++) if (!isalnum(new[i])) break; if ((i != strlen(new)) || (strlen(new) < 1) || (strlen(new) > 32)) { fprintf(stderr, "Bad scheme name.\n"); return -1; } if (strcmp(old, new) == 0) { fprintf(stderr, "Scheme unchanged.\n"); return 0; } if (chdir(configpath) != 0) { fprintf(stderr, "Could not change to %s.\n", configpath); return -1; } /* Shut down devices in old scheme */ if ((fetch_stab() == 0) && (stop_scheme(new) != 0)) return -1; /* Update scheme state */ if (old[0]) printf("Changing scheme from '%s' to '%s'...\n", old, new); else printf("Changing scheme to '%s'...\n", new); umask(022); f = fopen(scheme, "w"); if (f) { fprintf(f, "%s\n", new); fclose(f); } else perror("Could not set scheme."); /* Start up devices in new scheme */ if (start_scheme() != 0) fprintf(stderr, "Some devices did not start cleanly.\n"); } else { if (old[0]) printf("Current scheme: '%s'.\n", old); else printf("Current scheme: 'default'.\n"); } return 0;}/*====================================================================*/void usage(char *name){ int i; fprintf(stderr, "usage: %s command [socket #]\n", name); fprintf(stderr, " or %s [-c configpath] [-f scheme]" " [-s stab] scheme [name]\n", name); fprintf(stderr, " commands:"); for (i = 0; i < NCMD; i++) fprintf(stderr, " %s", cmdname[i]); fprintf(stderr, "\n"); exit(EXIT_FAILURE);}/*====================================================================*/#define MAX_SOCKS 8int main(int argc, char *argv[]){ int cmd, fd[MAX_SOCKS], ns, ret, i; int optch, errflg = 0; char *s, *opts = (getuid() == 0) ? "Vc:f:s:" : "V"; if (access("/var/lib/pcmcia", R_OK) == 0) { scheme = "/var/lib/pcmcia/scheme"; stabfile = "/var/lib/pcmcia/stab"; } else { scheme = "/var/run/pcmcia-scheme"; stabfile = "/var/run/stab"; } while ((optch = getopt(argc, argv, opts)) != -1) { switch (optch) { case 'V': fprintf(stderr, "cardctl version " CS_PKG_RELEASE "\n"); return 0; break; case 'c': configpath = strdup(optarg); break; case 'f': scheme = strdup(optarg); break; case 's': stabfile = strdup(optarg); break; default: errflg = 1; break; } } if (errflg || (argc == optind) || (argc > optind+2)) usage(argv[0]); if (geteuid() != 0) { fprintf(stderr, "cardctl must be setuid root\n"); exit(EXIT_FAILURE); } major = lookup_dev("pcmcia"); if (major < 0) { if (major == -ENODEV) fprintf(stderr, "no pcmcia driver in /proc/devices\n"); else perror("could not open /proc/devices"); exit(EXIT_FAILURE); } if (strcmp(argv[optind], "scheme") == 0) {#ifndef UNSAFE_TOOLS setuid(getuid());#endif if (do_scheme((argc == optind+1) ? NULL : argv[optind+1]) == 0) exit(EXIT_SUCCESS); else exit(EXIT_FAILURE); } for (cmd = 0; cmd < NCMD; cmd++) if (strcmp(argv[optind], cmdname[cmd]) == 0) break; if (cmd == NCMD) usage(argv[0]); ret = 0; if (argc == optind+2) { ns = strtol(argv[optind+1], &s, 0); if ((*argv[optind+1] == '\0') || (*s != '\0')) usage(argv[0]); fd[0] = open_sock(ns); if (fd[0] < 0) { perror("open_sock()"); exit(EXIT_FAILURE); }#ifndef UNSAFE_TOOLS setuid(getuid());#endif ret = do_cmd(fd[0], cmd); if (ret != 0) perror("ioctl()"); } else { for (ns = 0; ns < MAX_SOCKS; ns++) { fd[ns] = open_sock(ns); if (fd[ns] < 0) break; }#ifndef UNSAFE_TOOLS setuid(getuid());#endif if (ns == 0) { perror("open_sock()"); exit(EXIT_FAILURE); } for (ns = 0; (ns < MAX_SOCKS) && (fd[ns] >= 0); ns++) { if (cmd <= C_IDENT) printf("Socket %d:\n", ns); i = do_cmd(fd[ns], cmd); if ((i != 0) && (errno != ENODEV)) { perror("ioctl()"); ret = i; } } } if (ret != 0) exit(EXIT_FAILURE); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -