int printf(char *fmt , ...){ char str[50]; int index_f = 0; //跟随fmt赋值入str int index_s = 0; //跟随着str的位置标示 int insert = 0; //当有参数比如整数出现时转化为字符串,并记录插入的字符个数 int start = 0; int *p = &fmt; p += 1; while(1){ if(*(fmt + index_f) == 0x00){ str[index_s] = 0x00; sprintk(str + start); break; } if(*(fmt + index_f) == '%'){ index_f++; switch(*(fmt + index_f)){ case 'd': insert = itoa(*p , str + index_s); //将参数(整形)转化为字符串,并放入以str+index_s开头的串中 index_s += insert; //index_s需要加上插入的字符串个数insert p += 1; //p指向下一个参数地址 index_f++; //index_f指向fmt的下一个字符 break; case 'c': str[index_s] = (char)*p; p +=1; index_f++; index_s++; break; case 's': insert = strncpy(str + index_s , (char *)*p , 0); //*p为参数字符串的首地址 index_s += insert; p += 1; index_f++; break; default: break; } continue; } if(*(fmt + index_f) == '/'){ index_f++; switch(*(fmt + index_f)){ case 'n': str[index_s] = 0x00; //出现转义字符时,输出之前的部分 sprintk(str + start); index_s++; //重新设置index_s为输出后的部分 start = index_s; //start也要做相应设定 print_ctrl(); //输出回车 index_f++; break; case 't': break; default: break; } continue; } str[index_s] = *(fmt + index_f); index_f++; index_s++; } return index_s; }
static int print_ctrl2(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) { return print_ctrl(who, NULL, n, arg); }
static int ctrl_list(int cmd, int argc, char **argv) { struct rtnl_handle rth; struct nlmsghdr *nlh; struct genlmsghdr *ghdr; int ret = -1; char d[GENL_NAMSIZ]; struct { struct nlmsghdr n; char buf[4096]; } req; memset(&req, 0, sizeof(req)); nlh = &req.n; nlh->nlmsg_len = NLMSG_LENGTH(GENL_HDRLEN); nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; nlh->nlmsg_type = GENL_ID_CTRL; ghdr = NLMSG_DATA(&req.n); ghdr->cmd = CTRL_CMD_GETFAMILY; if (rtnl_open_byproto(&rth, 0, NETLINK_GENERIC) < 0) { fprintf(stderr, "Cannot open generic netlink socket\n"); exit(1); } if (cmd == CTRL_CMD_GETFAMILY) { if (argc != 2) { fprintf(stderr, "Wrong number of params\n"); return -1; } if (matches(*argv, "name") == 0) { NEXT_ARG(); strncpy(d, *argv, sizeof (d) - 1); addattr_l(nlh, 128, CTRL_ATTR_FAMILY_NAME, d, strlen(d) + 1); } else if (matches(*argv, "id") == 0) { __u16 id; NEXT_ARG(); if (get_u16(&id, *argv, 0)) { fprintf(stderr, "Illegal \"id\"\n"); goto ctrl_done; } addattr_l(nlh, 128, CTRL_ATTR_FAMILY_ID, &id, 2); } else { fprintf(stderr, "Wrong params\n"); goto ctrl_done; } if (rtnl_talk(&rth, nlh, 0, 0, nlh) < 0) { fprintf(stderr, "Error talking to the kernel\n"); goto ctrl_done; } if (print_ctrl(NULL, nlh, (void *) stdout) < 0) { fprintf(stderr, "Dump terminated\n"); goto ctrl_done; } } if (cmd == CTRL_CMD_UNSPEC) { nlh->nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST; nlh->nlmsg_seq = rth.dump = ++rth.seq; if (rtnl_send(&rth, nlh, nlh->nlmsg_len) < 0) { perror("Failed to send dump request\n"); goto ctrl_done; } rtnl_dump_filter(&rth, print_ctrl, stdout); } ret = 0; ctrl_done: rtnl_close(&rth); return ret; }