Le billet de ce jour attendra. Une urgence, j'ai un coup de gueule à lancer.
Ce matin, mon serveur était en drapeau. Pas planté, non, il fonctionnait juste à la vitesse d'un escargot arthritique avec une charge de plus de 75 ! Je veux bien croire qu'il n'est pas exactement ce qu'il est convenu d'appeler un foudre de guerre, mais tout de même, une charge de plus de 75 durant plusieurs heures pour une machine à deux voies sans la faire planter est un gage de stabilité du système. Il faut dire que je ne fais pas vraiment dans le bricolage :
$ show system/full
OpenVMS V8.3 on node DIRAC 10-AUG-2010 10:17:10.33 Uptime 281 07:52:21
Un sinistre individu que je qualifierais sans problème ni remords de sinistre imbécile s'est permis de lancer un « deny of service » sur les deux liens redondants connectant ce serveur au réseau internet. Ce type est un lecteur régulier des papiers présents sur ce site et ce n'est pas en réagissant ainsi qu'il m'empêchera de grincher.
Vous me demanderez certainement comment je puis affirmer qu'il est un lecteur régulier de ce blog. C'est très simple, ce serveur n'est pas un serveur hébergé quelque part sur la toile, c'est un serveur qui est chez moi. J'ai donc accès à tous les fichiers journaux et je connais d'adresse IP du responsable qui n'a même pas pris la peine de se cacher derrière une adresse IP dynamique ou un proxy quelconque. J'ai autre chose à faire aujourd'hui que de croiser les données pour trouver son identité, je le laisse avec sa conscience, mais au prochain DOS, je sévirai. Il paraît que la riposte graduée est à la mode !
Pour t'aider dans tes recherches, toi, petit minable d'internet, je vais te fournir de précieuses informations qui t'éviteront de perdre ton temps en vaines attaques. Le serveur en question est un AlphaServer 1200 avec deux processeurs Alpha ev56/533 MHz, 2 Go de mémoire et un ensemble de disques en plusieurs volumes Raid (neuf disques U320 SCSI). Son système d'exploitation est un OpenVMS 8.3 des familles à jour de ses patches de sécurité et muni d'un serveur WASD, un petit serveur web sans prétention dont Apache2 n'arrive même pas à la cheville — sous VMS, on peut programmer des interruptions qui sont largement plus efficaces que des threads. Il ne se présente comme un Apache tournant sous Linux que pour tromper l'ennemi et force est de constater que cela ne fonctionne pas si mal que ça puisque tu es tombé dans le panneau. Pour ton information aussi, ce serveur est derrière une passerelle qui, elle, fonctionne sous Debian/Sparc et fait tourner un « honey pot » ainsi qu'un système de banissement des adresses IP en fonction de leur activité légitime ou non. Le réseau en question est donc un peu plus compliqué et sécurisé que tu n'arrives à l'imaginer.
Lorsque tu essaieras la prochaine fois d'utiliser une faille d'Apache pour effectuer une injection de code, je te conseillerai d'injecter du code pour processeur Alpha, ce sera beaucoup plus efficace qu'une injection de code pour processeur i80386 comme celle que tu as essayée d'utiliser toute la nuit. Mais il faudra aussi que tu trouves une faille dans WASD et OpenVMS 8.3, ce qui est déjà une autre histoire.
Petit pirate deviendra — peut-être — grand. En attendant, je ne te salue pas.
Je ne sais pas si vous avez remarqué comme moi, mais depuis quelques jours, on n'entend plus parler de l'affaire Woerth-Bettencourt. En revanche, que n'a-t-on pas dit sur l'expulsion des Roms. Ce contre-feu est tellement gros qu'il a totalement masqué le scandale qui allait finir par emporter à plus ou moins brêve échéance le ministre du travail.
Il n'est pas question ici de prendre parti pour ou contre ce ministre, d'autres que moi s'en chargent, mais force est de constater qu'il y a eu une belle confusion d'intérêts. À tous les niveaux de cette affaire, les différents protagonistes étaient écartelés entre plusieurs intérêts contradictoires et, même s'ils n'ont pas cédé à leurs sirènes, le doute sera difficile à balayer.
Cette affaire a éclaté à point nommé. N'oubliez pas qu'Éric Woerth est actuellement chargé de la réforme des retraites. Un ministre affaibli par une telle affaire aura beaucoup de mal à conduire cette réforme jusqu'au bout. Nous pouvons donc nous demander jusqu'où cette affaire a été instrumentalisée par l'opposition pour torpiller cette réforme. Vous me direz que c'est le jeu. Certes, mais si l'opposition construisait un argumentaire solide pour répondre à cette réforme par une autre proposition plutôt que de faire de l'obstruction par la bande, elle ne pourrait qu'en sortir grandie. Là, elle ne fait qu'affaiblir un homme politique dont rien ne nous dit à ce jour qu'il soit mouillé dans cette affaire et l'opposition pourrait bien ne pas en retirer que des bénéfices.
Pour allumer un contre-feu, faire que les media parlent d'autre chose que de cette affaire, le gouvernement a monté en épingle une sombre histoire entre des Roms et les forces de l'ordre dans le centre de la France. À la suite de cette nouvelle affaire, il est question de reconduire certains Roms à la frontière en fermant tous les campements illégaux et de retirer la nationalité française à tous les étrangers naturalisés depuis moins de dix ans et coupables de délits. Président de la république et ministres issus de l'UMP martèlent ce message d'une seule voix, chacun surenchérissant sur le discours de son collègue.
Et sur qui donc retombe l'obligation de réfléchir à la possibilité de rédiger un projet de loi — à ne pas confondre avec une proposition qui ne serait jamais passée ? Sur Éric Besson ! Si ce ministre était issu des rangs de l'UMP, il y a fort à parier que jamais le gouvernement ne lui aurait demandé de rédiger un tel texte. Issu de l'ouverture, cela ne sera pas une grande perte s'il saute, ce n'est pas un ami de longue date…
En effet, les lois internationales interdisent à un état de créer des apatrides. Pourtant, lorsque l'on acquiert une nationalité, il y a de fortes chances que l'on perde sa nationalité d'origine. Cela dépend essentiellement de la nationalité d'origine, mais les cas d'acquisition d'une double nationalité par naturalisation française sont rares. Se voir retirer la nationalité française revient donc à être apatride.
Quant au problème des Roms, il est ubuesque. Les Roumanie et Bulgarie souhaitent adhérer à l'espace Schengen en 2011. Comment voulez-vous reconduire à la frontière des Roms qui pourront revenir immédiatement en France ? Autre problème : comment refuser à une partie de la population de ces deux pays ce qui est autorisé au reste de leur population ?
Il faut tout de même constater que ce contre-feu est parfaitement efficace. Tout le monde est tombé dans le panneau et Éric Woerth passe actuellement des vacances qui sont sans nul doute agréables.
Aïe, aïe, aïe, aïe, aïe… Nouvelle expérience ratée…
L'un de mes beaux-frères fait — en dehors de moi bien entendu, mais je suis irrécupérable et hors concours — sérieusement baisser les statistiques du taux de natalité familial. Je n'ai jamais abordé le sujet parce que c'est un sujet qui fâche et qui fâche d'autant plus qu'il ne semble pas vraiment apprécier de n'avoir que des filles.
Je n'ai pas eu à aborder le sujet car il est venu sur un plateau. Un jour où mes oreilles traînaient, quelle ne fut pas ma surprise d'entendre qu'il ne s'arrêtera qu'à partir du moment où il aura un fils pour qu'il devienne prêtre, prêtre traditionaliste s'entend. Cette réflexion explique peut-être la baisse de la natalité de cette branche puisque, le connaissant, je serais assez étonné qu'il ait demandé son avis à sa femme. Il me semble qu'elle est pourtant un peu concernée. Pourtant, au vu de l'éducation lamentable de ses enfants, il n'est pas vraiment nécessaire d'en rajouter au tableau.
Je trouve aberrant dans la société actuelle de prétendre occuper une place sociale en fonction du nombre de ses enfants. C'est pourtant ce qui se passe dans un certain milieu. En effet, il n'est pas tout de les faire, il faut leur donner une situation. Comme le disais si bien mon penseur préféré, José Artur, un enfant, c'est vingt minutes de plaisir, neuf mois d'attente et vingt ans d'emmerdes.
Je trouve encore plus absurde, sous prétexte qu'on ne pourra payer des étude à tous ses enfants, d'en orienter sciemment vers les ordres ou de négliger leur éducation car ce sont des filles. Voire de pousser aussi les filles vers la porte des couvents comme cela semble être le cas.
Mais ce n'est rien à côté de la réflexion initiale. Comment peut-on annoncer fièrement qu'on ne s'arrêtera d'avoir des enfants qu'à partir du moment où on aura un garçon ? Comment peut-on rajouter en plus qu'il devra être prêtre ? Son garçon, si un jour il en a un, aura ou n'aura pas la vocation pour devenir prêtre. Le forcer à endosser la soutane du prêtre traditionaliste n'est certainement pas la meilleure chose à faire.
À ce tarif-là, on ne peut plus parler de foi. Il s'agit au mieux d'endoctrinement, au pire d'une incommensurable et crasse bêtise. Que des gens qui défilent contre les avortements en se déclarant « pro vie » parce que l'embryon humain est une vie en devenir, donc une personne qui devrait avoir une certaine liberté ou un certain libre arbitre, soient capables de refuser a priori à cette personne le choix d'être ou de ne pas être prêtre me dépasse. Plus exactement, cela me sidère. Ils n'en sont certainement plus à une contradiction près.
Ne perdons jamais de vue que la doctrine à géométrie variable est la ligne de pensée la plus facile à suivre.
Lorsque j'ai commencé à travailler avec des outils informatiques, j'avais à ma disposition un panneau de clefs, une perforatrice en code 29 et un télétype de Digital. À chaque erreur dans un programme, il n'y avait aucune façon simple de la corriger. Si ce n'était pas trop compliqué à faire, j'avais à ma disposition un rouleau de scotch opaque et une pince à tiercé, mais dans la plupart des cas, il fallait repasser par l'étape performation des cartes. Autant vous dire qu'à l'époque, on faisait attention à ce qu'on écrivait car entre l'édition, la compilation et l'exécution d'un programme, il pouvait se passer plusieurs heures et il fallait recommencer tout le cycle à chaque correction.
Fig. 1 : authentique carte perforée à 80 colonnes en code IBM à 12 lignes
J'ai utilisé des cartes perforées à quatre-vingts colonnes jusqu'en 1997, ayant même écrit un pilote pour utiliser une perforatrice en code 29 depuis une SparcStation 20 tournant sous Solaris 2.5.1. Le simple fait de pouvoir utiliser un vrai éditeur (vi), un compilateur Fortran (gcc 2.7.2.1 et le g77 correspondant) et un debugger (gdb/ddd) avant de perforer les cartes a été un progrès indéniable. Il ne restait plus que le coup de marqueur à mettre en biais sur la tranche de la pile de cartes. Pour ceux qui n'ont jamais travaillé avec des cartes, ce trait de marqueur permet de trier assez rapidement un monceau de cartes lorsqu'on s'est pris les pieds dans un câble et que l'ensemble d'un classeur de carte gît en vrac sur le sol de la salle machine. Pour être sûr que le périphérique de sortie donnerait un résultat lisible, j'avais même poussé le vice à écrire un pilote pour un télétype DecWriter II.
Fig. 2 : authentique télétype DecWriter II
L'apparition des éditeurs modernes (LSE ou EVE sous VMS/OpenVMS, vi sous Unix), la multiplication des langages de programmation et l'augmentation de la puissance des machines ont profondément transformé le rapport qu'un développeur peut avoir avec ses programmes en réduisant le temps nécessaire à l'édition.
Dans les années 80, je voyais essentiellement des programmes écrits en Cobol ou Fortran 66 ou 77 sur des cartes ou des rubans, ou à l'aide d'éditeurs orientés lignes qui n'étaient guère plus pratiques que les perforatrices. Je pense en particulier à l'éditeur EDIT.CMD de Flex9/UniFLEX. Ceux d'entre vous qui ont eu l'immense joie d'écrire du code Fortran pour Flex9 comprendront aisément ce que je veux dire. Les premiers micro-ordinateurs proposaient des éditeurs Basic un peu moins rébarbatifs mais pas beaucoup plus pratiques.
La mode du C apparaît au début des années 90. Avant cette époque, la puissance limitée des machines rendait obligatoire l'utilisation d'un langage adapté au problème à coder, essentiellement parce qu'il fallait que le programme soit compact donc que la majorité des opérations effectuées soient disponibles dans des fonctions intrinsèques au langage employé. Il était illusoire de surcharger la mémoire par des bibliothèques inutiles sous peine d'obtenir un laconique « out of memory error ». La plupart des développeurs ont néanmoins adhéré à cette mode du C en partant du principe que ce langage était capable de résoudre tous leurs problèmes. C'est une grave erreur. Le C a été écrit pour développer des systèmes d'exploitation et non pour un usage générique. Il est ainsi très difficile d'écrire un code propre en C et le C de référence à l'époque, le Kernighan et Ritchie, n'était absolument pas adapté aux calculs complexes. Lorsqu'on rajoute que le C est directement issu du slogan « il est interdit d'interdire », on se demande même pourquoi des non spécialistes ont utilisé ce langage pour autre chose que de la programmation système.
Par la suite, les utilisateurs ont pris conscience des limites du C K&R et ont spécifié un C ANSI subtilement différent du C K&R (voir les joyeusetés concernant les passages de paramètres sous forme d'int qui attrapent tous les débutants et moins débutants), puis un C++, version objet d'un C jugé trop impératif.
Aujourd'hui, l'immense majorité des développeurs ne jure plus que par Java. Java va résoudre tous leurs problèmes. Grâce à Java, le développeur moderne deviendra riche, sera musclé et sa femme va revenir. Euh, non, ça, c'est pour le marabout qui laisse des papiers à la sortie du métro, mais l'idée est en gros la même.
Je ne veux pas parler de la syntaxe du langage même s'il est évident qu'il y aurait beaucoup à dire. Personnellement, j'ai toujours préféré un langage impératif ou fonctionnel à un langage objet parce l'abstraction de la programmation objet est tellement grande qu'on ne sait plus exactement ce qu'on fait. Écrire un algorithme dans un langage objet est relativement facile. Pire, c'est à la portée de n'importe qui. En revanche, l'optimiser est beaucoup plus ardu. La conséquence immédiate est une débauche de ressources, tant du point de vue de l'occupation de la mémoire que de celle du processeur.
Je ne veux pas parler non plus de la machine virtuelle Java qui me semble être une aberration technique sans nom. Je n'arriverai jamais à comprendre pourquoi on compile un programme Java dans un format binaire intermédiaire pour l'exécuter dans une machine virtuelle. On me dira que c'est pour des raisons de portabilité, mais l'argument ne tient pas puisqu'il faut porter la machine virtuelle, ce qui n'est pas plus simple. Autant porter directement un compilateur s'appuyant sur des API fixes comme POSIX ou utiliser une bibliothèque d'abstraction. On sait faire cela depuis longtemps sans aucun problème. Ceux qui ne me croient pas peuvent regarder l'antique bibliothèque porting library et en particulier les jackets des anciennes version de VMS qui permettaient d'utiliser un code POSIX sur un système qui ne l'était pas encore.
Dans un premier temps, je trouve que Java, contrairement à ce qui est trop souvent dit, n'est pas un langage discriminant. En d'autres termes, il ne permet pas de séparer un bon programmeur d'un mauvais. Trop de choses sont à la discrétion de la machine virtuelle qui ne s'en prive pas comme la gestion de la mémoire et les différentes ressources du calculateur, et la conséquence immédiate est que n'importe quel développeur du dimanche peut écrire des applications complexes, souvent jetables parce que leurs codes sources ne sont pas réutilisables, sans comprendre exactement ce que son ordinateur fera. Il est très facile d'écrire un programme de quelques lignes demandant plusieurs centaines de mégaoctets pour effectuer une tâche basique et tout le monde est content.
Java ne parle jamais de pointeur ni de récursion. C'est trop complexe et il faut masquer ces deux notions importantes au programmeur. Pire, le programmeur ne doit même pas savoir que cela existe. On ne peut pas prétendre écrire un bout de programme sérieux en C sans parler de pointeur ; en Java, si. Or les pointeurs sont partout, même s'ils sont plus ou moins masqués dans des objets Java comme des listes chaînées, des tables de hashage et j'en passe.
Les heureux développeurs qui ont fait leurs armes dans les écoles suivant la mode Java n'ont jamais eu à se dépêtrer dans des fichiers core de plusieurs megaoctets, avec la seule aide d'une calculette hexadécimale, lorsqu'il s'agit de déboguer des algorithmes efficaces de gestion de la mémoire (tables de hashage, allocateurs, ramasse-miettes…) qui se terminent par un laconique message de violation d'accès. Pire, ils ne savent pas utiliser un debugger et mettent au point leurs programmes à grands coups de System.out.println()
. C'est tellement pratique… De la même manière, ils n'ont jamais été confrontés à la programmation multithreadée et aux problèmes de concurrences même si le langage Java permet de définir des threads.
Je veux bien admettre que la programmation à l'aide de pointeurs ne soit pas nécessaire dans les trois quarts des programmes écrits aujourd'hui. Pire, je suis conscient que les pointeurs sont dangereux si on les laisse dans les mains de développeurs qui n'ont pas les idées claires et que la programmation fonctionnelle n'est que très peu utilisée en pratique.
Mais il reste le dernier quart, certainement le plus intéressant. Sans connaître ni maîtriser les pointeurs, il est illusoire de travailler sur un programme efficace ou un noyau de système d'exploitation. Il ne faut même pas espérer en comprendre le fonctionnement.
Sans comprendre la programmation fonctionnelle ou multithreadée, il est impossible d'écrire des algorithmes à la fois massivement parallèles et efficaces. Certes, Java dans certains cas arrive à utiliser des threads, mais ils restent dans une machine virtuelle. Ce n'est pas exactement une parallélisation de calculs.
Vous allez me dire que ce n'est valable que pour un quart des programmes. Certainement, mais ce n'est pas négligeable pour autant. Personnellement, en réécrivant la routine A* de la bibliothèque bien connue BOOST en C et Fortran, j'ai divisé par vingt le temps d'exécution de cette routine et divisé par dix la mémoire nécessaire à son exécution. Et BOOST n'est écrit qu'en C++, même pas en Java. Je n'ose imaginer ce qu'il en aurait été.
Rien n'est fait dans les formations Java pour apprendre aux étudiants à penser autrement que dans le paradigme Java. Ils n'arrivent pas à implanter un simple tri de liste chaînée. En revanche, ils sont capables d'assembler des tas de boîtes noires qui font la même chose mais dans une débauche de ressources tout à fait remarquable et qui ferait pleurer n'importe qui ayant travaillé sur des machines dont la mémoire vive était limitée à quelques malheureux kilooctets.
J'ai beaucoup de mal à imaginer que de tels développeurs deviennent un jour de véritables programmeurs. On me rétorquera que les écoles n'enseignent que ce que l'industrie demande, donc Java. Certainement, mais il ne faut pas oublier qu'il faudra toujours des artistes sachant utiliser des pointeurs et connaissant la programmation fonctionnelle ou la récursivité pour que ces développeurs aux petits pieds puissent coder leurs applications jetables. Il faudra toujours des gens capables d'écrire des systèmes d'exploitation ou des machines virtuelles, et ces développeurs Java en seront incapables.
Pire, ces formations orientées vers la programmation objet prétendent toutes simplifier la programmation par l'abstraction des différentes opérations dans des méthodes, des objets, des trucs et des bidules. Mais est-ce plus facile de réécrire une n-ième fois un arbre de hiérarchie d'objets ou d'utiliser une programmation fonctionnelle ? Personnellement, je ne suis pas sûr que la programmation objet soit aussi efficace qu'on le prétend dès qu'on parle de projets importants et complexes. Reprendre la définition d'objets lorsqu'ils sont manifestement inadaptés est quasiment impossible. Il vaut mieux jeter le code et le réécrire totalement.
Bref, je suis de plus en plus enclin à penser que la programmation objet n'a qu'un seul but : fournir des tas de programmeurs. Comme ces programmeurs seraient médiocres s'il fallait leur inculquer des concepts comme la programmation fonctionnelle ou les pointeurs, on préfère cacher leur médiocrité crasse dans la programmation objet où il est beaucoup plus difficile d'être mauvais. On privilégie la quantité à la qualité en changeant le paradigme et en comptant sur le fait que dans la plupart des cas, ça devrait passer. Effectivement, dans la plupart des cas, ça passe. Sauf de temps en temps où l'on fait un feu d'artifice à plusieurs millions de francs en faisant exploser une Fusée Ariane 5…
Vous me direz qu'en C, lorsqu'on a une erreur comme une violation d'accès, il est très souvent difficile d'en trouver la source. C'était vrai il y a quelques années. Aujourd'hui, il existe un nombre d'outils conséquent pour déverminer tous les accès fautifs à la mémoire, que ce soit en lecture ou en écriture, avant que le programme s'arrête sur une violation d'accès.
La conséquence de tout ça, c'est qu'un bon programmeur parlant C, Fortran, Ada, Scheme ou Haskell dans le texte arrivera à se mettre à Java en quelques jours et à écrire de bien meilleurs programmes qu'un développeur ayant cinq ans de pratique quotidienne de Java et ne connaissant que cela. La réciproque est fausse.
L'avenir n'est pas rose. Les hordes de développeurs Java écrivent actuellement du code non maintenable, ignoble, jetable, mais rapidement. La durée d'écriture d'une application est de plus en plus courte, ce qui nuit à sa qualité, mais cela ne semble encore gêner personne. Lorsque tous les dinosaures avec des écailles — ndlr. le dinosaure avec des écailles est l'ancêtre du geek — auront disparu, il ne restera plus que cette génération de sagouins qui n'aura plus les compétences requises à l'écriture de programmes efficaces.
À cet instant, on peut faire un parallèle avec la NASA. La NASA veut aujourd'hui envoyer à nouveau des hommes sur la lune et elle a annoncé qu'il lui faudra un certain nombre d'années pour y arriver. Je ne sais pas si vous avez déjà réfléchi au fait que l'ayant fait plusieurs fois entre 1969 et 1974, elle devrait pouvoir atteindre son but très facilement. Il y a juste un problème : toutes les compétences qui avaient permis à envoyer un homme sur la lune avec la puissance de calcul d'une calculatrice de poche actuelle ont disparu et il faut réinventer la roue.
La même situation risque de se produire à moyen terme dans le domaine de l'informatique. Après le café, il faudra régler l'addition et cette addition risque d'être salée.
J'ai conscience d'acheter mes chemises chez Marks & Spencer et d'apprécier les vestes croisées, mais ce n'est pas pour cela que le touriste de base doit me confondre avec quelqu'un parlant volontiers anglais ou, pire, avec un panneau indicateur. Il paraît que j'ai un physique qui pourrait me faire passer pour anglais, mais de là à me confondre avec un panneau indicateur, il y a un pas que je trouve assez difficile à franchir.
Concernant l'anglais, je ne le parle que contraint et forcé. Je vous promets de me mettre sérieusement à l'anglais lorsque j'aurai fini mon apprentissage du français. De toute façon, ce n'est pas bien grave, j'arrive à me débrouiller dans la langue de Shakespeare bien mieux que la plupart des anglais dans celle de Molière et je répondrai aux touristes perdus dans la capitale dans leur langue maternelle ou en anglais le jour où ils arriveront à me demander autre chose que
Plîse ? Ouhère are ze tchahmpse zilaïsis ?
J'ai trop peur qu'on les retrouve huit jours après à la Bourboule et qu'ils donnent en sanglotant aux autorités le signalement d'un sadique qui opérait à la gare du Nord. J'avoue n'avoir aucune envie de filer en Suisse et d'y attendre quelques années que cette histoire soit oubliée.
J'ai travaillé dans un certains nombre de pays dont des pays fermés totalement aux touristes et les gens de ces pays n'imaginent pas leur bonheur. Je hais les touristes ! Ils se croient chez eux alors qu'ils sont chez nous ! Le touriste en ville est comme le pigeon : c'est un parasite ! Je rêve d'un Paris sans touristes et sans pigeons. Le bonheur… Personne au mois d'août pour nous pousser dans les wagons bondés du métro… Personne pour nous demander le chemin de la tour Eiffel depuis le Trocadéro… Pour les provinciaux, depuis le Trocadéro, il faut être aveugle ou touriste pour ne pas voir la tour Eiffel qui est plantée juste de l'autre côté de la Seine. Elle doit être trop petite.
Et encore, il faut distinguer les touristes selon leurs origines :
On dit que le parisien est râleur et n'accueille pas bien le touriste, mais c'est faux ! C'est le touriste à Paris qui se comporte n'importe comment. Au bout d'un certain temps, ça fatigue.
Pages: << 1 ... 187 188 189 ...190 ...191 192 193 ...194 ...195 196 197 ... 204 >>