1 #include "wvistreamlist.h"
2 #include "wvstreamclone.h"
4 #include "wvstringlist.h"
5 #include "unifiltergen.h"
6 #include "wvstrutils.h"
7 #include "wvtclstring.h"
11 class WvSuperStackStream
: public WvStreamClone
17 WvSuperStackStream(IWvStream
*s
)
19 log("SuperStack >> ", WvLog::Debug2
),
20 inlog("SuperStack << ", WvLog::Debug2
)
22 const char setupstr
[] = {0xff, 0xfb, 3, 0};
23 print("%s", setupstr
); // telnet initiation sequence
24 print("\r\n", setupstr
);
32 time_t timeout
= 10000;
33 while (isok() && select(timeout
, true, false))
37 len
= read(buf
, sizeof(buf
));
40 inlog
.write(buf
, len
);
43 size_t used
= in
.used();
46 const unsigned char *cptr
= in
.get(used
);
47 if (!memcmp(cptr
+used
-2, ": ", 2))
48 timeout
= 200; // a prompt!
54 WvString
_cmd(WvStringParm c
)
62 WvString
cmd(WvStringParm c
)
71 WvString
cmd(WVSTRING_FORMAT_DECL
)
72 { return cmd(WvString(WVSTRING_FORMAT_CALL
)); }
74 void login(WvStringParm user
, WvStringParm pass
)
82 class SuperStackGen
: public UniFilterGen
89 SuperStackGen(IUniConfGen
*gen
, IWvStream
*conn
,
90 WvStringParm user
, WvStringParm pass
)
91 : UniFilterGen(gen
), log("SuperStackGen", WvLog::Info
),
94 refreshed_once
= false;
95 WvIStreamList::globallist
.append(&s
, false);
98 // refresh the inner whether *we* get refreshed or not
105 WvIStreamList::globallist
.unlink(&s
);
108 virtual void set(const UniConfKey
&key
, WvStringParm value
);
109 virtual bool refresh();
113 static IUniConfGen
*creator(WvStringParm s
, IObject
*, void *)
115 WvConstInPlaceBuf
buf(s
, s
.len());
116 IUniConfGen
*gen
= wvcreate
<IUniConfGen
>(wvtcl_getword(buf
));
117 IWvStream
*conn
= wvcreate
<IWvStream
>(wvtcl_getword(buf
));
118 WvString user
= wvtcl_getword(buf
), pass
= wvtcl_getword(buf
);
120 return new SuperStackGen(gen
, conn
, user
, pass
);
123 static WvMoniker
<IUniConfGen
> reg("vlan", creator
);
127 void SuperStackGen::set(const UniConfKey
&_key
, WvStringParm value
)
129 UniConfKey
key(_key
); // non-const
130 WvString
vlan(key
.pop());
132 if (key
.pop() == "ports")
134 WvString port
= key
.pop();
135 if (key
.pop() == "tagging")
137 WvString oldvalue
= inner()->get(_key
);
140 if (!value
&& !!oldvalue
)
141 s
.cmd("bridge vlan removePort %s %s", vlan
, port
);
142 else if (!oldvalue
|| !!strcasecmp(value
, oldvalue
))
144 s
.cmd("bridge vlan removePort %s %s", vlan
, port
);
145 if (!strcasecmp(value
, "802.1q"))
147 else if (!strcasecmp(value
, "none"))
150 s
.cmd("bridge vlan addPort %s %s %s", vlan
, port
, type
);
155 inner()->set(_key
, type
);
161 bool SuperStackGen::refresh()
163 // refreshing is super slow, so ignore any requests to do it more than
167 refreshed_once
= true;
169 inner()->set("/", WvString::null
);
172 vlans
.split(s
.cmd("bridge vlan summary all"), "\n");
173 WvStringList::Iter
vlan(vlans
);
174 for (vlan
.rewind(); vlan
.next(); )
178 if (sscanf(*vlan
, " %d %d %80s", &num
, &local
, name
) == 3)
180 log("Found vlan: vlan=%s, local=%s, name='%s'\n",
182 inner()->set(WvString("%s/name", num
), name
);
186 for (int port
= 1; port
<= 24; port
++)
189 char name
[81], tagging
[81];
193 tags
.split(s
.cmd("bridge port detail %s", port
), "\r\n");
194 WvStringList::Iter
tag(tags
);
195 for (tag
.rewind(); tag
.next(); )
197 if (sscanf(*tag
, "%d %d %80s %80s ",
198 &id
, &local
, name
, tagging
) == 4)
200 const char *cptr
= strrchr(*tag
, ' ');
204 tagstr
= trim_string(tagstr
.edit());
208 log("Port#%s is on vlan #%s (%s) using '%s' tagging\n",
209 port
, id
, name
, tagstr
);
210 inner()->set(WvString("%s/ports/%s/tagging", id
, port
),