~ubuntu-branches/ubuntu/hardy/newsbeuter/hardy-security

« back to all changes in this revision

Viewing changes to src/filebrowser_formaction.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Nico Golde
  • Date: 2007-05-08 18:35:46 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070508183546-kxo88s8lrtdyz3gv
Tags: 0.4-1
* New upstream release.
* Removed dpatch dependency and patch for header inclusion,
  included upstream.
* Changed Build-Dependencies to nxml >= 0.17.2 and mrss >= 0.17.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <filebrowser_formaction.h>
 
2
#include <logger.h>
 
3
#include <config.h>
 
4
#include <view.h>
 
5
 
 
6
#include <iostream>
 
7
#include <iomanip>
 
8
#include <sstream>
 
9
 
 
10
#include <unistd.h>
 
11
#include <sys/types.h>
 
12
#include <dirent.h>
 
13
#include <sys/param.h>
 
14
#include <sys/types.h>
 
15
#include <pwd.h>
 
16
#include <grp.h>
 
17
 
 
18
 
 
19
namespace newsbeuter {
 
20
 
 
21
filebrowser_formaction::filebrowser_formaction(view * vv, std::string formstr) 
 
22
        : formaction(vv,formstr), quit(false) { }
 
23
 
 
24
filebrowser_formaction::~filebrowser_formaction() { }
 
25
 
 
26
void filebrowser_formaction::process_operation(operation op) {
 
27
        char buf[1024];
 
28
        switch (op) {
 
29
                case OP_OPEN: 
 
30
                        {
 
31
                                GetLogger().log(LOG_DEBUG,"filebrowser_formaction: 'opening' item");
 
32
                                std::string focus = f->get_focus();
 
33
                                if (focus.length() > 0) {
 
34
                                        if (focus == "files") {
 
35
                                                std::string selection = fancy_unquote(f->get("listposname"));
 
36
                                                char filetype = selection[0];
 
37
                                                selection.erase(0,1);
 
38
                                                std::string filename(selection);
 
39
                                                switch (filetype) {
 
40
                                                        case 'd':
 
41
                                                                if (type == FBT_OPEN) {
 
42
                                                                        snprintf(buf, sizeof(buf), _("Open File - %s"), filename.c_str());
 
43
                                                                } else {
 
44
                                                                        snprintf(buf, sizeof(buf), _("Save File - %s"), filename.c_str());
 
45
                                                                }
 
46
                                                                f->set("head", buf);
 
47
                                                                ::chdir(filename.c_str());
 
48
                                                                f->set("listpos","0");
 
49
                                                                if (type == FBT_SAVE) {
 
50
                                                                        char cwdtmp[MAXPATHLEN];
 
51
                                                                        ::getcwd(cwdtmp,sizeof(cwdtmp));
 
52
                                                                        std::string fn(cwdtmp);
 
53
                                                                        fn.append(NEWSBEUTER_PATH_SEP);
 
54
                                                                        std::string fnstr = f->get("filenametext");
 
55
                                                                        const char * base = strrchr(fnstr.c_str(),'/');
 
56
                                                                        if (!base)
 
57
                                                                                base = fnstr.c_str();
 
58
                                                                        fn.append(base);
 
59
                                                                        f->set("filenametext",fn);
 
60
                                                                }
 
61
                                                                do_redraw = true;
 
62
                                                                break;
 
63
                                                        case '-': 
 
64
                                                                {
 
65
                                                                        char cwdtmp[MAXPATHLEN];
 
66
                                                                        ::getcwd(cwdtmp,sizeof(cwdtmp));
 
67
                                                                        std::string fn(cwdtmp);
 
68
                                                                        fn.append(NEWSBEUTER_PATH_SEP);
 
69
                                                                        fn.append(filename);
 
70
                                                                        f->set("filenametext",fn);
 
71
                                                                        f->set_focus("filename");
 
72
                                                                }
 
73
                                                                break;
 
74
                                                        default:
 
75
                                                                // TODO: show error message
 
76
                                                                break;
 
77
                                                }
 
78
                                        } else {
 
79
                                                bool do_pop = true;
 
80
                                                std::string fn = f->get("filenametext");
 
81
                                                struct stat sbuf;
 
82
                                                if (::stat(fn.c_str(), &sbuf)!=-1 && type == FBT_SAVE) {
 
83
                                                        char buf[2048];
 
84
                                                        snprintf(buf,sizeof(buf), _("Do you really want to overwrite `%s' (y:Yes n:No)? "), fn.c_str());
 
85
                                                        f->set_focus("files");
 
86
                                                        if (v->confirm(buf, "yn") == 'n') {
 
87
                                                                do_pop = false;
 
88
                                                        }
 
89
                                                        f->set_focus("filenametext");
 
90
                                                }
 
91
                                                if (do_pop)
 
92
                                                        v->pop_current_formaction();
 
93
                                        }
 
94
                                }
 
95
                        }
 
96
                        break;
 
97
                case OP_QUIT:
 
98
                        GetLogger().log(LOG_DEBUG,"view::filebrowser: quitting");
 
99
                        v->pop_current_formaction();
 
100
                        f->set("filenametext", "");
 
101
                default:
 
102
                        break;
 
103
        }
 
104
}
 
105
 
 
106
void filebrowser_formaction::prepare() {
 
107
        if (do_redraw) {
 
108
                char cwdtmp[MAXPATHLEN];
 
109
                std::string code = "{list";
 
110
                ::getcwd(cwdtmp,sizeof(cwdtmp));
 
111
                
 
112
                DIR * dir = ::opendir(cwdtmp);
 
113
                if (dir) {
 
114
                        struct dirent * de = ::readdir(dir);
 
115
                        while (de) {
 
116
                                if (strcmp(de->d_name,".")!=0)
 
117
                                        code.append(add_file(de->d_name));
 
118
                                de = ::readdir(dir);
 
119
                        }
 
120
                        ::closedir(dir);
 
121
                }
 
122
                
 
123
                code.append("}");
 
124
                
 
125
                // GetLogger().log(LOG_DEBUG, "filebrowser: code = %s", code.c_str());
 
126
                f->modify("files", "replace_inner", code);
 
127
                do_redraw = false;
 
128
        }
 
129
 
 
130
}
 
131
 
 
132
void filebrowser_formaction::init() {
 
133
        char cwdtmp[MAXPATHLEN];
 
134
        ::getcwd(cwdtmp,sizeof(cwdtmp));
 
135
        std::string cwd = cwdtmp;
 
136
 
 
137
        f->set("fileprompt", _("File: "));
 
138
 
 
139
        if (dir == "") {
 
140
                std::string save_path = v->get_cfg()->get_configvalue("save-path");
 
141
 
 
142
                GetLogger().log(LOG_DEBUG,"view::filebrowser: save-path is '%s'",save_path.c_str());
 
143
 
 
144
                dir = save_path;
 
145
        }
 
146
 
 
147
        GetLogger().log(LOG_DEBUG, "view::filebrowser: chdir(%s)", dir.c_str());
 
148
                        
 
149
        ::chdir(dir.c_str());
 
150
        ::getcwd(cwdtmp,sizeof(cwdtmp));
 
151
        
 
152
        f->set("filenametext", default_filename);
 
153
        
 
154
        char buf[1024];
 
155
        if (type == FBT_OPEN) {
 
156
                snprintf(buf, sizeof(buf), _("Open File - %s"), cwdtmp);
 
157
        } else {
 
158
                snprintf(buf, sizeof(buf), _("Save File - %s"), cwdtmp);
 
159
        }
 
160
        f->set("head", buf);
 
161
}
 
162
 
 
163
keymap_hint_entry * filebrowser_formaction::get_keymap_hint() {
 
164
        static keymap_hint_entry hints[] = {
 
165
                { OP_QUIT, _("Cancel") },
 
166
                { OP_OPEN, _("Save") },
 
167
                { OP_NIL, NULL }
 
168
        };
 
169
        return hints;
 
170
}
 
171
 
 
172
std::string filebrowser_formaction::fancy_quote(const std::string& s) {
 
173
        std::string x;
 
174
        for (unsigned int i=0;i<s.length();++i) {
 
175
                if (s[i] != ' ') {
 
176
                        x.append(1,s[i]);
 
177
                } else {
 
178
                        x.append(1,'/');
 
179
                }       
 
180
        }       
 
181
        return x;
 
182
}
 
183
 
 
184
std::string filebrowser_formaction::add_file(std::string filename) {
 
185
        std::string retval;
 
186
        struct stat sb;
 
187
        if (::stat(filename.c_str(),&sb)==0) {
 
188
                char type = '?';
 
189
                if (sb.st_mode & S_IFREG)
 
190
                        type = '-';
 
191
                else if (sb.st_mode & S_IFDIR)
 
192
                        type = 'd';
 
193
                else if (sb.st_mode & S_IFBLK)
 
194
                        type = 'b';
 
195
                else if (sb.st_mode & S_IFCHR)
 
196
                        type = 'c';
 
197
                else if (sb.st_mode & S_IFIFO)
 
198
                        type = 'p';
 
199
                else if (sb.st_mode & S_IFLNK)
 
200
                        type = 'l';
 
201
                        
 
202
                std::string rwxbits = get_rwx(sb.st_mode & 0777);
 
203
                std::string owner = "????????", group = "????????";
 
204
                
 
205
                struct passwd * spw = getpwuid(sb.st_uid);
 
206
                if (spw) {
 
207
                        owner = spw->pw_name;
 
208
                        for (int i=owner.length();i<8;++i) {
 
209
                                owner.append(" ");      
 
210
                        }       
 
211
                }
 
212
                struct group * sgr = getgrgid(sb.st_gid);
 
213
                if (sgr) {
 
214
                        group = sgr->gr_name;
 
215
                        for (int i=group.length();i<8;++i) {
 
216
                                group.append(" ");
 
217
                        }
 
218
                }
 
219
                
 
220
                std::ostringstream os;
 
221
                os << std::setw(12) << sb.st_size;
 
222
                std::string sizestr = os.str();
 
223
                
 
224
                std::string line;
 
225
                line.append(1,type);
 
226
                line.append(rwxbits);
 
227
                line.append(" ");
 
228
                line.append(owner);
 
229
                line.append(" ");
 
230
                line.append(group);
 
231
                line.append(" ");
 
232
                line.append(sizestr);
 
233
                line.append(" ");
 
234
                line.append(filename);
 
235
                
 
236
                retval = "{listitem[";
 
237
                retval.append(1,type);
 
238
                retval.append(fancy_quote(filename));
 
239
                retval.append("] text:");
 
240
                retval.append(stfl::quote(line));
 
241
                retval.append("}");
 
242
        }
 
243
        return retval;
 
244
}
 
245
 
 
246
std::string filebrowser_formaction::fancy_unquote(const std::string& s) {
 
247
        std::string x;
 
248
        for (unsigned int i=0;i<s.length();++i) {
 
249
                if (s[i] != '/') {
 
250
                        x.append(1,s[i]);
 
251
                } else {
 
252
                        x.append(1,' ');
 
253
                }       
 
254
        }       
 
255
        return x;       
 
256
}
 
257
 
 
258
std::string filebrowser_formaction::get_rwx(unsigned short val) {
 
259
        std::string str;
 
260
        for (int i=0;i<3;++i) {
 
261
                unsigned char bits = val % 8;
 
262
                val /= 8;
 
263
                switch (bits) {
 
264
                        case 0:
 
265
                                str = std::string("---") + str;
 
266
                                break;
 
267
                        case 1:
 
268
                                str = std::string("--x") + str;
 
269
                                break;
 
270
                        case 2:
 
271
                                str = std::string("-w-") + str;
 
272
                                break;
 
273
                        case 3:
 
274
                                str = std::string("-wx") + str;
 
275
                                break;
 
276
                        case 4:
 
277
                                str = std::string("r--") + str;
 
278
                                break;
 
279
                        case 5:
 
280
                                str = std::string("r-x") + str;
 
281
                                break;
 
282
                        case 6:
 
283
                                str = std::string("rw-") + str;
 
284
                                break;
 
285
                        case 7:
 
286
                                str = std::string("rwx") + str;
 
287
                }       
 
288
        }
 
289
        return str;
 
290
}
 
291
 
 
292
}