Advertisement
Guest User

Untitled

a guest
Sep 21st, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.93 KB | None | 0 0
  1. /* Implementiert in dieser Datei und in otp.c die Teilaufgabe (a) */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8.  
  9. #include "generate_otp.h"
  10. #include "vorgabe.h"
  11.  
  12. extern int exitcode;    /* diesen Wert gibt die main()-Funktion als Exit-
  13.                            Code zurueck (in otp.c definiert) */
  14.  
  15.  
  16.  
  17. /* praktische Fehlermeldungen fuer eure Fehlerbehandlungen */
  18. #define ERRMSG_OTPENC_EXISTS "Die .otpenc-Datei existiert bereits!"
  19. #define ERRMSG_OTPDEC_EXISTS "Die .otpdec-Datei existiert bereits!"
  20. #define ERRMSG_OTPENC_CREATE "Kann die .otpenc-Datei nicht erzeugen!"
  21. #define ERRMSG_OTPENC_WRITE "Die .otpenc-Datei laesst sich nicht schreiben!"
  22. #define ERRMSG_OTPENC_CLOSE "Kann die .otpenc-Datei nicht schliessen!"
  23. #define ERRMSG_OTPDEC_CREATE "Kann die .otpdec-Datei nicht erzeugen!"
  24. #define ERRMSG_OTPDEC_WRITE "Die .otpdec-Datei laesst sich nicht schreiben!"
  25. #define ERRMSG_OTPDEC_CLOSE "Kann die .otpdec-Datei nicht schliessen!"
  26.  
  27.  
  28.  
  29. void generate_otp(char *otpenc, char *otpdec, int otplen)
  30. {
  31.     /*
  32.        Hier sollen zwei Schluessel-Dateien angelegt werden (die beide
  33.        dieselben Zufallszahlen enthalten):
  34.          - eine Datei, um genau einmal zu verschluesseln (und dann beliebig
  35.            oft zu entschluesseln). "otpenc" enthaelt den (bereits vervoll-
  36.            staendigten) Dateinamen.
  37.          - eine weitere Datei, um beliebig oft zu entschluesseln, aber
  38.            niemals zu verschluesseln. "otpdec" enthaelt den Dateinamen.
  39.  
  40.        Wichtig: denkt auch immer an die Fehlerbehandlung.
  41.     */
  42.  
  43.     FILE *otpenc_file = NULL, *otpdec_file = NULL;
  44.     char buf[BUF_SIZE];
  45.  
  46.  
  47.     struct stat fileinfo = {0};
  48.     int val1;
  49.     int val2;
  50.     size_t val3;
  51.     size_t val4;
  52.     int mnr1 = bigendian(MAGIC_OTPENC_NEW);
  53.     int mnr2 = bigendian(MAGIC_OTPDEC);
  54.     int i = 0;
  55.     int count = 0;
  56.     size_t fill;
  57.  
  58.  
  59.     /* Makro zur Erleichterung der Fehlerbehandlung */
  60. #define cancel(failedcall, errmsg) {        \
  61.         perror(failedcall);         \
  62.         fprintf(stderr, "%s\n", errmsg);    \
  63.                                                 \
  64.         /* Schliesst beide Dateien, falls sie   \
  65.            erfolgreich geoeffnet wurden         \
  66.            (fclose(3)). Man sollte eigentlich   \
  67.            auch die unfertigen Dateien          \
  68.            loeschen, aber setzt remove(3) sehr  \
  69.            umsichtig ein! */                    \
  70. /* HIER MUESST IHR EUREN CODE EINFUEGEN! */     \
  71.     if (otpenc_file != NULL) {              \
  72.         fclose(otpenc_file);        \
  73.         remove(otpenc);         \
  74.     }                   \
  75.     if (otpdec_file != NULL) {      \
  76.         fclose(otpdec_file);        \
  77.         remove(otpdec);         \
  78.     }                   \
  79.         exitcode = EXIT_FAILURE;        \
  80.         return;                 \
  81.     }  /* cancel() */
  82.  
  83.  
  84.     /* Wenn ihr das parametrisierte Makro cancel() vervollstaendigt, dann
  85.        koennt ihr euch jede Menge Tipparbeit bei der Fehlerbehandlung
  86.        von Systemaufrufen ersparen. Ruft einfach im Fehlerfall cancel() mit
  87.        geeigneten Parametern auf:
  88.  
  89.            if (firgendwas() == ffehler)
  90.                cancel("firgendwas", ERRMSG_FEHLGESCHLAGEN);
  91.  
  92.        Andernfalls muesst ihr bei jedem Aufruf viel Code fuer die
  93.        Fehlermeldung und zum Schliessen (und vorsichtigen Loeschen) neu
  94.        schreiben!
  95.     */
  96.  
  97.  
  98.     /* (passt diesen printf() geringfuegig an) */
  99.     printf("Es werden zwei Dateien erzeugt, die dasselbe One-Time Pad "
  100.            "(also den\n"
  101.            "Schluessel) enthalten.\n\n"
  102.            "zum Verschluesseln: %s\n"
  103.            "zum Entschluesseln: %s\n"
  104.            "Schluessellaenge: %d Bytes\n\n",
  105.            otpenc, otpdec, otplen);
  106.  
  107.  
  108.     /* HINWEIS: Ihr habt schon ein paar Variablen vorgegeben, die ihr
  109.        verwenden koennt:
  110.        otpenc und otpdec mit den gegebenen Dateinamen,
  111.        otplen mit der gewuenschten Laenge des One-Time-Pads,
  112.        otpenc_file und otpdec_file fuer die geoeffneten Dateien,
  113.        und buf[BUF_SIZE] fuer den Puffer. */
  114.  
  115.  
  116.     /* Stellt zuerst mit stat(2) sicher, dass keine der beiden Dateien
  117.        bereits existiert (stat() soll fehlschlagen). Hier braucht ihr
  118.        cancel() noch nicht. */
  119. /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
  120.  
  121.     /* Das die Dateien, falls sie schon existieren, gelöscht werden, sollte uns nur das Testen vereinfachen, also bitte nicht
  122.     dran stören, uns ist bewusst, dass das nicht unbedingt so schön ist ;-) */
  123.  
  124.  
  125.     val1 = stat(otpenc, &fileinfo);
  126.     if (val1 != -1) {
  127.         perror("Datei zum kodieren existiert bereits und wird nun gelöscht.");
  128.         remove(otpenc);
  129.     }
  130.  
  131.     val2 = stat(otpdec, &fileinfo);
  132.     if (val2 != -1) {
  133.         perror("Datei zum dekodieren existiert bereits und wird nun gelöscht.");
  134.         remove(otpdec);
  135.     }
  136.    
  137.     /* Frage: Wieso sorgt "perror("Datei %s existiert bereits.", otpdec);" für den fehler "to many arguments"?
  138.     Normalerweise müsste das doch richtig interpretiert werden?? */
  139.  
  140.  
  141.     /* Erzeugt die beiden Dateien durch oeffnen mit fopen(3). Achtet auf
  142.        die Fehlerbehandlung und benutzt ab hier am besten cancel(). */
  143. /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
  144.    
  145.  
  146.     otpenc_file = fopen(otpenc, "w+");
  147.     if (otpenc_file == NULL) {
  148.         cancel("fopen", ERRMSG_OTPENC_CREATE);
  149.     }
  150.  
  151.     otpdec_file = fopen(otpdec, "w+");
  152.     if (otpdec_file == NULL) {
  153.         cancel("fopen", ERRMSG_OTPDEC_CREATE);
  154.     }
  155.  
  156.  
  157.     /* Schreibt die passenden magic numbers (MAGIC_OTPENC_NEW und
  158.        MAGIC_OTPDEC) mit fwrite(3). */
  159. /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
  160.  
  161.     val3 = fwrite(&mnr1, sizeof(int), 1, otpenc_file);
  162.     if (val3 != 1) {
  163.         cancel("fwrite", ERRMSG_OTPENC_WRITE);
  164.     }
  165.     val4 = fwrite(&mnr2, sizeof(int), 1, otpdec_file);
  166.     if(val4 != 1) {
  167.         cancel("fwrite", ERRMSG_OTPDEC_WRITE);
  168.     }
  169.  
  170.  
  171.     /* Schreibt das eigentliche One-Time Pad (den Schluessel) der Laenge
  172.        "otplen" in beide Dateien. Benutzt dazu die vorgegebene Funktion
  173.        pseudorandom() und fwrite(3). Da der Schluessel sehr lang sein kann,
  174.        muesst ihr ihn in einer Schleife blockweise (BUF_SIZE) schreiben. */
  175.     while (i < otplen) {  /* Ersetzt die 0 durch eine sinnvolle Bedingung. */
  176.  
  177. /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
  178.     if (otplen-(count*BUF_SIZE) < BUF_SIZE) {
  179.         fill = (size_t)(otplen-(count*BUF_SIZE));
  180.     }
  181.     else {
  182.         fill = BUF_SIZE;
  183.     }
  184.     pseudorandom(&buf, fill);
  185.     fwrite(&buf, sizeof(char), fill, otpenc_file);
  186.     if (ferror(otpenc_file)) {
  187.         cancel("fwrite", ERRMSG_OTPENC_WRITE);
  188.     }
  189.     fwrite(&buf, sizeof(char), fill, otpdec_file);
  190.     if (ferror(otpdec_file)) {
  191.         cancel("fwrite", ERRMSG_OTPDEC_WRITE);
  192.     }
  193.     i+= BUF_SIZE;
  194.     count++;
  195.     }
  196.  
  197.     /* Schliesst die Dateien wieder mit fclose(3). */
  198. /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
  199.     val1 = fclose(otpenc_file);
  200.     if (val1 != 0)
  201.         cancel("fclose", ERRMSG_OTPENC_CLOSE);
  202.     val2 = fclose(otpdec_file);
  203.     if (val2 != 0)
  204.         cancel("fclose", ERRMSG_OTPDEC_CLOSE);
  205.    
  206.     /* Gebt abschliessend eine Erfolgsmeldung aus. */
  207. /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
  208.  
  209.     printf("Beide Schlüsseldateien wurdern erfolgreich erstellt und befüllt.\n\n");
  210.  
  211. #undef cancel
  212. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement