1 /*
2 * $LynxId: LYUpload.c,v 1.41 2021/07/29 20:32:26 tom Exp $
3 *
4 * Routines to upload files to the local filesystem.
5 * Created by: Rick Mallett, Carleton University
6 * Report problems to rmallett@ccs.carleton.ca
7 * Modified 15-Dec-95 George Lindholm (lindholm@ucs.ubc.ca):
8 * Reread the upload menu page every time, in case the "upload" directory
9 * has changed (make the current directory that for the upload process).
10 * Prompt for the upload file name if there is no "%s" in the command
11 * string. Most protocols allow the user to specify the file name
12 * from the client side. Xmodem appears to be the only that can't
13 * figure out the filename from the transfer data so it needs the
14 * information from lynx (or an upload script which prompts for it).
15 * On the other hand, zmodem aborts when you give it a filename on
16 * the command line (great way of bypassing the nodotfile code :=( ).
17 */
18
19 #include <HTUtils.h>
20 #include <HTFile.h>
21 #include <HTParse.h>
22 #include <HTAlert.h>
23 #include <LYCurses.h>
24 #include <LYUtils.h>
25 #include <LYGlobalDefs.h>
26 #include <LYStrings.h>
27 #include <LYClean.h>
28 #include <LYGetFile.h>
29 #include <LYUpload.h>
30 #include <LYLocal.h>
31
32 #include <LYexit.h>
33 #include <LYLeaks.h>
34
35 #define SUBDIR_COMMAND "cd %s ; "
36
37 /*
38 * LYUpload uploads a file to a given location using a specified upload method.
39 * It parses an incoming link that looks like:
40 * LYNXDIRED://UPLOAD=<#>/TO=<STRING>
41 */
LYUpload(char * line)42 int LYUpload(char *line)
43 {
44 char *method, *directory;
45 int method_number;
46 int count;
47 char *the_upload = 0;
48 char tmpbuf[LY_MAXPATH];
49 char *filename = NULL;
50 lynx_list_item_type *upload_command = 0;
51 char *the_command = 0;
52
53 /*
54 * Use configured upload commands.
55 */
56 if ((directory = LYstrstr(line, "TO=")) == NULL)
57 goto failed;
58 *(directory - 1) = '\0';
59 /* go past "TO=" */
60 directory += 3;
61
62 if ((method = LYstrstr(line, "UPLOAD=")) == NULL)
63 goto failed;
64 /*
65 * Go past "UPLOAD=".
66 */
67 method += 7;
68 method_number = atoi(method);
69
70 for (count = 0, upload_command = uploaders; count < method_number;
71 count++, upload_command = upload_command->next) ; /* null body */
72
73 /*
74 * Parsed out the Method and the Location?
75 */
76 if (upload_command->command == NULL) {
77 HTAlert(gettext("ERROR! - upload command is misconfigured"));
78 goto failed;
79 }
80
81 /*
82 * Care about the local name?
83 */
84 if (HTCountCommandArgs(upload_command->command)) {
85 /*
86 * Commands have the form "command %s [etc]" where %s is the filename.
87 */
88 _statusline(FILENAME_PROMPT);
89 retry:
90 *tmpbuf = '\0';
91 if (LYGetStr(tmpbuf, FALSE, sizeof(tmpbuf), NORECALL) < 0)
92 goto cancelled;
93
94 if (*tmpbuf == '\0')
95 goto cancelled;
96
97 if (strstr(tmpbuf, "../") != NULL) {
98 HTAlert(gettext("Illegal redirection \"../\" found! Request ignored."));
99 goto cancelled;
100 } else if (StrChr(tmpbuf, '/') != NULL) {
101 HTAlert(gettext("Illegal character \"/\" found! Request ignored."));
102 goto cancelled;
103 } else if (tmpbuf[0] == '~') {
104 HTAlert(gettext("Illegal redirection using \"~\" found! Request ignored."));
105 goto cancelled;
106 }
107 HTSprintf0(&filename, "%s/%s", directory, tmpbuf);
108
109 #ifdef HAVE_POPEN
110 if (LYIsPipeCommand(filename)) {
111 HTAlert(CANNOT_WRITE_TO_FILE);
112 _statusline(NEW_FILENAME_PROMPT);
113 goto retry;
114 }
115 #endif
116 switch (LYValidateOutput(filename)) {
117 case 'Y':
118 break;
119 case 'N':
120 goto retry;
121 default:
122 goto cancelled;
123 }
124
125 /*
126 * See if we can write to it.
127 */
128 CTRACE((tfp, "LYUpload: filename is %s", filename));
129
130 HTAddParam(&the_upload, upload_command->command, 1, filename);
131 HTEndParam(&the_upload, upload_command->command, 1);
132 } else { /* No substitution, no changes */
133 StrAllocCopy(the_upload, upload_command->command);
134 }
135
136 HTAddParam(&the_command, SUBDIR_COMMAND, 1, directory);
137 HTEndParam(&the_command, SUBDIR_COMMAND, 1);
138 StrAllocCat(the_command, the_upload);
139
140 CTRACE((tfp, "command: %s\n", the_command));
141
142 stop_curses();
143 LYSystem(the_command);
144 start_curses();
145
146 FREE(the_command);
147 FREE(the_upload);
148 #if defined(MULTI_USER_UNIX)
149 if (filename != 0)
150 chmod(filename, HIDE_CHMOD);
151 #endif /* UNIX */
152 FREE(filename);
153
154 return 1;
155
156 failed:
157 HTAlert(gettext("Unable to upload file."));
158 return 0;
159
160 cancelled:
161 HTInfoMsg(CANCELLING);
162 return 0;
163 }
164
165 /*
166 * LYUpload_options writes out the current upload choices to a file so that the
167 * user can select printers in the same way that they select all other links.
168 * Upload links look like:
169 * LYNXDIRED://UPLOAD=<#>/TO=<STRING>
170 */
LYUpload_options(char ** newfile,char * directory)171 int LYUpload_options(char **newfile,
172 char *directory)
173 {
174 static char tempfile[LY_MAXPATH];
175 FILE *fp0;
176 lynx_list_item_type *cur_upload;
177 int count;
178 char *curloc = NULL;
179
180 if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0)
181 return (-1);
182
183 #ifdef VMS
184 StrAllocCopy(curloc, "/sys$login");
185 #else
186 StrAllocCopy(curloc, HTfullURL_toFile(directory));
187 LYTrimPathSep(curloc);
188 #endif /* VMS */
189
190 LYLocalFileToURL(newfile, tempfile);
191 LYRegisterUIPage(*newfile, UIP_UPLOAD_OPTIONS);
192
193 BeginInternalPage(fp0, UPLOAD_OPTIONS_TITLE, UPLOAD_OPTIONS_HELP);
194
195 fprintf(fp0, "<pre>\n");
196 fprintf(fp0, " <em>%s</em> %s\n", gettext("Upload To:"), curloc);
197 fprintf(fp0, "\n%s\n", gettext("Upload options:"));
198
199 if (uploaders != NULL) {
200 for (count = 0, cur_upload = uploaders;
201 cur_upload != NULL;
202 cur_upload = cur_upload->next, count++) {
203 fprintf(fp0, " <a href=\"LYNXDIRED://UPLOAD=%d/TO=%s\">",
204 count, curloc);
205 fprintf(fp0, "%s", (cur_upload->name ?
206 cur_upload->name : gettext("No Name Given")));
207 fprintf(fp0, "</a>\n");
208 }
209 } else {
210 fprintf(fp0, " <NONE>\n");
211 }
212
213 fprintf(fp0, "</pre>\n");
214 EndInternalPage(fp0);
215 LYCloseTempFP(fp0);
216
217 LYforce_no_cache = TRUE;
218 FREE(curloc);
219
220 return (0);
221 }
222