[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Lost] [Patch] Hardlinks für LostIO



Dieser Patch bringt LostIO die Fähigkeit Hardlinks zu erstellen und sie
zu löschen bei.
Index: console/console.c
===================================================================
--- console/console.c	(Revision 616)
+++ console/console.c	(Arbeitskopie)
@@ -65,7 +65,9 @@
     .read = &stdin_read,
     .write = NULL,
     .seek = NULL,
-    .close = NULL
+    .close = NULL,
+    .link = NULL,
+    .unlink = NULL
 };
 
Index: fat/main.c
===================================================================
--- fat/main.c	(Revision 616)
+++ fat/main.c	(Arbeitskopie)
@@ -66,6 +66,8 @@
     typehandle->write           = NULL;
     typehandle->seek            = NULL;
     typehandle->close           = NULL;
+    typehandle->link            = NULL;
+    typehandle->unlink          = NULL;
     lostio_register_typehandle(typehandle);
 
     //Den seek-handler aus Ramfile benutzen
Index: floppy/floppy.c
===================================================================
--- floppy/floppy.c	(Revision 616)
+++ floppy/floppy.c	(Arbeitskopie)
@@ -183,6 +183,8 @@
     typehandle->write       = &floppy_write_handler;
     typehandle->seek        = &floppy_seek_handler;
     typehandle->close       = NULL;
+    typehandle->link        = NULL;
+    typehandle->unlink      = NULL;
     lostio_register_typehandle(typehandle);
     
     // In diesem Verzeichnis liegen die Geraetedateien fuer die Einzelnen
Index: gui/src/main.c
===================================================================
--- gui/src/main.c	(Revision 616)
+++ gui/src/main.c	(Arbeitskopie)
@@ -220,6 +220,8 @@
     typehandle_control->write       = &control_write;
     typehandle_control->seek        = NULL;
     typehandle_control->close       = NULL;
+    typehandle_control->link        = NULL;
+    typehandle_control->unlink      = NULL;
     lostio_register_typehandle(typehandle_control);
     
     //Maus-Callback
@@ -232,6 +234,8 @@
     typehandle_control->write       = &mouse_write;
     typehandle_control->seek        = NULL;
     typehandle_control->close       = NULL;
+    typehandle_control->link        = NULL;
+    typehandle_control->unlink      = NULL;
     lostio_register_typehandle(typehandle_mouse);
     // vfstree bauen
     vfstree_create_node("/control" , 255, 0, NULL, 0);
Index: kbc/keyboard.c
===================================================================
--- kbc/keyboard.c	(Revision 616)
+++ kbc/keyboard.c	(Arbeitskopie)
@@ -192,6 +192,8 @@
     typehandle->write       = NULL;
     typehandle->seek        = NULL;
     typehandle->close       = NULL;
+    typehandle->link        = NULL;
+    typehandle->unlink      = NULL;
     lostio_register_typehandle(typehandle);
 
     vfstree_create_node("/keyboard", LOSTIO_TYPES_DIRECTORY, 0, 0, 0);
Index: kbc/mouse.c
===================================================================
--- kbc/mouse.c	(Revision 616)
+++ kbc/mouse.c	(Arbeitskopie)
@@ -41,6 +41,8 @@
     typehandle->write       = NULL;
     typehandle->seek        = NULL;
     typehandle->close       = NULL;
+    typehandle->link        = NULL;
+    typehandle->unlink      = NULL;
     lostio_register_typehandle(typehandle);
 
     //Registrierung von Callback-Dateien
@@ -53,6 +55,8 @@
     typehandle->write       = &mouse_callback_handler;
     typehandle->seek        = NULL;
     typehandle->close       = NULL;
+    typehandle->link        = NULL;
+    typehandle->unlink      = NULL;
     lostio_register_typehandle(typehandle);
 
     vfstree_create_node("/mouse", LOSTIO_TYPES_DIRECTORY, 0, 0, 0);
Index: keyboard/keyboard.c
===================================================================
--- keyboard/keyboard.c	(Revision 616)
+++ keyboard/keyboard.c	(Arbeitskopie)
@@ -197,6 +197,8 @@
     typehandle->write       = NULL;
     typehandle->seek        = NULL;
     typehandle->close       = NULL;
+    typehandle->link        = NULL;
+    typehandle->unlink      = NULL;
     lostio_register_typehandle(typehandle);
 
     //vfstree_create_node("/raw", 255, 0, (void*)BUFFER_TYPE_RAW);
Index: tcpip/lostio_if.c
===================================================================
--- tcpip/lostio_if.c	(Revision 616)
+++ tcpip/lostio_if.c	(Arbeitskopie)
@@ -89,7 +89,10 @@
     typehandle.write       = &lostio_tcp_write;
     typehandle.seek        = NULL;
     typehandle.close       = &lostio_tcp_close;;
+    typehandle.link        = NULL;
+    typehandle.unlink      = NULL;
 
+
     lostio_register_typehandle(&typehandle);
 
     get_typehandle(LOSTIO_TYPES_DIRECTORY)->not_found = lostio_tcp_not_found;
Index: textterm/main.c
===================================================================
--- textterm/main.c	(Revision 616)
+++ textterm/main.c	(Arbeitskopie)
@@ -37,6 +37,8 @@
     typehandle->write       = &terminal_write;
     typehandle->seek        = NULL;
     typehandle->close       = NULL;
+    typehandle->link        = NULL;
+    typehandle->unlink      = NULL;
     lostio_register_typehandle(typehandle);
     vfstree_create_node("/echo" , LOSTIO_TYPES_OUT, 0, NULL, 0);
     
Index: vesa/main.c
===================================================================
--- vesa/main.c	(Revision 616)
+++ vesa/main.c	(Arbeitskopie)
@@ -75,6 +75,8 @@
     typehandle_information->write       = NULL;
     typehandle_information->seek        = NULL;
     typehandle_information->close       = NULL;
+    typehandle_information->link        = NULL;
+    typehandle_information->unlink      = NULL;
     lostio_register_typehandle(typehandle_information);
     
     vfstree_create_node("/information" , 255, 0, NULL, 0);
Index: vga/main.c
===================================================================
--- vga/main.c	(Revision 616)
+++ vga/main.c	(Arbeitskopie)
@@ -75,6 +75,8 @@
     typehandle_information->write       = NULL;
     typehandle_information->seek        = NULL;
     typehandle_information->close       = NULL;
+    typehandle_information->link        = NULL;
+    typehandle_information->unlink      = NULL;
     lostio_register_typehandle(typehandle_information);
     
     vfstree_create_node("/information" , 255, 0, NULL, 0);
Index: videodriver/main.c
===================================================================
--- videodriver/main.c	(Revision 616)
+++ videodriver/main.c	(Arbeitskopie)
@@ -75,6 +75,8 @@
     typehandle_information->write       = NULL;
     typehandle_information->seek        = NULL;
     typehandle_information->close       = NULL;
+    typehandle_information->link        = NULL;
+    typehandle_information->unlink      = NULL;
     lostio_register_typehandle(typehandle_information);
     
     vfstree_create_node("/information" , 255, 0, NULL, 0);
Index: vterm/lostio.c
===================================================================
--- vterm/lostio.c	(Revision 616)
+++ vterm/lostio.c	(Arbeitskopie)
@@ -75,6 +75,8 @@
     typehandle->write       = NULL;
     typehandle->seek        = NULL;
     typehandle->close       = NULL;
+    typehandle->link        = NULL;
+    typehandle->unlink      = NULL;
     lostio_register_typehandle(typehandle);
 }
 
Index: lib/lostio/types/ramfile.c
===================================================================
--- lib/lostio/types/ramfile.c	(Revision 616)
+++ lib/lostio/types/ramfile.c	(Arbeitskopie)
@@ -68,6 +68,8 @@
     ramfile_typehandle->write        = &ramfile_write;
     ramfile_typehandle->seek         = &ramfile_seek;
     ramfile_typehandle->close        = NULL;
+    ramfile_typehandle->link         = NULL;
+    ramfile_typehandle->unlink       = NULL;
 
     lostio_register_typehandle(ramfile_typehandle);
 }
Index: lib/lostio/types/directory.c
===================================================================
--- lib/lostio/types/directory.c	(Revision 616)
+++ lib/lostio/types/directory.c	(Arbeitskopie)
@@ -61,6 +61,8 @@
     dir_typehandle->write        = NULL;
     dir_typehandle->seek         = &dir_seek;
     dir_typehandle->close        = NULL;
+    dir_typehandle->link         = NULL;
+    dir_typehandle->unlink       = NULL;
 
     lostio_register_typehandle(dir_typehandle);
 }
Index: lib/lost_link.c
===================================================================
--- lib/lost_link.c	(Revision 0)
+++ lib/lost_link.c	(Revision 0)
@@ -0,0 +1,202 @@
+/*  
+ * Copyright (c) 2007 The LOST Project. All rights reserved.
+ *
+ * This code is derived from software contributed to the LOST Project
+ * by Antoine Kaufmann.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the LOST Project
+ *     and its contributors.
+ * 4. Neither the name of the LOST Project nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR 
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <collections.h>
+#include <io.h>
+#include <rpc.h>
+
+/**
+ * Link erstellen
+ *
+ * @param target_path Pfad auf den der Link zeigen soll
+ * @param link_path Pfad an dem der Link erstellt werden soll
+ * @param hardlink TRUE, falls ein Hardlink erstellt werden soll, FALSE sonst
+ *
+ * @return 0 bei Erfolg, im Fehlerfall:
+ *      -1: Ziel nicht vorhanden
+ */
+int io_create_link(const char* target_path, const char* link_path,
+    bool hardlink)
+{
+    int result;
+    // Jetzt wird er absolute Pfad zum Link ermittelt. Das ist hier notwendig,
+    // damit ein io_split_dirname danach sicher funktioniert
+    char* link_full_path = io_get_absolute_path(link_path);
+    if (link_full_path == NULL) {
+        return -1;
+    }
+    
+    // Jetzt werden Datei- und Verzeichnisname geholt
+    char* link_filename = io_split_filename(link_full_path);
+    char* link_dirname = io_split_dirname(link_full_path);
+    if ((link_filename == NULL) || (link_dirname == NULL)) {
+        free(link_full_path);
+        free(link_filename);
+        free(link_dirname);
+        return -1;
+    }
+
+    // Link-Ziel oeffnen
+    FILE* target_file = fopen(target_path, "r");
+    if (target_file == NULL) {
+        // Wenn das Oeffnen nicht klappt ist die Datei nicht vorhanden,
+        // folglich kann auch kein Link darauf erstellt werden ;-)
+        free(link_full_path);
+        free(link_filename);
+        free(link_dirname);
+        return -2;
+    }
+    
+    // Verzeichnis oeffnen, in dem der Link angelegt werden soll
+    FILE* link_dir = fopen(link_dirname, "rd");
+    if (link_dir == NULL) {
+        fclose(target_file);
+        free(link_full_path);
+        free(link_filename);
+        free(link_dirname);
+        return -3;
+    }
+    
+    // Wenn die Beiden nicht im Selben Treiber liegen, ist der Fall eh
+    // erledigt.
+    if (link_dir->pid != target_file->pid) {
+        fclose(target_file);
+        fclose(link_dir);
+        free(link_full_path);
+        free(link_filename);
+        free(link_dirname);
+        return -4;
+    }
+
+    // Groesse der RPC-Daten errechnen
+    size_t link_len = strlen(link_filename) + 1;
+    size_t size = sizeof(io_link_request_t) + link_len + 1;
+    char buffer[size];
+
+    // Netten Pointer auf den Buffer eirichten
+    io_link_request_t* request = (io_link_request_t*) buffer;
+    
+    // Pfad kopieren
+    request->name_len = link_len - 1;
+    memcpy(request->name, link_filename, link_len);
+    
+    // Ziel eintragen
+    request->target_id = target_file->id;
+    request->dir_id = link_dir->id;
+
+    // RPC durchfuehren und auf Ergebnis warten
+    result = rpc_get_int(target_file->pid, "IO_LINK ", size, buffer);
+    
+    // Geoffnetes Link-Ziel und Link-Verzeichnis schliessen
+    fclose(target_file);
+    fclose(link_dir);
+    
+    // Durch Pfade belegten Speicher freigeben
+    free(link_full_path);
+    free(link_filename);
+    free(link_dirname);
+    return result;
+}
+
+/**
+ * Link loeschen
+ *
+ * @param link_path Pfad der geloescht werden soll
+ *
+ * @return 0 bei Erfolg, im Fehlerfall < 1
+ */
+int io_remove_link(const char* link_path)
+{
+    int result;
+    // Jetzt wird er absolute Pfad zum Link ermittelt. Das ist hier notwendig,
+    // damit ein io_split_dirname danach sicher funktioniert
+    char* link_full_path = io_get_absolute_path(link_path);
+    if (link_full_path == NULL) {
+        return -1;
+    }
+    
+    // Jetzt werden Datei- und Verzeichnisname geholt
+    char* link_dirname = io_split_dirname(link_full_path);
+    char* link_filename = io_split_filename(link_full_path);
+    if ((link_dirname == NULL) || (link_filename == NULL)) {
+        free(link_full_path);
+        free(link_dirname);
+        free(link_filename);
+        return -1;
+    }
+
+    // Verzeichnis oeffnen, in dem der Link angelegt werden soll
+    FILE* link_dir = fopen(link_dirname, "rd");
+    if (link_dir == NULL) {
+        free(link_full_path);
+        free(link_dirname);
+        free(link_filename);
+        return -3;
+    }
+
+
+    // Groesse der RPC-Daten errechnen
+    size_t link_len = strlen(link_filename) + 1;
+    size_t size = sizeof(io_unlink_request_t) + link_len + 1;
+    char buffer[size];
+
+    // Netten Pointer auf den Buffer eirichten
+    io_unlink_request_t* request = (io_unlink_request_t*) buffer;
+    
+    // Pfad kopieren
+    request->name_len = link_len - 1;
+    memcpy(request->name, link_filename, link_len);
+    
+    // Ziel eintragen
+    request->dir_id = link_dir->id;
+
+    // RPC durchfuehren und auf Ergebnis warten
+    result = rpc_get_int(link_dir->pid, "IO_ULINK", size, buffer);
+    
+    // Geoffnetes Link-Ziel und Link-Verzeichnis schliessen
+    fclose(link_dir);
+    
+    // Durch Pfade belegten Speicher freigeben
+    free(link_full_path);
+    free(link_filename);
+    free(link_dirname);
+    return result;
+}
+
Index: lib/lostio/handler.c
===================================================================
--- lib/lostio/handler.c	(Revision 616)
+++ lib/lostio/handler.c	(Arbeitskopie)
@@ -341,10 +343,90 @@
 }
 
 
+/**
+ * Ein Prozess hat ein io_link auf einem File-Handle dieses Treibers ausgefuehrt
+ */
+void rpc_io_link(pid_t pid, dword correlation_id, size_t data_size, void* data)
+{
+    io_link_request_t* link_request = (io_link_request_t*) data;
 
+    // Filehandles fuer Link-Ziel und Verzeichnis holen
+    lostio_filehandle_t* target_filehandle = get_filehandle(pid, link_request->
+        target_id);
+    lostio_filehandle_t* dir_filehandle = get_filehandle(pid, link_request->
+        dir_id);
 
+    // Wenn eines der Filehandles nicht exisitiert muss abgebrochen werden
+    if((target_filehandle == NULL) || (dir_filehandle == NULL))
+    {
+        rpc_send_int_response(pid, correlation_id, -1);
+        return;
+    }
 
+    // Typ-Handle fuer Verzeichnis holen
+    typehandle_t* typehandle = get_typehandle(dir_filehandle->node->type);
+    if((typehandle != NULL) && (typehandle->link != NULL))
+    {
+        // Pruefen, ob der Pfad wirklich Nullterminiert ist
+        if (strnlen(link_request->name, link_request->name_len + 1) !=
+            link_request->name_len)
+        {
+            rpc_send_int_response(pid, correlation_id, -2);
+            return;
+        }
+        int result = typehandle->link(target_filehandle, dir_filehandle,
+            link_request->name);
+        rpc_send_int_response(pid, correlation_id, result);
+    }
+    else
+    {
+        rpc_send_int_response(pid, correlation_id, -1);
+    }
+}
+
 /**
+ * Ein Prozess hat ein io_remove auf einem File-Handle dieses Treibers ausgefuehrt
+ */
+void rpc_io_unlink(pid_t pid, dword correlation_id, size_t data_size, void* data)
+{
+    io_unlink_request_t* unlink_request = (io_unlink_request_t*) data;
+
+    // Filehandles fuer Verzeichnis holen
+    lostio_filehandle_t* dir_filehandle = get_filehandle(pid, unlink_request->
+        dir_id);
+
+    // Wenn eines der Filehandles nicht exisitiert muss abgebrochen werden
+    if (dir_filehandle == NULL)
+    {
+        rpc_send_int_response(pid, correlation_id, -1);
+        return;
+    }
+
+    // Typ-Handle fuer Verzeichnis holen
+    typehandle_t* typehandle = get_typehandle(dir_filehandle->node->type);
+    if((typehandle != NULL) && (typehandle->link != NULL))
+    {
+        // Pruefen, ob der Pfad wirklich Nullterminiert ist
+        if (strnlen(unlink_request->name, unlink_request->name_len + 1) !=
+            unlink_request->name_len)
+        {
+            rpc_send_int_response(pid, correlation_id, -2);
+            return;
+        }
+        int result = typehandle->unlink(dir_filehandle, unlink_request->name);
+        rpc_send_int_response(pid, correlation_id, result);
+    }
+    else
+    {
+        rpc_send_int_response(pid, correlation_id, -1);
+    }
+}
+
+
+
+
+
+/**
  * Wird vom RPC-Handler bei einem fopen aufgerufen.
  *
  * @param path Pfad
Index: lib/lostio/lostio.c
===================================================================
--- lib/lostio/lostio.c	(Revision 616)
+++ lib/lostio/lostio.c	(Arbeitskopie)
@@ -74,6 +74,8 @@
     register_message_handler("IO_SEEK ", &rpc_io_seek);
     register_message_handler("IO_EOF  ", &rpc_io_eof);
     register_message_handler("IO_TELL ", &rpc_io_tell);
+    register_message_handler("IO_LINK ", &rpc_io_link);
+    register_message_handler("IO_ULINK", &rpc_io_unlink);
 }
 
 /**
Index: lib/lostio/include/lostio_internal.h
===================================================================
--- lib/lostio/include/lostio_internal.h	(Revision 616)
+++ lib/lostio/include/lostio_internal.h	(Arbeitskopie)
@@ -72,6 +72,13 @@
 ///RPC-Handler fuer ein tell
 void    rpc_io_tell(pid_t pid, dword correlation_id, size_t data_size, void* data);
 
+/// RPC-Handler zum erstellen eines Links
+void    rpc_io_link(pid_t pid, dword correlation_id, size_t data_size, void* data);
+
+/// RPC-Handler zum loeschen eines Links
+void    rpc_io_unlink(pid_t pid, dword correlation_id, size_t data_size, void* data);
+
+
 ///Knoten loeschen
 //bool vfstree_delete_node(char* path);
 
Index: include/io.h
===================================================================
--- include/io.h	(Revision 619)
+++ include/io.h	(Arbeitskopie)
@@ -121,9 +121,29 @@
     {
         io_resource_id_t id;
     } __attribute__ ((packed)) io_tell_request_t;
+    
+    typedef struct
+    {
+        io_resource_id_t target_id;
+        io_resource_id_t dir_id;
 
+        size_t name_len;
+        char name[];
+    } __attribute__ ((packed)) io_link_request_t;
+    
+    typedef struct
+    {
+        io_resource_id_t dir_id;
+
+        size_t name_len;
+        char name[];
+    } __attribute__ ((packed)) io_unlink_request_t;
 #endif
 
+int io_create_link(const char* target_path, const char* link_path,
+    bool hardlink);
+int io_remove_link(const char* link_path);
+
 char* io_get_absolute_path(const char* path);
 char* io_split_filename(const char* path);
 char* io_split_dirname(const char* path);