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*) posix_malloc(++len);
89 if(NULL != res) { strncpy(res, s, len); }
94 printf(
"%s: %sApostrophe replacement U+0027 => U+2019 done\n",
98 if(0x27 == (
int) s[i++])
100 if(POSIX_SIZE_MAX - len < (
size_t) 2)
102 PRINT_ERROR(
"Aborted before \x27size_t\x27 overflow");
110 res = (
char*) 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*) 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(POSIX_SIZE_MAX - len_tmp < x) { error = 1; }
280 if(POSIX_SIZE_MAX - len < len_tmp + x) { error = 1; }
284 tmp = (
char*) 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(POSIX_SIZE_MAX - len_tmp < x) { error = 1; }
305 if(POSIX_SIZE_MAX - len < len_tmp + x) { error = 1; }
309 tmp = (
char*) 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(POSIX_SIZE_MAX - len_tmp < (
size_t) 3) { error = 1; }
329 if(POSIX_SIZE_MAX - len < len_tmp + (
size_t) 3) { error = 1; }
333 len += len_tmp + (size_t) 3;
334 tmp = (
char*) posix_realloc(buf, len);
335 if(NULL == tmp) { error = 1; }
339 strcat(buf,
" \x27");
340 strncat(buf, recipient, len_tmp);
351 fs = posix_popen(buf,
"w");
352 if(NULL != fs) { res = posix_pclose(fs); }
356 posix_free((
void*) body);
357 posix_free((
void*) subject);
358 posix_free((
void*) recipient);
359 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*) posix_malloc(++len);
444 if(NULL == buf) { error = 1; }
445 else { strncpy(buf, command, len); }
451 len_tmp = strlen(uri);
452 if(POSIX_SIZE_MAX - len_tmp < (
size_t) 5) { error = 1; }
455 if(POSIX_SIZE_MAX - len < len_tmp + (
size_t) 5) { error = 1; }
459 len += len_tmp + (size_t) 5;
460 tmp = (
char*) posix_realloc(buf, len);
461 if(NULL == tmp) { error = 1; }
465 strcat(buf,
" \x27");
466 strncat(buf, uri, len_tmp);
467 strcat(buf,
"\x27 &");
476 fs = posix_popen(buf,
"w");
477 if(NULL != fs) { res = posix_pclose(fs); }
481 posix_free((
void*) uri);
482 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",
541 if(!rv) { posix_execlp(epn, epn, tfpn, (
char*) NULL); }
543 exit(POSIX_EXIT_FAILURE);
552 *(va_arg(ap,
long int*)) = (
long int) pid;
558 do { rv2 = posix_waitpid(pid, &status, 0); }
559 while((posix_pid_t) -1 == rv2 && POSIX_EINTR == posix_errno);
567 if(!status) { res = 0; }
571 if(!POSIX_WIFEXITED(status)) { res = POSIX_EXIT_FAILURE; }
572 else { res = POSIX_WEXITSTATUS(status); }
606 posix_pid_t pid = (posix_pid_t) editor_pid;
611 do { rv2 = posix_waitpid(pid, &status, POSIX_WNOHANG); }
612 while((posix_pid_t) -1 == rv2 && POSIX_EINTR == posix_errno);
622 if(!status) { res = 0; }
626 if(!POSIX_WIFEXITED(status)) { res = POSIX_EXIT_FAILURE; }
627 else { res = POSIX_WEXITSTATUS(status); }
651 posix_kill((posix_pid_t) editor_pid, POSIX_SIGTERM);
684 const char* res = article;
687 struct_posix_stat state;
695 size_t len = strlen(article);
704 if(POSIX_SIZE_MAX != len && strlen(filter_pathname))
709 printf(
"%s: %sArticle post processor pathname: \x22%s\x22\n",
719 if(POSIX_S_ISDIR(state.st_mode))
721 PRINT_ERROR(
"Directory specified for article postprocessor");
725 rv = posix_pipe(fd_in);
728 rv = posix_pipe(fd_out);
736 posix_close(fd_out[1]);
737 posix_close(fd_in[0]);
738 rv = posix_dup2(fd_out[0], POSIX_STDIN_FILENO);
741 rv = posix_dup2(fd_in[1], POSIX_STDOUT_FILENO);
747 posix_execl(filter_pathname, filter_pathname,
752 PRINT_ERROR(
"Executing article post processor failed");
753 exit(POSIX_EXIT_FAILURE);
757 posix_close(fd_out[0]);
758 posix_close(fd_in[1]);
760 rv = posix_fcntl(fd_out[1], POSIX_F_SETFL,
764 rv = posix_fcntl(fd_in[0], POSIX_F_SETFL,
774 while(!finished && !error)
779 rv3 = posix_write(fd_out[1], (
void*) &article[i],
783 if(POSIX_EINTR == posix_errno) {
continue; }
784 if(POSIX_EAGAIN != posix_errno)
790 else { i += (size_t) rv3; }
798 posix_close(fd_out[1]);
804 if((
size_t) 4096 > blen - bi)
807 if(!blen) { blen = 4096; }
809 p = (
char*) posix_realloc(buf, blen);
810 if(NULL == p) { error = 1;
break; }
814 rv3 = posix_read(fd_in[0], (
void*) &buf[bi],
818 if(POSIX_EINTR == posix_errno) {
continue; }
819 if(POSIX_EAGAIN != posix_errno) { error = 1; }
822 else if(0 < rv3) { bi += (size_t) rv3; }
829 "stdout before reading data");
844 rv = posix_kill(pid, POSIX_SIGTERM);
852 do { rv2 = posix_waitpid(pid, &status, 0); }
853 while((posix_pid_t) -1 == rv2
854 && POSIX_EINTR == posix_errno);
871 if(!pushed) { posix_close(fd_out[1]); }
872 posix_close(fd_in[0]);
881 if(NULL == res) { posix_free((
void*) buf); }
902 struct_posix_stat state;
915 len = strlen(article);
916 if(len && strlen(inews_pathname))
920 printf(
"%s: %sDelegation to external inews: \x22%s\x22\n",
930 if(POSIX_S_ISDIR(state.st_mode))
932 PRINT_ERROR(
"Directory specified for external inews");
946 rv = posix_pipe(fd_out);
954 posix_close(fd_out[1]);
955 rv = posix_dup2(fd_out[0], POSIX_STDIN_FILENO);
961 posix_execl(inews_pathname, inews_pathname, (
char*) NULL);
965 exit(POSIX_EXIT_FAILURE);
969 posix_close(fd_out[0]);
971 rv = posix_fcntl(fd_out[1], POSIX_F_SETFL, POSIX_O_NONBLOCK);
979 while(!pushed && !error)
984 rv3 = posix_write(fd_out[1], (
void*) &article[i], len - i);
987 if(POSIX_EINTR == posix_errno) {
continue; }
988 if(POSIX_EAGAIN != posix_errno)
994 else { i += (size_t) rv3; }
1001 posix_close(fd_out[1]);
1010 rv = posix_kill(pid, POSIX_SIGTERM);
1013 PRINT_ERROR(
"Termination of child process failed (bug)");
1017 do { rv2 = posix_waitpid(pid, &status, 0); }
1018 while((posix_pid_t) -1 == rv2 && POSIX_EINTR == posix_errno);
1032 printf(
"%s: %sExternal inews reported successful injection\n",
1037 if(!pushed) { posix_close(fd_out[1]); }
1038 posix_close(fd_out[0]);
1076 const char scheme_http[] =
"http";
1081 len = strlen(scheme_http);
1084 if(!uri[i]) { res = -2;
break; }
1085 if((
int) scheme_http[i] != tolower((
int) uri[i])) { res = -2;
break; }
1088 if(!res) {
if(
':' != uri[i++]) { res = -2; } }
1091 PRINT_ERROR(
"URI scheme for file download not supported");
1093 if(!res) {
if(
'/' != uri[i++]) { res = -1; } }
1094 if(!res) {
if(
'/' != uri[i++]) { res = -1; } }
1108 if(strcspn(uri,
"\x09\x20'?#") != len) { res = -1; }
1113 PRINT_ERROR(
"URI for file download has invalid format");
1119 printf(
"%s: %sFile download delegation to %s for: %s\n",