pwmc: add --sign-key-file and ".set sign-keyfile".
[libpwmd.git] / doc / tutorial.html
blob939ffa9c12af8e702543c24fc4767886fe0e941c
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
2 <HTML
3 ><HEAD
4 ><TITLE
5 >Libpwmd Tutorial</TITLE
6 ><META
7 NAME="GENERATOR"
8 CONTENT="Modular DocBook HTML Stylesheet Version 1.79"></HEAD
9 ><BODY
10 CLASS="ARTICLE"
11 ><DIV
12 CLASS="ARTICLE"
13 ><DIV
14 CLASS="TITLEPAGE"
15 ><H1
16 CLASS="TITLE"
17 ><A
18 NAME="AEN2"
19 >Libpwmd Tutorial</A
20 ></H1
21 ><H3
22 CLASS="AUTHOR"
23 ><A
24 NAME="AEN5"
25 ></A
26 ></H3
27 ><HR></DIV
28 ><DIV
29 CLASS="SECT1"
30 ><H2
31 CLASS="SECT1"
32 ><A
33 NAME="AEN9"
34 >Introduction</A
35 ></H2
36 ><P
37 >This is a tutorial showing the basic usage of libpwmd<A
38 NAME="AEN12"
39 HREF="#FTN.AEN12"
40 ><SPAN
41 CLASS="footnote"
42 >[2]</SPAN
43 ></A
44 >. Libpwmd<SPAN
45 CLASS="emphasis"
46 ><I
47 CLASS="EMPHASIS"
48 > </I
49 ></SPAN
50 >is a library making it easy for applications to use pwmd<A
51 NAME="AEN15"
52 HREF="#FTN.AEN15"
53 ><SPAN
54 CLASS="footnote"
55 >[3]</SPAN
56 ></A
57 > (<SPAN
58 CLASS="emphasis"
59 ><I
60 CLASS="EMPHASIS"
61 >Password Manager Daemon). Password Manager Daemon</I
62 ></SPAN
63 > is a universal data server. It began as a way to keep track of my passwords for accounts like email and websites but can be used to store anything you want.</P
64 ><P
65 >There are other password management tools but pwmd has a couple of distinguishing features:</P
66 ><P
67 ></P
68 ><UL
69 ><LI
70 ><P
71 >It does not depend on a desktop environment but has the ability for applications to connect to it like a desktop solution provides.</P
72 ></LI
73 ><LI
74 ><P
75 >Some portion of a stored data can be shared with another portion in the same data file. This feature behaves a lot like a symbolic link on a file system, XML entities, or HTML targets if you're familiar with those, but implemented in a different way. This means less duplication of content. See <A
76 HREF="#SEC.LINKING-ELEMENTS-1"
77 >the Section called <I
78 >Linking elements</I
79 ></A
80 > for details.</P
81 ></LI
82 ><LI
83 ><P
84 >The XML document is encrypted with libgcrypt and can also use gpg-agent. Libgcrypt provides symmetric encryption while gpg-agent supports both PKI and smartcards.</P
85 ></LI
86 ></UL
87 ><P
88 >Other features include:</P
89 ><P
90 ></P
91 ><UL
92 ><LI
93 ><P
94 >Multi-threaded. More than one client may access the same data file while optionally locking out other clients.</P
95 ></LI
96 ><LI
97 ><P
98 >Secure memory management. Pwmd will zero out memory before freeing it and the contents of the cached document are encrypted.</P
99 ></LI
100 ><LI
102 >Remote connections over TLS with client certificates used as authentication.</P
103 ></LI
104 ><LI
106 >Remote connections over SSH.</P
107 ></LI
108 ></UL
109 ></DIV
110 ><DIV
111 CLASS="SECT1"
112 ><HR><H2
113 CLASS="SECT1"
115 NAME="AEN37"
116 >File Format and Element Paths</A
117 ></H2
119 >The document is saved as an XML document and is manipulated by commands sent from a client. Commands that access data take what is called an <SPAN
120 CLASS="emphasis"
122 CLASS="EMPHASIS"
123 >element path</I
124 ></SPAN
125 > as an argument. An element path is a character string containing XML element names representing branches of an element tree. The branches are separated with a TAB (ASCII 0x09) character. Why a TAB? So other characters can be used in the element name. If for example a '/' were used as the separator, then a URL (i.e., http://sf.net/) could not be used as an element name.</P
127 >For the rest of this tutorial, when you see &lt;TAB&gt;, replace it with a real TAB character. For example, the element path "root&lt;TAB&gt;child&lt;TAB&gt;last" has the following element tree:</P
128 ><TABLE
129 BORDER="0"
130 BGCOLOR="#E0E0E0"
131 WIDTH="100%"
132 ><TR
133 ><TD
134 ><PRE
135 CLASS="SCREEN"
136 >&#60;root&#62;
137 &#60;child&#62;
138 &#60;last&#62;
139 Content or XML CDATA of the "last" element.
140 &#60;/last&#62;
141 &#60;/child&#62;
142 &#60;/root&#62;</PRE
143 ></TD
144 ></TR
145 ></TABLE
147 >I should say that the XML structure that pwmd uses is a little more complicated. It really looks like the following internally, but we will use the above format in this tutorial for simplicity:</P
148 ><TABLE
149 BORDER="0"
150 BGCOLOR="#E0E0E0"
151 WIDTH="100%"
152 ><TR
153 ><TD
154 ><PRE
155 CLASS="SCREEN"
156 >&#60;element _name="root"&#62;
157 &#60;element _name="child"&#62;
158 &#60;element _name="last"&#62;
159 Content or CDATA of the "last" element.
160 &#60;/element&#62;
161 &#60;/element&#62;
162 &#60;/element&#62;</PRE
163 ></TD
164 ></TR
165 ></TABLE
167 >Every element created has an element named <SPAN
168 CLASS="emphasis"
170 CLASS="EMPHASIS"
171 >element</I
172 ></SPAN
173 > with an attribute <SPAN
174 CLASS="emphasis"
176 CLASS="EMPHASIS"
177 >_name</I
178 ></SPAN
179 > associated with it. The value of the <SPAN
180 CLASS="emphasis"
182 CLASS="EMPHASIS"
183 >_name</I
184 ></SPAN
185 > attribute is what an element in an element path refers to. It is done this way so that a wider range of characters can be used in an element name while maintaining valid XML. In fact the only restriction of an element name is that it not contain whitespace characters and not begin with an exclamation point (ASCII 0x21 or !). See <SPAN
186 CLASS="emphasis"
188 CLASS="EMPHASIS"
190 HREF="#SEC.LINKING-ELEMENTS-1"
191 >the Section called <I
192 >Linking elements</I
193 ></A
194 > </I
195 ></SPAN
196 >for an exception.</P
198 >There is one other difference from your normal XML document in that only the first match of an element is considered for the current element tree depth. When an element of the current depth of an element tree is found, the next element in the element path is searched for beginning at the child node of the found element. From the example above:</P
199 ><TABLE
200 BORDER="0"
201 BGCOLOR="#E0E0E0"
202 WIDTH="100%"
203 ><TR
204 ><TD
205 ><PRE
206 CLASS="SCREEN"
207 >&#60;root&#62;
208 &#60;child&#62;
209 &#60;last&#62;
210 Content or XML CDATA of the "last" element.
211 &#60;/last&#62;
212 &#60;/child&#62;
213 &#60;child&#62;
214 This element will never be reached.
215 &#60;/child&#62;
216 &#60;/root&#62;</PRE
217 ></TD
218 ></TR
219 ></TABLE
221 >The second "child" element is never reached.</P
222 ></DIV
223 ><DIV
224 CLASS="SECT1"
225 ><HR><H2
226 CLASS="SECT1"
228 NAME="AEN54"
229 >Connecting to PWMD</A
230 ></H2
232 >You will need a <SPAN
233 CLASS="emphasis"
235 CLASS="EMPHASIS"
236 >pwmd</I
237 ></SPAN
238 > client to send commands to the pwmd server. <SPAN
239 CLASS="emphasis"
241 CLASS="EMPHASIS"
242 >libpwmd</I
243 ></SPAN
244 > includes a client named <SPAN
245 CLASS="emphasis"
247 CLASS="EMPHASIS"
248 >pwmc</I
249 ></SPAN
250 >. It is command-line based and there are not any fancy graphics, but it is good for understanding how <SPAN
251 CLASS="emphasis"
253 CLASS="EMPHASIS"
254 >pwmd</I
255 ></SPAN
256 > commands are processed. If you want a more user friendly client that resembles a file manager and has a point and click interface, try QPwmc <A
257 NAME="AEN61"
258 HREF="#FTN.AEN61"
259 ><SPAN
260 CLASS="footnote"
261 >[4]</SPAN
262 ></A
263 > which uses the Qt4 toolkit and is also a full featured client.</P
265 >In this tutorial we will use the <SPAN
266 CLASS="emphasis"
268 CLASS="EMPHASIS"
269 >pwmc</I
270 ></SPAN
271 > client included with libpwmd. <SPAN
272 CLASS="emphasis"
274 CLASS="EMPHASIS"
275 >pwmc</I
276 ></SPAN
277 > has two modes that commands are read from: interactive and stdin. The interactive mode uses the readline library and has command history, while reading from standard input (stdin) makes shell scripting and automation easy. For the examples, we will be connecting to the default local unix domain socket that pwmd waits for connections on. Remote connections are possible over TLS or an SSH channel but those are not covered here. Read the pwmc(1) manual page for details about how to do that.</P
279 >The example filename we will use is "datafile". It is initially a non-existent file but it will be created once we have saved to it. Now let us connect to the server in interactive mode and open the data file:</P
280 ><TABLE
281 BORDER="0"
282 BGCOLOR="#E0E0E0"
283 WIDTH="100%"
284 ><TR
285 ><TD
286 ><PRE
287 CLASS="SCREEN"
288 >$ pwmc datafile
289 Connected.
290 pwm&#62;</PRE
291 ></TD
292 ></TR
293 ></TABLE
295 >The "pwm&gt;" prompt is a readline prompt that has command history and can do filename completion. It also is annoying because, as mentioned, elements in element paths are TAB delimited, but command completion in readline uses the TAB character, too. To insert a real TAB character in interactive mode rather than do readline completion, you will need to first press CTRL-V and then press TAB.</P
296 ></DIV
297 ><DIV
298 CLASS="SECT1"
299 ><HR><H2
300 CLASS="SECT1"
302 NAME="AEN69"
303 >Commands</A
304 ></H2
306 >There are two different types of commands: client commands and protocol commands. The client commands are <SPAN
307 CLASS="emphasis"
309 CLASS="EMPHASIS"
310 >pwmc</I
311 ></SPAN
312 > specific and only available to the <SPAN
313 CLASS="emphasis"
315 CLASS="EMPHASIS"
316 >pwmc</I
317 ></SPAN
318 > client. Protocol commands are commands sent from any client and to the <SPAN
319 CLASS="emphasis"
321 CLASS="EMPHASIS"
322 >pwmd</I
323 ></SPAN
324 > server. All pwmc client commands are prefixed with a dot '.' followed by the command name. Protocol commands are sent without any prefix. To see the available pwmc and protocol commands, send the HELP command:</P
325 ><TABLE
326 BORDER="0"
327 BGCOLOR="#E0E0E0"
328 WIDTH="100%"
329 ><TR
330 ><TD
331 ><PRE
332 CLASS="SCREEN"
333 >pwm&#62; .help</PRE
334 ></TD
335 ></TR
336 ></TABLE
338 >or</P
339 ><TABLE
340 BORDER="0"
341 BGCOLOR="#E0E0E0"
342 WIDTH="100%"
343 ><TR
344 ><TD
345 ><PRE
346 CLASS="SCREEN"
347 >pwm&#62; help</PRE
348 ></TD
349 ></TR
350 ></TABLE
352 >To store some data in an element path, you will need to know what element path to create. It is up to you how you want your data organized. If for example you will be storing account information it may be good to categorize what the account is for: email, instant messaging, blogging, etc. An application that uses libpwmd may require that a certain element path exists. Refer to that applications documentation to determine what element paths need to be created.</P
354 >In the following example we will setup mail server element paths which can be used for other applications requiring a mail server configuration. First, lets create the hostname element path:</P
355 ><TABLE
356 BORDER="0"
357 BGCOLOR="#E0E0E0"
358 WIDTH="100%"
359 ><TR
360 ><TD
361 ><PRE
362 CLASS="SCREEN"
363 >pwm&#62; STORE</PRE
364 ></TD
365 ></TR
366 ></TABLE
368 >The STORE command is a <SPAN
369 CLASS="emphasis"
371 CLASS="EMPHASIS"
372 >pwmd</I
373 ></SPAN
374 > protocol command. This and a few other commands, use what is called a <SPAN
375 CLASS="emphasis"
377 CLASS="EMPHASIS"
378 >server inquire</I
379 ></SPAN
380 > to retrieve data from the client while other commands retrieve the data only from the command arguments. The server inquire will wait for the client to finish sending its data before completing the command. When responding to a server inquire in pwmc, pwmc will show a message telling you that it is waiting for data to be sent. Enter the element path and its content, then press &lt;CTRL-D&gt; twice to finish sending the data and to let <SPAN
381 CLASS="emphasis"
383 CLASS="EMPHASIS"
384 >pwmd</I
385 ></SPAN
386 > complete the command:</P
387 ><TABLE
388 BORDER="0"
389 BGCOLOR="#E0E0E0"
390 WIDTH="100%"
391 ><TR
392 ><TD
393 ><PRE
394 CLASS="SCREEN"
395 >pwm&#62; STORE
396 email&#60;TAB&#62;isp&#60;TAB&#62;IMAP&#60;TAB&#62;hostname&#60;TAB&#62;imap.server.com&#60;CTRL-D&#62;&#60;CTRL-D&#62;</PRE
397 ></TD
398 ></TR
399 ></TABLE
401 >Remember that you should replace &lt;TAB&gt; in the examples with a real TAB character. It should be known that when sending data via a server inquire there is no need to press &lt;CTRL-V&gt; to insert the &lt;TAB&gt; character. That is only needed to be done from the readline command prompt and when not doing a server inquire.</P
403 >After pressing the first &lt;CTRL-D&gt;, the characters that were entered are sent to <SPAN
404 CLASS="emphasis"
406 CLASS="EMPHASIS"
407 >pwmd</I
408 ></SPAN
409 > and the inquire continues. To terminate the inquire and finish sending data for the command press &lt;CTRL-D&gt; a second time.</P
411 >If you were to have pressed &lt;RETURN&gt; before any &lt;CTRL-D&gt; then the inquired line would have been sent in full including a newline character. Since in this example a newline character in a hostname is not a valid hostname, this is not what we want.</P
413 >We have just created an element path whose XML structure looks like the following:</P
414 ><TABLE
415 BORDER="0"
416 BGCOLOR="#E0E0E0"
417 WIDTH="100%"
418 ><TR
419 ><TD
420 ><PRE
421 CLASS="SCREEN"
422 >&#60;email&#62;
423 &#60;isp&#62;
424 &#60;IMAP&#62;
425 &#60;hostname&#62;imap.server.com&#60;/hostname&#62;
426 &#60;/IMAP&#62;
427 &#60;/isp&#62;
428 &#60;/email&#62;</PRE
429 ></TD
430 ></TR
431 ></TABLE
433 >The GET protocol command returns the value, or content, of the last element of an element path. To retrieve the hostname of the element path we just created, do:</P
434 ><TABLE
435 BORDER="0"
436 BGCOLOR="#E0E0E0"
437 WIDTH="100%"
438 ><TR
439 ><TD
440 ><PRE
441 CLASS="SCREEN"
442 >pwm&#62; GET email&#60;TAB&#62;isp&#60;TAB&#62;IMAP&#60;TAB&#62;hostname
443 imap.server.com</PRE
444 ></TD
445 ></TR
446 ></TABLE
448 >Remember that in interactive mode and when not doing a server inquire, you will need to press &lt;CTRL-V&gt; before pressing &lt;TAB&gt;.</P
450 >Let us create the rest of the needed elements:</P
451 ><TABLE
452 BORDER="0"
453 BGCOLOR="#E0E0E0"
454 WIDTH="100%"
455 ><TR
456 ><TD
457 ><PRE
458 CLASS="SCREEN"
459 >pwm&#62; STORE
460 email&#60;TAB&#62;isp&#60;TAB&#62;IMAP&#60;TAB&#62;port&#60;TAB&#62;993&#60;CTRL-D&#62;&#60;CTRL-D&#62;
461 pwm&#62; STORE
462 email&#60;TAB&#62;isp&#60;TAB&#62;IMAP&#60;TAB&#62;ssl&#60;TAB&#62;1&#60;CTRL-D&#62;&#60;CTRL-D&#62;
463 pwm&#62; STORE
464 email&#60;TAB&#62;isp&#60;TAB&#62;username&#60;TAB&#62;myusername&#60;CTRL-D&#62;&#60;CTRL-D&#62;
465 pwm&#62; STORE
466 email&#60;TAB&#62;isp&#60;TAB&#62;password&#60;TAB&#62;mypassword&#60;CTRL-D&#62;&#60;CTRL-D&#62;</PRE
467 ></TD
468 ></TR
469 ></TABLE
471 >Now the element structure for the "email" element looks like this:</P
472 ><TABLE
473 BORDER="0"
474 BGCOLOR="#E0E0E0"
475 WIDTH="100%"
476 ><TR
477 ><TD
478 ><PRE
479 CLASS="SCREEN"
480 >&#60;email&#62;
481 &#60;isp&#62;
482 &#60;IMAP&#62;
483 &#60;hostname&#62;imap.server.com&#60;/hostname&#62;
484 &#60;port&#62;993&#60;/port&#62;
485 &#60;ssl&#62;1&#60;/ssl&#62;
486 &#60;/IMAP&#62;
487 &#60;username&#62;myusername&#60;/username&#62;
488 &#60;password&#62;mypassword&#60;/password&#62;
489 &#60;/isp&#62;
490 &#60;/email&#62;</PRE
491 ></TD
492 ></TR
493 ></TABLE
495 >If you wanted to change your password (after changing it on the mail server, of course) just do as you did when initially creating the password element path. The new content will overwrite the existing content:</P
496 ><TABLE
497 BORDER="0"
498 BGCOLOR="#E0E0E0"
499 WIDTH="100%"
500 ><TR
501 ><TD
502 ><PRE
503 CLASS="SCREEN"
504 >pwm&#62; STORE
505 email&#60;TAB&#62;isp&#60;TAB&#62;password&#60;TAB&#62;newpassword&#60;CTRL-D&#62;&#60;CTRL-D&#62;</PRE
506 ></TD
507 ></TR
508 ></TABLE
510 >An application using libpwmd that needs to know mail server information now has all the information it needs. The only thing left to do now is to save the changes:</P
511 ><TABLE
512 BORDER="0"
513 BGCOLOR="#E0E0E0"
514 WIDTH="100%"
515 ><TR
516 ><TD
517 ><PRE
518 CLASS="SCREEN"
519 >pwm&#62; &#60;CTRL-D&#62;</PRE
520 ></TD
521 ></TR
522 ></TABLE
524 >After pressing &lt;CTRL-D&gt; a prompt will be shown asking what to do next. Press &ldquo;s&rdquo; to save what we have created.</P
526 >Since this is a new file, you will be prompted for a passphrase to use for encryption. Once done, the data file is encrypted and written to disk and the passphrase is cached in pwmd so you do not need to enter it the next time your data file is opened or saved. There are a few pwmd configuration parameters and commands that affect how this operates. See the <SPAN
527 CLASS="emphasis"
529 CLASS="EMPHASIS"
530 >pwmd</I
531 ></SPAN
532 > documentation for details.</P
533 ></DIV
534 ><DIV
535 CLASS="SECT1"
536 ><HR><H2
537 CLASS="SECT1"
539 NAME="SEC.LINKING-ELEMENTS-1"
540 >Linking elements</A
541 ></H2
543 >One distinguishing feature of pwmd is the ability to share data of one element path with another. If for example your ISP lets you host a blog on their server and you use a blogging client that can use libpwmd for authentication details, you can share authentication information with the email example above when the account details are the same. When element linking is used, this avoids the need to change the content for both the blogging and email password elements.</P
545 >This is done by setting a special &ldquo;target&rdquo; attribute for an element. It behaves similarly to the HTML &ldquo;target&rdquo; attribute or XML entities or a symbolic link on a filesystem. </P
547 >Let's create an example blogging element path:</P
548 ><TABLE
549 BORDER="0"
550 BGCOLOR="#E0E0E0"
551 WIDTH="100%"
552 ><TR
553 ><TD
554 ><PRE
555 CLASS="SCREEN"
556 >pwm&#62; STORE
557 blog&#60;TAB&#62;isp&#60;TAB&#62;hostname&#60;TAB&#62;blog.myisp.com&#60;CTRL-D&#62;&#60;CTRL-D&#62;
559 pwm&#62; ATTR SET target blog&#60;TAB&#62;isp&#60;TAB&#62;username email&#60;TAB&#62;isp&#60;TAB&#62;username
560 pwm&#62; ATTR SET target blog&#60;TAB&#62;isp&#60;TAB&#62;password email&#60;TAB&#62;isp&#60;TAB&#62;password</PRE
561 ></TD
562 ></TR
563 ></TABLE
565 >Now each access of the "blog/isp/username" and "blog/isp/password" element paths, which were created if they did not already exist, will point to "email/isp/username" and "email/isp/password", respectively. To retrieve the value or content of an element that contains a "target" attribute without following any &ldquo;target&rdquo; attribute, prefix the element with a '!' when specifying it in an element path. For example:</P
566 ><TABLE
567 BORDER="0"
568 BGCOLOR="#E0E0E0"
569 WIDTH="100%"
570 ><TR
571 ><TD
572 ><PRE
573 CLASS="SCREEN"
574 >pwm&#62; GET blog&#60;TAB&#62;isp&#60;TAB&#62;!password
575 ERR 536870938: No value</PRE
576 ></TD
577 ></TR
578 ></TABLE
580 >An error is returned because we have not assigned a value to the literal element. A literal element is an element that either contains no "target" attribute or ignores it by prefixing the element with the mentioned literal element character '!'. Let us try storing an example password to the literal element to show usage:</P
581 ><TABLE
582 BORDER="0"
583 BGCOLOR="#E0E0E0"
584 WIDTH="100%"
585 ><TR
586 ><TD
587 ><PRE
588 CLASS="SCREEN"
589 >pwmd&#62; STORE
590 blog&#60;TAB&#62;isp&#60;TAB&#62;!password&#60;TAB&#62;literalpassword&#60;CTRL-D&#62;&#60;CTRL-D&#62;</PRE
591 ></TD
592 ></TR
593 ></TABLE
595 >Now when we redo the previous GET command:</P
596 ><TABLE
597 BORDER="0"
598 BGCOLOR="#E0E0E0"
599 WIDTH="100%"
600 ><TR
601 ><TD
602 ><PRE
603 CLASS="SCREEN"
604 >pwm&#62; GET blog&#60;TAB&#62;isp&#60;TAB&#62;!password
605 literalpassword</PRE
606 ></TD
607 ></TR
608 ></TABLE
610 >This is the value of the literal password element of the element path. To follow the element path stored in the "target" attribute, omit the '!' in the password element. This will return the &ldquo;email/isp/password&rdquo; element content:</P
611 ><TABLE
612 BORDER="0"
613 BGCOLOR="#E0E0E0"
614 WIDTH="100%"
615 ><TR
616 ><TD
617 ><PRE
618 CLASS="SCREEN"
619 >pwm&#62; GET blog&#60;TAB&#62;isp&#60;TAB&#62;password
620 mypassword</PRE
621 ></TD
622 ></TR
623 ></TABLE
625 >A "target" attribute may also refer to another element with a "target" attribute. Every "target" attribute will be followed until there are no others to resolve. To get the real element path and resolve all "target" attributes, use the REALPATH command:</P
626 ><TABLE
627 BORDER="0"
628 BGCOLOR="#E0E0E0"
629 WIDTH="100%"
630 ><TR
631 ><TD
632 ><PRE
633 CLASS="SCREEN"
634 >pwm&#62; REALPATH blog&#60;TAB&#62;isp&#60;TAB&#62;password
635 !email&#60;TAB&#62;!isp&#60;TAB&#62;!password</PRE
636 ></TD
637 ></TR
638 ></TABLE
640 >As you can see each element is prefixed with the literal '!' character meaning that no "target" attribute exists in any element of the resulting element path.</P
642 >Using the LIST command is useful to show the element structure of a document:</P
643 ><TABLE
644 BORDER="0"
645 BGCOLOR="#E0E0E0"
646 WIDTH="100%"
647 ><TR
648 ><TD
649 ><PRE
650 CLASS="SCREEN"
651 >pwm&#62; LIST
652 !email
653 !blog
654 pwm&#62; LIST !email
655 !email
656 !email&#60;TAB&#62;!isp
657 !email&#60;TAB&#62;!isp&#60;TAB&#62;!username
658 !email&#60;TAB&#62;!isp&#60;TAB&#62;!password
659 !email&#60;TAB&#62;!isp&#60;TAB&#62;!IMAP&#60;TAB&#62;!hostname
660 !email&#60;TAB&#62;!isp&#60;TAB&#62;!IMAP&#60;TAB&#62;!port
661 !email&#60;TAB&#62;!isp&#60;TAB&#62;!IMAP&#60;TAB&#62;!ssl
662 pwm&#62; LIST !blog
663 !blog
664 !blog&#60;TAB&#62;!isp
665 !blog&#60;TAB&#62;!isp&#60;TAB&#62;!username
666 !blog&#60;TAB&#62;!isp&#60;TAB&#62;username
667 !blog&#60;TAB&#62;!isp&#60;TAB&#62;!password
668 !blog&#60;TAB&#62;!isp&#60;TAB&#62;password</PRE
669 ></TD
670 ></TR
671 ></TABLE
673 >Notice that there are two username and password elements in the &ldquo;blog&rdquo; element path: each with and without the literal element character prefix. This shows that both the username and password elements contain a "target" attribute.</P
675 >For the final example, we will remove the &ldquo;target&rdquo; attribute of the blogging password element:</P
676 ><TABLE
677 BORDER="0"
678 BGCOLOR="#E0E0E0"
679 WIDTH="100%"
680 ><TR
681 ><TD
682 ><PRE
683 CLASS="SCREEN"
684 >pwm&#62; ATTR DELETE target blog&#60;TAB&#62;isp&#60;TAB&#62;!password</PRE
685 ></TD
686 ></TR
687 ></TABLE
689 >If we were to have omitted the '!' from the password element then pwmd would try to remove the "target" attribute from the "email/isp/password" element path. That would return an error because no &ldquo;target&rdquo; attribute had been set for that element.</P
691 >Note that the "blog" and "isp" elements have no literal element character prepended to them in the example. It is not needed because they have no &ldquo;target&rdquo; attribute themselves.</P
693 >Using &ldquo;target&rdquo; attributes can be confusing. The best way to get the hang of linking elements is to experiment and use the LIST and DUMP commands to show the document structure. Remember to use the literal element prefix '!' when you do not want to follow any "target" attributes.</P
694 ></DIV
695 ></DIV
696 ><H3
697 CLASS="FOOTNOTES"
698 >Notes</H3
699 ><TABLE
700 BORDER="0"
701 CLASS="FOOTNOTES"
702 WIDTH="100%"
703 ><TR
704 ><TD
705 ALIGN="LEFT"
706 VALIGN="TOP"
707 WIDTH="5%"
709 NAME="FTN.AEN6"
710 HREF="#AEN6"
711 ><SPAN
712 CLASS="footnote"
713 >[1]</SPAN
714 ></A
715 ></TD
716 ><TD
717 ALIGN="LEFT"
718 VALIGN="TOP"
719 WIDTH="95%"
720 ><FONT
721 COLOR="RED"
722 >bjk@luxsci.net</FONT
723 ></TD
724 ></TR
725 ><TR
726 ><TD
727 ALIGN="LEFT"
728 VALIGN="TOP"
729 WIDTH="5%"
731 NAME="FTN.AEN12"
732 HREF="#AEN12"
733 ><SPAN
734 CLASS="footnote"
735 >[2]</SPAN
736 ></A
737 ></TD
738 ><TD
739 ALIGN="LEFT"
740 VALIGN="TOP"
741 WIDTH="95%"
742 ><FONT
743 COLOR="RED"
744 >http://libpwmd.sourceforge.net/</FONT
745 ></TD
746 ></TR
747 ><TR
748 ><TD
749 ALIGN="LEFT"
750 VALIGN="TOP"
751 WIDTH="5%"
753 NAME="FTN.AEN15"
754 HREF="#AEN15"
755 ><SPAN
756 CLASS="footnote"
757 >[3]</SPAN
758 ></A
759 ></TD
760 ><TD
761 ALIGN="LEFT"
762 VALIGN="TOP"
763 WIDTH="95%"
764 ><FONT
765 COLOR="RED"
766 >http://pwmd.sourceforge.net/</FONT
767 ></TD
768 ></TR
769 ><TR
770 ><TD
771 ALIGN="LEFT"
772 VALIGN="TOP"
773 WIDTH="5%"
775 NAME="FTN.AEN61"
776 HREF="#AEN61"
777 ><SPAN
778 CLASS="footnote"
779 >[4]</SPAN
780 ></A
781 ></TD
782 ><TD
783 ALIGN="LEFT"
784 VALIGN="TOP"
785 WIDTH="95%"
786 ><FONT
787 COLOR="RED"
788 >http://qpwmc.sourceforge.net/</FONT
789 ></TD
790 ></TR
791 ></TABLE
792 ></BODY
793 ></HTML