initial commit, lordsawar source, slightly modified
[lordsawar] / src / tarhelper.cpp
1 #include "tarhelper.h"
2 #include <fcntl.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <stdlib.h>
6 #include <fstream>
7 #include "File.h"
8 #include "ucompose.hpp"
9
10 Tar_Helper::Tar_Helper(std::string file, std::ios::openmode mode)
11 {
12   int m;
13   int perms = 0;
14   openmode = mode;
15   if (mode & std::ios::in) 
16     m = O_RDONLY;
17   else if (mode & std::ios::out)
18     {
19       m = O_WRONLY|O_CREAT;
20       perms = 0644;
21     }
22   else
23     return;
24
25   char *f = strdup(file.c_str());
26   int retval = tar_open (&t, f, NULL, m, perms, TAR_GNU);
27   free(f);
28   if (retval == -1)
29     t = NULL;
30       
31   if (mode & std::ios::in)
32     {
33       std::list<std::string> files = getFilenames();
34       tmpoutdir = String::ucompose("%1/%2.%3/", Glib::get_tmp_dir(), files.front(), getpid());
35       File::create_dir(tmpoutdir);
36     }
37   else
38     tmpoutdir = "";
39
40 }
41
42 bool Tar_Helper::saveFile(std::string filename, std::string destfile)
43 {
44   char *f = strdup(filename.c_str());
45   char *b;
46   if (destfile == "")
47     b = strdup(File::get_basename(filename,true).c_str());
48   else
49     b = strdup(destfile.c_str());
50   int retval = tar_append_file(t, f, b);
51   free (f);
52   free (b);
53   if (retval != 0)
54     return false;
55   return true;
56 }
57
58 void Tar_Helper::Close()
59 {
60   if (t)
61     {
62       if (openmode & std::ios::out)
63         tar_append_eof(t);
64     
65       tar_close(t);
66       t = NULL;
67       if (tmpoutdir != "")
68         File::erase_dir(tmpoutdir);
69     }
70 }
71     
72 std::string Tar_Helper::getFirstFile(bool &broken)
73 {
74   std::list<std::string> files = getFilenames();
75   return getFile(files.front(), broken);
76 }
77
78 std::string Tar_Helper::getFile(std::string filename, bool &broken)
79 {
80   char buf[T_BLOCKSIZE];
81   lseek(t->fd, 0, SEEK_SET);
82   int i, k;
83   bool found = false;
84   //cycle through looking to find a file by that name.
85   while ((i = th_read(t)) == 0)
86     {
87       char *f = th_get_pathname(t);
88       if (strcmp(f, filename.c_str()) == 0)
89           {
90             found = true;
91             break;
92           }
93       int size = th_get_size(t);
94       for (int i = size; i > 0; i -= T_BLOCKSIZE)
95         {
96           k = tar_block_read(t, buf);
97           if (k != T_BLOCKSIZE)
98             {
99               broken = true;
100               return "";
101             }
102         }
103     }
104   if (!found)
105     {
106       broken = true;
107       return "";
108     }
109
110   int size = th_get_size(t);
111   char *data = (char* )malloc(size);
112   size_t bytesread = 0;
113   for (int i = size; i > 0; i -= T_BLOCKSIZE)
114     {
115       k = tar_block_read(t, buf);
116       if (k != T_BLOCKSIZE)
117         {
118           broken = true;
119           return "";
120         }
121       memcpy (&data[bytesread], buf, i > T_BLOCKSIZE ? T_BLOCKSIZE : i);
122       bytesread +=  (i > T_BLOCKSIZE) ? T_BLOCKSIZE : i;
123     }
124   std::string outfile = tmpoutdir + filename;
125   FILE *fileptr = fopen(outfile.c_str(), "w");
126   fwrite(data, 1, size, fileptr);
127   fclose(fileptr);
128
129   broken = false;
130   return outfile;
131 }
132
133 std::list<std::string> Tar_Helper::getFilenames()
134 {
135   std::list<std::string> result;
136   int i, k;
137   char buf[T_BLOCKSIZE];
138   lseek(t->fd, 0, SEEK_SET);
139   //cycle through looking to find files with that extension.
140   while ((i = th_read(t)) == 0)
141     {
142       char *f = th_get_pathname(t);
143       result.push_back(f);
144         
145       int size = th_get_size(t);
146       for (int i = size; i > 0; i -= T_BLOCKSIZE)
147         {
148           k = tar_block_read(t, buf);
149           if (k != T_BLOCKSIZE)
150             return result;
151         }
152     }
153   return result;
154 }
155 std::list<std::string> Tar_Helper::getFilenamesWithExtension(std::string ext)
156 {
157   std::list<std::string> result;
158   int i, k;
159   char buf[T_BLOCKSIZE];
160   lseek(t->fd, 0, SEEK_SET);
161   //cycle through looking to find files with that extension.
162   while ((i = th_read(t)) == 0)
163     {
164       char *f = th_get_pathname(t);
165       if (File::nameEndsWith(f, ext) == true)
166         result.push_back(f);
167         
168       int size = th_get_size(t);
169       for (int i = size; i > 0; i -= T_BLOCKSIZE)
170         {
171           k = tar_block_read(t, buf);
172           if (k != T_BLOCKSIZE)
173             return result;
174         }
175     }
176   return result;
177 }
178
179 Tar_Helper::~Tar_Helper()
180 {
181   if (t)
182     Close();
183 }
184