00001
00002
00003
00004
00005
00006 #include <linux/config.h>
00007 #include <linux/linkage.h>
00008 #include <linux/string.h>
00009
00010 #include <clidef.h>
00011 #include <cliservdef.h>
00012 #include <descrip.h>
00013 #include <ssdef.h>
00014 #include <system_data_cells.h>
00015 #include <linux/slab.h>
00016
00017
00018
00019 #define MAXSYMNAM 64
00020
00021 typedef struct symbol symbol;
00022
00023 struct symbol { symbol *next;
00024 int namelen;
00025 char name[MAXSYMNAM];
00026
00027
00028
00029 int svaluelen;
00030 char svalue[1];
00031 };
00032
00033 int add_sym(struct dsc_descriptor * sym, struct dsc$descriptor * val) {
00034 symbol * s = kmalloc(sizeof(symbol)+64, GFP_KERNEL);
00035 s->namelen=sym->dsc_w_length;
00036 s->svaluelen=val->dsc_w_length;
00037 memcpy(s->name,sym->dsc_a_pointer,sym->dsc$w_length);
00038 memcpy(s->svalue,val->dsc_a_pointer,val->dsc$w_length);
00039 s->next=((symbol *)ctl_ag_clidata);
00040 ctl_ag_clidata=s;
00041 }
00042
00043 int mod_sym(symbol * sym, struct dsc_descriptor * val) {
00044 symbol * s = sym;
00045 s->svaluelen=val->dsc_w_length;
00046 memcpy(s->svalue,val->dsc_a_pointer,val->dsc$w_length);
00047 }
00048
00049 int find_sym(struct dsc_descriptor * sym) {
00050 symbol * tmp = ctl_ag_clidata;
00051 while (tmp) {
00052 #if 0
00053 printk("%d %d %s %s ", tmp->namelen, sym->dsc_w_length, sym->dsc$a_pointer,&tmp->name,tmp->namelen);
00054 #endif
00055 if (tmp->namelen==sym->dsc_w_length && 0==strncmp(sym->dsc$a_pointer,&tmp->name,tmp->namelen))
00056 return tmp;
00057 tmp=tmp->next;
00058 }
00059 return 0;
00060 }
00061
00062 int del_sym(struct dsc_descriptor * sym) {
00063 int a = find_sym(sym);
00064 if (a==0) return 0;
00065 symbol ** tmp = &ctl_ag_clidata;
00066 while (*tmp) {
00067 if ((*tmp)->namelen==sym->dsc_w_length && 0==strncmp(sym->dsc$a_pointer,&(*tmp)->name,(*tmp)->namelen))
00068 break;
00069 tmp=(*tmp);
00070 }
00071 void * tmp2=*tmp;
00072 *tmp=(*tmp)->next;
00073 kfree(tmp2);
00074 return 0;
00075 }
00076
00077 cre_or_mod_sym(struct dsc_descriptor * sym, struct dsc$descriptor * val) {
00078 symbol * s = find_sym(sym);
00079 if (s)
00080 mod_sym(s,val);
00081 else
00082 add_sym(sym,val);
00083 }
00084
00085 asmlinkage int exe_cli(void * cliv, int par1, int par2) {
00086 struct _clidef1 * cli = cliv;
00087 struct _clidef2 * cli2 = cliv;
00088 if (cli->cli_b_rqtype!=CLI$K_CLISERV) {
00089 printk("cli rqtype is not CLISERV\n");
00090 return 0;
00091 }
00092 switch (cli->cli_w_servcod) {
00093 case CLI_K_DEFLOCAL:
00094 cre_or_mod_sym(&cli2->cli_q_namdesc,&cli2->cli$q_valdesc);
00095 break;
00096 case CLI_K_CREALOG:
00097 break;
00098 case CLI_K_DELELOG:
00099 printk("no delete logical yet\n");
00100 break;
00101 case CLI_K_GETSYM:
00102 {
00103 symbol * s = find_sym(&cli2->cli_q_namdesc);
00104 if (s) {
00105 struct dsc_descriptor * d = &cli2->cli$q_valdesc;
00106 d->dsc_w_length=s->svaluelen;
00107 memcpy(d->dsc_a_pointer,s->svalue,d->dsc$w_length);
00108 } else
00109 return 0;
00110 }
00111 break;
00112 case CLI_K_DELELCL:
00113 del_sym(&cli2->cli_q_namdesc);
00114 break;
00115 default:
00116 printk("cli servcod %x not known\n",cli->cli_w_servcod);
00117 break;
00118 }
00119 return SS__NORMAL;
00120 }
00121