#include #include #include #include "test_wlan_proc_api.h" static inline int lower_ch(int ch) { if (ch >= 'A' && ch <= 'Z') return ch + 'a' - 'A'; return ch; } int ltq_strcmpi(char const *s1, char const *s2) { int c1, c2; if (!s1 || !s2) return 1; while (*s1 && *s2) { /*same length */ c1 = lower_ch(*s1); c2 = lower_ch(*s2); s1++; s2++; if (c1 != c2) return c1 - c2; } return *s1 - *s2; } #if 0 EXPORT_SYMBOL(ltq_strcmpi); #endif int ltq_strncmpi(const char *s1, const char *s2, size_t n) { int c1, c2; if (!s1 || !s2) return 1; for (; n > 0; s1++, s2++, --n) { c1 = lower_ch(*s1); c2 = lower_ch(*s2); if (c1 != c2) return c1 - c2; else if (c1 == '\0') return 0; } return 0; } #if 0 EXPORT_SYMBOL(ltq_strncmpi); #endif #if 0 char *ltq_strstri(char *string, char *substring) { register char *a, *b; /* First scan quickly through the two strings looking for a * single-character match. When it's found, then compare the * rest of the substring. */ if (!string || !substring) return (char *)0; b = substring; if (*b == 0) return string; for (; *string != 0; string += 1) { if (lower_ch(*string) != lower_ch(*b)) continue; a = string; while (1) { if (*b == 0) return string; if (lower_ch(*a++) != lower_ch(*b++)) break; } b = substring; } return (char *)0; } EXPORT_SYMBOL(ltq_strstri); #endif void ltq_replace_ch(char *p, int len, char orig_ch, char new_ch) { int i; if (p) for (i = 0; i < len; i++) { if (p[i] == orig_ch) p[i] = new_ch; } } #if 0 EXPORT_SYMBOL(ltq_replace_ch); #endif static unsigned int btoi(char *str) { unsigned int sum = 0; signed len = 0, i = 0; len = strlen(str); len = len - 1; while (len >= 0) { if (*(str + len) == '1') sum = (sum | (1 << i)); i++; len--; } return sum; } int ltq_atoi(unsigned char *str) { unsigned int n = 0; int i = 0; int nega_sign = 0; if (!str) return 0; ltq_replace_ch(str, strlen(str), ' ', 0); if (str[0] == 0) return 0; if (str[0] == 'b' || str[0] == 'B') { /*binary format */ n = btoi(str + 1); } else if ((str[0] == '0') && ((str[1] == 'x') || (str[1] == 'X'))) { /*hex format */ str += 2; while (str[i]) { n = n * 16; if (('0' <= str[i] && str[i] <= '9')) { n += str[i] - '0'; } else if (('A' <= str[i] && str[i] <= 'F')) { n += str[i] - 'A' + 10; ; } else if (('a' <= str[i] && str[i] <= 'f')) { n += str[i] - 'a' + 10; ; } else PRINTK(KERN_ERR "Wrong value:%u\n", str[i]); i++; } } else { if (str[i] == '-') { /*negative sign */ nega_sign = 1; i++; } while (str[i]) { n *= 10; n += str[i] - '0'; i++; } } if (nega_sign) n = -(int)n; return n; } #if 0 EXPORT_SYMBOL(ltq_atoi); #endif static void ltq_remove_leading_whitespace(char **p, int *len) { while (*len && ((**p == ' ') || (**p == '\r') || (**p == '\r'))) { (*p)++; (*len)--; } } /*Split buffer to multiple segment with seperator space. And put pointer to array[]. By the way, original buffer will be overwritten with '\0' at some place. */ int ltq_split_buffer(char *buffer, char *array[], int max_param_num) { int i, set_copy = 0; int res = 0; int len; for (i = 0; i < max_param_num; i++) array[i] = NULL; if (!buffer) return 0; len = strlen(buffer); for (i = 0; i < max_param_num;) { ltq_remove_leading_whitespace(&buffer, &len); for (; *buffer != ' ' && *buffer != '\0' && *buffer != '\r' && *buffer != '\n' && *buffer != '\t'; buffer++, len--) { /*Find first valid charactor */ set_copy = 1; if (!array[i]) array[i] = buffer; } if (set_copy == 1) { i++; if (*buffer == '\0' || *buffer == '\r' || *buffer == '\n') { *buffer = 0; break; } *buffer = 0; buffer++; len--; set_copy = 0; } else { if (*buffer == '\0' || *buffer == '\r' || *buffer == '\n') break; buffer++; len--; } } res = i; return res; } #if 0 EXPORT_SYMBOL(ltq_split_buffer); #endif static void *ltq_seq_start(struct seq_file *s, loff_t *pos) { struct ltq_proc_file_entry *p = s->private; if (p->pos < 0) return NULL; return p; } static void *ltq_seq_next(struct seq_file *s, void *v, loff_t *pos) { struct ltq_proc_file_entry *p = s->private; *pos = p->pos; if (p->pos >= 0) return p; else return NULL; } static void ltq_seq_stop(struct seq_file *s, void *v) { } static int ltq_seq_show(struct seq_file *s, void *v) { struct ltq_proc_file_entry *p = s->private; if (p->pos >= 0) p->pos = p->callback(s, p->pos); return 0; } static int ltq_proc_open(struct inode *inode, struct file *file); static const struct seq_operations dp_seq_ops = { .start = ltq_seq_start, .next = ltq_seq_next, .stop = ltq_seq_stop, .show = ltq_seq_show }; static int ltq_proc_open(struct inode *inode, struct file *file) { struct seq_file *s; struct ltq_proc_file_entry *p; struct ltq_proc_entry *entry; int ret; ret = seq_open(file, &dp_seq_ops); if (ret) return ret; s = file->private_data; p = (struct ltq_proc_file_entry *)kmalloc(sizeof(*p), GFP_KERNEL); if (!p) { (void)seq_release(inode, file); return -ENOMEM; } entry = PDE_DATA(inode); p->callback = entry->callback; if (entry->init_callback) p->pos = entry->init_callback(); else p->pos = 0; s->private = p; return 0; } static int ltq_proc_release(struct inode *inode, struct file *file) { struct seq_file *s; s = file->private_data; kfree(s->private); return seq_release(inode, file); } static int ltq_seq_single_show(struct seq_file *s, void *v) { struct ltq_proc_entry *p = s->private; p->single_callback(s); return 0; } static int ltq_proc_single_open(struct inode *inode, struct file *file) { return single_open(file, ltq_seq_single_show, PDE_DATA(inode)); } void ltq_proc_entry_create(struct proc_dir_entry *parent_node, struct ltq_proc_entry *proc_entry) { memset(&proc_entry->ops, 0, sizeof(struct file_operations)); proc_entry->ops.owner = THIS_MODULE; if (proc_entry->single_callback) { proc_entry->ops.open = ltq_proc_single_open; proc_entry->ops.release = single_release; } else { proc_entry->ops.open = ltq_proc_open; proc_entry->ops.release = ltq_proc_release; } proc_entry->ops.read = seq_read; proc_entry->ops.llseek = seq_lseek; proc_entry->ops.write = proc_entry->write_callback; proc_create_data(proc_entry->name, (S_IFREG | S_IRUGO), parent_node, &proc_entry->ops, proc_entry); } #if 0 /* FIXME */ EXPORT_SYMBOL(ltq_proc_entry_create); #endif