├── DFC ├── Richard III.txt ├── The Tempest.txt ├── dfc.conf └── dfc.py ├── DFS1 ├── dfs.conf └── dfs1.py ├── DFS2 ├── dfs.conf └── dfs2.py ├── DFS3 ├── dfs.conf └── dfs3.py ├── DFS4 ├── dfs.conf └── dfs4.py ├── README.md ├── extras ├── ClientAuth.py └── Hashing.py └── images └── PythonDFSdemo.gif /DFC/The Tempest.txt: -------------------------------------------------------------------------------- 1 | THE TEMPEST 2 | 3 | DRAMATIS PERSONAE 4 | 5 | ALONSO King of Naples. 6 | 7 | SEBASTIAN his brother. 8 | 9 | PROSPERO the right Duke of Milan. 10 | 11 | ANTONIO his brother, the usurping Duke of Milan. 12 | 13 | FERDINAND son to the King of Naples. 14 | 15 | GONZALO an honest old Counsellor. 16 | 17 | ADRIAN | 18 | | Lords. 19 | FRANCISCO | 20 | 21 | CALIBAN a savage and deformed Slave. 22 | 23 | TRINCULO a Jester. 24 | 25 | STEPHANO a drunken Butler. 26 | 27 | Master of a Ship. (Master:) 28 | 29 | Boatswain. (Boatswain:) 30 | 31 | Mariners. (Mariners:) 32 | 33 | MIRANDA daughter to Prospero. 34 | 35 | ARIEL an airy Spirit. 36 | 37 | IRIS | 38 | | 39 | CERES | 40 | | 41 | JUNO | presented by Spirits. 42 | | 43 | Nymphs | 44 | | 45 | Reapers | 46 | 47 | Other Spirits attending on Prospero. 48 | 49 | SCENE A ship at Sea: an island. 50 | 51 | THE TEMPEST 52 | 53 | ACT I 54 | 55 | SCENE I On a ship at sea: a tempestuous noise 56 | of thunder and lightning heard. 57 | 58 | [Enter a Master and a Boatswain] 59 | 60 | Master Boatswain! 61 | 62 | Boatswain Here, master: what cheer? 63 | 64 | Master Good, speak to the mariners: fall to't, yarely, 65 | or we run ourselves aground: bestir, bestir. 66 | 67 | [Exit] 68 | 69 | [Enter Mariners] 70 | 71 | Boatswain Heigh, my hearts! cheerly, cheerly, my hearts! 72 | yare, yare! Take in the topsail. Tend to the 73 | master's whistle. Blow, till thou burst thy wind, 74 | if room enough! 75 | 76 | [Enter ALONSO, SEBASTIAN, ANTONIO, FERDINAND, 77 | GONZALO, and others] 78 | 79 | ALONSO Good boatswain, have care. Where's the master? 80 | Play the men. 81 | 82 | Boatswain I pray now, keep below. 83 | 84 | ANTONIO Where is the master, boatswain? 85 | 86 | Boatswain Do you not hear him? You mar our labour: keep your 87 | cabins: you do assist the storm. 88 | 89 | GONZALO Nay, good, be patient. 90 | 91 | Boatswain When the sea is. Hence! What cares these roarers 92 | for the name of king? To cabin: silence! trouble us not. 93 | 94 | GONZALO Good, yet remember whom thou hast aboard. 95 | 96 | Boatswain None that I more love than myself. You are a 97 | counsellor; if you can command these elements to 98 | silence, and work the peace of the present, we will 99 | not hand a rope more; use your authority: if you 100 | cannot, give thanks you have lived so long, and make 101 | yourself ready in your cabin for the mischance of 102 | the hour, if it so hap. Cheerly, good hearts! Out 103 | of our way, I say. 104 | 105 | [Exit] 106 | 107 | GONZALO I have great comfort from this fellow: methinks he 108 | hath no drowning mark upon him; his complexion is 109 | perfect gallows. Stand fast, good Fate, to his 110 | hanging: make the rope of his destiny our cable, 111 | for our own doth little advantage. If he be not 112 | born to be hanged, our case is miserable. 113 | 114 | [Exeunt] 115 | 116 | [Re-enter Boatswain] 117 | 118 | Boatswain Down with the topmast! yare! lower, lower! Bring 119 | her to try with main-course. 120 | 121 | [A cry within] 122 | 123 | A plague upon this howling! they are louder than 124 | the weather or our office. 125 | 126 | [Re-enter SEBASTIAN, ANTONIO, and GONZALO] 127 | 128 | Yet again! what do you here? Shall we give o'er 129 | and drown? Have you a mind to sink? 130 | 131 | SEBASTIAN A pox o' your throat, you bawling, blasphemous, 132 | incharitable dog! 133 | 134 | Boatswain Work you then. 135 | 136 | ANTONIO Hang, cur! hang, you whoreson, insolent noisemaker! 137 | We are less afraid to be drowned than thou art. 138 | 139 | GONZALO I'll warrant him for drowning; though the ship were 140 | no stronger than a nutshell and as leaky as an 141 | unstanched wench. 142 | 143 | Boatswain Lay her a-hold, a-hold! set her two courses off to 144 | sea again; lay her off. 145 | 146 | [Enter Mariners wet] 147 | 148 | Mariners All lost! to prayers, to prayers! all lost! 149 | 150 | Boatswain What, must our mouths be cold? 151 | 152 | GONZALO The king and prince at prayers! let's assist them, 153 | For our case is as theirs. 154 | 155 | SEBASTIAN I'm out of patience. 156 | 157 | ANTONIO We are merely cheated of our lives by drunkards: 158 | This wide-chapp'd rascal--would thou mightst lie drowning 159 | The washing of ten tides! 160 | 161 | GONZALO He'll be hang'd yet, 162 | Though every drop of water swear against it 163 | And gape at widest to glut him. 164 | 165 | [A confused noise within: 'Mercy on us!'-- 166 | 'We split, we split!'--'Farewell, my wife and 167 | children!'-- 168 | 'Farewell, brother!'--'We split, we split, we split!'] 169 | 170 | ANTONIO Let's all sink with the king. 171 | 172 | SEBASTIAN Let's take leave of him. 173 | 174 | [Exeunt ANTONIO and SEBASTIAN] 175 | 176 | GONZALO Now would I give a thousand furlongs of sea for an 177 | acre of barren ground, long heath, brown furze, any 178 | thing. The wills above be done! but I would fain 179 | die a dry death. 180 | 181 | [Exeunt] 182 | 183 | THE TEMPEST 184 | 185 | ACT I 186 | 187 | SCENE II The island. Before PROSPERO'S cell. 188 | 189 | [Enter PROSPERO and MIRANDA] 190 | 191 | MIRANDA If by your art, my dearest father, you have 192 | Put the wild waters in this roar, allay them. 193 | The sky, it seems, would pour down stinking pitch, 194 | But that the sea, mounting to the welkin's cheek, 195 | Dashes the fire out. O, I have suffered 196 | With those that I saw suffer: a brave vessel, 197 | Who had, no doubt, some noble creature in her, 198 | Dash'd all to pieces. O, the cry did knock 199 | Against my very heart. Poor souls, they perish'd. 200 | Had I been any god of power, I would 201 | Have sunk the sea within the earth or ere 202 | It should the good ship so have swallow'd and 203 | The fraughting souls within her. 204 | 205 | PROSPERO Be collected: 206 | No more amazement: tell your piteous heart 207 | There's no harm done. 208 | 209 | MIRANDA O, woe the day! 210 | 211 | PROSPERO No harm. 212 | I have done nothing but in care of thee, 213 | Of thee, my dear one, thee, my daughter, who 214 | Art ignorant of what thou art, nought knowing 215 | Of whence I am, nor that I am more better 216 | Than Prospero, master of a full poor cell, 217 | And thy no greater father. 218 | 219 | MIRANDA More to know 220 | Did never meddle with my thoughts. 221 | 222 | PROSPERO 'Tis time 223 | I should inform thee farther. Lend thy hand, 224 | And pluck my magic garment from me. So: 225 | 226 | [Lays down his mantle] 227 | 228 | Lie there, my art. Wipe thou thine eyes; have comfort. 229 | The direful spectacle of the wreck, which touch'd 230 | The very virtue of compassion in thee, 231 | I have with such provision in mine art 232 | So safely ordered that there is no soul-- 233 | No, not so much perdition as an hair 234 | Betid to any creature in the vessel 235 | Which thou heard'st cry, which thou saw'st sink. Sit down; 236 | For thou must now know farther. 237 | 238 | MIRANDA You have often 239 | Begun to tell me what I am, but stopp'd 240 | And left me to a bootless inquisition, 241 | Concluding 'Stay: not yet.' 242 | 243 | PROSPERO The hour's now come; 244 | The very minute bids thee ope thine ear; 245 | Obey and be attentive. Canst thou remember 246 | A time before we came unto this cell? 247 | I do not think thou canst, for then thou wast not 248 | Out three years old. 249 | 250 | MIRANDA Certainly, sir, I can. 251 | 252 | PROSPERO By what? by any other house or person? 253 | Of any thing the image tell me that 254 | Hath kept with thy remembrance. 255 | 256 | MIRANDA 'Tis far off 257 | And rather like a dream than an assurance 258 | That my remembrance warrants. Had I not 259 | Four or five women once that tended me? 260 | 261 | PROSPERO Thou hadst, and more, Miranda. But how is it 262 | That this lives in thy mind? What seest thou else 263 | In the dark backward and abysm of time? 264 | If thou remember'st aught ere thou camest here, 265 | How thou camest here thou mayst. 266 | 267 | MIRANDA But that I do not. 268 | 269 | PROSPERO Twelve year since, Miranda, twelve year since, 270 | Thy father was the Duke of Milan and 271 | A prince of power. 272 | 273 | MIRANDA Sir, are not you my father? 274 | 275 | PROSPERO Thy mother was a piece of virtue, and 276 | She said thou wast my daughter; and thy father 277 | Was Duke of Milan; and thou his only heir 278 | And princess no worse issued. 279 | 280 | MIRANDA O the heavens! 281 | What foul play had we, that we came from thence? 282 | Or blessed was't we did? 283 | 284 | PROSPERO Both, both, my girl: 285 | By foul play, as thou say'st, were we heaved thence, 286 | But blessedly holp hither. 287 | 288 | MIRANDA O, my heart bleeds 289 | To think o' the teen that I have turn'd you to, 290 | Which is from my remembrance! Please you, farther. 291 | 292 | PROSPERO My brother and thy uncle, call'd Antonio-- 293 | I pray thee, mark me--that a brother should 294 | Be so perfidious!--he whom next thyself 295 | Of all the world I loved and to him put 296 | The manage of my state; as at that time 297 | Through all the signories it was the first 298 | And Prospero the prime duke, being so reputed 299 | In dignity, and for the liberal arts 300 | Without a parallel; those being all my study, 301 | The government I cast upon my brother 302 | And to my state grew stranger, being transported 303 | And rapt in secret studies. Thy false uncle-- 304 | Dost thou attend me? 305 | 306 | MIRANDA Sir, most heedfully. 307 | 308 | PROSPERO Being once perfected how to grant suits, 309 | How to deny them, who to advance and who 310 | To trash for over-topping, new created 311 | The creatures that were mine, I say, or changed 'em, 312 | Or else new form'd 'em; having both the key 313 | Of officer and office, set all hearts i' the state 314 | To what tune pleased his ear; that now he was 315 | The ivy which had hid my princely trunk, 316 | And suck'd my verdure out on't. Thou attend'st not. 317 | 318 | MIRANDA O, good sir, I do. 319 | 320 | PROSPERO I pray thee, mark me. 321 | I, thus neglecting worldly ends, all dedicated 322 | To closeness and the bettering of my mind 323 | With that which, but by being so retired, 324 | O'er-prized all popular rate, in my false brother 325 | Awaked an evil nature; and my trust, 326 | Like a good parent, did beget of him 327 | A falsehood in its contrary as great 328 | As my trust was; which had indeed no limit, 329 | A confidence sans bound. He being thus lorded, 330 | Not only with what my revenue yielded, 331 | But what my power might else exact, like one 332 | Who having into truth, by telling of it, 333 | Made such a sinner of his memory, 334 | To credit his own lie, he did believe 335 | He was indeed the duke; out o' the substitution 336 | And executing the outward face of royalty, 337 | With all prerogative: hence his ambition growing-- 338 | Dost thou hear? 339 | 340 | MIRANDA Your tale, sir, would cure deafness. 341 | 342 | PROSPERO To have no screen between this part he play'd 343 | And him he play'd it for, he needs will be 344 | Absolute Milan. Me, poor man, my library 345 | Was dukedom large enough: of temporal royalties 346 | He thinks me now incapable; confederates-- 347 | So dry he was for sway--wi' the King of Naples 348 | To give him annual tribute, do him homage, 349 | Subject his coronet to his crown and bend 350 | The dukedom yet unbow'd--alas, poor Milan!-- 351 | To most ignoble stooping. 352 | 353 | MIRANDA O the heavens! 354 | 355 | PROSPERO Mark his condition and the event; then tell me 356 | If this might be a brother. 357 | 358 | MIRANDA I should sin 359 | To think but nobly of my grandmother: 360 | Good wombs have borne bad sons. 361 | 362 | PROSPERO Now the condition. 363 | The King of Naples, being an enemy 364 | To me inveterate, hearkens my brother's suit; 365 | Which was, that he, in lieu o' the premises 366 | Of homage and I know not how much tribute, 367 | Should presently extirpate me and mine 368 | Out of the dukedom and confer fair Milan 369 | With all the honours on my brother: whereon, 370 | A treacherous army levied, one midnight 371 | Fated to the purpose did Antonio open 372 | The gates of Milan, and, i' the dead of darkness, 373 | The ministers for the purpose hurried thence 374 | Me and thy crying self. 375 | 376 | MIRANDA Alack, for pity! 377 | I, not remembering how I cried out then, 378 | Will cry it o'er again: it is a hint 379 | That wrings mine eyes to't. 380 | 381 | PROSPERO Hear a little further 382 | And then I'll bring thee to the present business 383 | Which now's upon's; without the which this story 384 | Were most impertinent. 385 | 386 | MIRANDA Wherefore did they not 387 | That hour destroy us? 388 | 389 | PROSPERO Well demanded, wench: 390 | My tale provokes that question. Dear, they durst not, 391 | So dear the love my people bore me, nor set 392 | A mark so bloody on the business, but 393 | With colours fairer painted their foul ends. 394 | In few, they hurried us aboard a bark, 395 | Bore us some leagues to sea; where they prepared 396 | A rotten carcass of a boat, not rigg'd, 397 | Nor tackle, sail, nor mast; the very rats 398 | Instinctively had quit it: there they hoist us, 399 | To cry to the sea that roar'd to us, to sigh 400 | To the winds whose pity, sighing back again, 401 | Did us but loving wrong. 402 | 403 | MIRANDA Alack, what trouble 404 | Was I then to you! 405 | 406 | PROSPERO O, a cherubim 407 | Thou wast that did preserve me. Thou didst smile. 408 | Infused with a fortitude from heaven, 409 | When I have deck'd the sea with drops full salt, 410 | Under my burthen groan'd; which raised in me 411 | An undergoing stomach, to bear up 412 | Against what should ensue. 413 | 414 | MIRANDA How came we ashore? 415 | 416 | PROSPERO By Providence divine. 417 | Some food we had and some fresh water that 418 | A noble Neapolitan, Gonzalo, 419 | Out of his charity, being then appointed 420 | Master of this design, did give us, with 421 | Rich garments, linens, stuffs and necessaries, 422 | Which since have steaded much; so, of his gentleness, 423 | Knowing I loved my books, he furnish'd me 424 | From mine own library with volumes that 425 | I prize above my dukedom. 426 | 427 | MIRANDA Would I might 428 | But ever see that man! 429 | 430 | PROSPERO Now I arise: 431 | 432 | [Resumes his mantle] 433 | 434 | Sit still, and hear the last of our sea-sorrow. 435 | Here in this island we arrived; and here 436 | Have I, thy schoolmaster, made thee more profit 437 | Than other princesses can that have more time 438 | For vainer hours and tutors not so careful. 439 | 440 | MIRANDA Heavens thank you for't! And now, I pray you, sir, 441 | For still 'tis beating in my mind, your reason 442 | For raising this sea-storm? 443 | 444 | PROSPERO Know thus far forth. 445 | By accident most strange, bountiful Fortune, 446 | Now my dear lady, hath mine enemies 447 | Brought to this shore; and by my prescience 448 | I find my zenith doth depend upon 449 | A most auspicious star, whose influence 450 | If now I court not but omit, my fortunes 451 | Will ever after droop. Here cease more questions: 452 | Thou art inclined to sleep; 'tis a good dulness, 453 | And give it way: I know thou canst not choose. 454 | 455 | [MIRANDA sleeps] 456 | 457 | Come away, servant, come. I am ready now. 458 | Approach, my Ariel, come. 459 | 460 | [Enter ARIEL] 461 | 462 | ARIEL All hail, great master! grave sir, hail! I come 463 | To answer thy best pleasure; be't to fly, 464 | To swim, to dive into the fire, to ride 465 | On the curl'd clouds, to thy strong bidding task 466 | Ariel and all his quality. 467 | 468 | PROSPERO Hast thou, spirit, 469 | Perform'd to point the tempest that I bade thee? 470 | 471 | ARIEL To every article. 472 | I boarded the king's ship; now on the beak, 473 | Now in the waist, the deck, in every cabin, 474 | I flamed amazement: sometime I'ld divide, 475 | And burn in many places; on the topmast, 476 | The yards and bowsprit, would I flame distinctly, 477 | Then meet and join. Jove's lightnings, the precursors 478 | O' the dreadful thunder-claps, more momentary 479 | And sight-outrunning were not; the fire and cracks 480 | Of sulphurous roaring the most mighty Neptune 481 | Seem to besiege and make his bold waves tremble, 482 | Yea, his dread trident shake. 483 | 484 | PROSPERO My brave spirit! 485 | Who was so firm, so constant, that this coil 486 | Would not infect his reason? 487 | 488 | ARIEL Not a soul 489 | But felt a fever of the mad and play'd 490 | Some tricks of desperation. All but mariners 491 | Plunged in the foaming brine and quit the vessel, 492 | Then all afire with me: the king's son, Ferdinand, 493 | With hair up-staring,--then like reeds, not hair,-- 494 | Was the first man that leap'd; cried, 'Hell is empty 495 | And all the devils are here.' 496 | 497 | PROSPERO Why that's my spirit! 498 | But was not this nigh shore? 499 | 500 | ARIEL Close by, my master. 501 | 502 | PROSPERO But are they, Ariel, safe? 503 | 504 | ARIEL Not a hair perish'd; 505 | On their sustaining garments not a blemish, 506 | But fresher than before: and, as thou badest me, 507 | In troops I have dispersed them 'bout the isle. 508 | The king's son have I landed by himself; 509 | Whom I left cooling of the air with sighs 510 | In an odd angle of the isle and sitting, 511 | His arms in this sad knot. 512 | 513 | PROSPERO Of the king's ship 514 | The mariners say how thou hast disposed 515 | And all the rest o' the fleet. 516 | 517 | ARIEL Safely in harbour 518 | Is the king's ship; in the deep nook, where once 519 | Thou call'dst me up at midnight to fetch dew 520 | From the still-vex'd Bermoothes, there she's hid: 521 | The mariners all under hatches stow'd; 522 | Who, with a charm join'd to their suffer'd labour, 523 | I have left asleep; and for the rest o' the fleet 524 | Which I dispersed, they all have met again 525 | And are upon the Mediterranean flote, 526 | Bound sadly home for Naples, 527 | Supposing that they saw the king's ship wreck'd 528 | And his great person perish. 529 | 530 | PROSPERO Ariel, thy charge 531 | Exactly is perform'd: but there's more work. 532 | What is the time o' the day? 533 | 534 | ARIEL Past the mid season. 535 | 536 | PROSPERO At least two glasses. The time 'twixt six and now 537 | Must by us both be spent most preciously. 538 | 539 | ARIEL Is there more toil? Since thou dost give me pains, 540 | Let me remember thee what thou hast promised, 541 | Which is not yet perform'd me. 542 | 543 | PROSPERO How now? moody? 544 | What is't thou canst demand? 545 | 546 | ARIEL My liberty. 547 | 548 | PROSPERO Before the time be out? no more! 549 | 550 | ARIEL I prithee, 551 | Remember I have done thee worthy service; 552 | Told thee no lies, made thee no mistakings, served 553 | Without or grudge or grumblings: thou didst promise 554 | To bate me a full year. 555 | 556 | PROSPERO Dost thou forget 557 | From what a torment I did free thee? 558 | 559 | ARIEL No. 560 | 561 | PROSPERO Thou dost, and think'st it much to tread the ooze 562 | Of the salt deep, 563 | To run upon the sharp wind of the north, 564 | To do me business in the veins o' the earth 565 | When it is baked with frost. 566 | 567 | ARIEL I do not, sir. 568 | 569 | PROSPERO Thou liest, malignant thing! Hast thou forgot 570 | The foul witch Sycorax, who with age and envy 571 | Was grown into a hoop? hast thou forgot her? 572 | 573 | ARIEL No, sir. 574 | 575 | PROSPERO Thou hast. Where was she born? speak; tell me. 576 | 577 | ARIEL Sir, in Argier. 578 | 579 | PROSPERO O, was she so? I must 580 | Once in a month recount what thou hast been, 581 | Which thou forget'st. This damn'd witch Sycorax, 582 | For mischiefs manifold and sorceries terrible 583 | To enter human hearing, from Argier, 584 | Thou know'st, was banish'd: for one thing she did 585 | They would not take her life. Is not this true? 586 | 587 | ARIEL Ay, sir. 588 | 589 | PROSPERO This blue-eyed hag was hither brought with child 590 | And here was left by the sailors. Thou, my slave, 591 | As thou report'st thyself, wast then her servant; 592 | And, for thou wast a spirit too delicate 593 | To act her earthy and abhorr'd commands, 594 | Refusing her grand hests, she did confine thee, 595 | By help of her more potent ministers 596 | And in her most unmitigable rage, 597 | Into a cloven pine; within which rift 598 | Imprison'd thou didst painfully remain 599 | A dozen years; within which space she died 600 | And left thee there; where thou didst vent thy groans 601 | As fast as mill-wheels strike. Then was this island-- 602 | Save for the son that she did litter here, 603 | A freckled whelp hag-born--not honour'd with 604 | A human shape. 605 | 606 | ARIEL Yes, Caliban her son. 607 | 608 | PROSPERO Dull thing, I say so; he, that Caliban 609 | Whom now I keep in service. Thou best know'st 610 | What torment I did find thee in; thy groans 611 | Did make wolves howl and penetrate the breasts 612 | Of ever angry bears: it was a torment 613 | To lay upon the damn'd, which Sycorax 614 | Could not again undo: it was mine art, 615 | When I arrived and heard thee, that made gape 616 | The pine and let thee out. 617 | 618 | ARIEL I thank thee, master. 619 | 620 | PROSPERO If thou more murmur'st, I will rend an oak 621 | And peg thee in his knotty entrails till 622 | Thou hast howl'd away twelve winters. 623 | 624 | ARIEL Pardon, master; 625 | I will be correspondent to command 626 | And do my spiriting gently. 627 | 628 | PROSPERO Do so, and after two days 629 | I will discharge thee. 630 | 631 | ARIEL That's my noble master! 632 | What shall I do? say what; what shall I do? 633 | 634 | PROSPERO Go make thyself like a nymph o' the sea: be subject 635 | To no sight but thine and mine, invisible 636 | To every eyeball else. Go take this shape 637 | And hither come in't: go, hence with diligence! 638 | 639 | [Exit ARIEL] 640 | 641 | Awake, dear heart, awake! thou hast slept well; Awake! 642 | 643 | MIRANDA The strangeness of your story put 644 | Heaviness in me. 645 | 646 | PROSPERO Shake it off. Come on; 647 | We'll visit Caliban my slave, who never 648 | Yields us kind answer. 649 | 650 | MIRANDA 'Tis a villain, sir, 651 | I do not love to look on. 652 | 653 | PROSPERO But, as 'tis, 654 | We cannot miss him: he does make our fire, 655 | Fetch in our wood and serves in offices 656 | That profit us. What, ho! slave! Caliban! 657 | Thou earth, thou! speak. 658 | 659 | CALIBAN [Within] There's wood enough within. 660 | 661 | PROSPERO Come forth, I say! there's other business for thee: 662 | Come, thou tortoise! when? 663 | 664 | [Re-enter ARIEL like a water-nymph] 665 | 666 | Fine apparition! My quaint Ariel, 667 | Hark in thine ear. 668 | 669 | ARIEL My lord it shall be done. 670 | 671 | [Exit] 672 | 673 | PROSPERO Thou poisonous slave, got by the devil himself 674 | Upon thy wicked dam, come forth! 675 | 676 | [Enter CALIBAN] 677 | 678 | CALIBAN As wicked dew as e'er my mother brush'd 679 | With raven's feather from unwholesome fen 680 | Drop on you both! a south-west blow on ye 681 | And blister you all o'er! 682 | 683 | PROSPERO For this, be sure, to-night thou shalt have cramps, 684 | Side-stitches that shall pen thy breath up; urchins 685 | Shall, for that vast of night that they may work, 686 | All exercise on thee; thou shalt be pinch'd 687 | As thick as honeycomb, each pinch more stinging 688 | Than bees that made 'em. 689 | 690 | CALIBAN I must eat my dinner. 691 | This island's mine, by Sycorax my mother, 692 | Which thou takest from me. When thou camest first, 693 | Thou strokedst me and madest much of me, wouldst give me 694 | Water with berries in't, and teach me how 695 | To name the bigger light, and how the less, 696 | That burn by day and night: and then I loved thee 697 | And show'd thee all the qualities o' the isle, 698 | The fresh springs, brine-pits, barren place and fertile: 699 | Cursed be I that did so! All the charms 700 | Of Sycorax, toads, beetles, bats, light on you! 701 | For I am all the subjects that you have, 702 | Which first was mine own king: and here you sty me 703 | In this hard rock, whiles you do keep from me 704 | The rest o' the island. 705 | 706 | PROSPERO Thou most lying slave, 707 | Whom stripes may move, not kindness! I have used thee, 708 | Filth as thou art, with human care, and lodged thee 709 | In mine own cell, till thou didst seek to violate 710 | The honour of my child. 711 | 712 | CALIBAN O ho, O ho! would't had been done! 713 | Thou didst prevent me; I had peopled else 714 | This isle with Calibans. 715 | 716 | PROSPERO Abhorred slave, 717 | Which any print of goodness wilt not take, 718 | Being capable of all ill! I pitied thee, 719 | Took pains to make thee speak, taught thee each hour 720 | One thing or other: when thou didst not, savage, 721 | Know thine own meaning, but wouldst gabble like 722 | A thing most brutish, I endow'd thy purposes 723 | With words that made them known. But thy vile race, 724 | Though thou didst learn, had that in't which 725 | good natures 726 | Could not abide to be with; therefore wast thou 727 | Deservedly confined into this rock, 728 | Who hadst deserved more than a prison. 729 | 730 | CALIBAN You taught me language; and my profit on't 731 | Is, I know how to curse. The red plague rid you 732 | For learning me your language! 733 | 734 | PROSPERO Hag-seed, hence! 735 | Fetch us in fuel; and be quick, thou'rt best, 736 | To answer other business. Shrug'st thou, malice? 737 | If thou neglect'st or dost unwillingly 738 | What I command, I'll rack thee with old cramps, 739 | Fill all thy bones with aches, make thee roar 740 | That beasts shall tremble at thy din. 741 | 742 | CALIBAN No, pray thee. 743 | 744 | [Aside] 745 | 746 | I must obey: his art is of such power, 747 | It would control my dam's god, Setebos, 748 | and make a vassal of him. 749 | 750 | PROSPERO So, slave; hence! 751 | 752 | [Exit CALIBAN] 753 | 754 | [Re-enter ARIEL, invisible, playing and singing; 755 | FERDINAND following] 756 | 757 | ARIEL'S song. 758 | 759 | Come unto these yellow sands, 760 | And then take hands: 761 | Courtsied when you have and kiss'd 762 | The wild waves whist, 763 | Foot it featly here and there; 764 | And, sweet sprites, the burthen bear. 765 | Hark, hark! 766 | 767 | [Burthen [dispersedly, within] Bow-wow] 768 | 769 | The watch-dogs bark! 770 | 771 | [Burthen Bow-wow] 772 | 773 | Hark, hark! I hear 774 | The strain of strutting chanticleer 775 | Cry, Cock-a-diddle-dow. 776 | 777 | FERDINAND Where should this music be? i' the air or the earth? 778 | It sounds no more: and sure, it waits upon 779 | Some god o' the island. Sitting on a bank, 780 | Weeping again the king my father's wreck, 781 | This music crept by me upon the waters, 782 | Allaying both their fury and my passion 783 | With its sweet air: thence I have follow'd it, 784 | Or it hath drawn me rather. But 'tis gone. 785 | No, it begins again. 786 | 787 | [ARIEL sings] 788 | 789 | Full fathom five thy father lies; 790 | Of his bones are coral made; 791 | Those are pearls that were his eyes: 792 | Nothing of him that doth fade 793 | But doth suffer a sea-change 794 | Into something rich and strange. 795 | Sea-nymphs hourly ring his knell 796 | 797 | [Burthen Ding-dong] 798 | 799 | Hark! now I hear them,--Ding-dong, bell. 800 | 801 | FERDINAND The ditty does remember my drown'd father. 802 | This is no mortal business, nor no sound 803 | That the earth owes. I hear it now above me. 804 | 805 | PROSPERO The fringed curtains of thine eye advance 806 | And say what thou seest yond. 807 | 808 | MIRANDA What is't? a spirit? 809 | Lord, how it looks about! Believe me, sir, 810 | It carries a brave form. But 'tis a spirit. 811 | 812 | PROSPERO No, wench; it eats and sleeps and hath such senses 813 | As we have, such. This gallant which thou seest 814 | Was in the wreck; and, but he's something stain'd 815 | With grief that's beauty's canker, thou mightst call him 816 | A goodly person: he hath lost his fellows 817 | And strays about to find 'em. 818 | 819 | MIRANDA I might call him 820 | A thing divine, for nothing natural 821 | I ever saw so noble. 822 | 823 | PROSPERO [Aside] It goes on, I see, 824 | As my soul prompts it. Spirit, fine spirit! I'll free thee 825 | Within two days for this. 826 | 827 | FERDINAND Most sure, the goddess 828 | On whom these airs attend! Vouchsafe my prayer 829 | May know if you remain upon this island; 830 | And that you will some good instruction give 831 | How I may bear me here: my prime request, 832 | Which I do last pronounce, is, O you wonder! 833 | If you be maid or no? 834 | 835 | MIRANDA No wonder, sir; 836 | But certainly a maid. 837 | 838 | FERDINAND My language! heavens! 839 | I am the best of them that speak this speech, 840 | Were I but where 'tis spoken. 841 | 842 | PROSPERO How? the best? 843 | What wert thou, if the King of Naples heard thee? 844 | 845 | FERDINAND A single thing, as I am now, that wonders 846 | To hear thee speak of Naples. He does hear me; 847 | And that he does I weep: myself am Naples, 848 | Who with mine eyes, never since at ebb, beheld 849 | The king my father wreck'd. 850 | 851 | MIRANDA Alack, for mercy! 852 | 853 | FERDINAND Yes, faith, and all his lords; the Duke of Milan 854 | And his brave son being twain. 855 | 856 | PROSPERO [Aside] The Duke of Milan 857 | And his more braver daughter could control thee, 858 | If now 'twere fit to do't. At the first sight 859 | They have changed eyes. Delicate Ariel, 860 | I'll set thee free for this. 861 | 862 | [To FERDINAND] 863 | 864 | A word, good sir; 865 | I fear you have done yourself some wrong: a word. 866 | 867 | MIRANDA Why speaks my father so ungently? This 868 | Is the third man that e'er I saw, the first 869 | That e'er I sigh'd for: pity move my father 870 | To be inclined my way! 871 | 872 | FERDINAND O, if a virgin, 873 | And your affection not gone forth, I'll make you 874 | The queen of Naples. 875 | 876 | PROSPERO Soft, sir! one word more. 877 | 878 | [Aside] 879 | 880 | They are both in either's powers; but this swift business 881 | I must uneasy make, lest too light winning 882 | Make the prize light. 883 | 884 | [To FERDINAND] 885 | 886 | One word more; I charge thee 887 | That thou attend me: thou dost here usurp 888 | The name thou owest not; and hast put thyself 889 | Upon this island as a spy, to win it 890 | From me, the lord on't. 891 | 892 | FERDINAND No, as I am a man. 893 | 894 | MIRANDA There's nothing ill can dwell in such a temple: 895 | If the ill spirit have so fair a house, 896 | Good things will strive to dwell with't. 897 | 898 | PROSPERO Follow me. 899 | Speak not you for him; he's a traitor. Come; 900 | I'll manacle thy neck and feet together: 901 | Sea-water shalt thou drink; thy food shall be 902 | The fresh-brook muscles, wither'd roots and husks 903 | Wherein the acorn cradled. Follow. 904 | 905 | FERDINAND No; 906 | I will resist such entertainment till 907 | Mine enemy has more power. 908 | 909 | [Draws, and is charmed from moving] 910 | 911 | MIRANDA O dear father, 912 | Make not too rash a trial of him, for 913 | He's gentle and not fearful. 914 | 915 | PROSPERO What? I say, 916 | My foot my tutor? Put thy sword up, traitor; 917 | Who makest a show but darest not strike, thy conscience 918 | Is so possess'd with guilt: come from thy ward, 919 | For I can here disarm thee with this stick 920 | And make thy weapon drop. 921 | 922 | MIRANDA Beseech you, father. 923 | 924 | PROSPERO Hence! hang not on my garments. 925 | 926 | MIRANDA Sir, have pity; 927 | I'll be his surety. 928 | 929 | PROSPERO Silence! one word more 930 | Shall make me chide thee, if not hate thee. What! 931 | An advocate for an imposter! hush! 932 | Thou think'st there is no more such shapes as he, 933 | Having seen but him and Caliban: foolish wench! 934 | To the most of men this is a Caliban 935 | And they to him are angels. 936 | 937 | MIRANDA My affections 938 | Are then most humble; I have no ambition 939 | To see a goodlier man. 940 | 941 | PROSPERO Come on; obey: 942 | Thy nerves are in their infancy again 943 | And have no vigour in them. 944 | 945 | FERDINAND So they are; 946 | My spirits, as in a dream, are all bound up. 947 | My father's loss, the weakness which I feel, 948 | The wreck of all my friends, nor this man's threats, 949 | To whom I am subdued, are but light to me, 950 | Might I but through my prison once a day 951 | Behold this maid: all corners else o' the earth 952 | Let liberty make use of; space enough 953 | Have I in such a prison. 954 | 955 | PROSPERO [Aside] It works. 956 | 957 | [To FERDINAND] 958 | 959 | Come on. 960 | Thou hast done well, fine Ariel! 961 | 962 | [To FERDINAND] 963 | 964 | Follow me. 965 | 966 | [To ARIEL] 967 | 968 | Hark what thou else shalt do me. 969 | 970 | MIRANDA Be of comfort; 971 | My father's of a better nature, sir, 972 | Than he appears by speech: this is unwonted 973 | Which now came from him. 974 | 975 | PROSPERO Thou shalt be free 976 | As mountain winds: but then exactly do 977 | All points of my command. 978 | 979 | ARIEL To the syllable. 980 | 981 | PROSPERO Come, follow. Speak not for him. 982 | 983 | [Exeunt] 984 | 985 | THE TEMPEST 986 | 987 | ACT II 988 | 989 | SCENE I Another part of the island. 990 | 991 | [Enter ALONSO, SEBASTIAN, ANTONIO, GONZALO, 992 | ADRIAN, FRANCISCO, and others] 993 | 994 | GONZALO Beseech you, sir, be merry; you have cause, 995 | So have we all, of joy; for our escape 996 | Is much beyond our loss. Our hint of woe 997 | Is common; every day some sailor's wife, 998 | The masters of some merchant and the merchant 999 | Have just our theme of woe; but for the miracle, 1000 | I mean our preservation, few in millions 1001 | Can speak like us: then wisely, good sir, weigh 1002 | Our sorrow with our comfort. 1003 | 1004 | ALONSO Prithee, peace. 1005 | 1006 | SEBASTIAN He receives comfort like cold porridge. 1007 | 1008 | ANTONIO The visitor will not give him o'er so. 1009 | 1010 | SEBASTIAN Look he's winding up the watch of his wit; 1011 | by and by it will strike. 1012 | 1013 | GONZALO Sir,-- 1014 | 1015 | SEBASTIAN One: tell. 1016 | 1017 | GONZALO When every grief is entertain'd that's offer'd, 1018 | Comes to the entertainer-- 1019 | 1020 | SEBASTIAN A dollar. 1021 | 1022 | GONZALO Dolour comes to him, indeed: you 1023 | have spoken truer than you purposed. 1024 | 1025 | SEBASTIAN You have taken it wiselier than I meant you should. 1026 | 1027 | GONZALO Therefore, my lord,-- 1028 | 1029 | ANTONIO Fie, what a spendthrift is he of his tongue! 1030 | 1031 | ALONSO I prithee, spare. 1032 | 1033 | GONZALO Well, I have done: but yet,-- 1034 | 1035 | SEBASTIAN He will be talking. 1036 | 1037 | ANTONIO Which, of he or Adrian, for a good 1038 | wager, first begins to crow? 1039 | 1040 | SEBASTIAN The old cock. 1041 | 1042 | ANTONIO The cockerel. 1043 | 1044 | SEBASTIAN Done. The wager? 1045 | 1046 | ANTONIO A laughter. 1047 | 1048 | SEBASTIAN A match! 1049 | 1050 | ADRIAN Though this island seem to be desert,-- 1051 | 1052 | SEBASTIAN Ha, ha, ha! So, you're paid. 1053 | 1054 | ADRIAN Uninhabitable and almost inaccessible,-- 1055 | 1056 | SEBASTIAN Yet,-- 1057 | 1058 | ADRIAN Yet,-- 1059 | 1060 | ANTONIO He could not miss't. 1061 | 1062 | ADRIAN It must needs be of subtle, tender and delicate 1063 | temperance. 1064 | 1065 | ANTONIO Temperance was a delicate wench. 1066 | 1067 | SEBASTIAN Ay, and a subtle; as he most learnedly delivered. 1068 | 1069 | ADRIAN The air breathes upon us here most sweetly. 1070 | 1071 | SEBASTIAN As if it had lungs and rotten ones. 1072 | 1073 | ANTONIO Or as 'twere perfumed by a fen. 1074 | 1075 | GONZALO Here is everything advantageous to life. 1076 | 1077 | ANTONIO True; save means to live. 1078 | 1079 | SEBASTIAN Of that there's none, or little. 1080 | 1081 | GONZALO How lush and lusty the grass looks! how green! 1082 | 1083 | ANTONIO The ground indeed is tawny. 1084 | 1085 | SEBASTIAN With an eye of green in't. 1086 | 1087 | ANTONIO He misses not much. 1088 | 1089 | SEBASTIAN No; he doth but mistake the truth totally. 1090 | 1091 | GONZALO But the rarity of it is,--which is indeed almost 1092 | beyond credit,-- 1093 | 1094 | SEBASTIAN As many vouched rarities are. 1095 | 1096 | GONZALO That our garments, being, as they were, drenched in 1097 | the sea, hold notwithstanding their freshness and 1098 | glosses, being rather new-dyed than stained with 1099 | salt water. 1100 | 1101 | ANTONIO If but one of his pockets could speak, would it not 1102 | say he lies? 1103 | 1104 | SEBASTIAN Ay, or very falsely pocket up his report 1105 | 1106 | GONZALO Methinks our garments are now as fresh as when we 1107 | put them on first in Afric, at the marriage of 1108 | the king's fair daughter Claribel to the King of Tunis. 1109 | 1110 | SEBASTIAN 'Twas a sweet marriage, and we prosper well in our return. 1111 | 1112 | ADRIAN Tunis was never graced before with such a paragon to 1113 | their queen. 1114 | 1115 | GONZALO Not since widow Dido's time. 1116 | 1117 | ANTONIO Widow! a pox o' that! How came that widow in? 1118 | widow Dido! 1119 | 1120 | SEBASTIAN What if he had said 'widower AEneas' too? Good Lord, 1121 | how you take it! 1122 | 1123 | ADRIAN 'Widow Dido' said you? you make me study of that: 1124 | she was of Carthage, not of Tunis. 1125 | 1126 | GONZALO This Tunis, sir, was Carthage. 1127 | 1128 | ADRIAN Carthage? 1129 | 1130 | GONZALO I assure you, Carthage. 1131 | 1132 | SEBASTIAN His word is more than the miraculous harp; he hath 1133 | raised the wall and houses too. 1134 | 1135 | ANTONIO What impossible matter will he make easy next? 1136 | 1137 | SEBASTIAN I think he will carry this island home in his pocket 1138 | and give it his son for an apple. 1139 | 1140 | ANTONIO And, sowing the kernels of it in the sea, bring 1141 | forth more islands. 1142 | 1143 | GONZALO Ay. 1144 | 1145 | ANTONIO Why, in good time. 1146 | 1147 | GONZALO Sir, we were talking that our garments seem now 1148 | as fresh as when we were at Tunis at the marriage 1149 | of your daughter, who is now queen. 1150 | 1151 | ANTONIO And the rarest that e'er came there. 1152 | 1153 | SEBASTIAN Bate, I beseech you, widow Dido. 1154 | 1155 | ANTONIO O, widow Dido! ay, widow Dido. 1156 | 1157 | GONZALO Is not, sir, my doublet as fresh as the first day I 1158 | wore it? I mean, in a sort. 1159 | 1160 | ANTONIO That sort was well fished for. 1161 | 1162 | GONZALO When I wore it at your daughter's marriage? 1163 | 1164 | ALONSO You cram these words into mine ears against 1165 | The stomach of my sense. Would I had never 1166 | Married my daughter there! for, coming thence, 1167 | My son is lost and, in my rate, she too, 1168 | Who is so far from Italy removed 1169 | I ne'er again shall see her. O thou mine heir 1170 | Of Naples and of Milan, what strange fish 1171 | Hath made his meal on thee? 1172 | 1173 | FRANCISCO Sir, he may live: 1174 | I saw him beat the surges under him, 1175 | And ride upon their backs; he trod the water, 1176 | Whose enmity he flung aside, and breasted 1177 | The surge most swoln that met him; his bold head 1178 | 'Bove the contentious waves he kept, and oar'd 1179 | Himself with his good arms in lusty stroke 1180 | To the shore, that o'er his wave-worn basis bow'd, 1181 | As stooping to relieve him: I not doubt 1182 | He came alive to land. 1183 | 1184 | ALONSO No, no, he's gone. 1185 | 1186 | SEBASTIAN Sir, you may thank yourself for this great loss, 1187 | That would not bless our Europe with your daughter, 1188 | But rather lose her to an African; 1189 | Where she at least is banish'd from your eye, 1190 | Who hath cause to wet the grief on't. 1191 | 1192 | ALONSO Prithee, peace. 1193 | 1194 | SEBASTIAN You were kneel'd to and importuned otherwise 1195 | By all of us, and the fair soul herself 1196 | Weigh'd between loathness and obedience, at 1197 | Which end o' the beam should bow. We have lost your 1198 | son, 1199 | I fear, for ever: Milan and Naples have 1200 | More widows in them of this business' making 1201 | Than we bring men to comfort them: 1202 | The fault's your own. 1203 | 1204 | ALONSO So is the dear'st o' the loss. 1205 | 1206 | GONZALO My lord Sebastian, 1207 | The truth you speak doth lack some gentleness 1208 | And time to speak it in: you rub the sore, 1209 | When you should bring the plaster. 1210 | 1211 | SEBASTIAN Very well. 1212 | 1213 | ANTONIO And most chirurgeonly. 1214 | 1215 | GONZALO It is foul weather in us all, good sir, 1216 | When you are cloudy. 1217 | 1218 | SEBASTIAN Foul weather? 1219 | 1220 | ANTONIO Very foul. 1221 | 1222 | GONZALO Had I plantation of this isle, my lord,-- 1223 | 1224 | ANTONIO He'ld sow't with nettle-seed. 1225 | 1226 | SEBASTIAN Or docks, or mallows. 1227 | 1228 | GONZALO And were the king on't, what would I do? 1229 | 1230 | SEBASTIAN 'Scape being drunk for want of wine. 1231 | 1232 | GONZALO I' the commonwealth I would by contraries 1233 | Execute all things; for no kind of traffic 1234 | Would I admit; no name of magistrate; 1235 | Letters should not be known; riches, poverty, 1236 | And use of service, none; contract, succession, 1237 | Bourn, bound of land, tilth, vineyard, none; 1238 | No use of metal, corn, or wine, or oil; 1239 | No occupation; all men idle, all; 1240 | And women too, but innocent and pure; 1241 | No sovereignty;-- 1242 | 1243 | SEBASTIAN Yet he would be king on't. 1244 | 1245 | ANTONIO The latter end of his commonwealth forgets the 1246 | beginning. 1247 | 1248 | GONZALO All things in common nature should produce 1249 | Without sweat or endeavour: treason, felony, 1250 | Sword, pike, knife, gun, or need of any engine, 1251 | Would I not have; but nature should bring forth, 1252 | Of its own kind, all foison, all abundance, 1253 | To feed my innocent people. 1254 | 1255 | SEBASTIAN No marrying 'mong his subjects? 1256 | 1257 | ANTONIO None, man; all idle: whores and knaves. 1258 | 1259 | GONZALO I would with such perfection govern, sir, 1260 | To excel the golden age. 1261 | 1262 | SEBASTIAN God save his majesty! 1263 | 1264 | ANTONIO Long live Gonzalo! 1265 | 1266 | GONZALO And,--do you mark me, sir? 1267 | 1268 | ALONSO Prithee, no more: thou dost talk nothing to me. 1269 | 1270 | GONZALO I do well believe your highness; and 1271 | did it to minister occasion to these gentlemen, 1272 | who are of such sensible and nimble lungs that 1273 | they always use to laugh at nothing. 1274 | 1275 | ANTONIO 'Twas you we laughed at. 1276 | 1277 | GONZALO Who in this kind of merry fooling am nothing 1278 | to you: so you may continue and laugh at 1279 | nothing still. 1280 | 1281 | ANTONIO What a blow was there given! 1282 | 1283 | SEBASTIAN An it had not fallen flat-long. 1284 | 1285 | GONZALO You are gentlemen of brave metal; you would lift 1286 | the moon out of her sphere, if she would continue 1287 | in it five weeks without changing. 1288 | 1289 | [Enter ARIEL, invisible, playing solemn music] 1290 | 1291 | SEBASTIAN We would so, and then go a bat-fowling. 1292 | 1293 | ANTONIO Nay, good my lord, be not angry. 1294 | 1295 | GONZALO No, I warrant you; I will not adventure 1296 | my discretion so weakly. Will you laugh 1297 | me asleep, for I am very heavy? 1298 | 1299 | ANTONIO Go sleep, and hear us. 1300 | 1301 | [All sleep except ALONSO, SEBASTIAN, and ANTONIO] 1302 | 1303 | ALONSO What, all so soon asleep! I wish mine eyes 1304 | Would, with themselves, shut up my thoughts: I find 1305 | They are inclined to do so. 1306 | 1307 | SEBASTIAN Please you, sir, 1308 | Do not omit the heavy offer of it: 1309 | It seldom visits sorrow; when it doth, 1310 | It is a comforter. 1311 | 1312 | ANTONIO We two, my lord, 1313 | Will guard your person while you take your rest, 1314 | And watch your safety. 1315 | 1316 | ALONSO Thank you. Wondrous heavy. 1317 | 1318 | [ALONSO sleeps. Exit ARIEL] 1319 | 1320 | SEBASTIAN What a strange drowsiness possesses them! 1321 | 1322 | ANTONIO It is the quality o' the climate. 1323 | 1324 | SEBASTIAN Why 1325 | Doth it not then our eyelids sink? I find not 1326 | Myself disposed to sleep. 1327 | 1328 | ANTONIO Nor I; my spirits are nimble. 1329 | They fell together all, as by consent; 1330 | They dropp'd, as by a thunder-stroke. What might, 1331 | Worthy Sebastian? O, what might?--No more:-- 1332 | And yet me thinks I see it in thy face, 1333 | What thou shouldst be: the occasion speaks thee, and 1334 | My strong imagination sees a crown 1335 | Dropping upon thy head. 1336 | 1337 | SEBASTIAN What, art thou waking? 1338 | 1339 | ANTONIO Do you not hear me speak? 1340 | 1341 | SEBASTIAN I do; and surely 1342 | It is a sleepy language and thou speak'st 1343 | Out of thy sleep. What is it thou didst say? 1344 | This is a strange repose, to be asleep 1345 | With eyes wide open; standing, speaking, moving, 1346 | And yet so fast asleep. 1347 | 1348 | ANTONIO Noble Sebastian, 1349 | Thou let'st thy fortune sleep--die, rather; wink'st 1350 | Whiles thou art waking. 1351 | 1352 | SEBASTIAN Thou dost snore distinctly; 1353 | There's meaning in thy snores. 1354 | 1355 | ANTONIO I am more serious than my custom: you 1356 | Must be so too, if heed me; which to do 1357 | Trebles thee o'er. 1358 | 1359 | SEBASTIAN Well, I am standing water. 1360 | 1361 | ANTONIO I'll teach you how to flow. 1362 | 1363 | SEBASTIAN Do so: to ebb 1364 | Hereditary sloth instructs me. 1365 | 1366 | ANTONIO O, 1367 | If you but knew how you the purpose cherish 1368 | Whiles thus you mock it! how, in stripping it, 1369 | You more invest it! Ebbing men, indeed, 1370 | Most often do so near the bottom run 1371 | By their own fear or sloth. 1372 | 1373 | SEBASTIAN Prithee, say on: 1374 | The setting of thine eye and cheek proclaim 1375 | A matter from thee, and a birth indeed 1376 | Which throes thee much to yield. 1377 | 1378 | ANTONIO Thus, sir: 1379 | Although this lord of weak remembrance, this, 1380 | Who shall be of as little memory 1381 | When he is earth'd, hath here almost persuade,-- 1382 | For he's a spirit of persuasion, only 1383 | Professes to persuade,--the king his son's alive, 1384 | 'Tis as impossible that he's undrown'd 1385 | And he that sleeps here swims. 1386 | 1387 | SEBASTIAN I have no hope 1388 | That he's undrown'd. 1389 | 1390 | ANTONIO O, out of that 'no hope' 1391 | What great hope have you! no hope that way is 1392 | Another way so high a hope that even 1393 | Ambition cannot pierce a wink beyond, 1394 | But doubt discovery there. Will you grant with me 1395 | That Ferdinand is drown'd? 1396 | 1397 | SEBASTIAN He's gone. 1398 | 1399 | ANTONIO Then, tell me, 1400 | Who's the next heir of Naples? 1401 | 1402 | SEBASTIAN Claribel. 1403 | 1404 | ANTONIO She that is queen of Tunis; she that dwells 1405 | Ten leagues beyond man's life; she that from Naples 1406 | Can have no note, unless the sun were post-- 1407 | The man i' the moon's too slow--till new-born chins 1408 | Be rough and razorable; she that--from whom? 1409 | We all were sea-swallow'd, though some cast again, 1410 | And by that destiny to perform an act 1411 | Whereof what's past is prologue, what to come 1412 | In yours and my discharge. 1413 | 1414 | SEBASTIAN What stuff is this! how say you? 1415 | 'Tis true, my brother's daughter's queen of Tunis; 1416 | So is she heir of Naples; 'twixt which regions 1417 | There is some space. 1418 | 1419 | ANTONIO A space whose every cubit 1420 | Seems to cry out, 'How shall that Claribel 1421 | Measure us back to Naples? Keep in Tunis, 1422 | And let Sebastian wake.' Say, this were death 1423 | That now hath seized them; why, they were no worse 1424 | Than now they are. There be that can rule Naples 1425 | As well as he that sleeps; lords that can prate 1426 | As amply and unnecessarily 1427 | As this Gonzalo; I myself could make 1428 | A chough of as deep chat. O, that you bore 1429 | The mind that I do! what a sleep were this 1430 | For your advancement! Do you understand me? 1431 | 1432 | SEBASTIAN Methinks I do. 1433 | 1434 | ANTONIO And how does your content 1435 | Tender your own good fortune? 1436 | 1437 | SEBASTIAN I remember 1438 | You did supplant your brother Prospero. 1439 | 1440 | ANTONIO True: 1441 | And look how well my garments sit upon me; 1442 | Much feater than before: my brother's servants 1443 | Were then my fellows; now they are my men. 1444 | 1445 | SEBASTIAN But, for your conscience? 1446 | 1447 | ANTONIO Ay, sir; where lies that? if 'twere a kibe, 1448 | 'Twould put me to my slipper: but I feel not 1449 | This deity in my bosom: twenty consciences, 1450 | That stand 'twixt me and Milan, candied be they 1451 | And melt ere they molest! Here lies your brother, 1452 | No better than the earth he lies upon, 1453 | If he were that which now he's like, that's dead; 1454 | Whom I, with this obedient steel, three inches of it, 1455 | Can lay to bed for ever; whiles you, doing thus, 1456 | To the perpetual wink for aye might put 1457 | This ancient morsel, this Sir Prudence, who 1458 | Should not upbraid our course. For all the rest, 1459 | They'll take suggestion as a cat laps milk; 1460 | They'll tell the clock to any business that 1461 | We say befits the hour. 1462 | 1463 | SEBASTIAN Thy case, dear friend, 1464 | Shall be my precedent; as thou got'st Milan, 1465 | I'll come by Naples. Draw thy sword: one stroke 1466 | Shall free thee from the tribute which thou payest; 1467 | And I the king shall love thee. 1468 | 1469 | ANTONIO Draw together; 1470 | And when I rear my hand, do you the like, 1471 | To fall it on Gonzalo. 1472 | 1473 | SEBASTIAN O, but one word. 1474 | 1475 | [They talk apart] 1476 | 1477 | [Re-enter ARIEL, invisible] 1478 | 1479 | ARIEL My master through his art foresees the danger 1480 | That you, his friend, are in; and sends me forth-- 1481 | For else his project dies--to keep them living. 1482 | 1483 | [Sings in GONZALO's ear] 1484 | 1485 | While you here do snoring lie, 1486 | Open-eyed conspiracy 1487 | His time doth take. 1488 | If of life you keep a care, 1489 | Shake off slumber, and beware: 1490 | Awake, awake! 1491 | 1492 | ANTONIO Then let us both be sudden. 1493 | 1494 | GONZALO Now, good angels 1495 | Preserve the king. 1496 | 1497 | [They wake] 1498 | 1499 | ALONSO Why, how now? ho, awake! Why are you drawn? 1500 | Wherefore this ghastly looking? 1501 | 1502 | GONZALO What's the matter? 1503 | 1504 | SEBASTIAN Whiles we stood here securing your repose, 1505 | Even now, we heard a hollow burst of bellowing 1506 | Like bulls, or rather lions: did't not wake you? 1507 | It struck mine ear most terribly. 1508 | 1509 | ALONSO I heard nothing. 1510 | 1511 | ANTONIO O, 'twas a din to fright a monster's ear, 1512 | To make an earthquake! sure, it was the roar 1513 | Of a whole herd of lions. 1514 | 1515 | ALONSO Heard you this, Gonzalo? 1516 | 1517 | GONZALO Upon mine honour, sir, I heard a humming, 1518 | And that a strange one too, which did awake me: 1519 | I shaked you, sir, and cried: as mine eyes open'd, 1520 | I saw their weapons drawn: there was a noise, 1521 | That's verily. 'Tis best we stand upon our guard, 1522 | Or that we quit this place; let's draw our weapons. 1523 | 1524 | ALONSO Lead off this ground; and let's make further search 1525 | For my poor son. 1526 | 1527 | GONZALO Heavens keep him from these beasts! 1528 | For he is, sure, i' the island. 1529 | 1530 | ALONSO Lead away. 1531 | 1532 | ARIEL Prospero my lord shall know what I have done: 1533 | So, king, go safely on to seek thy son. 1534 | 1535 | [Exeunt] 1536 | 1537 | THE TEMPEST 1538 | 1539 | ACT II 1540 | 1541 | SCENE II Another part of the island. 1542 | 1543 | [Enter CALIBAN with a burden of wood. A noise of 1544 | thunder heard] 1545 | 1546 | CALIBAN All the infections that the sun sucks up 1547 | From bogs, fens, flats, on Prosper fall and make him 1548 | By inch-meal a disease! His spirits hear me 1549 | And yet I needs must curse. But they'll nor pinch, 1550 | Fright me with urchin--shows, pitch me i' the mire, 1551 | Nor lead me, like a firebrand, in the dark 1552 | Out of my way, unless he bid 'em; but 1553 | For every trifle are they set upon me; 1554 | Sometime like apes that mow and chatter at me 1555 | And after bite me, then like hedgehogs which 1556 | Lie tumbling in my barefoot way and mount 1557 | Their pricks at my footfall; sometime am I 1558 | All wound with adders who with cloven tongues 1559 | Do hiss me into madness. 1560 | 1561 | [Enter TRINCULO] 1562 | 1563 | Lo, now, lo! 1564 | 1565 | Here comes a spirit of his, and to torment me 1566 | For bringing wood in slowly. I'll fall flat; 1567 | Perchance he will not mind me. 1568 | 1569 | TRINCULO Here's neither bush nor shrub, to bear off 1570 | any weather at all, and another storm brewing; 1571 | I hear it sing i' the wind: yond same black 1572 | cloud, yond huge one, looks like a foul 1573 | bombard that would shed his liquor. If it 1574 | should thunder as it did before, I know not 1575 | where to hide my head: yond same cloud cannot 1576 | choose but fall by pailfuls. What have we 1577 | here? a man or a fish? dead or alive? A fish: 1578 | he smells like a fish; a very ancient and fish- 1579 | like smell; a kind of not of the newest Poor- 1580 | John. A strange fish! Were I in England now, 1581 | as once I was, and had but this fish painted, 1582 | not a holiday fool there but would give a piece 1583 | of silver: there would this monster make a 1584 | man; any strange beast there makes a man: 1585 | when they will not give a doit to relieve a lame 1586 | beggar, they will lazy out ten to see a dead 1587 | Indian. Legged like a man and his fins like 1588 | arms! Warm o' my troth! I do now let loose 1589 | my opinion; hold it no longer: this is no fish, 1590 | but an islander, that hath lately suffered by a 1591 | thunderbolt. 1592 | 1593 | [Thunder] 1594 | 1595 | Alas, the storm is come again! my best way is to 1596 | creep under his gaberdine; there is no other 1597 | shelter hereabouts: misery acquaints a man with 1598 | strange bed-fellows. I will here shroud till the 1599 | dregs of the storm be past. 1600 | 1601 | [Enter STEPHANO, singing: a bottle in his hand] 1602 | 1603 | STEPHANO I shall no more to sea, to sea, 1604 | Here shall I die ashore-- 1605 | 1606 | This is a very scurvy tune to sing at a man's 1607 | funeral: well, here's my comfort. [Drinks] 1608 | 1609 | [Sings] 1610 | 1611 | The master, the swabber, the boatswain and I, 1612 | The gunner and his mate 1613 | Loved Mall, Meg and Marian and Margery, 1614 | But none of us cared for Kate; 1615 | For she had a tongue with a tang, 1616 | Would cry to a sailor, Go hang! 1617 | She loved not the savour of tar nor of pitch, 1618 | Yet a tailor might scratch her where'er she did itch: 1619 | Then to sea, boys, and let her go hang! 1620 | 1621 | This is a scurvy tune too: but here's my comfort. 1622 | [Drinks] 1623 | 1624 | CALIBAN Do not torment me: Oh! 1625 | 1626 | STEPHANO What's the matter? Have we devils here? Do you put 1627 | tricks upon's with savages and men of Ind, ha? I 1628 | have not scaped drowning to be afeard now of your 1629 | four legs; for it hath been said, As proper a man as 1630 | ever went on four legs cannot make him give ground; 1631 | and it shall be said so again while Stephano 1632 | breathes at's nostrils. 1633 | 1634 | CALIBAN The spirit torments me; Oh! 1635 | 1636 | STEPHANO This is some monster of the isle with four legs, who 1637 | hath got, as I take it, an ague. Where the devil 1638 | should he learn our language? I will give him some 1639 | relief, if it be but for that. if I can recover him 1640 | and keep him tame and get to Naples with him, he's a 1641 | present for any emperor that ever trod on neat's leather. 1642 | 1643 | CALIBAN Do not torment me, prithee; I'll bring my wood home faster. 1644 | 1645 | STEPHANO He's in his fit now and does not talk after the 1646 | wisest. He shall taste of my bottle: if he have 1647 | never drunk wine afore will go near to remove his 1648 | fit. If I can recover him and keep him tame, I will 1649 | not take too much for him; he shall pay for him that 1650 | hath him, and that soundly. 1651 | 1652 | CALIBAN Thou dost me yet but little hurt; thou wilt anon, I 1653 | know it by thy trembling: now Prosper works upon thee. 1654 | 1655 | STEPHANO Come on your ways; open your mouth; here is that 1656 | which will give language to you, cat: open your 1657 | mouth; this will shake your shaking, I can tell you, 1658 | and that soundly: you cannot tell who's your friend: 1659 | open your chaps again. 1660 | 1661 | TRINCULO I should know that voice: it should be--but he is 1662 | drowned; and these are devils: O defend me! 1663 | 1664 | STEPHANO Four legs and two voices: a most delicate monster! 1665 | His forward voice now is to speak well of his 1666 | friend; his backward voice is to utter foul speeches 1667 | and to detract. If all the wine in my bottle will 1668 | recover him, I will help his ague. Come. Amen! I 1669 | will pour some in thy other mouth. 1670 | 1671 | TRINCULO Stephano! 1672 | 1673 | STEPHANO Doth thy other mouth call me? Mercy, mercy! This is 1674 | a devil, and no monster: I will leave him; I have no 1675 | long spoon. 1676 | 1677 | TRINCULO Stephano! If thou beest Stephano, touch me and 1678 | speak to me: for I am Trinculo--be not afeard--thy 1679 | good friend Trinculo. 1680 | 1681 | STEPHANO If thou beest Trinculo, come forth: I'll pull thee 1682 | by the lesser legs: if any be Trinculo's legs, 1683 | these are they. Thou art very Trinculo indeed! How 1684 | camest thou to be the siege of this moon-calf? can 1685 | he vent Trinculos? 1686 | 1687 | TRINCULO I took him to be killed with a thunder-stroke. But 1688 | art thou not drowned, Stephano? I hope now thou art 1689 | not drowned. Is the storm overblown? I hid me 1690 | under the dead moon-calf's gaberdine for fear of 1691 | the storm. And art thou living, Stephano? O 1692 | Stephano, two Neapolitans 'scaped! 1693 | 1694 | STEPHANO Prithee, do not turn me about; my stomach is not constant. 1695 | 1696 | CALIBAN [Aside] These be fine things, an if they be 1697 | not sprites. 1698 | That's a brave god and bears celestial liquor. 1699 | I will kneel to him. 1700 | 1701 | STEPHANO How didst thou 'scape? How camest thou hither? 1702 | swear by this bottle how thou camest hither. I 1703 | escaped upon a butt of sack which the sailors 1704 | heaved o'erboard, by this bottle; which I made of 1705 | the bark of a tree with mine own hands since I was 1706 | cast ashore. 1707 | 1708 | CALIBAN I'll swear upon that bottle to be thy true subject; 1709 | for the liquor is not earthly. 1710 | 1711 | STEPHANO Here; swear then how thou escapedst. 1712 | 1713 | TRINCULO Swum ashore. man, like a duck: I can swim like a 1714 | duck, I'll be sworn. 1715 | 1716 | STEPHANO Here, kiss the book. Though thou canst swim like a 1717 | duck, thou art made like a goose. 1718 | 1719 | TRINCULO O Stephano. hast any more of this? 1720 | 1721 | STEPHANO The whole butt, man: my cellar is in a rock by the 1722 | sea-side where my wine is hid. How now, moon-calf! 1723 | how does thine ague? 1724 | 1725 | CALIBAN Hast thou not dropp'd from heaven? 1726 | 1727 | STEPHANO Out o' the moon, I do assure thee: I was the man i' 1728 | the moon when time was. 1729 | 1730 | CALIBAN I have seen thee in her and I do adore thee: 1731 | My mistress show'd me thee and thy dog and thy bush. 1732 | 1733 | STEPHANO Come, swear to that; kiss the book: I will furnish 1734 | it anon with new contents swear. 1735 | 1736 | TRINCULO By this good light, this is a very shallow monster! 1737 | I afeard of him! A very weak monster! The man i' 1738 | the moon! A most poor credulous monster! Well 1739 | drawn, monster, in good sooth! 1740 | 1741 | CALIBAN I'll show thee every fertile inch o' th' island; 1742 | And I will kiss thy foot: I prithee, be my god. 1743 | 1744 | TRINCULO By this light, a most perfidious and drunken 1745 | monster! when 's god's asleep, he'll rob his bottle. 1746 | 1747 | CALIBAN I'll kiss thy foot; I'll swear myself thy subject. 1748 | 1749 | STEPHANO Come on then; down, and swear. 1750 | 1751 | TRINCULO I shall laugh myself to death at this puppy-headed 1752 | monster. A most scurvy monster! I could find in my 1753 | heart to beat him,-- 1754 | 1755 | STEPHANO Come, kiss. 1756 | 1757 | TRINCULO But that the poor monster's in drink: an abominable monster! 1758 | 1759 | CALIBAN I'll show thee the best springs; I'll pluck thee berries; 1760 | I'll fish for thee and get thee wood enough. 1761 | A plague upon the tyrant that I serve! 1762 | I'll bear him no more sticks, but follow thee, 1763 | Thou wondrous man. 1764 | 1765 | TRINCULO A most ridiculous monster, to make a wonder of a 1766 | Poor drunkard! 1767 | 1768 | CALIBAN I prithee, let me bring thee where crabs grow; 1769 | And I with my long nails will dig thee pignuts; 1770 | Show thee a jay's nest and instruct thee how 1771 | To snare the nimble marmoset; I'll bring thee 1772 | To clustering filberts and sometimes I'll get thee 1773 | Young scamels from the rock. Wilt thou go with me? 1774 | 1775 | STEPHANO I prithee now, lead the way without any more 1776 | talking. Trinculo, the king and all our company 1777 | else being drowned, we will inherit here: here; 1778 | bear my bottle: fellow Trinculo, we'll fill him by 1779 | and by again. 1780 | 1781 | CALIBAN [Sings drunkenly] 1782 | Farewell master; farewell, farewell! 1783 | 1784 | TRINCULO A howling monster: a drunken monster! 1785 | 1786 | CALIBAN No more dams I'll make for fish 1787 | Nor fetch in firing 1788 | At requiring; 1789 | Nor scrape trencher, nor wash dish 1790 | 'Ban, 'Ban, Cacaliban 1791 | Has a new master: get a new man. 1792 | 1793 | Freedom, hey-day! hey-day, freedom! freedom, 1794 | hey-day, freedom! 1795 | 1796 | STEPHANO O brave monster! Lead the way. 1797 | 1798 | [Exeunt] 1799 | 1800 | THE TEMPEST 1801 | 1802 | ACT III 1803 | 1804 | SCENE I Before PROSPERO'S Cell. 1805 | 1806 | [Enter FERDINAND, bearing a log] 1807 | 1808 | FERDINAND There be some sports are painful, and their labour 1809 | Delight in them sets off: some kinds of baseness 1810 | Are nobly undergone and most poor matters 1811 | Point to rich ends. This my mean task 1812 | Would be as heavy to me as odious, but 1813 | The mistress which I serve quickens what's dead 1814 | And makes my labours pleasures: O, she is 1815 | Ten times more gentle than her father's crabbed, 1816 | And he's composed of harshness. I must remove 1817 | Some thousands of these logs and pile them up, 1818 | Upon a sore injunction: my sweet mistress 1819 | Weeps when she sees me work, and says, such baseness 1820 | Had never like executor. I forget: 1821 | But these sweet thoughts do even refresh my labours, 1822 | Most busy lest, when I do it. 1823 | 1824 | [Enter MIRANDA; and PROSPERO at a distance, unseen] 1825 | 1826 | MIRANDA Alas, now, pray you, 1827 | Work not so hard: I would the lightning had 1828 | Burnt up those logs that you are enjoin'd to pile! 1829 | Pray, set it down and rest you: when this burns, 1830 | 'Twill weep for having wearied you. My father 1831 | Is hard at study; pray now, rest yourself; 1832 | He's safe for these three hours. 1833 | 1834 | FERDINAND O most dear mistress, 1835 | The sun will set before I shall discharge 1836 | What I must strive to do. 1837 | 1838 | MIRANDA If you'll sit down, 1839 | I'll bear your logs the while: pray, give me that; 1840 | I'll carry it to the pile. 1841 | 1842 | FERDINAND No, precious creature; 1843 | I had rather crack my sinews, break my back, 1844 | Than you should such dishonour undergo, 1845 | While I sit lazy by. 1846 | 1847 | MIRANDA It would become me 1848 | As well as it does you: and I should do it 1849 | With much more ease; for my good will is to it, 1850 | And yours it is against. 1851 | 1852 | PROSPERO Poor worm, thou art infected! 1853 | This visitation shows it. 1854 | 1855 | MIRANDA You look wearily. 1856 | 1857 | FERDINAND No, noble mistress;'tis fresh morning with me 1858 | When you are by at night. I do beseech you-- 1859 | Chiefly that I might set it in my prayers-- 1860 | What is your name? 1861 | 1862 | MIRANDA Miranda.--O my father, 1863 | I have broke your hest to say so! 1864 | 1865 | FERDINAND Admired Miranda! 1866 | Indeed the top of admiration! worth 1867 | What's dearest to the world! Full many a lady 1868 | I have eyed with best regard and many a time 1869 | The harmony of their tongues hath into bondage 1870 | Brought my too diligent ear: for several virtues 1871 | Have I liked several women; never any 1872 | With so fun soul, but some defect in her 1873 | Did quarrel with the noblest grace she owed 1874 | And put it to the foil: but you, O you, 1875 | So perfect and so peerless, are created 1876 | Of every creature's best! 1877 | 1878 | MIRANDA I do not know 1879 | One of my sex; no woman's face remember, 1880 | Save, from my glass, mine own; nor have I seen 1881 | More that I may call men than you, good friend, 1882 | And my dear father: how features are abroad, 1883 | I am skilless of; but, by my modesty, 1884 | The jewel in my dower, I would not wish 1885 | Any companion in the world but you, 1886 | Nor can imagination form a shape, 1887 | Besides yourself, to like of. But I prattle 1888 | Something too wildly and my father's precepts 1889 | I therein do forget. 1890 | 1891 | FERDINAND I am in my condition 1892 | A prince, Miranda; I do think, a king; 1893 | I would, not so!--and would no more endure 1894 | This wooden slavery than to suffer 1895 | The flesh-fly blow my mouth. Hear my soul speak: 1896 | The very instant that I saw you, did 1897 | My heart fly to your service; there resides, 1898 | To make me slave to it; and for your sake 1899 | Am I this patient log--man. 1900 | 1901 | MIRANDA Do you love me? 1902 | 1903 | FERDINAND O heaven, O earth, bear witness to this sound 1904 | And crown what I profess with kind event 1905 | If I speak true! if hollowly, invert 1906 | What best is boded me to mischief! I 1907 | Beyond all limit of what else i' the world 1908 | Do love, prize, honour you. 1909 | 1910 | MIRANDA I am a fool 1911 | To weep at what I am glad of. 1912 | 1913 | PROSPERO Fair encounter 1914 | Of two most rare affections! Heavens rain grace 1915 | On that which breeds between 'em! 1916 | 1917 | FERDINAND Wherefore weep you? 1918 | 1919 | MIRANDA At mine unworthiness that dare not offer 1920 | What I desire to give, and much less take 1921 | What I shall die to want. But this is trifling; 1922 | And all the more it seeks to hide itself, 1923 | The bigger bulk it shows. Hence, bashful cunning! 1924 | And prompt me, plain and holy innocence! 1925 | I am your wife, it you will marry me; 1926 | If not, I'll die your maid: to be your fellow 1927 | You may deny me; but I'll be your servant, 1928 | Whether you will or no. 1929 | 1930 | FERDINAND My mistress, dearest; 1931 | And I thus humble ever. 1932 | 1933 | MIRANDA My husband, then? 1934 | 1935 | FERDINAND Ay, with a heart as willing 1936 | As bondage e'er of freedom: here's my hand. 1937 | 1938 | MIRANDA And mine, with my heart in't; and now farewell 1939 | Till half an hour hence. 1940 | 1941 | FERDINAND A thousand thousand! 1942 | 1943 | [Exeunt FERDINAND and MIRANDA severally] 1944 | 1945 | PROSPERO So glad of this as they I cannot be, 1946 | Who are surprised withal; but my rejoicing 1947 | At nothing can be more. I'll to my book, 1948 | For yet ere supper-time must I perform 1949 | Much business appertaining. 1950 | 1951 | [Exit] 1952 | 1953 | THE TEMPEST 1954 | 1955 | ACT III 1956 | 1957 | SCENE II Another part of the island. 1958 | 1959 | [Enter CALIBAN, STEPHANO, and TRINCULO] 1960 | 1961 | STEPHANO Tell not me; when the butt is out, we will drink 1962 | water; not a drop before: therefore bear up, and 1963 | board 'em. Servant-monster, drink to me. 1964 | 1965 | TRINCULO Servant-monster! the folly of this island! They 1966 | say there's but five upon this isle: we are three 1967 | of them; if th' other two be brained like us, the 1968 | state totters. 1969 | 1970 | STEPHANO Drink, servant-monster, when I bid thee: thy eyes 1971 | are almost set in thy head. 1972 | 1973 | TRINCULO Where should they be set else? he were a brave 1974 | monster indeed, if they were set in his tail. 1975 | 1976 | STEPHANO My man-monster hath drown'd his tongue in sack: 1977 | for my part, the sea cannot drown me; I swam, ere I 1978 | could recover the shore, five and thirty leagues off 1979 | and on. By this light, thou shalt be my lieutenant, 1980 | monster, or my standard. 1981 | 1982 | TRINCULO Your lieutenant, if you list; he's no standard. 1983 | 1984 | STEPHANO We'll not run, Monsieur Monster. 1985 | 1986 | TRINCULO Nor go neither; but you'll lie like dogs and yet say 1987 | nothing neither. 1988 | 1989 | STEPHANO Moon-calf, speak once in thy life, if thou beest a 1990 | good moon-calf. 1991 | 1992 | CALIBAN How does thy honour? Let me lick thy shoe. 1993 | I'll not serve him; he's not valiant. 1994 | 1995 | TRINCULO Thou liest, most ignorant monster: I am in case to 1996 | justle a constable. Why, thou deboshed fish thou, 1997 | was there ever man a coward that hath drunk so much 1998 | sack as I to-day? Wilt thou tell a monstrous lie, 1999 | being but half a fish and half a monster? 2000 | 2001 | CALIBAN Lo, how he mocks me! wilt thou let him, my lord? 2002 | 2003 | TRINCULO 'Lord' quoth he! That a monster should be such a natural! 2004 | 2005 | CALIBAN Lo, lo, again! bite him to death, I prithee. 2006 | 2007 | STEPHANO Trinculo, keep a good tongue in your head: if you 2008 | prove a mutineer,--the next tree! The poor monster's 2009 | my subject and he shall not suffer indignity. 2010 | 2011 | CALIBAN I thank my noble lord. Wilt thou be pleased to 2012 | hearken once again to the suit I made to thee? 2013 | 2014 | STEPHANO Marry, will I kneel and repeat it; I will stand, 2015 | and so shall Trinculo. 2016 | 2017 | [Enter ARIEL, invisible] 2018 | 2019 | CALIBAN As I told thee before, I am subject to a tyrant, a 2020 | sorcerer, that by his cunning hath cheated me of the island. 2021 | 2022 | ARIEL Thou liest. 2023 | 2024 | CALIBAN Thou liest, thou jesting monkey, thou: I would my 2025 | valiant master would destroy thee! I do not lie. 2026 | 2027 | STEPHANO Trinculo, if you trouble him any more in's tale, by 2028 | this hand, I will supplant some of your teeth. 2029 | 2030 | TRINCULO Why, I said nothing. 2031 | 2032 | STEPHANO Mum, then, and no more. Proceed. 2033 | 2034 | CALIBAN I say, by sorcery he got this isle; 2035 | From me he got it. if thy greatness will 2036 | Revenge it on him,--for I know thou darest, 2037 | But this thing dare not,-- 2038 | 2039 | STEPHANO That's most certain. 2040 | 2041 | CALIBAN Thou shalt be lord of it and I'll serve thee. 2042 | 2043 | STEPHANO How now shall this be compassed? 2044 | Canst thou bring me to the party? 2045 | 2046 | CALIBAN Yea, yea, my lord: I'll yield him thee asleep, 2047 | Where thou mayst knock a nail into his bead. 2048 | 2049 | ARIEL Thou liest; thou canst not. 2050 | 2051 | CALIBAN What a pied ninny's this! Thou scurvy patch! 2052 | I do beseech thy greatness, give him blows 2053 | And take his bottle from him: when that's gone 2054 | He shall drink nought but brine; for I'll not show him 2055 | Where the quick freshes are. 2056 | 2057 | STEPHANO Trinculo, run into no further danger: 2058 | interrupt the monster one word further, and, 2059 | by this hand, I'll turn my mercy out o' doors 2060 | and make a stock-fish of thee. 2061 | 2062 | TRINCULO Why, what did I? I did nothing. I'll go farther 2063 | off. 2064 | 2065 | STEPHANO Didst thou not say he lied? 2066 | 2067 | ARIEL Thou liest. 2068 | 2069 | STEPHANO Do I so? take thou that. 2070 | 2071 | [Beats TRINCULO] 2072 | 2073 | As you like this, give me the lie another time. 2074 | 2075 | TRINCULO I did not give the lie. Out o' your 2076 | wits and bearing too? A pox o' your bottle! 2077 | this can sack and drinking do. A murrain on 2078 | your monster, and the devil take your fingers! 2079 | 2080 | CALIBAN Ha, ha, ha! 2081 | 2082 | STEPHANO Now, forward with your tale. Prithee, stand farther 2083 | off. 2084 | 2085 | CALIBAN Beat him enough: after a little time 2086 | I'll beat him too. 2087 | 2088 | STEPHANO Stand farther. Come, proceed. 2089 | 2090 | CALIBAN Why, as I told thee, 'tis a custom with him, 2091 | I' th' afternoon to sleep: there thou mayst brain him, 2092 | Having first seized his books, or with a log 2093 | Batter his skull, or paunch him with a stake, 2094 | Or cut his wezand with thy knife. Remember 2095 | First to possess his books; for without them 2096 | He's but a sot, as I am, nor hath not 2097 | One spirit to command: they all do hate him 2098 | As rootedly as I. Burn but his books. 2099 | He has brave utensils,--for so he calls them-- 2100 | Which when he has a house, he'll deck withal 2101 | And that most deeply to consider is 2102 | The beauty of his daughter; he himself 2103 | Calls her a nonpareil: I never saw a woman, 2104 | But only Sycorax my dam and she; 2105 | But she as far surpasseth Sycorax 2106 | As great'st does least. 2107 | 2108 | STEPHANO Is it so brave a lass? 2109 | 2110 | CALIBAN Ay, lord; she will become thy bed, I warrant. 2111 | And bring thee forth brave brood. 2112 | 2113 | STEPHANO Monster, I will kill this man: his daughter and I 2114 | will be king and queen--save our graces!--and 2115 | Trinculo and thyself shall be viceroys. Dost thou 2116 | like the plot, Trinculo? 2117 | 2118 | TRINCULO Excellent. 2119 | 2120 | STEPHANO Give me thy hand: I am sorry I beat thee; but, 2121 | while thou livest, keep a good tongue in thy head. 2122 | 2123 | CALIBAN Within this half hour will he be asleep: 2124 | Wilt thou destroy him then? 2125 | 2126 | STEPHANO Ay, on mine honour. 2127 | 2128 | ARIEL This will I tell my master. 2129 | 2130 | CALIBAN Thou makest me merry; I am full of pleasure: 2131 | Let us be jocund: will you troll the catch 2132 | You taught me but while-ere? 2133 | 2134 | STEPHANO At thy request, monster, I will do reason, any 2135 | reason. Come on, Trinculo, let us sing. 2136 | 2137 | [Sings] 2138 | 2139 | Flout 'em and scout 'em 2140 | And scout 'em and flout 'em 2141 | Thought is free. 2142 | 2143 | CALIBAN That's not the tune. 2144 | 2145 | [Ariel plays the tune on a tabour and pipe] 2146 | 2147 | STEPHANO What is this same? 2148 | 2149 | TRINCULO This is the tune of our catch, played by the picture 2150 | of Nobody. 2151 | 2152 | STEPHANO If thou beest a man, show thyself in thy likeness: 2153 | if thou beest a devil, take't as thou list. 2154 | 2155 | TRINCULO O, forgive me my sins! 2156 | 2157 | STEPHANO He that dies pays all debts: I defy thee. Mercy upon us! 2158 | 2159 | CALIBAN Art thou afeard? 2160 | 2161 | STEPHANO No, monster, not I. 2162 | 2163 | CALIBAN Be not afeard; the isle is full of noises, 2164 | Sounds and sweet airs, that give delight and hurt not. 2165 | Sometimes a thousand twangling instruments 2166 | Will hum about mine ears, and sometime voices 2167 | That, if I then had waked after long sleep, 2168 | Will make me sleep again: and then, in dreaming, 2169 | The clouds methought would open and show riches 2170 | Ready to drop upon me that, when I waked, 2171 | I cried to dream again. 2172 | 2173 | STEPHANO This will prove a brave kingdom to me, where I shall 2174 | have my music for nothing. 2175 | 2176 | CALIBAN When Prospero is destroyed. 2177 | 2178 | STEPHANO That shall be by and by: I remember the story. 2179 | 2180 | TRINCULO The sound is going away; let's follow it, and 2181 | after do our work. 2182 | 2183 | STEPHANO Lead, monster; we'll follow. I would I could see 2184 | this tabourer; he lays it on. 2185 | 2186 | TRINCULO Wilt come? I'll follow, Stephano. 2187 | 2188 | [Exeunt] 2189 | 2190 | THE TEMPEST 2191 | 2192 | ACT III 2193 | 2194 | SCENE III Another part of the island. 2195 | 2196 | [Enter ALONSO, SEBASTIAN, ANTONIO, GONZALO, 2197 | ADRIAN, FRANCISCO, and others] 2198 | 2199 | GONZALO By'r lakin, I can go no further, sir; 2200 | My old bones ache: here's a maze trod indeed 2201 | Through forth-rights and meanders! By your patience, 2202 | I needs must rest me. 2203 | 2204 | ALONSO Old lord, I cannot blame thee, 2205 | Who am myself attach'd with weariness, 2206 | To the dulling of my spirits: sit down, and rest. 2207 | Even here I will put off my hope and keep it 2208 | No longer for my flatterer: he is drown'd 2209 | Whom thus we stray to find, and the sea mocks 2210 | Our frustrate search on land. Well, let him go. 2211 | 2212 | ANTONIO [Aside to SEBASTIAN] I am right glad that he's so 2213 | out of hope. 2214 | Do not, for one repulse, forego the purpose 2215 | That you resolved to effect. 2216 | 2217 | SEBASTIAN [Aside to ANTONIO] The next advantage 2218 | Will we take throughly. 2219 | 2220 | ANTONIO [Aside to SEBASTIAN] Let it be to-night; 2221 | For, now they are oppress'd with travel, they 2222 | Will not, nor cannot, use such vigilance 2223 | As when they are fresh. 2224 | 2225 | SEBASTIAN [Aside to ANTONIO] I say, to-night: no more. 2226 | 2227 | [Solemn and strange music] 2228 | 2229 | ALONSO What harmony is this? My good friends, hark! 2230 | 2231 | GONZALO Marvellous sweet music! 2232 | 2233 | [Enter PROSPERO above, invisible. Enter several 2234 | strange Shapes, bringing in a banquet; 2235 | they dance about it with gentle actions of 2236 | salutation; and, inviting the King, &c. to 2237 | eat, they depart] 2238 | 2239 | ALONSO Give us kind keepers, heavens! What were these? 2240 | 2241 | SEBASTIAN A living drollery. Now I will believe 2242 | That there are unicorns, that in Arabia 2243 | There is one tree, the phoenix' throne, one phoenix 2244 | At this hour reigning there. 2245 | 2246 | ANTONIO I'll believe both; 2247 | And what does else want credit, come to me, 2248 | And I'll be sworn 'tis true: travellers ne'er did 2249 | lie, 2250 | Though fools at home condemn 'em. 2251 | 2252 | GONZALO If in Naples 2253 | I should report this now, would they believe me? 2254 | If I should say, I saw such islanders-- 2255 | For, certes, these are people of the island-- 2256 | Who, though they are of monstrous shape, yet, note, 2257 | Their manners are more gentle-kind than of 2258 | Our human generation you shall find 2259 | Many, nay, almost any. 2260 | 2261 | PROSPERO [Aside] Honest lord, 2262 | Thou hast said well; for some of you there present 2263 | Are worse than devils. 2264 | 2265 | ALONSO I cannot too much muse 2266 | Such shapes, such gesture and such sound, expressing, 2267 | Although they want the use of tongue, a kind 2268 | Of excellent dumb discourse. 2269 | 2270 | PROSPERO [Aside] Praise in departing. 2271 | 2272 | FRANCISCO They vanish'd strangely. 2273 | 2274 | SEBASTIAN No matter, since 2275 | They have left their viands behind; for we have stomachs. 2276 | Will't please you taste of what is here? 2277 | 2278 | ALONSO Not I. 2279 | 2280 | GONZALO Faith, sir, you need not fear. When we were boys, 2281 | Who would believe that there were mountaineers 2282 | Dew-lapp'd like bulls, whose throats had hanging at 'em 2283 | Wallets of flesh? or that there were such men 2284 | Whose heads stood in their breasts? which now we find 2285 | Each putter-out of five for one will bring us 2286 | Good warrant of. 2287 | 2288 | ALONSO I will stand to and feed, 2289 | Although my last: no matter, since I feel 2290 | The best is past. Brother, my lord the duke, 2291 | Stand to and do as we. 2292 | 2293 | [Thunder and lightning. Enter ARIEL, like a 2294 | harpy; claps his wings upon the table; and, 2295 | with a quaint device, the banquet vanishes] 2296 | 2297 | ARIEL You are three men of sin, whom Destiny, 2298 | That hath to instrument this lower world 2299 | And what is in't, the never-surfeited sea 2300 | Hath caused to belch up you; and on this island 2301 | Where man doth not inhabit; you 'mongst men 2302 | Being most unfit to live. I have made you mad; 2303 | And even with such-like valour men hang and drown 2304 | Their proper selves. 2305 | 2306 | [ALONSO, SEBASTIAN &c. draw their swords] 2307 | 2308 | You fools! I and my fellows 2309 | Are ministers of Fate: the elements, 2310 | Of whom your swords are temper'd, may as well 2311 | Wound the loud winds, or with bemock'd-at stabs 2312 | Kill the still-closing waters, as diminish 2313 | One dowle that's in my plume: my fellow-ministers 2314 | Are like invulnerable. If you could hurt, 2315 | Your swords are now too massy for your strengths 2316 | And will not be uplifted. But remember-- 2317 | For that's my business to you--that you three 2318 | From Milan did supplant good Prospero; 2319 | Exposed unto the sea, which hath requit it, 2320 | Him and his innocent child: for which foul deed 2321 | The powers, delaying, not forgetting, have 2322 | Incensed the seas and shores, yea, all the creatures, 2323 | Against your peace. Thee of thy son, Alonso, 2324 | They have bereft; and do pronounce by me: 2325 | Lingering perdition, worse than any death 2326 | Can be at once, shall step by step attend 2327 | You and your ways; whose wraths to guard you from-- 2328 | Which here, in this most desolate isle, else falls 2329 | Upon your heads--is nothing but heart-sorrow 2330 | And a clear life ensuing. 2331 | 2332 | [He vanishes in thunder; then, to soft music 2333 | enter the Shapes again, and dance, with 2334 | mocks and mows, and carrying out the table] 2335 | 2336 | PROSPERO Bravely the figure of this harpy hast thou 2337 | Perform'd, my Ariel; a grace it had, devouring: 2338 | Of my instruction hast thou nothing bated 2339 | In what thou hadst to say: so, with good life 2340 | And observation strange, my meaner ministers 2341 | Their several kinds have done. My high charms work 2342 | And these mine enemies are all knit up 2343 | In their distractions; they now are in my power; 2344 | And in these fits I leave them, while I visit 2345 | Young Ferdinand, whom they suppose is drown'd, 2346 | And his and mine loved darling. 2347 | 2348 | [Exit above] 2349 | 2350 | GONZALO I' the name of something holy, sir, why stand you 2351 | In this strange stare? 2352 | 2353 | ALONSO O, it is monstrous, monstrous: 2354 | Methought the billows spoke and told me of it; 2355 | The winds did sing it to me, and the thunder, 2356 | That deep and dreadful organ-pipe, pronounced 2357 | The name of Prosper: it did bass my trespass. 2358 | Therefore my son i' the ooze is bedded, and 2359 | I'll seek him deeper than e'er plummet sounded 2360 | And with him there lie mudded. 2361 | [Exit] 2362 | 2363 | SEBASTIAN But one fiend at a time, 2364 | I'll fight their legions o'er. 2365 | 2366 | ANTONIO I'll be thy second. 2367 | 2368 | [Exeunt SEBASTIAN, and ANTONIO] 2369 | 2370 | GONZALO All three of them are desperate: their great guilt, 2371 | Like poison given to work a great time after, 2372 | Now 'gins to bite the spirits. I do beseech you 2373 | That are of suppler joints, follow them swiftly 2374 | And hinder them from what this ecstasy 2375 | May now provoke them to. 2376 | 2377 | ADRIAN Follow, I pray you. 2378 | 2379 | [Exeunt] 2380 | 2381 | THE TEMPEST 2382 | 2383 | ACT IV 2384 | 2385 | SCENE I Before PROSPERO'S cell. 2386 | 2387 | [Enter PROSPERO, FERDINAND, and MIRANDA] 2388 | 2389 | PROSPERO If I have too austerely punish'd you, 2390 | Your compensation makes amends, for I 2391 | Have given you here a third of mine own life, 2392 | Or that for which I live; who once again 2393 | I tender to thy hand: all thy vexations 2394 | Were but my trials of thy love and thou 2395 | Hast strangely stood the test here, afore Heaven, 2396 | I ratify this my rich gift. O Ferdinand, 2397 | Do not smile at me that I boast her off, 2398 | For thou shalt find she will outstrip all praise 2399 | And make it halt behind her. 2400 | 2401 | FERDINAND I do believe it 2402 | Against an oracle. 2403 | 2404 | PROSPERO Then, as my gift and thine own acquisition 2405 | Worthily purchased take my daughter: but 2406 | If thou dost break her virgin-knot before 2407 | All sanctimonious ceremonies may 2408 | With full and holy rite be minister'd, 2409 | No sweet aspersion shall the heavens let fall 2410 | To make this contract grow: but barren hate, 2411 | Sour-eyed disdain and discord shall bestrew 2412 | The union of your bed with weeds so loathly 2413 | That you shall hate it both: therefore take heed, 2414 | As Hymen's lamps shall light you. 2415 | 2416 | FERDINAND As I hope 2417 | For quiet days, fair issue and long life, 2418 | With such love as 'tis now, the murkiest den, 2419 | The most opportune place, the strong'st suggestion. 2420 | Our worser genius can, shall never melt 2421 | Mine honour into lust, to take away 2422 | The edge of that day's celebration 2423 | When I shall think: or Phoebus' steeds are founder'd, 2424 | Or Night kept chain'd below. 2425 | 2426 | PROSPERO Fairly spoke. 2427 | Sit then and talk with her; she is thine own. 2428 | What, Ariel! my industrious servant, Ariel! 2429 | 2430 | [Enter ARIEL] 2431 | 2432 | ARIEL What would my potent master? here I am. 2433 | 2434 | PROSPERO Thou and thy meaner fellows your last service 2435 | Did worthily perform; and I must use you 2436 | In such another trick. Go bring the rabble, 2437 | O'er whom I give thee power, here to this place: 2438 | Incite them to quick motion; for I must 2439 | Bestow upon the eyes of this young couple 2440 | Some vanity of mine art: it is my promise, 2441 | And they expect it from me. 2442 | 2443 | ARIEL Presently? 2444 | 2445 | PROSPERO Ay, with a twink. 2446 | 2447 | ARIEL Before you can say 'come' and 'go,' 2448 | And breathe twice and cry 'so, so,' 2449 | Each one, tripping on his toe, 2450 | Will be here with mop and mow. 2451 | Do you love me, master? no? 2452 | 2453 | PROSPERO Dearly my delicate Ariel. Do not approach 2454 | Till thou dost hear me call. 2455 | 2456 | ARIEL Well, I conceive. 2457 | 2458 | [Exit] 2459 | 2460 | PROSPERO Look thou be true; do not give dalliance 2461 | Too much the rein: the strongest oaths are straw 2462 | To the fire i' the blood: be more abstemious, 2463 | Or else, good night your vow! 2464 | 2465 | FERDINAND I warrant you sir; 2466 | The white cold virgin snow upon my heart 2467 | Abates the ardour of my liver. 2468 | 2469 | PROSPERO Well. 2470 | Now come, my Ariel! bring a corollary, 2471 | Rather than want a spirit: appear and pertly! 2472 | No tongue! all eyes! be silent. 2473 | 2474 | [Soft music] 2475 | 2476 | [Enter IRIS] 2477 | 2478 | IRIS Ceres, most bounteous lady, thy rich leas 2479 | Of wheat, rye, barley, vetches, oats and pease; 2480 | Thy turfy mountains, where live nibbling sheep, 2481 | And flat meads thatch'd with stover, them to keep; 2482 | Thy banks with pioned and twilled brims, 2483 | Which spongy April at thy hest betrims, 2484 | To make cold nymphs chaste crowns; and thy broom -groves, 2485 | Whose shadow the dismissed bachelor loves, 2486 | Being lass-lorn: thy pole-clipt vineyard; 2487 | And thy sea-marge, sterile and rocky-hard, 2488 | Where thou thyself dost air;--the queen o' the sky, 2489 | Whose watery arch and messenger am I, 2490 | Bids thee leave these, and with her sovereign grace, 2491 | Here on this grass-plot, in this very place, 2492 | To come and sport: her peacocks fly amain: 2493 | Approach, rich Ceres, her to entertain. 2494 | 2495 | [Enter CERES] 2496 | 2497 | CERES Hail, many-colour'd messenger, that ne'er 2498 | Dost disobey the wife of Jupiter; 2499 | Who with thy saffron wings upon my flowers 2500 | Diffusest honey-drops, refreshing showers, 2501 | And with each end of thy blue bow dost crown 2502 | My bosky acres and my unshrubb'd down, 2503 | Rich scarf to my proud earth; why hath thy queen 2504 | Summon'd me hither, to this short-grass'd green? 2505 | 2506 | IRIS A contract of true love to celebrate; 2507 | And some donation freely to estate 2508 | On the blest lovers. 2509 | 2510 | CERES Tell me, heavenly bow, 2511 | If Venus or her son, as thou dost know, 2512 | Do now attend the queen? Since they did plot 2513 | The means that dusky Dis my daughter got, 2514 | Her and her blind boy's scandal'd company 2515 | I have forsworn. 2516 | 2517 | IRIS Of her society 2518 | Be not afraid: I met her deity 2519 | Cutting the clouds towards Paphos and her son 2520 | Dove-drawn with her. Here thought they to have done 2521 | Some wanton charm upon this man and maid, 2522 | Whose vows are, that no bed-right shall be paid 2523 | Till Hymen's torch be lighted: but vain; 2524 | Mars's hot minion is returned again; 2525 | Her waspish-headed son has broke his arrows, 2526 | Swears he will shoot no more but play with sparrows 2527 | And be a boy right out. 2528 | 2529 | CERES High'st queen of state, 2530 | Great Juno, comes; I know her by her gait. 2531 | 2532 | [Enter JUNO] 2533 | 2534 | JUNO How does my bounteous sister? Go with me 2535 | To bless this twain, that they may prosperous be 2536 | And honour'd in their issue. 2537 | 2538 | [They sing:] 2539 | 2540 | JUNO Honour, riches, marriage-blessing, 2541 | Long continuance, and increasing, 2542 | Hourly joys be still upon you! 2543 | Juno sings her blessings upon you. 2544 | 2545 | CERES Earth's increase, foison plenty, 2546 | Barns and garners never empty, 2547 | Vines and clustering bunches growing, 2548 | Plants with goodly burthen bowing; 2549 | Spring come to you at the farthest 2550 | In the very end of harvest! 2551 | Scarcity and want shall shun you; 2552 | Ceres' blessing so is on you. 2553 | 2554 | FERDINAND This is a most majestic vision, and 2555 | Harmoniously charmingly. May I be bold 2556 | To think these spirits? 2557 | 2558 | PROSPERO Spirits, which by mine art 2559 | I have from their confines call'd to enact 2560 | My present fancies. 2561 | 2562 | FERDINAND Let me live here ever; 2563 | So rare a wonder'd father and a wife 2564 | Makes this place Paradise. 2565 | 2566 | [Juno and Ceres whisper, and send Iris on 2567 | employment] 2568 | 2569 | PROSPERO Sweet, now, silence! 2570 | Juno and Ceres whisper seriously; 2571 | There's something else to do: hush, and be mute, 2572 | Or else our spell is marr'd. 2573 | 2574 | IRIS You nymphs, call'd Naiads, of the windring brooks, 2575 | With your sedged crowns and ever-harmless looks, 2576 | Leave your crisp channels and on this green land 2577 | Answer your summons; Juno does command: 2578 | Come, temperate nymphs, and help to celebrate 2579 | A contract of true love; be not too late. 2580 | 2581 | [Enter certain Nymphs] 2582 | 2583 | You sunburnt sicklemen, of August weary, 2584 | Come hither from the furrow and be merry: 2585 | Make holiday; your rye-straw hats put on 2586 | And these fresh nymphs encounter every one 2587 | In country footing. 2588 | 2589 | [Enter certain Reapers, properly habited: they 2590 | join with the Nymphs in a graceful dance; 2591 | towards the end whereof PROSPERO starts 2592 | suddenly, and speaks; after which, to a 2593 | strange, hollow, and confused noise, they 2594 | heavily vanish] 2595 | 2596 | PROSPERO [Aside] I had forgot that foul conspiracy 2597 | Of the beast Caliban and his confederates 2598 | Against my life: the minute of their plot 2599 | Is almost come. 2600 | 2601 | [To the Spirits] 2602 | 2603 | Well done! avoid; no more! 2604 | 2605 | FERDINAND This is strange: your father's in some passion 2606 | That works him strongly. 2607 | 2608 | MIRANDA Never till this day 2609 | Saw I him touch'd with anger so distemper'd. 2610 | 2611 | PROSPERO You do look, my son, in a moved sort, 2612 | As if you were dismay'd: be cheerful, sir. 2613 | Our revels now are ended. These our actors, 2614 | As I foretold you, were all spirits and 2615 | Are melted into air, into thin air: 2616 | And, like the baseless fabric of this vision, 2617 | The cloud-capp'd towers, the gorgeous palaces, 2618 | The solemn temples, the great globe itself, 2619 | Ye all which it inherit, shall dissolve 2620 | And, like this insubstantial pageant faded, 2621 | Leave not a rack behind. We are such stuff 2622 | As dreams are made on, and our little life 2623 | Is rounded with a sleep. Sir, I am vex'd; 2624 | Bear with my weakness; my, brain is troubled: 2625 | Be not disturb'd with my infirmity: 2626 | If you be pleased, retire into my cell 2627 | And there repose: a turn or two I'll walk, 2628 | To still my beating mind. 2629 | 2630 | FERDINAND | 2631 | | We wish your peace. 2632 | MIRANDA | 2633 | 2634 | [Exeunt] 2635 | 2636 | PROSPERO Come with a thought I thank thee, Ariel: come. 2637 | 2638 | [Enter ARIEL] 2639 | 2640 | ARIEL Thy thoughts I cleave to. What's thy pleasure? 2641 | 2642 | PROSPERO Spirit, 2643 | We must prepare to meet with Caliban. 2644 | 2645 | ARIEL Ay, my commander: when I presented Ceres, 2646 | I thought to have told thee of it, but I fear'd 2647 | Lest I might anger thee. 2648 | 2649 | PROSPERO Say again, where didst thou leave these varlets? 2650 | 2651 | ARIEL I told you, sir, they were red-hot with drinking; 2652 | So fun of valour that they smote the air 2653 | For breathing in their faces; beat the ground 2654 | For kissing of their feet; yet always bending 2655 | Towards their project. Then I beat my tabour; 2656 | At which, like unback'd colts, they prick'd 2657 | their ears, 2658 | Advanced their eyelids, lifted up their noses 2659 | As they smelt music: so I charm'd their ears 2660 | That calf-like they my lowing follow'd through 2661 | Tooth'd briers, sharp furzes, pricking goss and thorns, 2662 | Which entered their frail shins: at last I left them 2663 | I' the filthy-mantled pool beyond your cell, 2664 | There dancing up to the chins, that the foul lake 2665 | O'erstunk their feet. 2666 | 2667 | PROSPERO This was well done, my bird. 2668 | Thy shape invisible retain thou still: 2669 | The trumpery in my house, go bring it hither, 2670 | For stale to catch these thieves. 2671 | 2672 | ARIEL I go, I go. 2673 | 2674 | [Exit] 2675 | 2676 | PROSPERO A devil, a born devil, on whose nature 2677 | Nurture can never stick; on whom my pains, 2678 | Humanely taken, all, all lost, quite lost; 2679 | And as with age his body uglier grows, 2680 | So his mind cankers. I will plague them all, 2681 | Even to roaring. 2682 | 2683 | [Re-enter ARIEL, loaden with glistering apparel, &c] 2684 | 2685 | Come, hang them on this line. 2686 | 2687 | [PROSPERO and ARIEL remain invisible. Enter 2688 | CALIBAN, STEPHANO, and TRINCULO, all wet] 2689 | 2690 | CALIBAN Pray you, tread softly, that the blind mole may not 2691 | Hear a foot fall: we now are near his cell. 2692 | 2693 | STEPHANO Monster, your fairy, which you say is 2694 | a harmless fairy, has done little better than 2695 | played the Jack with us. 2696 | 2697 | TRINCULO Monster, I do smell all horse-piss; at 2698 | which my nose is in great indignation. 2699 | 2700 | STEPHANO So is mine. Do you hear, monster? If I should take 2701 | a displeasure against you, look you,-- 2702 | 2703 | TRINCULO Thou wert but a lost monster. 2704 | 2705 | CALIBAN Good my lord, give me thy favour still. 2706 | Be patient, for the prize I'll bring thee to 2707 | Shall hoodwink this mischance: therefore speak softly. 2708 | All's hush'd as midnight yet. 2709 | 2710 | TRINCULO Ay, but to lose our bottles in the pool,-- 2711 | 2712 | STEPHANO There is not only disgrace and dishonour in that, 2713 | monster, but an infinite loss. 2714 | 2715 | TRINCULO That's more to me than my wetting: yet this is your 2716 | harmless fairy, monster. 2717 | 2718 | STEPHANO I will fetch off my bottle, though I be o'er ears 2719 | for my labour. 2720 | 2721 | CALIBAN Prithee, my king, be quiet. Seest thou here, 2722 | This is the mouth o' the cell: no noise, and enter. 2723 | Do that good mischief which may make this island 2724 | Thine own for ever, and I, thy Caliban, 2725 | For aye thy foot-licker. 2726 | 2727 | STEPHANO Give me thy hand. I do begin to have bloody thoughts. 2728 | 2729 | TRINCULO O king Stephano! O peer! O worthy Stephano! look 2730 | what a wardrobe here is for thee! 2731 | 2732 | CALIBAN Let it alone, thou fool; it is but trash. 2733 | 2734 | TRINCULO O, ho, monster! we know what belongs to a frippery. 2735 | O king Stephano! 2736 | 2737 | STEPHANO Put off that gown, Trinculo; by this hand, I'll have 2738 | that gown. 2739 | 2740 | TRINCULO Thy grace shall have it. 2741 | 2742 | CALIBAN The dropsy drown this fool I what do you mean 2743 | To dote thus on such luggage? Let's alone 2744 | And do the murder first: if he awake, 2745 | From toe to crown he'll fill our skins with pinches, 2746 | Make us strange stuff. 2747 | 2748 | STEPHANO Be you quiet, monster. Mistress line, 2749 | is not this my jerkin? Now is the jerkin under 2750 | the line: now, jerkin, you are like to lose your 2751 | hair and prove a bald jerkin. 2752 | 2753 | TRINCULO Do, do: we steal by line and level, an't like your grace. 2754 | 2755 | STEPHANO I thank thee for that jest; here's a garment for't: 2756 | wit shall not go unrewarded while I am king of this 2757 | country. 'Steal by line and level' is an excellent 2758 | pass of pate; there's another garment for't. 2759 | 2760 | TRINCULO Monster, come, put some lime upon your fingers, and 2761 | away with the rest. 2762 | 2763 | CALIBAN I will have none on't: we shall lose our time, 2764 | And all be turn'd to barnacles, or to apes 2765 | With foreheads villanous low. 2766 | 2767 | STEPHANO Monster, lay-to your fingers: help to bear this 2768 | away where my hogshead of wine is, or I'll turn you 2769 | out of my kingdom: go to, carry this. 2770 | 2771 | TRINCULO And this. 2772 | 2773 | STEPHANO Ay, and this. 2774 | 2775 | [A noise of hunters heard. Enter divers Spirits, 2776 | in shape of dogs and hounds, and hunt them about, 2777 | PROSPERO and ARIEL setting them on] 2778 | 2779 | PROSPERO Hey, Mountain, hey! 2780 | 2781 | ARIEL Silver I there it goes, Silver! 2782 | 2783 | PROSPERO Fury, Fury! there, Tyrant, there! hark! hark! 2784 | 2785 | [CALIBAN, STEPHANO, and TRINCULO, are 2786 | driven out] 2787 | 2788 | Go charge my goblins that they grind their joints 2789 | With dry convulsions, shorten up their sinews 2790 | With aged cramps, and more pinch-spotted make them 2791 | Than pard or cat o' mountain. 2792 | 2793 | ARIEL Hark, they roar! 2794 | 2795 | PROSPERO Let them be hunted soundly. At this hour 2796 | Lie at my mercy all mine enemies: 2797 | Shortly shall all my labours end, and thou 2798 | Shalt have the air at freedom: for a little 2799 | Follow, and do me service. 2800 | 2801 | [Exeunt] 2802 | 2803 | THE TEMPEST 2804 | 2805 | ACT V 2806 | 2807 | SCENE I Before PROSPERO'S cell. 2808 | 2809 | [Enter PROSPERO in his magic robes, and ARIEL] 2810 | 2811 | PROSPERO Now does my project gather to a head: 2812 | My charms crack not; my spirits obey; and time 2813 | Goes upright with his carriage. How's the day? 2814 | 2815 | ARIEL On the sixth hour; at which time, my lord, 2816 | You said our work should cease. 2817 | 2818 | PROSPERO I did say so, 2819 | When first I raised the tempest. Say, my spirit, 2820 | How fares the king and's followers? 2821 | 2822 | ARIEL Confined together 2823 | In the same fashion as you gave in charge, 2824 | Just as you left them; all prisoners, sir, 2825 | In the line-grove which weather-fends your cell; 2826 | They cannot budge till your release. The king, 2827 | His brother and yours, abide all three distracted 2828 | And the remainder mourning over them, 2829 | Brimful of sorrow and dismay; but chiefly 2830 | Him that you term'd, sir, 'The good old lord Gonzalo;' 2831 | His tears run down his beard, like winter's drops 2832 | From eaves of reeds. Your charm so strongly works 'em 2833 | That if you now beheld them, your affections 2834 | Would become tender. 2835 | 2836 | PROSPERO Dost thou think so, spirit? 2837 | 2838 | ARIEL Mine would, sir, were I human. 2839 | 2840 | PROSPERO And mine shall. 2841 | Hast thou, which art but air, a touch, a feeling 2842 | Of their afflictions, and shall not myself, 2843 | One of their kind, that relish all as sharply, 2844 | Passion as they, be kindlier moved than thou art? 2845 | Though with their high wrongs I am struck to the quick, 2846 | Yet with my nobler reason 'gaitist my fury 2847 | Do I take part: the rarer action is 2848 | In virtue than in vengeance: they being penitent, 2849 | The sole drift of my purpose doth extend 2850 | Not a frown further. Go release them, Ariel: 2851 | My charms I'll break, their senses I'll restore, 2852 | And they shall be themselves. 2853 | 2854 | ARIEL I'll fetch them, sir. 2855 | 2856 | [Exit] 2857 | 2858 | PROSPERO Ye elves of hills, brooks, standing lakes and groves, 2859 | And ye that on the sands with printless foot 2860 | Do chase the ebbing Neptune and do fly him 2861 | When he comes back; you demi-puppets that 2862 | By moonshine do the green sour ringlets make, 2863 | Whereof the ewe not bites, and you whose pastime 2864 | Is to make midnight mushrooms, that rejoice 2865 | To hear the solemn curfew; by whose aid, 2866 | Weak masters though ye be, I have bedimm'd 2867 | The noontide sun, call'd forth the mutinous winds, 2868 | And 'twixt the green sea and the azured vault 2869 | Set roaring war: to the dread rattling thunder 2870 | Have I given fire and rifted Jove's stout oak 2871 | With his own bolt; the strong-based promontory 2872 | Have I made shake and by the spurs pluck'd up 2873 | The pine and cedar: graves at my command 2874 | Have waked their sleepers, oped, and let 'em forth 2875 | By my so potent art. But this rough magic 2876 | I here abjure, and, when I have required 2877 | Some heavenly music, which even now I do, 2878 | To work mine end upon their senses that 2879 | This airy charm is for, I'll break my staff, 2880 | Bury it certain fathoms in the earth, 2881 | And deeper than did ever plummet sound 2882 | I'll drown my book. 2883 | 2884 | [Solemn music] 2885 | 2886 | [Re-enter ARIEL before: then ALONSO, with a 2887 | frantic gesture, attended by GONZALO; 2888 | SEBASTIAN and ANTONIO in like manner, 2889 | attended by ADRIAN and FRANCISCO they all 2890 | enter the circle which PROSPERO had made, 2891 | and there stand charmed; which PROSPERO 2892 | observing, speaks:] 2893 | 2894 | A solemn air and the best comforter 2895 | To an unsettled fancy cure thy brains, 2896 | Now useless, boil'd within thy skull! There stand, 2897 | For you are spell-stopp'd. 2898 | Holy Gonzalo, honourable man, 2899 | Mine eyes, even sociable to the show of thine, 2900 | Fall fellowly drops. The charm dissolves apace, 2901 | And as the morning steals upon the night, 2902 | Melting the darkness, so their rising senses 2903 | Begin to chase the ignorant fumes that mantle 2904 | Their clearer reason. O good Gonzalo, 2905 | My true preserver, and a loyal sir 2906 | To him you follow'st! I will pay thy graces 2907 | Home both in word and deed. Most cruelly 2908 | Didst thou, Alonso, use me and my daughter: 2909 | Thy brother was a furtherer in the act. 2910 | Thou art pinch'd fort now, Sebastian. Flesh and blood, 2911 | You, brother mine, that entertain'd ambition, 2912 | Expell'd remorse and nature; who, with Sebastian, 2913 | Whose inward pinches therefore are most strong, 2914 | Would here have kill'd your king; I do forgive thee, 2915 | Unnatural though thou art. Their understanding 2916 | Begins to swell, and the approaching tide 2917 | Will shortly fill the reasonable shore 2918 | That now lies foul and muddy. Not one of them 2919 | That yet looks on me, or would know me Ariel, 2920 | Fetch me the hat and rapier in my cell: 2921 | I will discase me, and myself present 2922 | As I was sometime Milan: quickly, spirit; 2923 | Thou shalt ere long be free. 2924 | 2925 | [ARIEL sings and helps to attire him] 2926 | 2927 | Where the bee sucks. there suck I: 2928 | In a cowslip's bell I lie; 2929 | There I couch when owls do cry. 2930 | On the bat's back I do fly 2931 | After summer merrily. 2932 | Merrily, merrily shall I live now 2933 | Under the blossom that hangs on the bough. 2934 | 2935 | PROSPERO Why, that's my dainty Ariel! I shall miss thee: 2936 | But yet thou shalt have freedom: so, so, so. 2937 | To the king's ship, invisible as thou art: 2938 | There shalt thou find the mariners asleep 2939 | Under the hatches; the master and the boatswain 2940 | Being awake, enforce them to this place, 2941 | And presently, I prithee. 2942 | 2943 | ARIEL I drink the air before me, and return 2944 | Or ere your pulse twice beat. 2945 | 2946 | [Exit] 2947 | 2948 | GONZALO All torment, trouble, wonder and amazement 2949 | Inhabits here: some heavenly power guide us 2950 | Out of this fearful country! 2951 | 2952 | PROSPERO Behold, sir king, 2953 | The wronged Duke of Milan, Prospero: 2954 | For more assurance that a living prince 2955 | Does now speak to thee, I embrace thy body; 2956 | And to thee and thy company I bid 2957 | A hearty welcome. 2958 | 2959 | ALONSO Whether thou best he or no, 2960 | Or some enchanted trifle to abuse me, 2961 | As late I have been, I not know: thy pulse 2962 | Beats as of flesh and blood; and, since I saw thee, 2963 | The affliction of my mind amends, with which, 2964 | I fear, a madness held me: this must crave, 2965 | An if this be at all, a most strange story. 2966 | Thy dukedom I resign and do entreat 2967 | Thou pardon me my wrongs. But how should Prospero 2968 | Be living and be here? 2969 | 2970 | PROSPERO First, noble friend, 2971 | Let me embrace thine age, whose honour cannot 2972 | Be measured or confined. 2973 | 2974 | GONZALO Whether this be 2975 | Or be not, I'll not swear. 2976 | 2977 | PROSPERO You do yet taste 2978 | Some subtilties o' the isle, that will not let you 2979 | Believe things certain. Welcome, my friends all! 2980 | 2981 | [Aside to SEBASTIAN and ANTONIO] 2982 | 2983 | But you, my brace of lords, were I so minded, 2984 | I here could pluck his highness' frown upon you 2985 | And justify you traitors: at this time 2986 | I will tell no tales. 2987 | 2988 | SEBASTIAN [Aside] The devil speaks in him. 2989 | 2990 | PROSPERO No. 2991 | For you, most wicked sir, whom to call brother 2992 | Would even infect my mouth, I do forgive 2993 | Thy rankest fault; all of them; and require 2994 | My dukedom of thee, which perforce, I know, 2995 | Thou must restore. 2996 | 2997 | ALONSO If thou be'st Prospero, 2998 | Give us particulars of thy preservation; 2999 | How thou hast met us here, who three hours since 3000 | Were wreck'd upon this shore; where I have lost-- 3001 | How sharp the point of this remembrance is!-- 3002 | My dear son Ferdinand. 3003 | 3004 | PROSPERO I am woe for't, sir. 3005 | 3006 | ALONSO Irreparable is the loss, and patience 3007 | Says it is past her cure. 3008 | 3009 | PROSPERO I rather think 3010 | You have not sought her help, of whose soft grace 3011 | For the like loss I have her sovereign aid 3012 | And rest myself content. 3013 | 3014 | ALONSO You the like loss! 3015 | 3016 | PROSPERO As great to me as late; and, supportable 3017 | To make the dear loss, have I means much weaker 3018 | Than you may call to comfort you, for I 3019 | Have lost my daughter. 3020 | 3021 | ALONSO A daughter? 3022 | O heavens, that they were living both in Naples, 3023 | The king and queen there! that they were, I wish 3024 | Myself were mudded in that oozy bed 3025 | Where my son lies. When did you lose your daughter? 3026 | 3027 | PROSPERO In this last tempest. I perceive these lords 3028 | At this encounter do so much admire 3029 | That they devour their reason and scarce think 3030 | Their eyes do offices of truth, their words 3031 | Are natural breath: but, howsoe'er you have 3032 | Been justled from your senses, know for certain 3033 | That I am Prospero and that very duke 3034 | Which was thrust forth of Milan, who most strangely 3035 | Upon this shore, where you were wreck'd, was landed, 3036 | To be the lord on't. No more yet of this; 3037 | For 'tis a chronicle of day by day, 3038 | Not a relation for a breakfast nor 3039 | Befitting this first meeting. Welcome, sir; 3040 | This cell's my court: here have I few attendants 3041 | And subjects none abroad: pray you, look in. 3042 | My dukedom since you have given me again, 3043 | I will requite you with as good a thing; 3044 | At least bring forth a wonder, to content ye 3045 | As much as me my dukedom. 3046 | 3047 | [Here PROSPERO discovers FERDINAND and MIRANDA 3048 | playing at chess] 3049 | 3050 | MIRANDA Sweet lord, you play me false. 3051 | 3052 | FERDINAND No, my dear'st love, 3053 | I would not for the world. 3054 | 3055 | MIRANDA Yes, for a score of kingdoms you should wrangle, 3056 | And I would call it, fair play. 3057 | 3058 | ALONSO If this prove 3059 | A vision of the Island, one dear son 3060 | Shall I twice lose. 3061 | 3062 | SEBASTIAN A most high miracle! 3063 | 3064 | FERDINAND Though the seas threaten, they are merciful; 3065 | I have cursed them without cause. 3066 | 3067 | [Kneels] 3068 | 3069 | ALONSO Now all the blessings 3070 | Of a glad father compass thee about! 3071 | Arise, and say how thou camest here. 3072 | 3073 | MIRANDA O, wonder! 3074 | How many goodly creatures are there here! 3075 | How beauteous mankind is! O brave new world, 3076 | That has such people in't! 3077 | 3078 | PROSPERO 'Tis new to thee. 3079 | 3080 | ALONSO What is this maid with whom thou wast at play? 3081 | Your eld'st acquaintance cannot be three hours: 3082 | Is she the goddess that hath sever'd us, 3083 | And brought us thus together? 3084 | 3085 | FERDINAND Sir, she is mortal; 3086 | But by immortal Providence she's mine: 3087 | I chose her when I could not ask my father 3088 | For his advice, nor thought I had one. She 3089 | Is daughter to this famous Duke of Milan, 3090 | Of whom so often I have heard renown, 3091 | But never saw before; of whom I have 3092 | Received a second life; and second father 3093 | This lady makes him to me. 3094 | 3095 | ALONSO I am hers: 3096 | But, O, how oddly will it sound that I 3097 | Must ask my child forgiveness! 3098 | 3099 | PROSPERO There, sir, stop: 3100 | Let us not burthen our remembrance with 3101 | A heaviness that's gone. 3102 | 3103 | GONZALO I have inly wept, 3104 | Or should have spoke ere this. Look down, you god, 3105 | And on this couple drop a blessed crown! 3106 | For it is you that have chalk'd forth the way 3107 | Which brought us hither. 3108 | 3109 | ALONSO I say, Amen, Gonzalo! 3110 | 3111 | GONZALO Was Milan thrust from Milan, that his issue 3112 | Should become kings of Naples? O, rejoice 3113 | Beyond a common joy, and set it down 3114 | With gold on lasting pillars: In one voyage 3115 | Did Claribel her husband find at Tunis, 3116 | And Ferdinand, her brother, found a wife 3117 | Where he himself was lost, Prospero his dukedom 3118 | In a poor isle and all of us ourselves 3119 | When no man was his own. 3120 | 3121 | ALONSO [To FERDINAND and MIRANDA] Give me your hands: 3122 | Let grief and sorrow still embrace his heart 3123 | That doth not wish you joy! 3124 | 3125 | GONZALO Be it so! Amen! 3126 | 3127 | [Re-enter ARIEL, with the Master and Boatswain 3128 | amazedly following] 3129 | 3130 | O, look, sir, look, sir! here is more of us: 3131 | I prophesied, if a gallows were on land, 3132 | This fellow could not drown. Now, blasphemy, 3133 | That swear'st grace o'erboard, not an oath on shore? 3134 | Hast thou no mouth by land? What is the news? 3135 | 3136 | Boatswain The best news is, that we have safely found 3137 | Our king and company; the next, our ship-- 3138 | Which, but three glasses since, we gave out split-- 3139 | Is tight and yare and bravely rigg'd as when 3140 | We first put out to sea. 3141 | 3142 | ARIEL [Aside to PROSPERO] Sir, all this service 3143 | Have I done since I went. 3144 | 3145 | PROSPERO [Aside to ARIEL] My tricksy spirit! 3146 | 3147 | ALONSO These are not natural events; they strengthen 3148 | From strange to stranger. Say, how came you hither? 3149 | 3150 | Boatswain If I did think, sir, I were well awake, 3151 | I'ld strive to tell you. We were dead of sleep, 3152 | And--how we know not--all clapp'd under hatches; 3153 | Where but even now with strange and several noises 3154 | Of roaring, shrieking, howling, jingling chains, 3155 | And more diversity of sounds, all horrible, 3156 | We were awaked; straightway, at liberty; 3157 | Where we, in all her trim, freshly beheld 3158 | Our royal, good and gallant ship, our master 3159 | Capering to eye her: on a trice, so please you, 3160 | Even in a dream, were we divided from them 3161 | And were brought moping hither. 3162 | 3163 | ARIEL [Aside to PROSPERO] Was't well done? 3164 | 3165 | PROSPERO [Aside to ARIEL] Bravely, my diligence. Thou shalt be free. 3166 | 3167 | ALONSO This is as strange a maze as e'er men trod 3168 | And there is in this business more than nature 3169 | Was ever conduct of: some oracle 3170 | Must rectify our knowledge. 3171 | 3172 | PROSPERO Sir, my liege, 3173 | Do not infest your mind with beating on 3174 | The strangeness of this business; at pick'd leisure 3175 | Which shall be shortly, single I'll resolve you, 3176 | Which to you shall seem probable, of every 3177 | These happen'd accidents; till when, be cheerful 3178 | And think of each thing well. 3179 | 3180 | [Aside to ARIEL] 3181 | 3182 | Come hither, spirit: 3183 | Set Caliban and his companions free; 3184 | Untie the spell. 3185 | 3186 | [Exit ARIEL] 3187 | 3188 | How fares my gracious sir? 3189 | There are yet missing of your company 3190 | Some few odd lads that you remember not. 3191 | 3192 | [Re-enter ARIEL, driving in CALIBAN, STEPHANO 3193 | and TRINCULO, in their stolen apparel] 3194 | 3195 | STEPHANO Every man shift for all the rest, and 3196 | let no man take care for himself; for all is 3197 | but fortune. Coragio, bully-monster, coragio! 3198 | 3199 | TRINCULO If these be true spies which I wear in my head, 3200 | here's a goodly sight. 3201 | 3202 | CALIBAN O Setebos, these be brave spirits indeed! 3203 | How fine my master is! I am afraid 3204 | He will chastise me. 3205 | 3206 | SEBASTIAN Ha, ha! 3207 | What things are these, my lord Antonio? 3208 | Will money buy 'em? 3209 | 3210 | ANTONIO Very like; one of them 3211 | Is a plain fish, and, no doubt, marketable. 3212 | 3213 | PROSPERO Mark but the badges of these men, my lords, 3214 | Then say if they be true. This mis-shapen knave, 3215 | His mother was a witch, and one so strong 3216 | That could control the moon, make flows and ebbs, 3217 | And deal in her command without her power. 3218 | These three have robb'd me; and this demi-devil-- 3219 | For he's a bastard one--had plotted with them 3220 | To take my life. Two of these fellows you 3221 | Must know and own; this thing of darkness! 3222 | Acknowledge mine. 3223 | 3224 | CALIBAN I shall be pinch'd to death. 3225 | 3226 | ALONSO Is not this Stephano, my drunken butler? 3227 | 3228 | SEBASTIAN He is drunk now: where had he wine? 3229 | 3230 | ALONSO And Trinculo is reeling ripe: where should they 3231 | Find this grand liquor that hath gilded 'em? 3232 | How camest thou in this pickle? 3233 | 3234 | TRINCULO I have been in such a pickle since I 3235 | saw you last that, I fear me, will never out of 3236 | my bones: I shall not fear fly-blowing. 3237 | 3238 | SEBASTIAN Why, how now, Stephano! 3239 | 3240 | STEPHANO O, touch me not; I am not Stephano, but a cramp. 3241 | 3242 | PROSPERO You'ld be king o' the isle, sirrah? 3243 | 3244 | STEPHANO I should have been a sore one then. 3245 | 3246 | ALONSO This is a strange thing as e'er I look'd on. 3247 | 3248 | [Pointing to Caliban] 3249 | 3250 | PROSPERO He is as disproportion'd in his manners 3251 | As in his shape. Go, sirrah, to my cell; 3252 | Take with you your companions; as you look 3253 | To have my pardon, trim it handsomely. 3254 | 3255 | CALIBAN Ay, that I will; and I'll be wise hereafter 3256 | And seek for grace. What a thrice-double ass 3257 | Was I, to take this drunkard for a god 3258 | And worship this dull fool! 3259 | 3260 | PROSPERO Go to; away! 3261 | 3262 | ALONSO Hence, and bestow your luggage where you found it. 3263 | 3264 | SEBASTIAN Or stole it, rather. 3265 | 3266 | [Exeunt CALIBAN, STEPHANO, and TRINCULO] 3267 | 3268 | PROSPERO Sir, I invite your highness and your train 3269 | To my poor cell, where you shall take your rest 3270 | For this one night; which, part of it, I'll waste 3271 | With such discourse as, I not doubt, shall make it 3272 | Go quick away; the story of my life 3273 | And the particular accidents gone by 3274 | Since I came to this isle: and in the morn 3275 | I'll bring you to your ship and so to Naples, 3276 | Where I have hope to see the nuptial 3277 | Of these our dear-beloved solemnized; 3278 | And thence retire me to my Milan, where 3279 | Every third thought shall be my grave. 3280 | 3281 | ALONSO I long 3282 | To hear the story of your life, which must 3283 | Take the ear strangely. 3284 | 3285 | PROSPERO I'll deliver all; 3286 | And promise you calm seas, auspicious gales 3287 | And sail so expeditious that shall catch 3288 | Your royal fleet far off. 3289 | 3290 | [Aside to ARIEL] 3291 | 3292 | My Ariel, chick, 3293 | That is thy charge: then to the elements 3294 | Be free, and fare thou well! Please you, draw near. 3295 | 3296 | [Exeunt] 3297 | 3298 | THE TEMPEST 3299 | 3300 | EPILOGUE 3301 | 3302 | SPOKEN BY PROSPERO 3303 | 3304 | Now my charms are all o'erthrown, 3305 | And what strength I have's mine own, 3306 | Which is most faint: now, 'tis true, 3307 | I must be here confined by you, 3308 | Or sent to Naples. Let me not, 3309 | Since I have my dukedom got 3310 | And pardon'd the deceiver, dwell 3311 | In this bare island by your spell; 3312 | But release me from my bands 3313 | With the help of your good hands: 3314 | Gentle breath of yours my sails 3315 | Must fill, or else my project fails, 3316 | Which was to please. Now I want 3317 | Spirits to enforce, art to enchant, 3318 | And my ending is despair, 3319 | Unless I be relieved by prayer, 3320 | Which pierces so that it assaults 3321 | Mercy itself and frees all faults. 3322 | As you from crimes would pardon'd be, 3323 | Let your indulgence set me free. -------------------------------------------------------------------------------- /DFC/dfc.conf: -------------------------------------------------------------------------------- 1 | Server DFS1 127.0.0.1:10001 2 | Server DFS2 127.0.0.1:10002 3 | Server DFS3 127.0.0.1:10003 4 | Server DFS3 127.0.0.1:10004 5 | Username: Alice 6 | Password: 9f451d98e0daf53c49f42095ee3b7220 7 | Username: Bob 8 | Password: cb5ead8bc8bca45f007bc7a995964460 9 | Username: Eve 10 | Password: ca2d3b7e3704505de305a608d832e91d 11 | -------------------------------------------------------------------------------- /DFC/dfc.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ 4 | Distributed File System 5 | Client 6 | Marcelo Sanches 7 | Jan 2019 8 | """ 9 | 10 | # DFC 11 | 12 | # modules 13 | import re 14 | import os 15 | import sys 16 | import glob 17 | import time 18 | import pickle 19 | import socket 20 | import hashlib 21 | 22 | # check argument to open dfc.conf 23 | def check_args(): 24 | 25 | # error handling no argument 26 | if len(sys.argv) != 2: 27 | print("ERROR: Must supply an argument \nUSAGE: py dfc.py dfc.conf") 28 | sys.exit() 29 | 30 | # error handling argument passed 31 | elif sys.argv[1].lower() != 'dfc.conf': 32 | print("ERROR: Must supply a valid argument \nUSAGE: py dfc.py dfc.conf") 33 | sys.exit() 34 | 35 | # error if there is no dfc.conf file 36 | elif os.path.isfile(sys.argv[1]) != True: 37 | print("ERROR: dfc.conf not found.") 38 | sys.exit() 39 | 40 | # if no error, return dfc.conf 41 | else: 42 | return sys.argv[1] 43 | 44 | 45 | # params for user auth from dfc.conf 46 | def user_auth(): 47 | 48 | # get usernames 49 | fh = open('dfc.conf', mode='r', encoding='cp1252') 50 | users=re.findall(r'Username: .*', fh.read()) 51 | usernames=list() 52 | for i in range(0, len(users)): 53 | usernames.append(str(users[i]).split()[1]) 54 | fh.close() 55 | 56 | # get passwords 57 | fh = open('dfc.conf', mode='r', encoding='cp1252') 58 | passes=re.findall(r'Password: .*', fh.read()) 59 | passwords=list() 60 | for i in range(0, len(passes)): 61 | passwords.append(str(passes[i]).split()[1]) 62 | fh.close() 63 | 64 | # dict with usernames:passwords 65 | global auth_dict 66 | auth_dict = {} 67 | for i in range(0, len(users)): 68 | entry={usernames[i]:passwords[i]} 69 | auth_dict.update(entry) 70 | 71 | return auth_dict 72 | 73 | # client-side auth 74 | def authenticate(): 75 | 76 | # config params 77 | user_auth() 78 | 79 | # authenticate username 80 | 81 | # initialize an auth status 82 | auth_status = '' 83 | 84 | # give user 4 attempts 85 | for i in range(0, 4): 86 | if auth_status == 'Valid username.': 87 | # go to password auth 88 | pass 89 | 90 | else: 91 | # get username 92 | username = input('username: ') 93 | 94 | # initialize username auth 95 | username_auth = [] 96 | ct = 0 97 | for key, value in auth_dict.items(): 98 | ct += 1 99 | if username == key: 100 | # get specific username index in dictionary 101 | username_auth.append(ct) 102 | else: 103 | username_auth.append(0) 104 | 105 | if i < 2: 106 | if sum(username_auth) > 0: 107 | auth_status = 'Valid username.' 108 | continue 109 | else: 110 | print('Username does not exist. You have ' +str(3-i) + ' attempts left.') 111 | continue 112 | elif i == 2: 113 | if sum(username_auth) > 0: 114 | auth_status = 'Valid username.' 115 | continue 116 | else: 117 | print('Username does not exist. You have ' +str(3-i) + ' attempt left.') 118 | continue 119 | else: 120 | if sum(username_auth) > 0: 121 | auth_status = 'Valid username.' 122 | continue 123 | else: 124 | print('Username does not exist. You have no more attempts.\nExiting now....') 125 | sys.exit() 126 | 127 | # authenticate password 128 | # get the index of the user in the auth_dict to check password in that index 129 | user_index = sum(username_auth) 130 | 131 | # re-initialize auth status 132 | auth_status = '' 133 | for i in range(0, 4): 134 | if auth_status == 'Valid password.': 135 | # pass authentication 136 | pass 137 | 138 | else: 139 | # get password 140 | password = input('password: ') 141 | # hash 142 | hash=hashlib.md5() 143 | hash.update(password.encode()) 144 | password = hash.hexdigest() 145 | 146 | # initialize password auth 147 | password_auth = [] 148 | ct = 0 149 | for key, value in auth_dict.items(): 150 | ct += 1 151 | if password == value: 152 | password_auth.append(ct) 153 | else: 154 | password_auth.append(0) 155 | 156 | if i < 2: 157 | if sum(password_auth) > 0: 158 | # check that index of password matches user index 159 | if user_index == sum(password_auth): 160 | auth_status = 'Valid password.' 161 | continue 162 | else: 163 | print('Wrong password. You have ' +str(3-i) + ' attempts left.') 164 | continue 165 | else: 166 | print('Wrong password. You have ' +str(3-i) + ' attempts left.') 167 | continue 168 | elif i == 2: 169 | if sum(password_auth) > 0: 170 | if user_index == sum(password_auth): 171 | auth_status = 'Valid password.' 172 | continue 173 | else: 174 | print('Wrong password. You have ' +str(3-i) + ' attempt left.') 175 | continue 176 | else: 177 | print('Wrong password. You have ' +str(3-i) + ' attempt left.') 178 | continue 179 | else: 180 | if user_index == sum(password_auth): 181 | auth_status = 'Valid password.' 182 | continue 183 | else: 184 | print('Wrong password. You have no more attempts.\nExiting now....') 185 | sys.exit() 186 | 187 | # Final auth after passing all checks 188 | print('Authorization Granted.') 189 | global final_authorization 190 | final_authorization = (username, password) 191 | return final_authorization 192 | 193 | 194 | # config params for server 195 | def server_conf(): 196 | 197 | # open config file 198 | fh = open('dfc.conf', mode='r', encoding='cp1252') 199 | params = re.findall(r'DFS.*', fh.read()) 200 | 201 | # get server names 202 | s_names = list() 203 | for i in range(0, len(params)): 204 | s_names.append(str(params[i]).split()[1].split(":")[0]) 205 | 206 | # get server ports 207 | s_ports = list() 208 | for i in range(0, len(params)): 209 | s_ports.append(str(params[i]).split()[1].split(":")[1]) 210 | 211 | # dict with server names 212 | s_names_dict = {} 213 | for i in range(0, len(params)): 214 | entry={'server' +str(i+1):s_names[i]} 215 | s_names_dict.update(entry) 216 | 217 | # dict with server ports 218 | s_ports_dict = {} 219 | for i in range(0, len(params)): 220 | entry={'server' +str(i+1):s_ports[i]} 221 | s_ports_dict.update(entry) 222 | 223 | # lists of (sever name, server port) lists 224 | global server_list 225 | server_list = list() 226 | ct = 0 227 | for i in range(0, len(params)): 228 | ct += 1 229 | server_list.append((s_names_dict['server' +str(ct)],\ 230 | int(s_ports_dict['server' + str(ct)]))) 231 | return server_list 232 | 233 | 234 | # split a file given a chunk size 235 | def split_files(filename, chunksize): 236 | 237 | # create chunks 238 | with open(filename + '.txt', 'rb') as bytefile: 239 | content = bytearray(os.path.getsize(filename + '.txt')) 240 | bytefile.readinto(content) 241 | 242 | for count, i in enumerate(range(0, len(content), chunksize)): 243 | with open(filename + '_' + str(count+1) + '.txt.', 'wb') as fh: 244 | fh.write(content[i: i + chunksize]) 245 | 246 | 247 | # determine server location for chunk pairs 248 | def chunk_pairs(filename): 249 | 250 | # group chunks in paired lists # per table: 251 | pair1 = [filename +'_1.txt', filename +'_2.txt'] # 1,2 252 | pair2 = [filename +'_2.txt', filename +'_3.txt'] # 2,3 253 | pair3 = [filename +'_3.txt', filename +'_4.txt'] # 3,4 254 | pair4 = [filename +'_4.txt', filename +'_1.txt'] # 4,1 255 | 256 | # md5 hash value of file 257 | 258 | hash=hashlib.md5() 259 | with open(filename +'.txt', 'rb') as fh: 260 | buffer = fh.read() 261 | hash.update(buffer) 262 | 263 | # molulus determines server pairs 264 | storeval = int(hash.hexdigest(), 16) % 4 265 | 266 | # server pairs depending on modulus 267 | if storeval == 0: 268 | dfs1 = pair1 269 | dfs2 = pair2 270 | dfs3 = pair3 271 | dfs4 = pair4 272 | elif storeval == 1: 273 | dfs1 = pair4 274 | dfs2 = pair1 275 | dfs3 = pair2 276 | dfs4 = pair3 277 | elif storeval == 2: 278 | dfs1 = pair3 279 | dfs2 = pair4 280 | dfs3 = pair1 281 | dfs4 = pair2 282 | else: 283 | dfs1 = pair2 284 | dfs2 = pair3 285 | dfs3 = pair4 286 | dfs4 = pair1 287 | 288 | return dfs1, dfs2, dfs3, dfs4 289 | 290 | 291 | # get command from user 292 | def get_command(): 293 | 294 | global command 295 | command = '' 296 | for i in range(0, 4): 297 | if command != '': 298 | return command 299 | break 300 | else: 301 | comm = input('Please specify a command [get, list, put]: ') 302 | if i < 2: 303 | if comm.lower() == 'get': 304 | command = 'get' 305 | continue 306 | elif comm.lower() == 'list': 307 | command = 'list' 308 | continue 309 | elif comm.lower() == 'put': 310 | command = 'put' 311 | continue 312 | else: 313 | print('There is no such command. You have ' +str(3-i) + ' attempts left.') 314 | continue 315 | elif i == 2: 316 | if comm.lower() == 'get': 317 | command = 'get' 318 | continue 319 | elif comm.lower() == 'list': 320 | command = 'list' 321 | continue 322 | elif comm.lower() == 'put': 323 | command = 'put' 324 | continue 325 | else: 326 | print('There is no such command. You have ' +str(3-i) + ' attempt left.') 327 | continue 328 | else: 329 | print('There is no such command. You have no more attempts.\nExiting now....') 330 | sys.exit() 331 | 332 | # get a file name from user 333 | def get_filename(): 334 | for i in range(0, 2): 335 | if i == 0: 336 | txtfiles = [] 337 | print('Current files: ') 338 | print('-' * 15) 339 | for file in glob.glob("*.txt"): 340 | txtfiles.append(file) 341 | print(file.split(".")[0]) 342 | print('\n') 343 | filename = input('Please specify a file: ') 344 | 345 | # check if file exists 346 | try: 347 | statinfo = os.stat(filename + '.txt') 348 | break 349 | except FileNotFoundError: 350 | print('There is no such file in the directory.\nPlease try again.\n') 351 | continue 352 | else: 353 | txtfiles = [] 354 | print('Current files: ') 355 | print('-' * 15) 356 | for file in glob.glob("*.txt"): 357 | txtfiles.append(file) 358 | print(file.split(".")[0]) 359 | print('\n') 360 | filename = input('Please specify a file: ') 361 | 362 | # check if file exists 363 | try: 364 | statinfo = os.stat(filename + '.txt') 365 | except FileNotFoundError: 366 | print('There is no such file in the directory.\nExiting now...') 367 | sys.exit() 368 | 369 | global filename_statinfo 370 | filename_statinfo = (filename, statinfo) 371 | return filename_statinfo 372 | 373 | 374 | 375 | # define client socket connection 376 | def client(): 377 | 378 | # authenticate with client ---------------------------- 379 | authenticate() 380 | username = final_authorization[0] 381 | password = final_authorization[1] 382 | 383 | # connect to servers ---------------------------------- 384 | 385 | # config params for servers 386 | server_conf() 387 | 388 | # DFS1 389 | try: 390 | client_socket1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 391 | client_socket1.connect(server_list[0]) 392 | status1 = ('Connected to server', 'DFS1') 393 | print(status1[0], status1[1]) 394 | time.sleep(1) 395 | except ConnectionRefusedError: 396 | status1 = ('Could not connect to server', 'DFS1') 397 | print(status1[0], status1[1]) 398 | 399 | # DFS2 400 | try: 401 | client_socket2 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 402 | client_socket2.connect(server_list[1]) 403 | status2 = ('Connected to server', 'DFS2') 404 | print(status2[0], status2[1]) 405 | time.sleep(1) 406 | except ConnectionRefusedError: 407 | status2 = ('Could not connect to server', 'DFS2') 408 | print(status2[0], status2[1]) 409 | 410 | # DFS3 411 | try: 412 | client_socket3 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 413 | client_socket3.connect(server_list[2]) 414 | status3 = ('Connected to server', 'DFS3') 415 | print(status3[0], status3[1]) 416 | time.sleep(1) 417 | except ConnectionRefusedError: 418 | status3 = ('Could not connect to server', 'DFS3') 419 | print(status3[0], status3[1]) 420 | 421 | # DFS4 422 | try: 423 | client_socket4 = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 424 | client_socket4.connect(server_list[3]) 425 | status4 = ('Connected to server', 'DFS4') 426 | print(status4[0], status4[1]) 427 | time.sleep(1) 428 | except ConnectionRefusedError: 429 | status4 = ('Could not connect to server', 'DFS4') 430 | print(status4[0], status4[1]) 431 | 432 | 433 | # if all servers are down, exit client 434 | if status1[0] == 'Could not connect to server' and status2[0] == 'Could not connect to server' \ 435 | and status3[0] == 'Could not connect to server' and status4[0] == 'Could not connect to server': 436 | print('All servers are down.\nExiting now...') 437 | sys.exit() 438 | else: 439 | pass 440 | 441 | # looping lists: connections, and server names 442 | conns = (client_socket1, client_socket2, client_socket3, client_socket4) 443 | DFSS = ('DFS1', 'DFS2', 'DFS3', 'DFS4') 444 | 445 | 446 | # authenticate with servers --------------------------- 447 | 448 | # send usernames 449 | for i in range(0,4): 450 | try: 451 | conns[i].send(username.encode()) 452 | time.sleep(1) 453 | except OSError: 454 | pass 455 | 456 | # send passwords 457 | for i in range(0,4): 458 | try: 459 | conns[i].send(password.encode()) 460 | except OSError: 461 | pass 462 | 463 | # server authorization response 464 | for i in range(0,4): 465 | try: 466 | response = conns[i].recv(1024) 467 | print('From ' +DFSS[i] +': ' +response.decode()) 468 | except OSError: 469 | pass 470 | 471 | # get command from user ------------------------------- 472 | get_command() 473 | 474 | # PUT 475 | if command.lower() == 'put': 476 | for i in range(0,4): 477 | try: 478 | conns[i].send(command.encode()) 479 | except OSError: 480 | pass 481 | 482 | # get a file name from user 483 | get_filename() 484 | filename = filename_statinfo[0] 485 | statinfo = filename_statinfo[1] 486 | 487 | # determine size of file and chunks 488 | filesize = statinfo.st_size 489 | buffersize = round(float(filesize)/4) +4 490 | 491 | # split files into 4 chunks 492 | split_files(filename, buffersize) 493 | 494 | # determine chunk pairs and server locations 495 | dfs1, dfs2, dfs3, dfs4 = chunk_pairs(filename) 496 | 497 | # list to loop through 498 | dfss = (dfs1, dfs2, dfs3, dfs4) 499 | 500 | # send chunk pairs to servers 501 | 502 | # buffer size 503 | for i in range(0,4): 504 | try: 505 | conns[i].send(str(buffersize).encode()) 506 | except OSError: 507 | pass 508 | 509 | # chunk1 name and data 510 | for i in range(0,4): 511 | try: 512 | conns[i].send(dfss[i][0].encode()) 513 | time.sleep(0.5) 514 | chunk1=open(dfss[i][0], 'rb').read() 515 | conns[i].send(chunk1) 516 | print('\nSending ' +str(dfss[i][0]) +'...\n') 517 | except OSError: 518 | pass 519 | 520 | # get chunk1 response 521 | for i in range(0,4): 522 | try: 523 | response=conns[i].recv(1024).decode() 524 | if response == 'Chunk 1 successfully transferred.\n': 525 | print(DFSS[i] +' Chunk 1 transfer complete.') 526 | else: 527 | print(DFSS[i] +' Chunk 1 transfer failed.') 528 | except OSError: 529 | pass 530 | 531 | # chunk2 name and data 532 | for i in range(0,4): 533 | try: 534 | conns[i].send(dfss[i][1].encode()) 535 | time.sleep(0.5) 536 | chunk2=open(dfss[i][1], 'rb').read() 537 | conns[i].send(chunk2) 538 | print('\nSending ' +str(dfss[i][1]) +'...\n') 539 | except OSError: 540 | pass 541 | 542 | # get chunk2 response 543 | for i in range(0,4): 544 | try: 545 | response=conns[i].recv(1024).decode() 546 | if response == 'Chunk 2 successfully transferred.\n': 547 | print(DFSS[i] +' Chunk 2 transfer complete.') 548 | else: 549 | print(DFSS[i] +' Chunk 2 transfer incomplete.') 550 | except OSError: 551 | pass 552 | 553 | # delete chunks from client directory 554 | os.remove(str(dfs1[0])) 555 | os.remove(str(dfs1[1])) 556 | os.remove(str(dfs3[0])) 557 | os.remove(str(dfs3[1])) 558 | 559 | print('\nExiting now...') 560 | sys.exit() 561 | 562 | # LIST 563 | elif command.lower() == 'list': 564 | 565 | # inform servers 566 | for i in range(0,4): 567 | try: 568 | conns[i].send(command.encode()) 569 | except OSError: 570 | pass 571 | 572 | # get list of files, print to console 573 | for i in range(0,4): 574 | try: 575 | file_names=conns[i].recv(4096).decode() 576 | # print a table for each server 577 | print('\nCurrent ' +DFSS[i] +'\%s files:' %username) 578 | print('-' * 27) 579 | print(file_names) 580 | except OSError: 581 | pass 582 | 583 | # print to console whether a file is reconstructable? 584 | 585 | 586 | # ask if user wants to put a file 587 | print('\nWould you like to get files, put files, or exit?') 588 | answer = input('[get, put, exit]: ') 589 | 590 | # inform servers 591 | for i in range(0,4): 592 | try: 593 | conns[i].send(answer.encode()) 594 | except OSError: 595 | pass 596 | 597 | # PUT (within LIST) 598 | if answer.lower() == 'put': 599 | 600 | # get a file name from user 601 | get_filename() 602 | filename = filename_statinfo[0] 603 | statinfo = filename_statinfo[1] 604 | 605 | # determine size of file and chunks 606 | filesize = statinfo.st_size 607 | buffersize = round(float(filesize)/4) +4 608 | 609 | # split files into 4 chunks 610 | split_files(filename, buffersize) 611 | 612 | # determine chunk pairs and server locations 613 | dfs1, dfs2, dfs3, dfs4 = chunk_pairs(filename) 614 | 615 | # list to loop through 616 | dfss = (dfs1, dfs2, dfs3, dfs4) 617 | 618 | # send chunk pairs to servers 619 | 620 | # buffer size 621 | for i in range(0,4): 622 | try: 623 | conns[i].send(str(buffersize).encode()) 624 | except OSError: 625 | pass 626 | 627 | # chunk1 name and data 628 | for i in range(0,4): 629 | try: 630 | conns[i].send(dfss[i][0].encode()) 631 | time.sleep(0.5) 632 | chunk1=open(dfss[i][0], 'rb').read() 633 | conns[i].send(chunk1) 634 | print('\nSending ' +str(dfss[i][0]) +'...\n') 635 | except OSError: 636 | pass 637 | 638 | # get chunk1 response 639 | for i in range(0,4): 640 | try: 641 | response=conns[i].recv(1024).decode() 642 | if response == 'Chunk 1 successfully transferred.\n': 643 | print(DFSS[i] +' Chunk 1 transfer complete.') 644 | else: 645 | print(DFSS[i] +' Chunk 1 transfer failed.') 646 | except OSError: 647 | pass 648 | 649 | # chunk2 name and data 650 | for i in range(0,4): 651 | try: 652 | conns[i].send(dfss[i][1].encode()) 653 | time.sleep(0.5) 654 | chunk2=open(dfss[i][1], 'rb').read() 655 | conns[i].send(chunk2) 656 | print('\nSending ' +str(dfss[i][1]) +'...\n') 657 | except OSError: 658 | pass 659 | 660 | # get chunk2 response 661 | for i in range(0,4): 662 | try: 663 | response=conns[i].recv(1024).decode() 664 | if response == 'Chunk 2 successfully transferred.\n': 665 | print(DFSS[i] +' Chunk 2 transfer complete.') 666 | else: 667 | print(DFSS[i] +' Chunk 2 transfer incomplete.') 668 | except OSError: 669 | pass 670 | 671 | # delete chunks from client directory 672 | os.remove(str(dfs1[0])) 673 | os.remove(str(dfs1[1])) 674 | os.remove(str(dfs3[0])) 675 | os.remove(str(dfs3[1])) 676 | 677 | print('\nExiting now...') 678 | sys.exit() 679 | 680 | 681 | # GET (within LIST) 682 | elif answer.lower() == 'get': 683 | # already informed servers! 684 | 685 | # create a subdirectory for user in client 686 | new_dir_path = os.getcwd() +'\\' +username 687 | 688 | if os.path.isdir(new_dir_path) == False: 689 | try: 690 | os.mkdir(new_dir_path) 691 | print ("Successfully created the directory %s " % new_dir_path) 692 | pass 693 | except OSError: 694 | print ("Creation of the directory %s failed" % new_dir_path) 695 | else: 696 | pass 697 | 698 | # get filename from user 699 | filename = input('Please specify a file: ') 700 | 701 | # send file name to server 702 | for i in range(0,4): 703 | try: 704 | conns[i].send(filename.encode()) 705 | except OSError: 706 | pass 707 | 708 | # receive server answer 709 | for i in range(0,4): 710 | try: 711 | answer=conns[i].recv(1024).decode() 712 | except OSError: 713 | pass 714 | 715 | # get buffersize if answer is positive 716 | for i in range(0,4): 717 | if answer == 'Server is preparing file transfer...': 718 | try: 719 | buffersize=int(conns[i].recv(1024).decode()) 720 | except OSError: 721 | pass 722 | else: 723 | try: 724 | print(answer) 725 | sys.exit() 726 | except OSError: 727 | pass 728 | 729 | # get names of first batch of chunks 730 | chunk_list = [] 731 | for i in range(0,4): 732 | try: 733 | name=conns[i].recv(1024).decode() 734 | chunk_list.append(name) 735 | except OSError: 736 | pass 737 | 738 | # get first batch of chunks 739 | # if not all servers are connected limit range to len(chunk_list) 740 | for i in range(0,len(chunk_list)): 741 | try: 742 | chunk1=conns[i].recv(buffersize).decode() 743 | with open(os.path.join(new_dir_path, chunk_list[i]), 'w') as fh: 744 | fh.write(chunk1) 745 | print('File chunks successfully transferred.') 746 | except OSError: 747 | pass 748 | 749 | # check that all chunks arrived 750 | arrived = chunk_list 751 | num_chunks = len(arrived) 752 | 753 | # if not all 4 arrived 754 | if num_chunks < 4: 755 | 756 | # send NACK 757 | NACK = 'Transfer incomplete' 758 | print(NACK +'\nOnly ' +str(num_chunks) +' out of 4 chunks arrived.') 759 | for i in range(0,4): 760 | try: 761 | conns[i].send(NACK.encode()) 762 | except OSError: 763 | pass 764 | 765 | # get names of second batch 766 | chunk2_list = [] 767 | for i in range(0,4): 768 | try: 769 | name2=conns[i].recv(1024).decode() 770 | chunk2_list.append(name2) 771 | except OSError: 772 | pass 773 | 774 | # get second batch 775 | print('Receiving second batch...') 776 | for i in range(0,len(chunk2_list)): 777 | try: 778 | chunk2=conns[i].recv(buffersize).decode() 779 | with open(os.path.join(new_dir_path, chunk2_list[i]), 'w') as fh: 780 | fh.write(chunk2) 781 | print('File chunks successfully transferred.') 782 | except OSError: 783 | pass 784 | 785 | # check if the chunks are the correct ones now 786 | # list all files (list already ordered) 787 | arrived2 = os.listdir(new_dir_path) 788 | 789 | # subset the 4 chunks of interst (filename) 790 | arrived2_clean = [] 791 | for i in range(0, len(arrived2)): 792 | if arrived2[i].split('_')[0] == filename: 793 | arrived2_clean.append(arrived2[i]) 794 | else: 795 | pass 796 | 797 | # create integer list 798 | arrived2_intlist = [] 799 | for i in range(0,len(arrived2_clean)): 800 | arrived2_intlist.append(int(arrived2_clean[i].split('_')[1].split('.')[0])) 801 | 802 | # compare with [1,2,3,4], if a match 803 | if arrived2_intlist == [1,2,3,4]: 804 | print('Chunks 1 through 4 are present.') 805 | 806 | # send FIN 807 | FIN = 'Transfer successful.' 808 | for i in range(0,4): 809 | try: 810 | conns[i].send(FIN.encode()) 811 | except OSError: 812 | pass 813 | 814 | # concatenate chunks into file 815 | final_filename = arrived2_clean[0].split('_')[0] +'.txt' 816 | 817 | with open(username +'\\' +final_filename, 'wb') as outfile: 818 | for chunk_name in arrived2_clean: 819 | with open(username +'\\' +chunk_name, 'rb') as infile: 820 | outfile.write(infile.read()) 821 | 822 | print('File successfully reconstructed.') 823 | 824 | # delete temporary files 825 | for i in range(0,len(arrived2_clean)): 826 | try: 827 | os.remove(str(username +'\\' +arrived2_clean[i])) 828 | except IndexError: 829 | pass 830 | 831 | print('Exiting now...') 832 | sys.exit() 833 | 834 | else: 835 | 836 | FIN = 'Transfer failed.\nExiting now...' 837 | for i in range(0,4): 838 | try: 839 | conns[i].send(FIN.encode()) 840 | except OSError: 841 | pass 842 | 843 | print(FIN) 844 | sys.exit() 845 | 846 | # else if there are 4 chunks 847 | else: 848 | # which might contain repeated chunks 849 | print('A total of ' +str(num_chunks) +' chunks arrived.') 850 | 851 | # check if the 4 chunks are all different [1 through 4] 852 | # create a list for numbers 853 | arrived_ordered = [] 854 | for i in range(0,4): 855 | arrived_ordered.append(int(arrived[i].split('_')[1].split('.')[0])) 856 | 857 | # should be [1,2,3,4] 858 | arrived_ordered.sort() 859 | 860 | # if it is, as expected 861 | if arrived_ordered == [1,2,3,4]: 862 | 863 | print('All four chunks are present.') 864 | 865 | # send FIN ACK 866 | FIN = 'Transfer successful.' 867 | for i in range(0,4): 868 | try: 869 | conns[i].send(FIN.encode()) 870 | except OSError: 871 | pass 872 | 873 | # concatenate chunks into file 874 | chunk_list.sort() 875 | final_filename = chunk_list[0].split('_')[0] +'.txt' 876 | 877 | with open(username +'\\' +final_filename, 'wb') as outfile: 878 | for chunk_name in chunk_list: 879 | with open(username +'\\' +chunk_name, 'rb') as infile: 880 | outfile.write(infile.read()) 881 | 882 | print('File successfully reconstructed.') 883 | 884 | # delete temporary files 885 | for i in range(0,4): 886 | try: 887 | os.remove(str(username +'\\' +chunk_list[i])) 888 | except IndexError: 889 | pass 890 | 891 | print('Exiting now...') 892 | sys.exit() 893 | 894 | else: 895 | # if the ordered list is not [1,2,3,4] 896 | FIN = 'Transfer failed.\Exiting now...' 897 | for i in range(0,4): 898 | try: 899 | conns[i].send(FIN.encode()) 900 | except OSError: 901 | pass 902 | 903 | print(FIN) 904 | sys.exit() 905 | 906 | # end of GET (within LIST) -------------------------------- 907 | 908 | elif answer.lower() == 'exit': 909 | print('Exiting now...') 910 | sys.exit() 911 | 912 | # allow user to try again possibly... 913 | else: 914 | print('This method does not exist.\nExiting now...') 915 | sys.exit() 916 | 917 | # GET ---------------------------------------- 918 | else: 919 | # inform servers 920 | for i in range(0,4): 921 | try: 922 | conns[i].send(command.encode()) 923 | except OSError: 924 | pass 925 | 926 | 927 | # create a subdirectory for user in client 928 | new_dir_path = os.getcwd() +'\\' +username 929 | 930 | if os.path.isdir(new_dir_path) == False: 931 | try: 932 | os.mkdir(new_dir_path) 933 | print ("Successfully created the directory %s " % new_dir_path) 934 | pass 935 | except OSError: 936 | print ("Creation of the directory %s failed" % new_dir_path) 937 | else: 938 | pass 939 | 940 | # get filename from user 941 | filename = input('Please specify a file: ') 942 | 943 | # send file name to server 944 | for i in range(0,4): 945 | try: 946 | conns[i].send(filename.encode()) 947 | except OSError: 948 | pass 949 | 950 | # receive server answer 951 | for i in range(0,4): 952 | try: 953 | answer=conns[i].recv(1024).decode() 954 | except OSError: 955 | pass 956 | 957 | # get buffersize if answer is positive 958 | for i in range(0,4): 959 | if answer == 'Server is preparing file transfer...': 960 | try: 961 | buffersize=int(conns[i].recv(1024).decode()) 962 | print(answer) 963 | except OSError: 964 | pass 965 | 966 | else: 967 | try: 968 | print(answer) 969 | sys.exit() 970 | except OSError: 971 | pass 972 | 973 | # get names of first batch of chunks 974 | chunk_list = [] 975 | for i in range(0,4): 976 | try: 977 | name=conns[i].recv(1024).decode() 978 | chunk_list.append(name) 979 | except OSError: 980 | pass 981 | 982 | # get first batch of chunks 983 | # if not all servers are connected limit range to len(chunk_list) 984 | for i in range(0,len(chunk_list)): 985 | try: 986 | chunk1=conns[i].recv(buffersize).decode() 987 | with open(os.path.join(new_dir_path, chunk_list[i]), 'w') as fh: 988 | fh.write(chunk1) 989 | print('File chunks successfully transferred.') 990 | except OSError: 991 | pass 992 | 993 | # check that all chunks arrived 994 | arrived = chunk_list 995 | num_chunks = len(arrived) 996 | 997 | # if not all 4 arrived 998 | if num_chunks < 4: 999 | 1000 | # send NACK 1001 | NACK = 'Transfer incomplete' 1002 | print(NACK +'\nOnly ' +str(num_chunks) +' out of 4 chunks arrived.') 1003 | for i in range(0,4): 1004 | try: 1005 | conns[i].send(NACK.encode()) 1006 | except OSError: 1007 | pass 1008 | 1009 | # get names of second batch 1010 | chunk2_list = [] 1011 | for i in range(0,4): 1012 | try: 1013 | name2=conns[i].recv(1024).decode() 1014 | chunk2_list.append(name2) 1015 | except OSError: 1016 | pass 1017 | 1018 | # get second batch 1019 | print('Receiving second batch...') 1020 | for i in range(0,len(chunk2_list)): 1021 | try: 1022 | chunk2=conns[i].recv(buffersize).decode() 1023 | with open(os.path.join(new_dir_path, chunk2_list[i]), 'w') as fh: 1024 | fh.write(chunk2) 1025 | print('File chunks successfully transferred.') 1026 | except OSError: 1027 | pass 1028 | 1029 | # check if the chunks are the correct ones now 1030 | # list all files (list already ordered) 1031 | arrived2 = os.listdir(new_dir_path) 1032 | 1033 | # subset the 4 chunks of interst (filename) 1034 | arrived2_clean = [] 1035 | for i in range(0, len(arrived2)): 1036 | if arrived2[i].split('_')[0] == filename: 1037 | arrived2_clean.append(arrived2[i]) 1038 | else: 1039 | pass 1040 | 1041 | # create integer list 1042 | arrived2_intlist = [] 1043 | for i in range(0,len(arrived2_clean)): 1044 | arrived2_intlist.append(int(arrived2_clean[i].split('_')[1].split('.')[0])) 1045 | 1046 | # compare with [1,2,3,4], if a match 1047 | if arrived2_intlist == [1,2,3,4]: 1048 | print('Chunks 1 through 4 are present.') 1049 | 1050 | # send FIN 1051 | FIN = 'Transfer successful.' 1052 | for i in range(0,4): 1053 | try: 1054 | conns[i].send(FIN.encode()) 1055 | except OSError: 1056 | pass 1057 | 1058 | # concatenate chunks into file 1059 | final_filename = arrived2_clean[0].split('_')[0] +'.txt' 1060 | 1061 | with open(username +'\\' +final_filename, 'wb') as outfile: 1062 | for chunk_name in arrived2_clean: 1063 | with open(username +'\\' +chunk_name, 'rb') as infile: 1064 | outfile.write(infile.read()) 1065 | 1066 | print('File successfully reconstructed.') 1067 | 1068 | # delete temporary files 1069 | for i in range(0,len(arrived2_clean)): 1070 | try: 1071 | os.remove(str(username +'\\' +arrived2_clean[i])) 1072 | except IndexError: 1073 | pass 1074 | 1075 | print('Exiting now...') 1076 | sys.exit() 1077 | 1078 | else: 1079 | 1080 | FIN = 'Transfer failed.\nExiting now...' 1081 | for i in range(0,4): 1082 | try: 1083 | conns[i].send(FIN.encode()) 1084 | except OSError: 1085 | pass 1086 | 1087 | print(FIN) 1088 | sys.exit() 1089 | 1090 | # else if there are 4 chunks 1091 | else: 1092 | # which might contain repeated chunks 1093 | print('A total of ' +str(num_chunks) +' chunks arrived.') 1094 | 1095 | # check if the 4 chunks are all different [1 through 4] 1096 | # create a list for numbers 1097 | arrived_ordered = [] 1098 | for i in range(0,4): 1099 | arrived_ordered.append(int(arrived[i].split('_')[1].split('.')[0])) 1100 | 1101 | # should be [1,2,3,4] 1102 | arrived_ordered.sort() 1103 | 1104 | # if it is, as expected 1105 | if arrived_ordered == [1,2,3,4]: 1106 | 1107 | print('All four chunks are present.') 1108 | 1109 | # send FIN ACK 1110 | FIN = 'Transfer successful.' 1111 | for i in range(0,4): 1112 | try: 1113 | conns[i].send(FIN.encode()) 1114 | except OSError: 1115 | pass 1116 | 1117 | # concatenate chunks into file 1118 | chunk_list.sort() 1119 | final_filename = chunk_list[0].split('_')[0] +'.txt' 1120 | 1121 | with open(username +'\\' +final_filename, 'wb') as outfile: 1122 | for chunk_name in chunk_list: 1123 | with open(username +'\\' +chunk_name, 'rb') as infile: 1124 | outfile.write(infile.read()) 1125 | 1126 | print('File successfully reconstructed.') 1127 | 1128 | # delete temporary files 1129 | for i in range(0,4): 1130 | try: 1131 | os.remove(str(username +'\\' +chunk_list[i])) 1132 | except IndexError: 1133 | pass 1134 | 1135 | print('Exiting now...') 1136 | sys.exit() 1137 | 1138 | else: 1139 | # if the ordered list is not [1,2,3,4] 1140 | FIN = 'Transfer failed.\Exiting now...' 1141 | for i in range(0,4): 1142 | try: 1143 | conns[i].send(FIN.encode()) 1144 | except OSError: 1145 | pass 1146 | 1147 | print(FIN) 1148 | sys.exit() 1149 | 1150 | 1151 | # run client 1152 | if __name__=='__main__': 1153 | check_args() 1154 | client() -------------------------------------------------------------------------------- /DFS1/dfs.conf: -------------------------------------------------------------------------------- 1 | Server DFS1 127.0.0.1:10001 2 | Server DFS2 127.0.0.1:10002 3 | Server DFS3 127.0.0.1:10003 4 | Server DFS3 127.0.0.1:10004 5 | Username: Alice 6 | Password: 9f451d98e0daf53c49f42095ee3b7220 7 | Username: Bob 8 | Password: cb5ead8bc8bca45f007bc7a995964460 9 | Username: Eve 10 | Password: ca2d3b7e3704505de305a608d832e91d -------------------------------------------------------------------------------- /DFS1/dfs1.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ 4 | Distributed File System 5 | Server 1 6 | Marcelo Sanches 7 | Jan 2019 8 | """ 9 | 10 | # modules 11 | import os 12 | import re 13 | import sys 14 | import time 15 | import socket 16 | import glob 17 | import pickle 18 | 19 | # function to check port number assignment 20 | def check_args(): 21 | 22 | # error handling argument 23 | if len(sys.argv) != 2: 24 | print("ERROR: Must supply port number \nUSAGE: py dfs1.py 10001") 25 | sys.exit() 26 | 27 | # error handling port number 28 | else: 29 | try: 30 | if int(sys.argv[1]) != 10001: 31 | print("ERROR: Port number must be 10001") 32 | sys.exit() 33 | else: 34 | return int(sys.argv[1]) 35 | 36 | except ValueError: 37 | print("ERROR: Port number must be a number.") 38 | sys.exit() 39 | 40 | check_args() 41 | 42 | # get authentication parameters 43 | def auth_params(): 44 | 45 | # use dfs configuration file 46 | config_file='dfs.conf' 47 | 48 | # get usernames from config file 49 | fh=open(config_file, mode='r', encoding='cp1252') 50 | users=re.findall(r'Username: .*', fh.read()) 51 | usernames=list() 52 | for i in range(0, len(users)): 53 | usernames.append(str(users[i]).split()[1]) 54 | fh.close() 55 | 56 | # get passwords from config file 57 | fh=open(config_file, mode='r', encoding='cp1252') 58 | passes=re.findall(r'Password: .*', fh.read()) 59 | passwords=list() 60 | for i in range(0, len(passes)): 61 | passwords.append(str(passes[i]).split()[1]) 62 | fh.close() 63 | 64 | # create dict with usernames:passwords 65 | global auth_dict 66 | auth_dict = {} 67 | for i in range(0, len(users)): 68 | entry={usernames[i]:passwords[i]} 69 | auth_dict.update(entry) 70 | 71 | return auth_dict 72 | 73 | # authorize client, given username and password 74 | def client_auth(auth_dict, username, password): 75 | ct = 0 76 | auth_status='' 77 | for key, value in auth_dict.items(): 78 | ct += 1 79 | if auth_status != '': 80 | pass 81 | else: 82 | # check all users up to last 83 | if ct < len(auth_dict): 84 | 85 | if username == key: 86 | print('Correct username.') 87 | 88 | if password == value: 89 | print('Correct password.') 90 | 91 | auth_status='Authorization Granted.\n' 92 | print(auth_status) 93 | conn.send(auth_status.encode()) 94 | pass 95 | else: 96 | print('Incorrect password.') 97 | auth_status = 'Authorization Denied.\n' 98 | print(auth_status) 99 | conn.send(auth_status.encode()) 100 | sys.exit() 101 | else: 102 | continue 103 | 104 | # check last user 105 | else: 106 | if username == key: 107 | print('Correct username.') 108 | 109 | if password == value: 110 | print('Correct password.') 111 | 112 | auth_status='Authorization Granted.\n' 113 | print(auth_status) 114 | conn.send(auth_status.encode()) 115 | pass 116 | else: 117 | print('Incorrect password.') 118 | auth_status = 'Authorization Denied.\n' 119 | print(auth_status) 120 | conn.send(auth_status.encode()) 121 | sys.exit() 122 | else: 123 | print('Incorrect username.') 124 | auth_status = 'Authorization Denied.\n' 125 | print(auth_status) 126 | conn.send(auth_status.encode()) 127 | sys.exit() 128 | 129 | # put files into servers 130 | def put(new_dir_path): 131 | 132 | # get size of buffer 133 | try: 134 | buffersize = int(conn.recv(2048).decode()) 135 | print('The buffer size is: ' +str(buffersize)) 136 | except ValueError: 137 | print('The buffer size is not a number. \nExiting now...') 138 | sys.exit() 139 | 140 | # receive chunk 1 name and data 141 | name1 = conn.recv(1024).decode() 142 | chunk1 = conn.recv(buffersize).decode() 143 | print('Receiving ' +name1 +'...\n') 144 | 145 | # create file folder for chunks 146 | file_folder = name1.split('_')[0] 147 | new_folder_path = os.getcwd() +'\\' +username +'\\' +file_folder 148 | 149 | if os.path.isdir(new_folder_path) == False: 150 | try: 151 | os.mkdir(new_folder_path) 152 | print ("Successfully created the folder %s " % new_folder_path) 153 | pass 154 | except OSError: 155 | print ("Creation of the folder %s failed" % new_folder_path) 156 | else: 157 | pass 158 | 159 | # write chunk1 to file folder 160 | fh=open(os.path.join(new_folder_path, name1), 'w') 161 | fh.write(chunk1) 162 | fh.close() 163 | 164 | # inform client if transfer was successful [check if file exists] 165 | exists = new_folder_path +'\\' +name1 166 | if os.path.isfile(exists) == True: 167 | response = 'Chunk 1 successfully transferred.\n' 168 | print(response) 169 | conn.send(response.encode()) 170 | else: 171 | response = 'Chunk 1 transfer incomplete.\n' 172 | print(response) 173 | conn.send(response.encode()) 174 | 175 | # receive chunk 2 name and data 176 | name2 = conn.recv(1024).decode() 177 | chunk2 = conn.recv(buffersize).decode() 178 | print('Receiving ' +name2 +'...\n') 179 | 180 | # write chunk2 to file folder 181 | fh=open(os.path.join(new_folder_path, name2), 'w') 182 | fh.write(chunk2) 183 | fh.close() 184 | 185 | # inform client if transfer was successful [check if file exists] 186 | exists = new_folder_path +'\\' +name2 187 | if os.path.isfile(exists) == True: 188 | response = 'Chunk 2 successfully transferred.\n' 189 | print(response) 190 | conn.send(response.encode()) 191 | else: 192 | response = 'Chunk 2 transfer incomplete.\n' 193 | print(response) 194 | conn.send(response.encode()) 195 | 196 | # close connection after chunks are sent 197 | print('Exiting now...') 198 | sys.exit() 199 | 200 | 201 | # creates new directory for user 202 | def new_dir(username): 203 | 204 | # define new path 205 | global new_dir_path 206 | new_dir_path = os.getcwd() +'\\' +username 207 | 208 | # if path does not exist, create new dir 209 | if os.path.isdir(new_dir_path) == False: 210 | try: 211 | os.mkdir(new_dir_path) 212 | print ("Successfully created the directory %s " % new_dir_path) 213 | return new_dir_path 214 | except OSError: 215 | print ("Creation of the directory %s failed" % new_dir_path) 216 | 217 | # return the dir path if exists, however 218 | else: 219 | return new_dir_path 220 | pass 221 | 222 | # command to list files in servers 223 | def list_files(username): 224 | 225 | # get list of files from subdirectory 226 | user_dir = os.getcwd() +'\\' +username 227 | file_dir_list = next(os.walk(user_dir))[1] 228 | 229 | # if user has no file directory (has never sent files) 230 | if file_dir_list == []: 231 | response='There are no files yet.' 232 | print(response) 233 | conn.send(response.encode()) 234 | 235 | else: 236 | # start a list of files 237 | file_list = [] 238 | for i in range(0, len(file_dir_list)): 239 | file_dir = file_dir_list[i] 240 | file_list.append(os.listdir(user_dir +"\\" +file_dir)) 241 | 242 | # if user has a file directory yet no files 243 | if file_list == [[]]: 244 | response='There are no files yet.' 245 | print(response) 246 | conn.send(response.encode()) 247 | 248 | else: 249 | # if user has files, write a txt file with their names 250 | with open('filenames.txt', 'w') as fh: 251 | for list in file_list: 252 | for file in range(0, len(list)): 253 | fh.write('%s\n' % list[file]) 254 | 255 | # send list (the txt file) to client 256 | file_names=open('filenames.txt', 'rb').read() 257 | conn.send(file_names) 258 | print('\nSending file names...\n') 259 | 260 | # delete the file 261 | os.remove('filenames.txt') 262 | 263 | 264 | # gets files from servers 265 | def get(username): 266 | 267 | # get file name from client 268 | filename = conn.recv(1024).decode() 269 | print('User ' +username +' requested: ' +filename) 270 | 271 | # check whether file exists 272 | 273 | # establish paths 274 | user_dir = os.getcwd() +'\\' +username 275 | file_dir = os.path.join(user_dir, filename) 276 | user_dir_filelist = next(os.walk(user_dir))[1] 277 | 278 | # if user directory is empty 279 | if user_dir_filelist == []: 280 | response='Your directory has no files yet.\nExiting now...' 281 | print('User directory has no file folders.\nExiting now...') 282 | conn.send(response.encode()) 283 | sys.exit() 284 | 285 | # else, if user dir is not empty 286 | else: 287 | # check if there are any file chunks 288 | # establish list of chunks 289 | file_dir_chunklist = next(os.walk(file_dir))[2] 290 | 291 | if file_dir_chunklist == []: 292 | response='You do not have any files in the folder yet.\nExiting now...' 293 | print('File folder empty.\nExiting now...') 294 | conn.send(response.encode()) 295 | sys.exit() 296 | 297 | # if there are any file chunks... 298 | else: 299 | # send chunks ('get', from user's perspective) 300 | ct = 0 301 | for chunk in user_dir_filelist: 302 | ct += 1 303 | if ct < len(user_dir_filelist): 304 | # file exists, send file 305 | if filename == chunk: 306 | response='Server is preparing file transfer...' 307 | print('File found.') 308 | conn.send(response.encode()) 309 | time.sleep(1) 310 | break 311 | else: 312 | continue 313 | # if ct == length of list 314 | else: 315 | if filename == chunk: 316 | response='Server is preparing file transfer...' 317 | print('File found.') 318 | conn.send(response.encode()) 319 | time.sleep(1) 320 | pass 321 | # otherwise, exit 322 | else: 323 | response='No such file exists.\nExiting now...' 324 | print(response) 325 | conn.send(response.encode()) 326 | sys.exit() 327 | 328 | # establish chunk paths 329 | name1, name2 = os.listdir(file_dir) 330 | chunk1 = username +'\\' +chunk +'\\' +name1 331 | chunk2 = username +'\\' +chunk +'\\' +name2 332 | 333 | # send buffersize 334 | statinfo=os.stat(chunk1) 335 | buffersize=round(float(statinfo.st_size)) +4 336 | conn.send(str(buffersize).encode()) 337 | time.sleep(1) 338 | 339 | # send first batch of chunks 340 | # get numbers of chunks 341 | chunk1_num = name1.split('_')[1] 342 | chunk2_num = name2.split('_')[1] 343 | 344 | if chunk1_num == '1.txt' and chunk2_num == '4.txt': 345 | # send chunk 2 instead 346 | conn.send(name2.encode()) 347 | time.sleep(0.5) 348 | chunk2=open(chunk2,'rb').read() 349 | conn.send(chunk2) 350 | # name it chunk 1, however 351 | print('Sending chunk 1: ' +name2) 352 | else: 353 | # all other cases send chunk 1 354 | conn.send(name1.encode()) 355 | time.sleep(0.5) 356 | chunk1=open(chunk1,'rb').read() 357 | conn.send(chunk1) 358 | print('Sending chunk 1: ' +name1) 359 | 360 | # get a FIN or a NACK 361 | FINACK = conn.recv(1024).decode() 362 | 363 | # if NACK, send second batch 364 | if FINACK == 'Transfer incomplete': 365 | 366 | # second batch, reverse rules 367 | if chunk1_num == '1.txt' and chunk2_num == '4.txt': 368 | # send chunk 1 instead 369 | conn.send(name1.encode()) 370 | time.sleep(0.5) 371 | chunk1=open(chunk1,'rb').read() 372 | conn.send(chunk1) 373 | # name it chunk 2, however 374 | print('Sending chunk 2: ' +name1) 375 | else: 376 | # all other cases send chunk 2 377 | conn.send(name2.encode()) 378 | time.sleep(0.5) 379 | chunk2=open(chunk2,'rb').read() 380 | conn.send(chunk2) 381 | print('Sending chunk 2: ' +name2) 382 | 383 | # get actual FIN since previous was NACK 384 | FIN = conn.recv(1024).decode() 385 | print(FIN) 386 | 387 | # iff FIN, exit (FINACK == 'Transfer successful.') 388 | else: 389 | 390 | # print and exit 391 | print(FINACK +'\nExiting now...') 392 | 393 | sys.exit() 394 | 395 | 396 | # RUN DFS ------------------------------------------------- 397 | 398 | server_name = '127.0.0.1' 399 | server_port = int(sys.argv[1]) 400 | 401 | # define socket 402 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 403 | server_socket.bind((server_name, server_port)) 404 | server_socket.listen(5) 405 | print('Server listening...') 406 | 407 | while True: 408 | conn, client_address = server_socket.accept() 409 | print('Connected to Client.') 410 | 411 | # get username 412 | username = conn.recv(2048) 413 | username = username.decode() 414 | print('received username') 415 | 416 | # get password 417 | password = conn.recv(2048) 418 | password = password.decode() 419 | print('received password') 420 | 421 | # authorize client 422 | auth_params() 423 | client_auth(auth_dict, username, password) 424 | 425 | # create a new directory for user, if none exists 426 | new_dir(username) 427 | 428 | # receive command from user 429 | command = conn.recv(1024).decode() 430 | print('The user requested to ' +command + ' files.') 431 | 432 | # PUT 433 | if command == 'put': 434 | put(new_dir_path) 435 | 436 | # LIST 437 | elif command == 'list': 438 | list_files(username) 439 | 440 | # after listing, get further action 441 | answer = conn.recv(1024).decode() 442 | print('The user now requests to ' +answer +' files.') 443 | 444 | # PUT within LIST 445 | if answer == 'put': 446 | print('Receiving files...') 447 | put(new_dir_path) 448 | 449 | # GET within LIST 450 | elif answer == 'get': 451 | get(username) 452 | 453 | # exit 454 | else: 455 | print('Exiting now...') 456 | sys.exit() 457 | 458 | # GET 459 | elif command == 'get': 460 | get(username) 461 | 462 | # handle wrong command 463 | else: 464 | print('Command does not exist.\nExiting now...') 465 | sys.exit() 466 | 467 | conn.close() -------------------------------------------------------------------------------- /DFS2/dfs.conf: -------------------------------------------------------------------------------- 1 | Server DFS1 127.0.0.1:10001 2 | Server DFS2 127.0.0.1:10002 3 | Server DFS3 127.0.0.1:10003 4 | Server DFS3 127.0.0.1:10004 5 | Username: Alice 6 | Password: 9f451d98e0daf53c49f42095ee3b7220 7 | Username: Bob 8 | Password: cb5ead8bc8bca45f007bc7a995964460 9 | Username: Eve 10 | Password: ca2d3b7e3704505de305a608d832e91d -------------------------------------------------------------------------------- /DFS2/dfs2.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ 4 | Distributed File System 5 | Server 2 6 | Marcelo Sanches 7 | Jan 2019 8 | """ 9 | 10 | # modules 11 | import os 12 | import re 13 | import sys 14 | import time 15 | import socket 16 | import glob 17 | import pickle 18 | 19 | # function to check port number assignment 20 | def check_args(): 21 | 22 | # error handling argument 23 | if len(sys.argv) != 2: 24 | print("ERROR: Must supply port number \nUSAGE: py dfs2.py 10002") 25 | sys.exit() 26 | 27 | # error handling port number 28 | else: 29 | try: 30 | if int(sys.argv[1]) != 10002: 31 | print("ERROR: Port number must be 10002") 32 | sys.exit() 33 | else: 34 | return int(sys.argv[1]) 35 | 36 | except ValueError: 37 | print("ERROR: Port number must be a number.") 38 | sys.exit() 39 | 40 | check_args() 41 | 42 | # get authentication parameters 43 | def auth_params(): 44 | 45 | # use dfs configuration file 46 | config_file='dfs.conf' 47 | 48 | # get usernames from config file 49 | fh=open(config_file, mode='r', encoding='cp1252') 50 | users=re.findall(r'Username: .*', fh.read()) 51 | usernames=list() 52 | for i in range(0, len(users)): 53 | usernames.append(str(users[i]).split()[1]) 54 | fh.close() 55 | 56 | # get passwords from config file 57 | fh=open(config_file, mode='r', encoding='cp1252') 58 | passes=re.findall(r'Password: .*', fh.read()) 59 | passwords=list() 60 | for i in range(0, len(passes)): 61 | passwords.append(str(passes[i]).split()[1]) 62 | fh.close() 63 | 64 | # create dict with usernames:passwords 65 | global auth_dict 66 | auth_dict = {} 67 | for i in range(0, len(users)): 68 | entry={usernames[i]:passwords[i]} 69 | auth_dict.update(entry) 70 | 71 | return auth_dict 72 | 73 | # authorize client, given username and password 74 | def client_auth(auth_dict, username, password): 75 | ct = 0 76 | auth_status='' 77 | for key, value in auth_dict.items(): 78 | ct += 1 79 | if auth_status != '': 80 | pass 81 | else: 82 | # check all users up to last 83 | if ct < len(auth_dict): 84 | 85 | if username == key: 86 | print('Correct username.') 87 | 88 | if password == value: 89 | print('Correct password.') 90 | 91 | auth_status='Authorization Granted.\n' 92 | print(auth_status) 93 | conn.send(auth_status.encode()) 94 | pass 95 | else: 96 | print('Incorrect password.') 97 | auth_status = 'Authorization Denied.\n' 98 | print(auth_status) 99 | conn.send(auth_status.encode()) 100 | sys.exit() 101 | else: 102 | continue 103 | 104 | # check last user 105 | else: 106 | if username == key: 107 | print('Correct username.') 108 | 109 | if password == value: 110 | print('Correct password.') 111 | 112 | auth_status='Authorization Granted.\n' 113 | print(auth_status) 114 | conn.send(auth_status.encode()) 115 | pass 116 | else: 117 | print('Incorrect password.') 118 | auth_status = 'Authorization Denied.\n' 119 | print(auth_status) 120 | conn.send(auth_status.encode()) 121 | sys.exit() 122 | else: 123 | print('Incorrect username.') 124 | auth_status = 'Authorization Denied.\n' 125 | print(auth_status) 126 | conn.send(auth_status.encode()) 127 | sys.exit() 128 | 129 | # put files into servers 130 | def put(new_dir_path): 131 | 132 | # get size of buffer 133 | try: 134 | buffersize = int(conn.recv(2048).decode()) 135 | print('The buffer size is: ' +str(buffersize)) 136 | except ValueError: 137 | print('The buffer size is not a number. \nExiting now...') 138 | sys.exit() 139 | 140 | # receive chunk 1 name and data 141 | name1 = conn.recv(1024).decode() 142 | chunk1 = conn.recv(buffersize).decode() 143 | print('Receiving ' +name1 +'...\n') 144 | 145 | # create file folder for chunks 146 | file_folder = name1.split('_')[0] 147 | new_folder_path = os.getcwd() +'\\' +username +'\\' +file_folder 148 | 149 | if os.path.isdir(new_folder_path) == False: 150 | try: 151 | os.mkdir(new_folder_path) 152 | print ("Successfully created the folder %s " % new_folder_path) 153 | pass 154 | except OSError: 155 | print ("Creation of the folder %s failed" % new_folder_path) 156 | else: 157 | pass 158 | 159 | # write chunk1 to file folder 160 | fh=open(os.path.join(new_folder_path, name1), 'w') 161 | fh.write(chunk1) 162 | fh.close() 163 | 164 | # inform client if transfer was successful [check if file exists] 165 | exists = new_folder_path +'\\' +name1 166 | if os.path.isfile(exists) == True: 167 | response = 'Chunk 1 successfully transferred.\n' 168 | print(response) 169 | conn.send(response.encode()) 170 | else: 171 | response = 'Chunk 1 transfer incomplete.\n' 172 | print(response) 173 | conn.send(response.encode()) 174 | 175 | # receive chunk 2 name and data 176 | name2 = conn.recv(1024).decode() 177 | chunk2 = conn.recv(buffersize).decode() 178 | print('Receiving ' +name2 +'...\n') 179 | 180 | # write chunk2 to file folder 181 | fh=open(os.path.join(new_folder_path, name2), 'w') 182 | fh.write(chunk2) 183 | fh.close() 184 | 185 | # inform client if transfer was successful [check if file exists] 186 | exists = new_folder_path +'\\' +name2 187 | if os.path.isfile(exists) == True: 188 | response = 'Chunk 2 successfully transferred.\n' 189 | print(response) 190 | conn.send(response.encode()) 191 | else: 192 | response = 'Chunk 2 transfer incomplete.\n' 193 | print(response) 194 | conn.send(response.encode()) 195 | 196 | # close connection after chunks are sent 197 | print('Exiting now...') 198 | sys.exit() 199 | 200 | 201 | # creates new directory for user 202 | def new_dir(username): 203 | 204 | # define new path 205 | global new_dir_path 206 | new_dir_path = os.getcwd() +'\\' +username 207 | 208 | # if path does not exist, create new dir 209 | if os.path.isdir(new_dir_path) == False: 210 | try: 211 | os.mkdir(new_dir_path) 212 | print ("Successfully created the directory %s " % new_dir_path) 213 | return new_dir_path 214 | except OSError: 215 | print ("Creation of the directory %s failed" % new_dir_path) 216 | 217 | # return the dir path if exists, however 218 | else: 219 | return new_dir_path 220 | pass 221 | 222 | # command to list files in servers 223 | def list_files(username): 224 | 225 | # get list of files from subdirectory 226 | user_dir = os.getcwd() +'\\' +username 227 | file_dir_list = next(os.walk(user_dir))[1] 228 | 229 | # if user has no file directory (has never sent files) 230 | if file_dir_list == []: 231 | response='There are no files yet.' 232 | print(response) 233 | conn.send(response.encode()) 234 | 235 | else: 236 | # start a list of files 237 | file_list = [] 238 | for i in range(0, len(file_dir_list)): 239 | file_dir = file_dir_list[i] 240 | file_list.append(os.listdir(user_dir +"\\" +file_dir)) 241 | 242 | # if user has a file directory yet no files 243 | if file_list == [[]]: 244 | response='There are no files yet.' 245 | print(response) 246 | conn.send(response.encode()) 247 | 248 | else: 249 | # if user has files, write a txt file with their names 250 | with open('filenames.txt', 'w') as fh: 251 | for list in file_list: 252 | for file in range(0, len(list)): 253 | fh.write('%s\n' % list[file]) 254 | 255 | # send list (the txt file) to client 256 | file_names=open('filenames.txt', 'rb').read() 257 | conn.send(file_names) 258 | print('\nSending file names...\n') 259 | 260 | # delete the file 261 | os.remove('filenames.txt') 262 | 263 | 264 | # gets files from servers 265 | def get(username): 266 | 267 | # get file name from client 268 | filename = conn.recv(1024).decode() 269 | print('User ' +username +' requested: ' +filename) 270 | 271 | # check whether file exists 272 | 273 | # establish paths 274 | user_dir = os.getcwd() +'\\' +username 275 | file_dir = os.path.join(user_dir, filename) 276 | user_dir_filelist = next(os.walk(user_dir))[1] 277 | 278 | # if user directory is empty 279 | if user_dir_filelist == []: 280 | response='Your directory has no files yet.\nExiting now...' 281 | print('User directory has no file folders.\nExiting now...') 282 | conn.send(response.encode()) 283 | sys.exit() 284 | 285 | # else, if user dir is not empty 286 | else: 287 | # check if there are any file chunks 288 | # establish list of chunks 289 | file_dir_chunklist = next(os.walk(file_dir))[2] 290 | 291 | if file_dir_chunklist == []: 292 | response='You do not have any files in the folder yet.\nExiting now...' 293 | print('File folder empty.\nExiting now...') 294 | conn.send(response.encode()) 295 | sys.exit() 296 | 297 | # if there are any file chunks... 298 | else: 299 | # send chunks ('get', from user's perspective) 300 | ct = 0 301 | for chunk in user_dir_filelist: 302 | ct += 1 303 | if ct < len(user_dir_filelist): 304 | # file exists, send file 305 | if filename == chunk: 306 | response='Server is preparing file transfer...' 307 | print('File found.') 308 | conn.send(response.encode()) 309 | time.sleep(1) 310 | break 311 | else: 312 | continue 313 | # if ct == length of list 314 | else: 315 | if filename == chunk: 316 | response='Server is preparing file transfer...' 317 | print('File found.') 318 | conn.send(response.encode()) 319 | time.sleep(1) 320 | pass 321 | # otherwise, exit 322 | else: 323 | response='No such file exists.\nExiting now...' 324 | print(response) 325 | conn.send(response.encode()) 326 | sys.exit() 327 | 328 | # establish chunk paths 329 | name1, name2 = os.listdir(file_dir) 330 | chunk1 = username +'\\' +chunk +'\\' +name1 331 | chunk2 = username +'\\' +chunk +'\\' +name2 332 | 333 | # send buffersize 334 | statinfo=os.stat(chunk1) 335 | buffersize=round(float(statinfo.st_size)) +4 336 | conn.send(str(buffersize).encode()) 337 | time.sleep(1) 338 | 339 | # send first batch of chunks 340 | # get numbers of chunks 341 | chunk1_num = name1.split('_')[1] 342 | chunk2_num = name2.split('_')[1] 343 | 344 | if chunk1_num == '1.txt' and chunk2_num == '4.txt': 345 | # send chunk 2 instead 346 | conn.send(name2.encode()) 347 | time.sleep(0.5) 348 | chunk2=open(chunk2,'rb').read() 349 | conn.send(chunk2) 350 | # name it chunk 1, however 351 | print('Sending chunk 1: ' +name2) 352 | else: 353 | # all other cases send chunk 1 354 | conn.send(name1.encode()) 355 | time.sleep(0.5) 356 | chunk1=open(chunk1,'rb').read() 357 | conn.send(chunk1) 358 | print('Sending chunk 1: ' +name1) 359 | 360 | # get a FIN or a NACK 361 | FINACK = conn.recv(1024).decode() 362 | 363 | # if NACK, send second batch 364 | if FINACK == 'Transfer incomplete': 365 | 366 | # second batch, reverse rules 367 | if chunk1_num == '1.txt' and chunk2_num == '4.txt': 368 | # send chunk 1 instead 369 | conn.send(name1.encode()) 370 | time.sleep(0.5) 371 | chunk1=open(chunk1,'rb').read() 372 | conn.send(chunk1) 373 | # name it chunk 2, however 374 | print('Sending chunk 2: ' +name1) 375 | else: 376 | # all other cases send chunk 2 377 | conn.send(name2.encode()) 378 | time.sleep(0.5) 379 | chunk2=open(chunk2,'rb').read() 380 | conn.send(chunk2) 381 | print('Sending chunk 2: ' +name2) 382 | 383 | # get actual FIN since previous was NACK 384 | FIN = conn.recv(1024).decode() 385 | print(FIN) 386 | 387 | # iff FIN, exit (FINACK == 'Transfer successful.') 388 | else: 389 | 390 | # print and exit 391 | print(FINACK +'\nExiting now...') 392 | 393 | sys.exit() 394 | 395 | 396 | # RUN DFS ------------------------------------------------- 397 | 398 | server_name = '127.0.0.1' 399 | server_port = int(sys.argv[1]) 400 | 401 | # define socket 402 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 403 | server_socket.bind((server_name, server_port)) 404 | server_socket.listen(5) 405 | print('Server listening...') 406 | 407 | while True: 408 | conn, client_address = server_socket.accept() 409 | print('Connected to Client.') 410 | 411 | # get username 412 | username = conn.recv(2048) 413 | username = username.decode() 414 | print('received username') 415 | 416 | # get password 417 | password = conn.recv(2048) 418 | password = password.decode() 419 | print('received password') 420 | 421 | # authorize client 422 | auth_params() 423 | client_auth(auth_dict, username, password) 424 | 425 | # create a new directory for user, if none exists 426 | new_dir(username) 427 | 428 | # receive command from user 429 | command = conn.recv(1024).decode() 430 | print('The user requested to ' +command + ' files.') 431 | 432 | # PUT 433 | if command == 'put': 434 | put(new_dir_path) 435 | 436 | # LIST 437 | elif command == 'list': 438 | list_files(username) 439 | 440 | # after listing, get further action 441 | answer = conn.recv(1024).decode() 442 | print('The user now requests to ' +answer +' files.') 443 | 444 | # PUT within LIST 445 | if answer == 'put': 446 | print('Receiving files...') 447 | put(new_dir_path) 448 | 449 | # GET within LIST 450 | elif answer == 'get': 451 | get(username) 452 | 453 | # exit 454 | else: 455 | print('Exiting now...') 456 | sys.exit() 457 | 458 | # GET 459 | elif command == 'get': 460 | get(username) 461 | 462 | # handle wrong command 463 | else: 464 | print('Command does not exist.\nExiting now...') 465 | sys.exit() 466 | 467 | conn.close() -------------------------------------------------------------------------------- /DFS3/dfs.conf: -------------------------------------------------------------------------------- 1 | Server DFS1 127.0.0.1:10001 2 | Server DFS2 127.0.0.1:10002 3 | Server DFS3 127.0.0.1:10003 4 | Server DFS3 127.0.0.1:10004 5 | Username: Alice 6 | Password: 9f451d98e0daf53c49f42095ee3b7220 7 | Username: Bob 8 | Password: cb5ead8bc8bca45f007bc7a995964460 9 | Username: Eve 10 | Password: ca2d3b7e3704505de305a608d832e91d -------------------------------------------------------------------------------- /DFS3/dfs3.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ 4 | Distributed File System 5 | Server 3 6 | Marcelo Sanches 7 | Jan 2019 8 | """ 9 | 10 | # modules 11 | import os 12 | import re 13 | import sys 14 | import time 15 | import socket 16 | import glob 17 | import pickle 18 | 19 | # function to check port number assignment 20 | def check_args(): 21 | 22 | # error handling argument 23 | if len(sys.argv) != 2: 24 | print("ERROR: Must supply port number \nUSAGE: py dfs3.py 10003") 25 | sys.exit() 26 | 27 | # error handling port number 28 | else: 29 | try: 30 | if int(sys.argv[1]) != 10003: 31 | print("ERROR: Port number must be 10003") 32 | sys.exit() 33 | else: 34 | return int(sys.argv[1]) 35 | 36 | except ValueError: 37 | print("ERROR: Port number must be a number.") 38 | sys.exit() 39 | 40 | check_args() 41 | 42 | # get authentication parameters 43 | def auth_params(): 44 | 45 | # use dfs configuration file 46 | config_file='dfs.conf' 47 | 48 | # get usernames from config file 49 | fh=open(config_file, mode='r', encoding='cp1252') 50 | users=re.findall(r'Username: .*', fh.read()) 51 | usernames=list() 52 | for i in range(0, len(users)): 53 | usernames.append(str(users[i]).split()[1]) 54 | fh.close() 55 | 56 | # get passwords from config file 57 | fh=open(config_file, mode='r', encoding='cp1252') 58 | passes=re.findall(r'Password: .*', fh.read()) 59 | passwords=list() 60 | for i in range(0, len(passes)): 61 | passwords.append(str(passes[i]).split()[1]) 62 | fh.close() 63 | 64 | # create dict with usernames:passwords 65 | global auth_dict 66 | auth_dict = {} 67 | for i in range(0, len(users)): 68 | entry={usernames[i]:passwords[i]} 69 | auth_dict.update(entry) 70 | 71 | return auth_dict 72 | 73 | # authorize client, given username and password 74 | def client_auth(auth_dict, username, password): 75 | ct = 0 76 | auth_status='' 77 | for key, value in auth_dict.items(): 78 | ct += 1 79 | if auth_status != '': 80 | pass 81 | else: 82 | # check all users up to last 83 | if ct < len(auth_dict): 84 | 85 | if username == key: 86 | print('Correct username.') 87 | 88 | if password == value: 89 | print('Correct password.') 90 | 91 | auth_status='Authorization Granted.\n' 92 | print(auth_status) 93 | conn.send(auth_status.encode()) 94 | pass 95 | else: 96 | print('Incorrect password.') 97 | auth_status = 'Authorization Denied.\n' 98 | print(auth_status) 99 | conn.send(auth_status.encode()) 100 | sys.exit() 101 | else: 102 | continue 103 | 104 | # check last user 105 | else: 106 | if username == key: 107 | print('Correct username.') 108 | 109 | if password == value: 110 | print('Correct password.') 111 | 112 | auth_status='Authorization Granted.\n' 113 | print(auth_status) 114 | conn.send(auth_status.encode()) 115 | pass 116 | else: 117 | print('Incorrect password.') 118 | auth_status = 'Authorization Denied.\n' 119 | print(auth_status) 120 | conn.send(auth_status.encode()) 121 | sys.exit() 122 | else: 123 | print('Incorrect username.') 124 | auth_status = 'Authorization Denied.\n' 125 | print(auth_status) 126 | conn.send(auth_status.encode()) 127 | sys.exit() 128 | 129 | # put files into servers 130 | def put(new_dir_path): 131 | 132 | # get size of buffer 133 | try: 134 | buffersize = int(conn.recv(2048).decode()) 135 | print('The buffer size is: ' +str(buffersize)) 136 | except ValueError: 137 | print('The buffer size is not a number. \nExiting now...') 138 | sys.exit() 139 | 140 | # receive chunk 1 name and data 141 | name1 = conn.recv(1024).decode() 142 | chunk1 = conn.recv(buffersize).decode() 143 | print('Receiving ' +name1 +'...\n') 144 | 145 | # create file folder for chunks 146 | file_folder = name1.split('_')[0] 147 | new_folder_path = os.getcwd() +'\\' +username +'\\' +file_folder 148 | 149 | if os.path.isdir(new_folder_path) == False: 150 | try: 151 | os.mkdir(new_folder_path) 152 | print ("Successfully created the folder %s " % new_folder_path) 153 | pass 154 | except OSError: 155 | print ("Creation of the folder %s failed" % new_folder_path) 156 | else: 157 | pass 158 | 159 | # write chunk1 to file folder 160 | fh=open(os.path.join(new_folder_path, name1), 'w') 161 | fh.write(chunk1) 162 | fh.close() 163 | 164 | # inform client if transfer was successful [check if file exists] 165 | exists = new_folder_path +'\\' +name1 166 | if os.path.isfile(exists) == True: 167 | response = 'Chunk 1 successfully transferred.\n' 168 | print(response) 169 | conn.send(response.encode()) 170 | else: 171 | response = 'Chunk 1 transfer incomplete.\n' 172 | print(response) 173 | conn.send(response.encode()) 174 | 175 | # receive chunk 2 name and data 176 | name2 = conn.recv(1024).decode() 177 | chunk2 = conn.recv(buffersize).decode() 178 | print('Receiving ' +name2 +'...\n') 179 | 180 | # write chunk2 to file folder 181 | fh=open(os.path.join(new_folder_path, name2), 'w') 182 | fh.write(chunk2) 183 | fh.close() 184 | 185 | # inform client if transfer was successful [check if file exists] 186 | exists = new_folder_path +'\\' +name2 187 | if os.path.isfile(exists) == True: 188 | response = 'Chunk 2 successfully transferred.\n' 189 | print(response) 190 | conn.send(response.encode()) 191 | else: 192 | response = 'Chunk 2 transfer incomplete.\n' 193 | print(response) 194 | conn.send(response.encode()) 195 | 196 | # close connection after chunks are sent 197 | print('Exiting now...') 198 | sys.exit() 199 | 200 | 201 | # creates new directory for user 202 | def new_dir(username): 203 | 204 | # define new path 205 | global new_dir_path 206 | new_dir_path = os.getcwd() +'\\' +username 207 | 208 | # if path does not exist, create new dir 209 | if os.path.isdir(new_dir_path) == False: 210 | try: 211 | os.mkdir(new_dir_path) 212 | print ("Successfully created the directory %s " % new_dir_path) 213 | return new_dir_path 214 | except OSError: 215 | print ("Creation of the directory %s failed" % new_dir_path) 216 | 217 | # return the dir path if exists, however 218 | else: 219 | return new_dir_path 220 | pass 221 | 222 | # command to list files in servers 223 | def list_files(username): 224 | 225 | # get list of files from subdirectory 226 | user_dir = os.getcwd() +'\\' +username 227 | file_dir_list = next(os.walk(user_dir))[1] 228 | 229 | # if user has no file directory (has never sent files) 230 | if file_dir_list == []: 231 | response='There are no files yet.' 232 | print(response) 233 | conn.send(response.encode()) 234 | 235 | else: 236 | # start a list of files 237 | file_list = [] 238 | for i in range(0, len(file_dir_list)): 239 | file_dir = file_dir_list[i] 240 | file_list.append(os.listdir(user_dir +"\\" +file_dir)) 241 | 242 | # if user has a file directory yet no files 243 | if file_list == [[]]: 244 | response='There are no files yet.' 245 | print(response) 246 | conn.send(response.encode()) 247 | 248 | else: 249 | # if user has files, write a txt file with their names 250 | with open('filenames.txt', 'w') as fh: 251 | for list in file_list: 252 | for file in range(0, len(list)): 253 | fh.write('%s\n' % list[file]) 254 | 255 | # send list (the txt file) to client 256 | file_names=open('filenames.txt', 'rb').read() 257 | conn.send(file_names) 258 | print('\nSending file names...\n') 259 | 260 | # delete the file 261 | os.remove('filenames.txt') 262 | 263 | 264 | # gets files from servers 265 | def get(username): 266 | 267 | # get file name from client 268 | filename = conn.recv(1024).decode() 269 | print('User ' +username +' requested: ' +filename) 270 | 271 | # check whether file exists 272 | 273 | # establish paths 274 | user_dir = os.getcwd() +'\\' +username 275 | file_dir = os.path.join(user_dir, filename) 276 | user_dir_filelist = next(os.walk(user_dir))[1] 277 | 278 | # if user directory is empty 279 | if user_dir_filelist == []: 280 | response='Your directory has no files yet.\nExiting now...' 281 | print('User directory has no file folders.\nExiting now...') 282 | conn.send(response.encode()) 283 | sys.exit() 284 | 285 | # else, if user dir is not empty 286 | else: 287 | # check if there are any file chunks 288 | # establish list of chunks 289 | file_dir_chunklist = next(os.walk(file_dir))[2] 290 | 291 | if file_dir_chunklist == []: 292 | response='You do not have any files in the folder yet.\nExiting now...' 293 | print('File folder empty.\nExiting now...') 294 | conn.send(response.encode()) 295 | sys.exit() 296 | 297 | # if there are any file chunks... 298 | else: 299 | # send chunks ('get', from user's perspective) 300 | ct = 0 301 | for chunk in user_dir_filelist: 302 | ct += 1 303 | if ct < len(user_dir_filelist): 304 | # file exists, send file 305 | if filename == chunk: 306 | response='Server is preparing file transfer...' 307 | print('File found.') 308 | conn.send(response.encode()) 309 | time.sleep(1) 310 | break 311 | else: 312 | continue 313 | # if ct == length of list 314 | else: 315 | if filename == chunk: 316 | response='Server is preparing file transfer...' 317 | print('File found.') 318 | conn.send(response.encode()) 319 | time.sleep(1) 320 | pass 321 | # otherwise, exit 322 | else: 323 | response='No such file exists.\nExiting now...' 324 | print(response) 325 | conn.send(response.encode()) 326 | sys.exit() 327 | 328 | # establish chunk paths 329 | name1, name2 = os.listdir(file_dir) 330 | chunk1 = username +'\\' +chunk +'\\' +name1 331 | chunk2 = username +'\\' +chunk +'\\' +name2 332 | 333 | # send buffersize 334 | statinfo=os.stat(chunk1) 335 | buffersize=round(float(statinfo.st_size)) +4 336 | conn.send(str(buffersize).encode()) 337 | time.sleep(1) 338 | 339 | # send first batch of chunks 340 | # get numbers of chunks 341 | chunk1_num = name1.split('_')[1] 342 | chunk2_num = name2.split('_')[1] 343 | 344 | if chunk1_num == '1.txt' and chunk2_num == '4.txt': 345 | # send chunk 2 instead 346 | conn.send(name2.encode()) 347 | time.sleep(0.5) 348 | chunk2=open(chunk2,'rb').read() 349 | conn.send(chunk2) 350 | # name it chunk 1, however 351 | print('Sending chunk 1: ' +name2) 352 | else: 353 | # all other cases send chunk 1 354 | conn.send(name1.encode()) 355 | time.sleep(0.5) 356 | chunk1=open(chunk1,'rb').read() 357 | conn.send(chunk1) 358 | print('Sending chunk 1: ' +name1) 359 | 360 | # get a FIN or a NACK 361 | FINACK = conn.recv(1024).decode() 362 | 363 | # if NACK, send second batch 364 | if FINACK == 'Transfer incomplete': 365 | 366 | # second batch, reverse rules 367 | if chunk1_num == '1.txt' and chunk2_num == '4.txt': 368 | # send chunk 1 instead 369 | conn.send(name1.encode()) 370 | time.sleep(0.5) 371 | chunk1=open(chunk1,'rb').read() 372 | conn.send(chunk1) 373 | # name it chunk 2, however 374 | print('Sending chunk 2: ' +name1) 375 | else: 376 | # all other cases send chunk 2 377 | conn.send(name2.encode()) 378 | time.sleep(0.5) 379 | chunk2=open(chunk2,'rb').read() 380 | conn.send(chunk2) 381 | print('Sending chunk 2: ' +name2) 382 | 383 | # get actual FIN since previous was NACK 384 | FIN = conn.recv(1024).decode() 385 | print(FIN) 386 | 387 | # iff FIN, exit (FINACK == 'Transfer successful.') 388 | else: 389 | 390 | # print and exit 391 | print(FINACK +'\nExiting now...') 392 | 393 | sys.exit() 394 | 395 | 396 | # RUN DFS ------------------------------------------------- 397 | 398 | server_name = '127.0.0.1' 399 | server_port = int(sys.argv[1]) 400 | 401 | # define socket 402 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 403 | server_socket.bind((server_name, server_port)) 404 | server_socket.listen(5) 405 | print('Server listening...') 406 | 407 | while True: 408 | conn, client_address = server_socket.accept() 409 | print('Connected to Client.') 410 | 411 | # get username 412 | username = conn.recv(2048) 413 | username = username.decode() 414 | print('received username') 415 | 416 | # get password 417 | password = conn.recv(2048) 418 | password = password.decode() 419 | print('received password') 420 | 421 | # authorize client 422 | auth_params() 423 | client_auth(auth_dict, username, password) 424 | 425 | # create a new directory for user, if none exists 426 | new_dir(username) 427 | 428 | # receive command from user 429 | command = conn.recv(1024).decode() 430 | print('The user requested to ' +command + ' files.') 431 | 432 | # PUT 433 | if command == 'put': 434 | put(new_dir_path) 435 | 436 | # LIST 437 | elif command == 'list': 438 | list_files(username) 439 | 440 | # after listing, get further action 441 | answer = conn.recv(1024).decode() 442 | print('The user now requests to ' +answer +' files.') 443 | 444 | # PUT within LIST 445 | if answer == 'put': 446 | print('Receiving files...') 447 | put(new_dir_path) 448 | 449 | # GET within LIST 450 | elif answer == 'get': 451 | get(username) 452 | 453 | # exit 454 | else: 455 | print('Exiting now...') 456 | sys.exit() 457 | 458 | # GET 459 | elif command == 'get': 460 | get(username) 461 | 462 | # handle wrong command 463 | else: 464 | print('Command does not exist.\nExiting now...') 465 | sys.exit() 466 | 467 | conn.close() -------------------------------------------------------------------------------- /DFS4/dfs.conf: -------------------------------------------------------------------------------- 1 | Server DFS1 127.0.0.1:10001 2 | Server DFS2 127.0.0.1:10002 3 | Server DFS3 127.0.0.1:10003 4 | Server DFS3 127.0.0.1:10004 5 | Username: Alice 6 | Password: 9f451d98e0daf53c49f42095ee3b7220 7 | Username: Bob 8 | Password: cb5ead8bc8bca45f007bc7a995964460 9 | Username: Eve 10 | Password: ca2d3b7e3704505de305a608d832e91d -------------------------------------------------------------------------------- /DFS4/dfs4.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | """ 4 | Distributed File System 5 | Server 4 6 | Marcelo Sanches 7 | Jan 2019 8 | """ 9 | 10 | # modules 11 | import os 12 | import re 13 | import sys 14 | import time 15 | import socket 16 | import glob 17 | import pickle 18 | 19 | # function to check port number assignment 20 | def check_args(): 21 | 22 | # error handling argument 23 | if len(sys.argv) != 2: 24 | print("ERROR: Must supply port number \nUSAGE: py dfs4.py 10004") 25 | sys.exit() 26 | 27 | # error handling port number 28 | else: 29 | try: 30 | if int(sys.argv[1]) != 10004: 31 | print("ERROR: Port number must be 10004") 32 | sys.exit() 33 | else: 34 | return int(sys.argv[1]) 35 | 36 | except ValueError: 37 | print("ERROR: Port number must be a number.") 38 | sys.exit() 39 | 40 | check_args() 41 | 42 | # get authentication parameters 43 | def auth_params(): 44 | 45 | # use dfs configuration file 46 | config_file='dfs.conf' 47 | 48 | # get usernames from config file 49 | fh=open(config_file, mode='r', encoding='cp1252') 50 | users=re.findall(r'Username: .*', fh.read()) 51 | usernames=list() 52 | for i in range(0, len(users)): 53 | usernames.append(str(users[i]).split()[1]) 54 | fh.close() 55 | 56 | # get passwords from config file 57 | fh=open(config_file, mode='r', encoding='cp1252') 58 | passes=re.findall(r'Password: .*', fh.read()) 59 | passwords=list() 60 | for i in range(0, len(passes)): 61 | passwords.append(str(passes[i]).split()[1]) 62 | fh.close() 63 | 64 | # create dict with usernames:passwords 65 | global auth_dict 66 | auth_dict = {} 67 | for i in range(0, len(users)): 68 | entry={usernames[i]:passwords[i]} 69 | auth_dict.update(entry) 70 | 71 | return auth_dict 72 | 73 | # authorize client, given username and password 74 | def client_auth(auth_dict, username, password): 75 | ct = 0 76 | auth_status='' 77 | for key, value in auth_dict.items(): 78 | ct += 1 79 | if auth_status != '': 80 | pass 81 | else: 82 | # check all users up to last 83 | if ct < len(auth_dict): 84 | 85 | if username == key: 86 | print('Correct username.') 87 | 88 | if password == value: 89 | print('Correct password.') 90 | 91 | auth_status='Authorization Granted.\n' 92 | print(auth_status) 93 | conn.send(auth_status.encode()) 94 | pass 95 | else: 96 | print('Incorrect password.') 97 | auth_status = 'Authorization Denied.\n' 98 | print(auth_status) 99 | conn.send(auth_status.encode()) 100 | sys.exit() 101 | else: 102 | continue 103 | 104 | # check last user 105 | else: 106 | if username == key: 107 | print('Correct username.') 108 | 109 | if password == value: 110 | print('Correct password.') 111 | 112 | auth_status='Authorization Granted.\n' 113 | print(auth_status) 114 | conn.send(auth_status.encode()) 115 | pass 116 | else: 117 | print('Incorrect password.') 118 | auth_status = 'Authorization Denied.\n' 119 | print(auth_status) 120 | conn.send(auth_status.encode()) 121 | sys.exit() 122 | else: 123 | print('Incorrect username.') 124 | auth_status = 'Authorization Denied.\n' 125 | print(auth_status) 126 | conn.send(auth_status.encode()) 127 | sys.exit() 128 | 129 | # put files into servers 130 | def put(new_dir_path): 131 | 132 | # get size of buffer 133 | try: 134 | buffersize = int(conn.recv(2048).decode()) 135 | print('The buffer size is: ' +str(buffersize)) 136 | except ValueError: 137 | print('The buffer size is not a number. \nExiting now...') 138 | sys.exit() 139 | 140 | # receive chunk 1 name and data 141 | name1 = conn.recv(1024).decode() 142 | chunk1 = conn.recv(buffersize).decode() 143 | print('Receiving ' +name1 +'...\n') 144 | 145 | # create file folder for chunks 146 | file_folder = name1.split('_')[0] 147 | new_folder_path = os.getcwd() +'\\' +username +'\\' +file_folder 148 | 149 | if os.path.isdir(new_folder_path) == False: 150 | try: 151 | os.mkdir(new_folder_path) 152 | print ("Successfully created the folder %s " % new_folder_path) 153 | pass 154 | except OSError: 155 | print ("Creation of the folder %s failed" % new_folder_path) 156 | else: 157 | pass 158 | 159 | # write chunk1 to file folder 160 | fh=open(os.path.join(new_folder_path, name1), 'w') 161 | fh.write(chunk1) 162 | fh.close() 163 | 164 | # inform client if transfer was successful [check if file exists] 165 | exists = new_folder_path +'\\' +name1 166 | if os.path.isfile(exists) == True: 167 | response = 'Chunk 1 successfully transferred.\n' 168 | print(response) 169 | conn.send(response.encode()) 170 | else: 171 | response = 'Chunk 1 transfer incomplete.\n' 172 | print(response) 173 | conn.send(response.encode()) 174 | 175 | # receive chunk 2 name and data 176 | name2 = conn.recv(1024).decode() 177 | chunk2 = conn.recv(buffersize).decode() 178 | print('Receiving ' +name2 +'...\n') 179 | 180 | # write chunk2 to file folder 181 | fh=open(os.path.join(new_folder_path, name2), 'w') 182 | fh.write(chunk2) 183 | fh.close() 184 | 185 | # inform client if transfer was successful [check if file exists] 186 | exists = new_folder_path +'\\' +name2 187 | if os.path.isfile(exists) == True: 188 | response = 'Chunk 2 successfully transferred.\n' 189 | print(response) 190 | conn.send(response.encode()) 191 | else: 192 | response = 'Chunk 2 transfer incomplete.\n' 193 | print(response) 194 | conn.send(response.encode()) 195 | 196 | # close connection after chunks are sent 197 | print('Exiting now...') 198 | sys.exit() 199 | 200 | 201 | # creates new directory for user 202 | def new_dir(username): 203 | 204 | # define new path 205 | global new_dir_path 206 | new_dir_path = os.getcwd() +'\\' +username 207 | 208 | # if path does not exist, create new dir 209 | if os.path.isdir(new_dir_path) == False: 210 | try: 211 | os.mkdir(new_dir_path) 212 | print ("Successfully created the directory %s " % new_dir_path) 213 | return new_dir_path 214 | except OSError: 215 | print ("Creation of the directory %s failed" % new_dir_path) 216 | 217 | # return the dir path if exists, however 218 | else: 219 | return new_dir_path 220 | pass 221 | 222 | # command to list files in servers 223 | def list_files(username): 224 | 225 | # get list of files from subdirectory 226 | user_dir = os.getcwd() +'\\' +username 227 | file_dir_list = next(os.walk(user_dir))[1] 228 | 229 | # if user has no file directory (has never sent files) 230 | if file_dir_list == []: 231 | response='There are no files yet.' 232 | print(response) 233 | conn.send(response.encode()) 234 | 235 | else: 236 | # start a list of files 237 | file_list = [] 238 | for i in range(0, len(file_dir_list)): 239 | file_dir = file_dir_list[i] 240 | file_list.append(os.listdir(user_dir +"\\" +file_dir)) 241 | 242 | # if user has a file directory yet no files 243 | if file_list == [[]]: 244 | response='There are no files yet.' 245 | print(response) 246 | conn.send(response.encode()) 247 | 248 | else: 249 | # if user has files, write a txt file with their names 250 | with open('filenames.txt', 'w') as fh: 251 | for list in file_list: 252 | for file in range(0, len(list)): 253 | fh.write('%s\n' % list[file]) 254 | 255 | # send list (the txt file) to client 256 | file_names=open('filenames.txt', 'rb').read() 257 | conn.send(file_names) 258 | print('\nSending file names...\n') 259 | 260 | # delete the file 261 | os.remove('filenames.txt') 262 | 263 | 264 | # gets files from servers 265 | def get(username): 266 | 267 | # get file name from client 268 | filename = conn.recv(1024).decode() 269 | print('User ' +username +' requested: ' +filename) 270 | 271 | # check whether file exists 272 | 273 | # establish paths 274 | user_dir = os.getcwd() +'\\' +username 275 | file_dir = os.path.join(user_dir, filename) 276 | user_dir_filelist = next(os.walk(user_dir))[1] 277 | 278 | # if user directory is empty 279 | if user_dir_filelist == []: 280 | response='Your directory has no files yet.\nExiting now...' 281 | print('User directory has no file folders.\nExiting now...') 282 | conn.send(response.encode()) 283 | sys.exit() 284 | 285 | # else, if user dir is not empty 286 | else: 287 | # check if there are any file chunks 288 | # establish list of chunks 289 | file_dir_chunklist = next(os.walk(file_dir))[2] 290 | 291 | if file_dir_chunklist == []: 292 | response='You do not have any files in the folder yet.\nExiting now...' 293 | print('File folder empty.\nExiting now...') 294 | conn.send(response.encode()) 295 | sys.exit() 296 | 297 | # if there are any file chunks... 298 | else: 299 | # send chunks ('get', from user's perspective) 300 | ct = 0 301 | for chunk in user_dir_filelist: 302 | ct += 1 303 | if ct < len(user_dir_filelist): 304 | # file exists, send file 305 | if filename == chunk: 306 | response='Server is preparing file transfer...' 307 | print('File found.') 308 | conn.send(response.encode()) 309 | time.sleep(1) 310 | break 311 | else: 312 | continue 313 | # if ct == length of list 314 | else: 315 | if filename == chunk: 316 | response='Server is preparing file transfer...' 317 | print('File found.') 318 | conn.send(response.encode()) 319 | time.sleep(1) 320 | pass 321 | # otherwise, exit 322 | else: 323 | response='No such file exists.\nExiting now...' 324 | print(response) 325 | conn.send(response.encode()) 326 | sys.exit() 327 | 328 | # establish chunk paths 329 | name1, name2 = os.listdir(file_dir) 330 | chunk1 = username +'\\' +chunk +'\\' +name1 331 | chunk2 = username +'\\' +chunk +'\\' +name2 332 | 333 | # send buffersize 334 | statinfo=os.stat(chunk1) 335 | buffersize=round(float(statinfo.st_size)) +4 336 | conn.send(str(buffersize).encode()) 337 | time.sleep(1) 338 | 339 | # send first batch of chunks 340 | # get numbers of chunks 341 | chunk1_num = name1.split('_')[1] 342 | chunk2_num = name2.split('_')[1] 343 | 344 | if chunk1_num == '1.txt' and chunk2_num == '4.txt': 345 | # send chunk 2 instead 346 | conn.send(name2.encode()) 347 | time.sleep(0.5) 348 | chunk2=open(chunk2,'rb').read() 349 | conn.send(chunk2) 350 | # name it chunk 1, however 351 | print('Sending chunk 1: ' +name2) 352 | else: 353 | # all other cases send chunk 1 354 | conn.send(name1.encode()) 355 | time.sleep(0.5) 356 | chunk1=open(chunk1,'rb').read() 357 | conn.send(chunk1) 358 | print('Sending chunk 1: ' +name1) 359 | 360 | # get a FIN or a NACK 361 | FINACK = conn.recv(1024).decode() 362 | 363 | # if NACK, send second batch 364 | if FINACK == 'Transfer incomplete': 365 | 366 | # second batch, reverse rules 367 | if chunk1_num == '1.txt' and chunk2_num == '4.txt': 368 | # send chunk 1 instead 369 | conn.send(name1.encode()) 370 | time.sleep(0.5) 371 | chunk1=open(chunk1,'rb').read() 372 | conn.send(chunk1) 373 | # name it chunk 2, however 374 | print('Sending chunk 2: ' +name1) 375 | else: 376 | # all other cases send chunk 2 377 | conn.send(name2.encode()) 378 | time.sleep(0.5) 379 | chunk2=open(chunk2,'rb').read() 380 | conn.send(chunk2) 381 | print('Sending chunk 2: ' +name2) 382 | 383 | # get actual FIN since previous was NACK 384 | FIN = conn.recv(1024).decode() 385 | print(FIN) 386 | 387 | # iff FIN, exit (FINACK == 'Transfer successful.') 388 | else: 389 | 390 | # print and exit 391 | print(FINACK +'\nExiting now...') 392 | 393 | sys.exit() 394 | 395 | 396 | # RUN DFS ------------------------------------------------- 397 | 398 | server_name = '127.0.0.1' 399 | server_port = int(sys.argv[1]) 400 | 401 | # define socket 402 | server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 403 | server_socket.bind((server_name, server_port)) 404 | server_socket.listen(5) 405 | print('Server listening...') 406 | 407 | while True: 408 | conn, client_address = server_socket.accept() 409 | print('Connected to Client.') 410 | 411 | # get username 412 | username = conn.recv(2048) 413 | username = username.decode() 414 | print('received username') 415 | 416 | # get password 417 | password = conn.recv(2048) 418 | password = password.decode() 419 | print('received password') 420 | 421 | # authorize client 422 | auth_params() 423 | client_auth(auth_dict, username, password) 424 | 425 | # create a new directory for user, if none exists 426 | new_dir(username) 427 | 428 | # receive command from user 429 | command = conn.recv(1024).decode() 430 | print('The user requested to ' +command + ' files.') 431 | 432 | # PUT 433 | if command == 'put': 434 | put(new_dir_path) 435 | 436 | # LIST 437 | elif command == 'list': 438 | list_files(username) 439 | 440 | # after listing, get further action 441 | answer = conn.recv(1024).decode() 442 | print('The user now requests to ' +answer +' files.') 443 | 444 | # PUT within LIST 445 | if answer == 'put': 446 | print('Receiving files...') 447 | put(new_dir_path) 448 | 449 | # GET within LIST 450 | elif answer == 'get': 451 | get(username) 452 | 453 | # exit 454 | else: 455 | print('Exiting now...') 456 | sys.exit() 457 | 458 | # GET 459 | elif command == 'get': 460 | get(username) 461 | 462 | # handle wrong command 463 | else: 464 | print('Command does not exist.\nExiting now...') 465 | sys.exit() 466 | 467 | conn.close() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # A Low-Level Python Distributed File System (DFS) 3 | 4 | ## Project Description 5 | 6 | This project was conceived as a proof-of-concept for a low-level implementation of a Python DFS using only 7 | stdlib modules (i.e. 'socket' for networking) to transfer and store files in a distributed and resilient manner. 8 | 9 | This project is an MVP, and as such it does not incorporate all the [design goals of a DFS](https://en.wikipedia.org/wiki/Clustered_file_system#Distributed_file_systems). 10 | This Python DFS is defined here simply as a cluster of servers in a server-client architecture, hosting potentially large text files 11 | that need to be transferred and stored reliably and securely in a fault-tolerant way. 12 | 13 | Below I demonstrate how to run the Python DFS locally, simulating a distributed cluster. 14 | A given file is distributed (`PUT `) from the DFC (the Client) to four DFS (the Servers) in chunks, 15 | which can be retrieved (`GET `) and used to reconstruct the file. 16 | 17 | There's a built-in redundancy in the way the file chunks are stored in the servers, ensuring that if a given server fails, 18 | the file can still be reconstructed. Traffic optimization is achieved by not sending any redundant file chunks unless necessary. 19 | Some security is implemented via authentication, and storage of password hashes. 20 | 21 | 22 | ## Running the Project 23 | 24 | **RUN** (any number of) servers first, then the client: 25 | 26 | ``` 27 | $ py dfs1.py 10001 28 | $ py dfs2.py 10002 29 | $ py dfs3.py 10003 30 | $ py dfs4.py 10004 31 | 32 | $ py dfc.py dfc.conf 33 | ``` 34 | 35 | **USERS and PASSWORDS**: 36 | 37 | ``` 38 | Alice: Crimson33 39 | Bob: Velvet77 40 | Eve: Magellan101 41 | ``` 42 | 43 | Usernames and passwords can be changed in the configuration files. Changes must adhere to the 44 | spacing and syntax found in the conf files and be identical across all .conf files (dfs and dfc 45 | .conf files are identical except for the name). 46 | 47 | The password hashing algorithm is md5. If another is desired, all the appropriate hashes must be 48 | recomputed in the dfc.py file (CTRL+F: 'hashlib'). 49 | 50 | 51 | ## Commands 52 | 53 | 54 | - **`[PUT]` method**: 55 | 56 | `PUT` sends any text files located within the DFC folder into the DFS folders for distributed storage. 57 | 58 | `PUT` splits files into 4 chunks, stores pairs of chunks into each server after hashing 59 | file and taking the modulus of the hash to ensure fair distribution, according to 60 | the table below. The duplication of files ensures reliability if 1 server is down. 61 | 62 | `PUT` also lists files within the DFC folder which are available for transfer. 63 | 64 | 65 | ### File Chunk Pair Locations 66 | 67 | 68 | |hash mod|DFS1|DFS2|DFS3|DFS4| 69 | |:--:|:-----:|:-----:|:-----:|:-----:| 70 | | 0 | (1,2) | (2,3) | (3,4) | (4,1) | 71 | | 1 | (4,1) | (1,2) | (2,3) | (3,4) | 72 | | 2 | (3,4) | (4,1) | (1,2) | (2,3) | 73 | | 3 | (2,3) | (3,4) | (4,1) | (1,2) | 74 | 75 | 76 | 77 | - **`[GET]` method**: 78 | 79 | 80 | `GET` retrieves files from the servers into a user folder within the DFC folder. 81 | 82 | `GET` joins the 4 chunks into a single file. If a single server is down, this operation can 83 | still succeed. If the operation fails, the file is not created and the user gets a 'Transfer failed' message. 84 | 85 | 86 | 87 | - **`[LIST]` method**: 88 | 89 | `LIST` provides a list of file chunks a user has stored in the server. 90 | From the list, a user can glean file names and specify a file to `GET`. 91 | If a user chooses `PUT` within `LIST`, the user can determine a file to send for distributed storage. 92 | 93 | 94 | 95 | - __Note__: When prompted for a file name, specify file name without the .txt extension. 96 | 97 | 98 | ## Test Cases 99 | 100 | 1. For any user: first cases vs last case differ, as they enter different loops within code 101 | 102 | 2. For any number of running servers (0 through 4) 103 | 104 | 3. For any combination of servers: 105 | 106 | - BEFORE a user dir exists 107 | - AFTER user dir exists but BEFORE a file dir exists 108 | - AFTER user dir and file dir exist but BEFORE files exist 109 | - AFTER files exist but not all files 110 | - AFTER all dirs and files exist: Reliability of file transfer should be guaranteed with 1 server down, and in some cases for 2 servers down (consult table of chunk locations). 111 | 112 | 4. For any combination and order of commands: 113 | 114 | - The natural order is `PUT`, `LIST`, `GET` 115 | - Test any order 116 | - Test `GET` or `PUT` within `LIST` 117 | 118 | ## Demo 119 | 120 | Here I show some ways to test the file system for reliability when one server is down. 121 | On the left are the three servers up (DFS1, DFS2, DFS3) and on the right the client (DFC). 122 | 123 | ![image: PythonDFSdemo](./images/PythonDFSdemo.gif) 124 | 125 | 126 | ## Problems Fixed 127 | 128 | - Concatention of usernamepassword and `buffersizechunkname`: used timeouts (`time.sleep(0.5)`) 129 | - `LIST` error: case when there *is* a directory, i.e. user has TRIED to put files or actually put files, yet there are no files 130 | - `GET` error: same case as above, also fixed in `GET` within `LIST` 131 | - `GET` within list: had already sent answer ('get'), deleted code block for sending it again (as in `GET`) 132 | - ONLY reconstruct file if all chunks are present, otherwise print/send 'Transfer failed' message 133 | - `GET` second batch: reliability with server down, +1 file in DFC user dir (check filename) 134 | - HASH passwords, store hashes in dfc.conf and dfs.conf 135 | - Client-side authorization grants access to any correct username with any correct password (fixed) 136 | - When all servers are down, exit client instead of running through the entire program 137 | 138 | ## Ideas for Future Iterations 139 | 140 | - Populate .conf files dynamically via a `SET` method for usernames and passwords 141 | - Chunks stored and retrieved with every other line empty 142 | - Less exiting out: `GOTO` equivalent? 143 | - SALT passwords 144 | - ENCRYPT all traffic 145 | - Send other file types (images, etc.) 146 | - Redo in a streaming architecture 147 | 148 | --- -------------------------------------------------------------------------------- /extras/ClientAuth.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | # Client-side user authentication functions 4 | 5 | 6 | # modules 7 | import re 8 | import hashlib 9 | 10 | # params for user auth from dfc.conf 11 | def user_auth(): 12 | 13 | # get usernames 14 | fh = open('dfc.conf', mode='r', encoding='cp1252') 15 | users=re.findall(r'Username: .*', fh.read()) 16 | usernames=list() 17 | for i in range(0, len(users)): 18 | usernames.append(str(users[i]).split()[1]) 19 | fh.close() 20 | 21 | # get passwords 22 | fh = open('dfc.conf', mode='r', encoding='cp1252') 23 | passes=re.findall(r'Password: .*', fh.read()) 24 | passwords=list() 25 | for i in range(0, len(passes)): 26 | passwords.append(str(passes[i]).split()[1]) 27 | fh.close() 28 | 29 | # dict with usernames:passwords 30 | global auth_dict 31 | auth_dict = {} 32 | for i in range(0, len(users)): 33 | entry={usernames[i]:passwords[i]} 34 | auth_dict.update(entry) 35 | 36 | return auth_dict 37 | 38 | # client-side auth 39 | def authenticate(): 40 | 41 | # config params 42 | user_auth() 43 | 44 | # authenticate username 45 | 46 | # initialize an auth status 47 | auth_status = '' 48 | 49 | # give user 4 attempts 50 | for i in range(0, 4): 51 | if auth_status == 'Correct username.': 52 | # go to password auth 53 | pass 54 | 55 | else: 56 | # get username 57 | username = input('username: ') 58 | 59 | # initialize username auth 60 | username_auth = [] 61 | ct = 0 62 | for key, value in auth_dict.items(): 63 | ct += 1 64 | if username == key: 65 | # get specific username index in dictionary 66 | username_auth.append(ct) 67 | else: 68 | username_auth.append(0) 69 | 70 | if i < 2: 71 | if sum(username_auth) > 0: 72 | auth_status = 'Correct username.' 73 | continue 74 | else: 75 | print('Wrong username. You have ' +str(3-i) + ' attempts left.') 76 | continue 77 | elif i == 2: 78 | if sum(username_auth) > 0: 79 | auth_status = 'Correct username.' 80 | continue 81 | else: 82 | print('Wrong username. You have ' +str(3-i) + ' attempt left.') 83 | continue 84 | else: 85 | if sum(username_auth) > 0: 86 | auth_status = 'Correct username.' 87 | continue 88 | else: 89 | print('Wrong username. You have no more attempts.\nExiting now....') 90 | continue 91 | 92 | # authenticate password 93 | # get the index of the user in the auth_dict to check password in that index 94 | user_index = sum(username_auth) 95 | 96 | # re-initialize auth status 97 | auth_status = '' 98 | for i in range(0, 4): 99 | if auth_status == 'Existing password.': 100 | # pass authentication 101 | pass 102 | 103 | else: 104 | # get password 105 | password = input('password: ') 106 | hash=hashlib.md5() 107 | hash.update(password.encode()) 108 | password = hash.hexdigest() 109 | 110 | # initialize password auth 111 | password_auth = [] 112 | ct = 0 113 | for key, value in auth_dict.items(): 114 | ct += 1 115 | if password == value: 116 | password_auth.append(ct) 117 | else: 118 | password_auth.append(0) 119 | 120 | if i < 2: 121 | if sum(password_auth) > 0: 122 | auth_status = 'Existing password.' 123 | continue 124 | else: 125 | print('Wrong password. You have ' +str(3-i) + ' attempts left.') 126 | continue 127 | elif i == 2: 128 | if sum(password_auth) > 0: 129 | auth_status = 'Existing password.' 130 | continue 131 | else: 132 | print('Wrong password. You have ' +str(3-i) + ' attempt left.') 133 | continue 134 | else: 135 | if sum(password_auth) > 0: 136 | auth_status = 'Existing password.' 137 | continue 138 | else: 139 | print('Wrong password. You have no more attempts.\nExiting now....') 140 | sys.exit() 141 | 142 | # Check that specific user used that password (auth username:password combination) 143 | 144 | # get the index of the password in the auth_dict 145 | pass_index = sum(password_auth) 146 | 147 | if user_index == pass_index: 148 | pass 149 | else: 150 | print('Wrong password. You have no more attempts.\nExiting now....') 151 | sys.exit() 152 | 153 | # Final auth after passing all checks 154 | print('Authorization Granted.') 155 | global final_authorization 156 | final_authorization = (username, password) 157 | return final_authorization 158 | 159 | 160 | 161 | authenticate() -------------------------------------------------------------------------------- /extras/Hashing.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | # Hashes a command-line given password 4 | 5 | import hashlib 6 | 7 | password = input('Enter password: ') 8 | hash=hashlib.md5() 9 | hash.update(password.encode()) 10 | password = hash.hexdigest() 11 | print(password) 12 | 13 | -------------------------------------------------------------------------------- /images/PythonDFSdemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BigBangData/PythonDFS/96037596c6d9e0b44c37138299107d9ebd8789a5/images/PythonDFSdemo.gif --------------------------------------------------------------------------------