24 #include "fileutils.h"
27 #include "sighandler.h"
47 #define MAIN_ERR_PREFIX "EXT: "
72 static char* ext_check_data(
const char* s,
int conv)
75 const char* rsqm =
"\xE2\x80\x99";
85 if(NULL == strchr(s, 0x27))
88 res = (
char*) api_posix_malloc(++len);
89 if(NULL != res) { memcpy(res, s, len); }
94 printf(
"%s: %sApostrophe replacement U+0027 => U+2019 done\n",
98 if(0x27 == (
int) s[i++])
100 if(API_POSIX_SIZE_MAX - len < (
size_t) 2)
102 PRINT_ERROR(
"Aborted before \x27size_t\x27 overflow");
110 res = (
char*) api_posix_malloc(++len);
116 if(0x27 != (
int) s[i]) { res[ri++] = s[i]; }
174 const char* mailto =
"mailto:";
175 const char* command =
"xdg-email --utf8";
176 const char* opt_subject =
" --subject \x27";
177 const char* opt_body =
" --body \x27";
188 if(NULL != recipient)
190 len = strlen(mailto);
191 if(strlen(recipient) >= len && !strncmp(recipient, mailto, len))
203 if(NULL == recipient)
221 recipient = ext_check_data(recipient, 0);
222 if(NULL == recipient)
226 PRINT_ERROR(
"URI with \x27mailto\x27 scheme cannot be handled");
230 PRINT_ERROR(
"e-mail recipient address cannot be handled");
238 printf(
"%s: %se-mail delegation to xdg-email for: %s\n",
245 subject = ext_check_data(subject, 1);
248 PRINT_ERROR(
"e-mail subject cannot be handled (ignored)");
253 body = ext_check_data(body, 1);
256 PRINT_ERROR(
"e-mail body cannot be handled (ignored)");
266 len = strlen(command);
267 buf = (
char*) api_posix_malloc(++len);
268 if(NULL == buf) { error = 1; }
269 else { strncpy(buf, command, len); }
273 if(!error && !uri && NULL != subject)
275 len_tmp = strlen(subject);
276 x = strlen(opt_subject) + (size_t) 1;
277 if(API_POSIX_SIZE_MAX - len_tmp < x) { error = 1; }
280 if(API_POSIX_SIZE_MAX - len < len_tmp + x) { error = 1; }
284 tmp = (
char*) api_posix_realloc(buf, len);
285 if(NULL == tmp) { error = 1; }
289 strcat(buf, opt_subject);
290 strncat(buf, subject, len_tmp);
298 if(!error && !uri && NULL != body)
300 len_tmp = strlen(body);
301 x = strlen(opt_body) + (size_t) 1;
302 if(API_POSIX_SIZE_MAX - len_tmp < x) { error = 1; }
305 if(API_POSIX_SIZE_MAX - len < len_tmp + x) { error = 1; }
309 tmp = (
char*) api_posix_realloc(buf, len);
310 if(NULL == tmp) { error = 1; }
314 strcat(buf, opt_body);
315 strncat(buf, body, len_tmp);
325 len_tmp = strlen(recipient);
326 if(API_POSIX_SIZE_MAX - len_tmp < (
size_t) 3) { error = 1; }
329 if(API_POSIX_SIZE_MAX - len < len_tmp + (
size_t) 3) { error = 1; }
333 len += len_tmp + (size_t) 3;
334 tmp = (
char*) api_posix_realloc(buf, len);
335 if(NULL == tmp) { error = 1; }
339 strcat(buf,
" \x27");
340 strncat(buf, recipient, len_tmp);
351 fs = api_posix_popen(buf,
"w");
352 if(NULL != fs) { res = api_posix_pclose(fs); }
356 api_posix_free((
void*) body);
357 api_posix_free((
void*) subject);
358 api_posix_free((
void*) recipient);
359 api_posix_free((
void*) buf);
395 const char* command =
"open";
397 const char* command =
"xdg-open";
412 if(NULL == uri) {
PRINT_ERROR(
"No URI specified"); }
423 uri = ext_check_data(uri, 0);
440 printf(
"%s: %sURI delegation to %s for: %s\n",
442 len = strlen(command);
443 buf = (
char*) api_posix_malloc(++len);
444 if(NULL == buf) { error = 1; }
445 else { strncpy(buf, command, len); }
451 len_tmp = strlen(uri);
452 if(API_POSIX_SIZE_MAX - len_tmp < (
size_t) 5) { error = 1; }
455 if(API_POSIX_SIZE_MAX - len < len_tmp + (
size_t) 5) { error = 1; }
459 len += len_tmp + (size_t) 5;
460 tmp = (
char*) api_posix_realloc(buf, len);
461 if(NULL == tmp) { error = 1; }
465 strcat(buf,
" \x27");
467 strcat(buf,
"\x27 &");
476 fs = api_posix_popen(buf,
"w");
477 if(NULL != fs) { res = api_posix_pclose(fs); }
481 api_posix_free((
void*) uri);
482 api_posix_free((
void*) buf);
522 size_t len = strlen(epn);
528 if(len && NULL != tfpn)
532 printf(
"%s: %sExternal editor (path)name: \x22%s\x22\n",
536 pid = api_posix_fork();
541 if(!rv) { api_posix_execlp(epn, epn, tfpn, (
char*) NULL); }
543 exit(API_POSIX_EXIT_FAILURE);
552 *(va_arg(ap,
long int*)) = (
long int) pid;
558 do { rv2 = api_posix_waitpid(pid, &status, 0); }
559 while((api_posix_pid_t) -1 == rv2
560 && API_POSIX_EINTR == api_posix_errno);
568 if(!status) { res = 0; }
572 if(!API_POSIX_WIFEXITED(status))
574 res = API_POSIX_EXIT_FAILURE;
576 else { res = API_POSIX_WEXITSTATUS(status); }
610 api_posix_pid_t pid = (api_posix_pid_t) editor_pid;
615 do { rv2 = api_posix_waitpid(pid, &status, API_POSIX_WNOHANG); }
616 while((api_posix_pid_t) -1 == rv2 && API_POSIX_EINTR == api_posix_errno);
626 if(!status) { res = 0; }
630 if(!API_POSIX_WIFEXITED(status)) { res = API_POSIX_EXIT_FAILURE; }
631 else { res = API_POSIX_WEXITSTATUS(status); }
655 api_posix_kill((api_posix_pid_t) editor_pid, API_POSIX_SIGTERM);
688 const char* res = article;
691 api_posix_struct_stat state;
699 size_t len = strlen(article);
700 api_posix_ssize_t rv3;
708 if(API_POSIX_SIZE_MAX != len && strlen(filter_pathname))
713 printf(
"%s: %sArticle post processor pathname: \x22%s\x22\n",
723 if(API_POSIX_S_ISDIR(state.st_mode))
725 PRINT_ERROR(
"Directory specified for article postprocessor");
729 rv = api_posix_pipe(fd_in);
732 rv = api_posix_pipe(fd_out);
736 pid = api_posix_fork();
740 api_posix_close(fd_out[1]);
741 api_posix_close(fd_in[0]);
742 rv = api_posix_dup2(fd_out[0], API_POSIX_STDIN_FILENO);
745 rv = api_posix_dup2(fd_in[1], API_POSIX_STDOUT_FILENO);
751 api_posix_execl(filter_pathname, filter_pathname,
756 PRINT_ERROR(
"Executing article post processor failed");
757 exit(API_POSIX_EXIT_FAILURE);
761 api_posix_close(fd_out[0]);
762 api_posix_close(fd_in[1]);
764 rv = api_posix_fcntl(fd_out[1], API_POSIX_F_SETFL,
765 API_POSIX_O_NONBLOCK);
768 rv = api_posix_fcntl(fd_in[0], API_POSIX_F_SETFL,
769 API_POSIX_O_NONBLOCK);
778 while(!finished && !error)
783 rv3 = api_posix_write(fd_out[1],
788 if(API_POSIX_EINTR == api_posix_errno)
792 if(API_POSIX_EAGAIN != api_posix_errno)
798 else { i += (size_t) rv3; }
806 api_posix_close(fd_out[1]);
812 if((
size_t) 4096 > blen - bi)
815 if(!blen) { blen = 4096; }
817 p = (
char*) api_posix_realloc(buf, blen);
818 if(NULL == p) { error = 1;
break; }
822 rv3 = api_posix_read(fd_in[0], (
void*) &buf[bi],
826 if(API_POSIX_EINTR == api_posix_errno)
830 if(API_POSIX_EAGAIN != api_posix_errno)
836 else if(0 < rv3) { bi += (size_t) rv3; }
843 "stdout before reading data");
858 rv = api_posix_kill(pid, API_POSIX_SIGTERM);
866 do { rv2 = api_posix_waitpid(pid, &status, 0); }
867 while((api_posix_pid_t) -1 == rv2
868 && API_POSIX_EINTR == api_posix_errno);
885 if(!pushed) { api_posix_close(fd_out[1]); }
886 api_posix_close(fd_in[0]);
895 if(NULL == res) { api_posix_free((
void*) buf); }
916 api_posix_struct_stat state;
923 api_posix_ssize_t rv3;
929 len = strlen(article);
930 if(len && strlen(inews_pathname))
934 printf(
"%s: %sDelegation to external inews: \x22%s\x22\n",
944 if(API_POSIX_S_ISDIR(state.st_mode))
946 PRINT_ERROR(
"Directory specified for external inews");
960 rv = api_posix_pipe(fd_out);
964 pid = api_posix_fork();
968 api_posix_close(fd_out[1]);
969 rv = api_posix_dup2(fd_out[0], API_POSIX_STDIN_FILENO);
975 api_posix_execl(inews_pathname, inews_pathname, (
char*) NULL);
979 exit(API_POSIX_EXIT_FAILURE);
983 api_posix_close(fd_out[0]);
985 rv = api_posix_fcntl(fd_out[1], API_POSIX_F_SETFL,
986 API_POSIX_O_NONBLOCK);
994 while(!pushed && !error)
999 rv3 = api_posix_write(fd_out[1], (
void*) &article[i],
1003 if(API_POSIX_EINTR == api_posix_errno) {
continue; }
1004 if(API_POSIX_EAGAIN != api_posix_errno)
1010 else { i += (size_t) rv3; }
1017 api_posix_close(fd_out[1]);
1026 rv = api_posix_kill(pid, API_POSIX_SIGTERM);
1029 PRINT_ERROR(
"Termination of child process failed (bug)");
1033 do { rv2 = api_posix_waitpid(pid, &status, 0); }
1034 while((api_posix_pid_t) -1 == rv2
1035 && API_POSIX_EINTR == api_posix_errno);
1049 printf(
"%s: %sExternal inews reported successful injection\n",
1054 if(!pushed) { api_posix_close(fd_out[1]); }
1055 api_posix_close(fd_out[0]);
1093 const char scheme_http[] =
"http";
1098 len = strlen(scheme_http);
1101 if(!uri[i]) { res = -2;
break; }
1102 if((
int) scheme_http[i] != tolower((
int) uri[i])) { res = -2;
break; }
1105 if(!res) {
if(
':' != uri[i++]) { res = -2; } }
1108 PRINT_ERROR(
"URI scheme for file download not supported");
1110 if(!res) {
if(
'/' != uri[i++]) { res = -1; } }
1111 if(!res) {
if(
'/' != uri[i++]) { res = -1; } }
1125 if(strcspn(uri,
"\x09\x20'?#") != len) { res = -1; }
1130 PRINT_ERROR(
"URI for file download has invalid format");
1136 printf(
"%s: %sFile download delegation to %s for: %s\n",