ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/docs/pws2004/freenet.mgp
Revision: 1.8
Committed: Sat Jul 3 01:37:09 2004 UTC (22 years, 3 months ago) by root
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 %include "std.mgp"
2     %%default 1 bimage "gtk/gtk-window.jpg" 1024x768, center
3     %page
4 root 1.5 %charset "iso8859-1"
5 root 1.7 %bimage "bg.png" 1280x1024
6 root 1.1
7     Freenet
8    
9 root 1.6
10    
11 root 1.1 "I worry about my child and the Internet all
12     the time, even though she's too young to have
13     logged on yet. Here's what I worry about. I
14     worry that 10 or 15 years from now, she will
15     come to me and say 'Daddy, where were you
16     when they took freedom of the press away from
17     the Internet?'"
18    
19     --Mike Godwin, Electronic Frontier Foundation
20    
21    
22     %center
23     %%image "gtk/hello31.jpg" 0 200 200 1
24    
25     %page
26    
27     Ziele
28    
29    
30 root 1.7
31    
32 root 1.1 Projekt, Dokumentation und Implementation frei und für jeden zugänglich
33     %pause
34    
35 root 1.7
36 root 1.1 Informationsfreiheit ohne Zensur
37     %pause
38    
39     garantiert anonyme Veröffentlichung
40     %pause
41    
42     garantierter Zugang zur Information
43    
44     %page
45    
46     Implementation
47    
48    
49 root 1.7
50    
51 root 1.1 virtuelles Netzwerk
52     %pause
53     Ausfall auch großer Teile des Netzes werden kompensiert
54    
55     %pause
56     einzelne Knoten
57     %pause
58     kennen die gespeicherten Daten nicht
59     %pause
60 root 1.3 können Datenverkehr anderer Knoten nicht lesen
61 root 1.1 %pause
62     kennen Sender und Empfänger von Daten nicht
63    
64    
65     %page
66    
67 root 1.3 Freenet aus "Benutzersicht"
68 root 1.1
69 root 1.6
70 root 1.1 %pause
71     Alle Daten werden in Datenblöcken (keys) organisiert
72 root 1.6
73 root 1.1 %pause
74     Keys werden in das Netzwerk "eingefügt"
75     %pause
76 root 1.6
77 root 1.1 Maximale Größe eines Datenblocks: 1MB
78     %pause
79 root 1.6
80 root 1.1 HTML-Seiten werden üblicherweise in einem Key gespeichert
81     %pause
82 root 1.6
83 root 1.3 Große Dateien werden mit forward error correction in kleinere Blöcke geteilt
84     %pause
85 root 1.1 Algorithm::FEC
86    
87    
88     %page
89    
90     Freenet-URLs
91    
92 root 1.6
93 root 1.1 Übliche Form eines Freenet-Links:
94    
95 root 1.6 %font "t4"
96     http://localhost:8888/
97     CHK@pfAv9IejYPXDguEkUhiNUMAwI,blzDbhN~q4JrfRWw
98     //Suffix
99 root 1.1 %font "s"
100    
101     %pause
102     http://localhost:8888/ nur der Pfad zum HTTP-Proxy des Knotens
103     %pause
104     CHK ist der Typ (hier: Content Hash Key)
105     %pause
106     Dahinter Folgen Parameter (meist Schlüssel u.ä.), "base64"-codiert
107     %pause
108 root 1.3 Suffix (nach //) wird von Freenet ignoriert
109 root 1.1
110     %page
111    
112     Content Hash Keys
113    
114 root 1.6
115 root 1.1 %font "t3"
116     CHK@pfAv9IejYPLQwaTLXDguEkUhiNUMAwI,blzDbhN~8Q28esq4JrfRWw
117     ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
118     Typ Routing-Key Crypto-Key
119     %font "s"
120    
121 root 1.6
122 root 1.1 %pause
123     Crypto-Key wird aus den Daten generiert
124     verschlüsselt die Daten
125 root 1.6
126 root 1.1 %pause
127     Routing-Key wird aus dem Crypto-Key generiert
128     dient zum Indizieren und Suchen der Daten
129 root 1.6
130 root 1.1 %pause
131 root 1.6 Daten können mehrfach eingefügt werden. Da gleiche Daten == gleicher Key wird das Netzwerk nicht belastet
132 root 1.1
133     %page
134    
135 root 1.2 Freenet Live
136    
137 root 1.8 %system "/opt/bin/links -g -mode 1024x756 http://129.13.162.73:8888/"
138 root 1.2
139     %page
140    
141 root 1.3 Abrufen eines Keys (1)
142 root 1.2
143 root 1.6
144 root 1.2 Beispiel: ein Bild der Seite "Thought-Crime":
145    
146     %font "t3"
147     CHK@pfAv9IejYPLQwaTLXDguEkUhiNUMAwI,blzDbhN~8Q28esq4JrfRWw
148     %font "s"
149    
150 root 1.3 1. Suche nach CHK@pfAvI...kUhiNUMAwI
151 root 1.2 %pause
152 root 1.3 (a5f02ff487a36...e12452188d50c0302)
153 root 1.2 %pause
154     0c == 4k, 0302 == CHK + Twofish
155     %pause
156     Skalierbarkeit durch lineare Suche
157 root 1.6
158 root 1.2 %pause
159     2. Entschlüsseln der Daten mit blzDbhN~8Q28esq4JrfRWw
160     (6e5cc36e137ef10dbc7acab826b7d15b)
161    
162     %page
163    
164 root 1.3 Abrufen eines Keys (2)
165 root 1.2
166 root 1.6
167     Abgerufene Daten bestehen aus Metadaten und Daten
168 root 1.2
169     Metadaten:
170    
171     %font "t3"
172     Revision=1
173     EndPart
174     Document
175     Info.Format=image/png
176     End
177     %font "s"
178    
179     Daten:
180    
181     %font "t3"
182     PNG^Z...
183     %font "s"
184    
185     %page
186    
187 root 1.1 Signed Subspace Key
188    
189 root 1.6
190 root 1.1 %font "t3"
191     SSK@Sc6qV~D6iFhaYord6HtbjJ8MaEYPAgM,Jrd6HtbjJfw1UO1g/YoYo
192     ^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
193     Typ Public Key PAgM Entropie + Daten
194     %font "s"
195    
196     %pause
197     Daten werden mit einem private Key signiert
198 root 1.6
199 root 1.1 %pause
200     maximale Größe 32K
201 root 1.6
202 root 1.1 %pause
203     mit einem Schüsselpaar können viele Keys eingefügt werden
204     Unterscheidung über angehängte Daten
205    
206     %page
207    
208 root 1.2 Und nun: Perl
209 root 1.1
210    
211 root 1.2 Net::Freenet::FCP
212     http://www.sf.net/projects/perlfcp
213     %pause
214     stark bei Metadaten
215     %pause
216 root 1.1
217 root 1.2 Net::FCP
218     CPAN
219     %pause
220     stark beim asynchronen Einfügen bzw. Abrufen
221     %pause
222 root 1.6 ist von mir :)
223 root 1.1
224 root 1.2 %page
225 root 1.1
226 root 1.2 Einfache Abfragen
227 root 1.1
228 root 1.6 %pause
229 root 1.2 Abfragen benutzen das Freenet Client Protocol (FCP)
230     %pause
231     ein einziger Horror
232     %pause
233     zum Glück gibt's Perl :)
234     %pause
235 root 1.1
236 root 1.2 %font "t5"
237     use Net::FCP;
238     my $fcp = new Net::FCP;
239 root 1.6
240 root 1.2 %pause
241     my ($meta, $data)
242     = @{ $fcp->client_get (
243     "freenet:SSK@0O....PAgM/fx/3//"
244     15
245     ) };
246 root 1.1
247 root 1.2 %font "s"
248 root 1.1
249 root 1.2 %page
250 root 1.1
251 root 1.2 Fehlerbehandlung
252 root 1.1
253 root 1.6
254     %pause
255 root 1.2 Bei Nichtfinden: die
256     %pause
257     Net::FCP::Exception<<data_not_found,>>
258     %pause
259     einfach nochmal probieren
260 root 1.6
261 root 1.2 %pause
262     Bei Netzwerkfehlern: die
263     %pause
264     Net::FCP::Exception<<short_data,reason:unexpected eof or internal node error>>
265     %pause
266     einfach nochmal probieren
267 root 1.6
268 root 1.2 %pause
269     Bei Schluckauf: die
270     %pause
271     einfach nochmal probieren
272     %pause
273 root 1.1
274 root 1.2 Daher: eval { } benutzen.
275 root 1.1
276 root 1.2 %page
277 root 1.1
278 root 1.2 Metadaten in Perl
279 root 1.1
280 root 1.6
281 root 1.2 %pause
282     Metadaten in Perl: Net::FCP::Metadata-Objekte
283     %pause
284 root 1.1
285 root 1.2 Am besten einmal ausgeben lassen:
286 root 1.1
287 root 1.2 %font "t5"
288     use Data::Dumper;
289     print STDERR Dumper $meta;
290     print $data;
291     %font "s"
292 root 1.1
293 root 1.2 %pause
294     z.B. mit eg/fetch1:
295 root 1.1
296 root 1.2 %font "t4"
297     eg/fetch1 SSK@0OhV.......oPAgM/fx/3// >data
298     %font "s"
299 root 1.1
300 root 1.2 %page
301 root 1.1
302 root 1.2 Metadaten einer Freesite
303 root 1.1
304 root 1.6
305 root 1.2 Stark gekürzt:
306 root 1.6
307 root 1.2 %pause
308 root 1.6 %font "t5"
309 root 1.2 version => { 'revision' => '1' },
310     document => [ {
311 root 1.6 info => { format => 'image/png' },
312     redirect=> { target => 'freenet:CHK@...' },
313     name => 'activelink.png'
314     } ],
315 root 1.2 raw => 'Version
316     Revision=1
317     ...
318     End
319     '
320     };
321     %font "s"
322 root 1.1
323 root 1.2 %page
324 root 1.1
325 root 1.2 Manifest-Metadaten
326 root 1.1
327    
328 root 1.2 Beispiele für Keys aus den Metadaten der Freesite:
329 root 1.1
330 root 1.2 %pause
331     %font "t3"
332     Hauptseite
333     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3//
334 root 1.6
335 root 1.2 %pause
336     Icon
337     SSK@0OhVDWutibbBMbXmbxNXW0M6YFoPAgM/fx/3//activelink.png
338     %font "s"
339 root 1.1
340    
341 root 1.2 %pause
342 root 1.3 client_get liefert identische Daten
343 root 1.1
344 root 1.2 %pause
345     Freenet ignoriert alles hinter //
346 root 1.1
347 root 1.2 %page
348 root 1.1
349 root 1.2 Manifest-Metadaten
350 root 1.1
351 root 1.6
352 root 1.3 Selbst nachschauen durch Lookup in den Metadaten:
353 root 1.2 %pause
354 root 1.1
355 root 1.6 %font "t5"
356 root 1.2 $link = grep $_->{name} eq "activelink.png",
357     @{ $metadata->{document} };
358     %pause
359     print $link->{redirect};
360     %font "s"
361 root 1.1
362 root 1.2 %pause
363     kein Redirect => Daten sind angehängt
364 root 1.1
365 root 1.2 %page
366 root 1.1
367 root 1.3 Freesite-Management
368 root 1.1
369 root 1.6
370 root 1.3 %pause
371 root 1.6 Wie verändert man Daten, die nicht mehr veränderbar sind?
372 root 1.1
373 root 1.3 %pause
374     Lösung 1: Veränderbare Keys (TUKs)
375     %pause
376     Viel Rauch, wenig Realität
377 root 1.6
378 root 1.3 %pause
379     Lösung 2: Editions
380     %pause
381     Links auf zukünftige Inhalte
382     %pause
383     "verkettete Liste"
384 root 1.6
385 root 1.3 %pause
386     Lösung 3: DBR-Links
387     %pause
388     Date-Based-Redirects
389 root 1.1
390 root 1.3 %page
391 root 1.1
392 root 1.3 Editions (1)
393 root 1.1
394 root 1.6
395     A-HREF + IMG-Element, zeigt auf activelink der nächsten
396     Edition.
397 root 1.1
398 root 1.3 %pause
399     Beispiel: Freesite "Freenet Explained"
400 root 1.1
401 root 1.6 %font "t5"
402 root 1.3 SSK@0OhV...oPAgM/fx/4//
403     # Link-Ziel
404     SSK@0OhV...oPAgM/fx/4//activelink.png
405     # IMG-SRC
406     %font "s"
407 root 1.1
408 root 1.3 %pause
409     Edition 4 existiert noch nicht
410     %pause
411     Editionen werden durchnummeriert
412     %pause
413     Für Spider: .next-Eintrag
414 root 1.1
415 root 1.3 %page
416 root 1.1
417 root 1.3 Editions (2)
418 root 1.1
419    
420 root 1.3 %pause
421     Vorteile:
422     %pause
423     "relativ" einfach für Autoren
424     %pause
425     realisierbar mit "Hausmittel"
426     %pause
427     keine Pflege notwendig
428     %pause
429 root 1.1
430 root 1.3 Nachteile:
431     %pause
432     umständlich in der Benutzung
433     %pause
434     "es ist und bleibt ein Hack"
435 root 1.1
436 root 1.3 %page
437 root 1.1
438 root 1.3 Date-Based-Redirects (1)
439 root 1.1
440    
441 root 1.3 Unterstützung spezieller Redirects
442     %pause
443 root 1.6 Timestamp statt fortlaufender Nummer
444 root 1.3 %pause
445 root 1.6 Spezielle Metadaten
446 root 1.3 %pause
447 root 1.1
448 root 1.3 Beispiel "The Freenet Help Index":
449     %pause
450 root 1.1
451 root 1.6 %font "t4"
452 root 1.3 'version' => { 'revision' => '1' },
453     'document' => [
454     { 'date_redirect' => {
455     'increment' => '15180',
456     'target' => 'SSK@rjY...8PAgM/FreenetHelp'
457 root 1.1 }
458 root 1.3 }
459     ],
460     %font "s"
461    
462     %page
463 root 1.1
464 root 1.3 Date-Based-Redirects (2)
465 root 1.1
466    
467 root 1.3 Vorteile:
468     %pause
469     einfach in der Benutzung
470     %pause
471 root 1.6 "sauber" über Metadaten implementiert
472 root 1.3 %pause
473     festgelegter Key
474     %pause
475 root 1.1
476 root 1.3 Nachteile:
477     %pause
478     feste Abstände zwischen Updates
479     %pause
480     häufige Pflege
481     %pause
482     keine inserts == keine Freesite
483 root 1.1
484 root 1.3 %page
485 root 1.1
486 root 1.4 DBRs in Perl
487 root 1.1
488 root 1.6
489     %font "t5"
490 root 1.3 %pause
491     my $D = $metadata->{document}[0];
492 root 1.4
493 root 1.3 %pause
494     my $incr = (hex $D->{increment}) || 86400;
495     my $offs = (hex $D->{offset}) || 0;
496     my $targ = $D->{target} || die;
497 root 1.4
498 root 1.3 %pause
499 root 1.4 my ($head, $tail) = split /\//, $targ, 2;
500 root 1.1
501 root 1.3 %pause
502     my $NOW = time;
503     my $time = $NOW - $NOW % $incr + $offs;
504     %pause
505     my $result = sprintf "%s/%x-%s",
506     $head, $time, $tail;
507     %pause
508     %font "t3"
509 root 1.1
510     SSK@rjYFfgPHfolmcStiaoxESFfBXz8PAgM/40a16900-FreenetHelp
511    
512 root 1.3 %page
513    
514     Effiziente Freenet-Abfragen
515 root 1.1
516 root 1.6
517 root 1.3 %pause
518     Problem:
519 root 1.6 Freenet == hohe Latenz
520 root 1.4 %pause
521 root 1.3 parallele Anfragen absolut notwendig
522 root 1.4 %pause
523 root 1.3 Implementation über Threads schlecht
524 root 1.4 %pause
525 root 1.3 Perl hat keine echten Threads
526    
527 root 1.4 %pause
528 root 1.6 %font "s"
529 root 1.3 Lösung:
530 root 1.4 %pause
531 root 1.6 Ereignisgesteuerung
532 root 1.4 %pause
533     Unterstützung für Coro, Event, Glib, Tk...
534 root 1.3
535     %page
536 root 1.1
537 root 1.4 Transaktionen
538    
539 root 1.6
540     %pause
541 root 1.4 Implementation von $fcp->client_get:
542 root 1.1
543 root 1.4 %pause
544     %font "t5"
545 root 1.1 my $txn = $fcp->txn_client_get (...);
546    
547 root 1.4 %pause
548     return $txn->result;
549    
550     %pause
551     %font "s"
552 root 1.6 Jeder FCP-Requesttyp besitzt eine txn_-Methode.
553 root 1.1
554 root 1.4 %pause
555     Parallelisierung:
556     %pause
557 root 1.1
558 root 1.4 %font "t5"
559 root 1.1 map $_->result,
560     map $_->txn_client_get ($_),
561     @download;
562    
563 root 1.4 %page
564 root 1.1
565 root 1.4 Asynchrone Abfragen
566 root 1.1
567    
568 root 1.4 %pause
569     Ziel: n ausstehende Anfragen zu jedem Zeitpunkt
570 root 1.1
571 root 1.4 %pause
572     Callback bei Beendigung
573 root 1.1
574    
575 root 1.4 %pause
576     %font "t5"
577     my $txn = $fcp->txn_client_get (...)
578     ->cb (\&callback);
579     %font "s"
580 root 1.1
581 root 1.4 %pause
582     txn-Methoden sind i.Allg. "chainbar"
583 root 1.1
584 root 1.4 %page
585 root 1.1
586 root 1.4 Hauptprogramm
587 root 1.1
588 root 1.6
589 root 1.4 Hauptprogramm muß in die Hauptschleife springen:
590 root 1.1
591 root 1.4 %font "t5"
592     use Net::FCP qw(event=Event);
593 root 1.1
594 root 1.4 %pause
595     my $fcp = new Net::FCP;
596     $fcp->txn_client_get ($_)->cb (\&finished)
597     for @ARGV;
598 root 1.1
599 root 1.4 %pause
600     Event::loop;
601 root 1.1
602 root 1.4 %font "s"
603     %pause
604     Angabe des Event-Moduls nur im Hauptprogramm
605 root 1.1
606 root 1.4 %page
607 root 1.1
608 root 1.6 Callback
609 root 1.1
610    
611 root 1.4 %font "t5"
612 root 1.6 %pause
613     sub finished {
614     my ($txn) = @_;
615 root 1.1
616 root 1.6 %pause
617     # .. neue txn starten
618 root 1.4
619 root 1.6 %pause
620     my ($meta, $data) = eval {
621     @{ $txn->result }
622     };
623 root 1.1
624 root 1.6 %pause
625     if ($@) {
626     warn "error $@, who cares :)"
627     } else {
628     warn "Lo and Behold! We got soemthing!";
629     # tue etwas
630     }
631 root 1.4 }
632 root 1.1
633 root 1.4 %page
634 root 1.1
635 root 1.4 Callbacks und Threads
636 root 1.1
637 root 1.6
638     Das Coro Modul ermöglicht es,
639     "Callback-Stil" und "Thread-Stil" zu mischen:
640 root 1.1
641 root 1.4 %pause
642 root 1.6 %font "t4"
643     use Net::FCP qw(event=Coro);
644 root 1.1
645 root 1.6 my $fcp = new Net::FCP;
646 root 1.1
647 root 1.6 # Achtung. Pseudocode :)
648     for my $url (@urls) {
649     async {
650     %pause
651     my ($meta, $data) = @{ $fcp->client_get ($url) };
652    
653     for (@alle_splitfile_blöcke) {
654     $fcp->txn_client_get (...)
655     ->cb (\&save_splitfile_block);
656     }
657     };
658     }
659 root 1.1
660 root 1.4 %page
661 root 1.1
662 root 1.4 Splitfiles
663 root 1.1
664    
665 root 1.6
666    
667 root 1.4 %pause
668     Zerteilen von großen Dateien in:
669 root 1.1
670 root 1.4 %pause
671     Segmente (max. 128MB)
672 root 1.1
673 root 1.4 %pause
674     Datenblöcke (max 1MB)
675 root 1.1
676 root 1.4 %pause
677     Checkblöcke (50% der Gesamtzahl)
678 root 1.1
679    
680 root 1.4 %page
681 root 1.1
682 root 1.4 Publizieren
683 root 1.1
684 root 1.6
685 root 1.4 Einfügen von Keys ist so einfach(?) wie auslesen
686 root 1.1
687 root 1.4 %pause
688     %font "t4"
689     $fcp->client_put ($uri, $meta, $data, $htl, $remove);
690     %font "s"
691 root 1.1
692 root 1.4 %pause
693     Parallelität mit txn_client_put
694     %pause
695     Key Collisions sind O.K.
696     %pause
697     Key wird automatisch erzeugt:
698 root 1.1
699 root 1.4 %pause
700     %font "t4"
701 root 1.6 my $attr = $fcp->client_put
702     ('CHK@', "", "Daten\n", 20);
703     print "Eingefügte URI: $attr->{uri}\n";
704 root 1.1
705 root 1.4 %pause
706     %font "t3"
707     => freenet:CHK@MT~LuxKHH8fugJehkcgp239h7C4KAwI,378rJzHVZbsQbd7VGMHxSg
708 root 1.1
709 root 1.4 %page
710 root 1.1
711 root 1.4 SSK-Keys generieren
712 root 1.1
713 root 1.6
714 root 1.4 SSK = Spezialfall von SVK
715 root 1.1
716 root 1.4 %pause
717     %font "t4"
718     my ($public, $private, $crypto)
719     = @{ $fcp->generate_svk_pair };
720     %font "s"
721 root 1.1
722 root 1.4 %pause
723     Einfüge- und Ausleseschlüssel:
724 root 1.1
725 root 1.4 %pause
726     %font "t4"
727     my $name = "..."; # beliebig
728     my $get = "SSK\@${public}PAgM,$crypto/$name";
729     %pause
730     my $put = "SSK\@$private,$crypto/$name";
731     %font "s"
732 root 1.6
733 root 1.4 %pause
734     Net::FCP::Key::SSK
735 root 1.1
736 root 1.4 %page
737 root 1.1
738 root 1.4 Erzeugen einer Freesite (1)
739 root 1.1
740 root 1.6
741 root 1.4 %pause
742     %font "t4"
743     perl -MNet::FCP -MNet::FCP::Key::SSK
744 root 1.6 -e 'Net::FCP::Key::SSK->new_from_fcp
745     (Net::FCP->new)
746 root 1.4 ->save ($ARGV[0])' mykey
747 root 1.1
748 root 1.6
749    
750     %font "t5"
751 root 1.4 %pause
752 root 1.6 # Definitionen
753     my $edition = 1;
754     my $keyfile = "mykey";
755     my $htl = 10;
756 root 1.1
757 root 1.4 %pause
758 root 1.6 # Module
759     use Net::FCP qw(event=Event);
760     use Net::FCP::Metadata;
761     use Net::FCP::Key::SSK;
762 root 1.1
763 root 1.4 %page
764    
765     Erzeugen einer Freesite (2)
766    
767 root 1.6
768 root 1.4 %font "t4"
769     %pause
770     # Notwendige Objekte erzeugen/laden
771     my $fcp = new Net::FCP;
772     my $ssk = new_from_file Net::FCP::Key::SSK $keyfile;
773    
774     %pause
775     \# Hilfsfunktion zum (asynchronen) Einfügen
776     sub add_key {
777     my ($name, $key, $meta, $data) = @_;
778    
779     $fcp->txn_client_put ($chk, $meta, $data, $htl, 1)
780     ->cb (sub {
781     eval {
782     my $attr = $_[0]->result;
783     } or warn "'$name': $@";
784     });
785     }
786 root 1.1
787 root 1.4 %page
788 root 1.1
789 root 1.4 Erzeugen einer Freesite (3)
790 root 1.1
791 root 1.6
792    
793 root 1.4 %font "t4"
794     \# Hilfsfunktion für Dateien
795     sub add_file {
796     my ($name, $path, $contenttype) = @_;
797    
798     # lies die Datei ein
799     my $data = ...
800    
801     my $chk = $fcp->generate_chk ("", $data);
802     $manifest->add_redirect ($name => $chk,
803     format => $contenttype);
804     add_key $name, $chk, "", $data;
805     }
806 root 1.1
807 root 1.4 %page
808 root 1.1
809 root 1.4 Erzeugen einer Freesite (4)
810 root 1.1
811 root 1.6
812 root 1.4 %font "t4"
813     \# Hauptprogramm: Manifest erzeugen
814 root 1.1
815 root 1.4 my $manifest = new Net::FCP::Metadata;
816 root 1.1
817 root 1.4 %pause
818     \# .prev-Link
819 root 1.6 $manifest->add_redirect (
820     ".prev" => $ssk->gen_pub ($edition - 1))
821 root 1.4 if $edition > 1;
822 root 1.1
823 root 1.4 %pause
824     \# .next-Link
825 root 1.6 $manifest->add_redirect (
826     ".next" => $ssk->gen_pub ($edition + 1));
827 root 1.1
828 root 1.4 %page
829 root 1.1
830 root 1.4 Erzeugen einer Freesite (5)
831 root 1.1
832 root 1.6
833 root 1.4 %font "t4"
834     \# Dateien hinzufügen
835 root 1.1
836 root 1.4 %pause
837     add_file "activelink.png" => "logo.png", "image/png";
838     add_file "" => "index.html", "text/html";
839     add_file "index.html" => "index.html", "text/html";
840     add_file "freesite" => "freesite", "text/plain";
841 root 1.1
842 root 1.4 %pause
843     \# Manifest einfügen
844     my $site = $ssk->gen_pub ($edition);
845 root 1.6
846 root 1.4 %pause
847     add_key "manifest", $site, $manifest, "";
848 root 1.1
849 root 1.4 %pause
850     print "site generated as $site//\n";
851 root 1.1
852 root 1.4 %pause
853     Event::loop;
854 root 1.1
855    
856 root 1.4 %page
857 root 1.1
858 root 1.4 Erzeugen einer Freesite (6)
859 root 1.1
860    
861 root 1.4 Ausgabe des Programms:
862 root 1.1
863 root 1.6 %font "t5"
864 root 1.4 %pause
865     site generated as SSK@wg...gPAgM,Jr...UO1g/1//
866     %pause
867     Insert of 'freesite' (1688 bytes) ok.
868     Insert of 'activelink.png' (1346 bytes) ok.
869     Insert of 'index.html' (200 bytes) ok.
870     Insert of '' (200 bytes) ok.
871     Insert of 'manifest' (0 bytes) ok.
872 root 1.1
873 root 1.4 %page
874 root 1.1
875 root 1.4 Fragen?
876 root 1.1
877    
878    
879