Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Tools / DiskTool / actions.c
1 /*
2  * Acess2 DiskTool
3  * - By John Hodge (thePowersGang)
4  *
5  * actions.c
6  * - High level actions that call the VFS
7  * # Kernel-space compiled
8  */
9 #include <acess.h>
10 #include <disktool_common.h>
11 #include <Storage/LVM/include/lvm.h>
12
13 // === IMPORTS ===
14 extern int      NativeFS_Install(char **Arguments);
15 extern int      LVM_Cleanup(void);
16
17 // === PROTOTYPES ===
18 void    DiskTool_Initialise(void)       __attribute__((constructor(102)));
19 void    DiskTool_Cleanup(void);
20  int    DiskTool_int_TranslateOpen(const char *File, int Mode);
21  int    DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest);
22  int    DiskTool_LVM_Write(void *Handle, Uint64 Block, size_t BlockCount, const void *Dest);
23 void    DiskTool_LVM_Cleanup(void *Handle);
24
25 // === GLOBALS ===
26 tLVM_VolType    gDiskTool_VolumeType = {
27         .Name = "DiskTool",
28         .Read  = DiskTool_LVM_Read,
29         .Write = DiskTool_LVM_Write,
30         .Cleanup = DiskTool_LVM_Cleanup
31 };
32
33 // === CODE ===
34 void DiskTool_Initialise(void)
35 {
36         VFS_Init();
37         NativeFS_Install(NULL);
38         VFS_MkDir("/Native");
39         VFS_Mount("/", "/Native", "nativefs", "");
40 }
41
42 void DiskTool_Cleanup(void)
43 {
44          int    vfs_rv, lvm_rv;
45          int    nNochangeLoop = 0;
46         // Unmount all
47         do {
48                 lvm_rv = LVM_Cleanup();
49                 vfs_rv = VFS_UnmountAll();
50                 Log_Debug("DiskTool", "Unmounted %i volumes", vfs_rv);
51                 if( vfs_rv == 0 && lvm_rv == 0 ) {
52                         nNochangeLoop ++;
53                         if(nNochangeLoop == 2) {
54                                 Log_Error("DiskTool", "Possible handle leak");
55                                 break;
56                         }
57                 }
58                 else {
59                         nNochangeLoop = 0;
60                 }
61         }
62         while( vfs_rv >= 0 || lvm_rv != 0 );
63 }
64
65 int DiskTool_RegisterLVM(const char *Identifier, const char *Path)
66 {
67         int fd = DiskTool_int_TranslateOpen(Path, VFS_OPENFLAG_READ|VFS_OPENFLAG_WRITE);
68         if(fd == -1) {
69                 Log_Notice("DiskTool", "Can't open '%s' for LVM %s", Path, Identifier);
70                 return -1;
71         }
72         VFS_Seek(fd, 0, SEEK_END);
73         LVM_AddVolume( &gDiskTool_VolumeType, Identifier, (void*)(tVAddr)fd, 512, VFS_Tell(fd)/512);
74         Log_Debug("DiskTool", "Registered '%s' for LVM %s", Path, Identifier);
75         return 0;
76 }
77
78 int DiskTool_MountImage(const char *Identifier, const char *Path)
79 {
80         // Validate Identifier and make mountpoint string
81         char mountpoint[sizeof("/Mount/") + strlen(Identifier) + 1];
82         strcpy(mountpoint, "/Mount/");
83         strcat(mountpoint, Identifier);
84         
85         // Translate path       
86         size_t tpath_len = DiskTool_int_TranslatePath(NULL, Path);
87         char tpath[tpath_len-1];
88         DiskTool_int_TranslatePath(tpath, Path);
89         
90         // Call mount
91         VFS_MkDir(mountpoint);
92         // TODO: Detect filesystem?
93         return VFS_Mount(tpath, mountpoint, "", "");
94 }
95
96 int DiskTool_MkDir(const char *Directory)
97 {
98         return -1;
99 }
100
101 int DiskTool_Copy(const char *Source, const char *Destination)
102 {
103         int src = DiskTool_int_TranslateOpen(Source, VFS_OPENFLAG_READ);
104         if( src == -1 ) {
105                 Log_Error("DiskTool", "Unable to open %s for reading", Source);
106                 return -1;
107         }
108         int dst = DiskTool_int_TranslateOpen(Destination, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_CREATE);
109         if( dst == -1 ) {
110                 Log_Error("DiskTool", "Unable to open %s for writing", Destination);
111                 VFS_Close(src);
112                 return -1;
113         }
114
115         char    buf[1024];
116         size_t  len, total = 0;
117         while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
118                 VFS_Write(dst, len, buf);
119                 total += len;
120         }
121         VFS_Write(dst, len, buf), total += len;
122
123         Log_Notice("DiskTool", "Copied %i from %s to %s", total, Source, Destination);
124
125         VFS_Close(dst);
126         VFS_Close(src);
127         
128         return 0;
129 }
130
131 int DiskTool_ListDirectory(const char *Directory)
132 {
133         int fd = DiskTool_int_TranslateOpen(Directory, VFS_OPENFLAG_READ|VFS_OPENFLAG_DIRECTORY);
134         if(fd == -1) {
135 //              fprintf(stderr, "Can't open '%s'\n", Directory);
136                 return -1;
137         }
138
139         Log("Directory listing of '%s'", Directory);    
140
141         char    name[256];
142         while( VFS_ReadDir(fd, name) )
143         {
144                 tFInfo  fi;
145                 int child = VFS_OpenChild(fd, name, 0);
146                 if( child != -1 )
147                 {
148                         VFS_FInfo(child, &fi, 0);
149                         VFS_Close(child);
150                 }
151                 Log("- %02x %6lli %s", fi.flags, fi.size, name);
152         }
153         
154         VFS_Close(fd);
155         
156         return 0;
157 }
158
159 int DiskTool_Cat(const char *File)
160 {
161         int src = DiskTool_int_TranslateOpen(File, VFS_OPENFLAG_READ);
162         if( src == -1 ) {
163                 Log_Error("DiskTool", "Unable to open %s for reading", File);
164                 return -1;
165         }
166         
167         char    buf[1024];
168         size_t  len, total = 0;
169         while( (len = VFS_Read(src, sizeof(buf), buf)) == sizeof(buf) ) {
170                 _fwrite_stdout(len, buf);
171                 total += len;
172         }
173         _fwrite_stdout(len, buf);
174         total += len;
175
176         Log_Notice("DiskTool", "%i bytes from %s", total, File);
177
178         VFS_Close(src);
179         return 0;
180 }
181
182 int DiskTool_LVM_Read(void *Handle, Uint64 Block, size_t BlockCount, void *Dest)
183 {
184         return VFS_ReadAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
185 }
186 int DiskTool_LVM_Write(void *Handle, Uint64 Block, size_t BlockCount, const void *Dest)
187 {
188         return VFS_WriteAt( (int)(tVAddr)Handle, Block*512, BlockCount*512, Dest) / 512;
189 }
190 void DiskTool_LVM_Cleanup(void *Handle)
191 {
192         VFS_Close( (int)(tVAddr)Handle );
193 }
194
195 // --- Internal helpers ---
196 int DiskTool_int_TranslateOpen(const char *File, int Flags)
197 {
198         size_t tpath_len = DiskTool_int_TranslatePath(NULL, File);
199         if(tpath_len == 0)
200                 return -1;
201         char tpath[tpath_len-1];
202         DiskTool_int_TranslatePath(tpath, File);
203
204         return VFS_Open(tpath, Flags);
205 }
206

UCC git Repository :: git.ucc.asn.au