"Fossies" - the Fresh Open Source Software Archive

Member "citadel/sendcommand.c" (5 Jun 2021, 4606 Bytes) of package /linux/www/citadel.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sendcommand.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Command-line utility to transmit a server command.
    3  *
    4  * Copyright (c) 1987-2021 by the citadel.org team
    5  *
    6  * This program is open source software; you can redistribute it and/or modify
    7  * it under the terms of the GNU General Public License version 3.
    8  *
    9  * This program is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  */
   14 
   15 #include <stdio.h>
   16 #include <stdlib.h>
   17 #include <unistd.h>
   18 #include <sys/types.h>
   19 #include <sys/wait.h>
   20 #include <string.h>
   21 #include <fcntl.h>
   22 #include <stdio.h>
   23 #include <ctype.h>
   24 #include <signal.h>
   25 #include <errno.h>
   26 #include <limits.h>
   27 #include <sys/socket.h>
   28 #include <sys/un.h>
   29 #include "citadel.h"
   30 #include "citadel_dirs.h"
   31 #include <libcitadel.h>
   32 
   33 int serv_sock = (-1);
   34 
   35 int uds_connectsock(char *sockpath) {
   36     int s;
   37     struct sockaddr_un addr;
   38 
   39     memset(&addr, 0, sizeof(addr));
   40     addr.sun_family = AF_UNIX;
   41     strncpy(addr.sun_path, sockpath, sizeof addr.sun_path);
   42 
   43     s = socket(AF_UNIX, SOCK_STREAM, 0);
   44     if (s < 0) {
   45         fprintf(stderr, "sendcommand: Can't create socket: %s\n", strerror(errno));
   46         exit(3);
   47     }
   48 
   49     if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
   50         fprintf(stderr, "sendcommand: can't connect: %s\n", strerror(errno));
   51         close(s);
   52         exit(3);
   53     }
   54 
   55     return s;
   56 }
   57 
   58 
   59 /*
   60  * input binary data from socket
   61  */
   62 void serv_read(char *buf, int bytes) {
   63     int len, rlen;
   64 
   65     len = 0;
   66     while (len < bytes) {
   67         rlen = read(serv_sock, &buf[len], bytes - len);
   68         if (rlen < 1) {
   69             return;
   70         }
   71         len = len + rlen;
   72     }
   73 }
   74 
   75 
   76 /*
   77  * send binary to server
   78  */
   79 void serv_write(char *buf, int nbytes) {
   80     int bytes_written = 0;
   81     int retval;
   82     while (bytes_written < nbytes) {
   83         retval = write(serv_sock, &buf[bytes_written], nbytes - bytes_written);
   84         if (retval < 1) {
   85             return;
   86         }
   87         bytes_written = bytes_written + retval;
   88     }
   89 }
   90 
   91 
   92 /*
   93  * input string from socket - implemented in terms of serv_read()
   94  */
   95 void serv_gets(char *buf) {
   96     int i;
   97 
   98     /* Read one character at a time.
   99      */
  100     for (i = 0;; i++) {
  101         serv_read(&buf[i], 1);
  102         if (buf[i] == '\n' || i == (SIZ-1))
  103             break;
  104     }
  105 
  106     /* If we got a long line, discard characters until the newline.
  107      */
  108     if (i == (SIZ-1)) {
  109         while (buf[i] != '\n') {
  110             serv_read(&buf[i], 1);
  111         }
  112     }
  113 
  114     /* Strip all trailing nonprintables (crlf)
  115      */
  116     buf[i] = 0;
  117 }
  118 
  119 
  120 /*
  121  * send line to server - implemented in terms of serv_write()
  122  */
  123 void serv_puts(char *buf) {
  124     serv_write(buf, strlen(buf));
  125     serv_write("\n", 1);
  126 }
  127 
  128 
  129 /*
  130  * Main loop.  Do things and have fun.
  131  */
  132 int main(int argc, char **argv) {
  133     int a;
  134     int watchdog = 60;
  135     char buf[SIZ];
  136     int xfermode = 0;
  137     char ctdldir[PATH_MAX]=CTDLDIR;
  138 
  139     /* Parse command line */
  140     while ((a = getopt(argc, argv, "h:w:")) != EOF) {
  141         switch (a) {
  142         case 'h':
  143             strncpy(ctdldir, optarg, sizeof ctdldir);
  144             break;
  145         case 'w':
  146             watchdog = atoi(optarg);
  147             break;
  148         default:
  149             fprintf(stderr, "sendcommand: usage: sendcommand [-h server_dir] [-w watchdog_timeout]\n");
  150             return(1);
  151         }
  152     }
  153 
  154     fprintf(stderr, "sendcommand: started (pid=%d) connecting to Citadel server with data directory %s\n",
  155         (int) getpid(),
  156         ctdldir
  157     );
  158     fflush(stderr);
  159 
  160     if (chdir(ctdldir) != 0) {
  161         fprintf(stderr, "sendcommand: %s: %s\n", ctdldir, strerror(errno));
  162         exit(errno);
  163     }
  164 
  165     alarm(watchdog);
  166     serv_sock = uds_connectsock(file_citadel_admin_socket);
  167     serv_gets(buf);
  168     fprintf(stderr, "%s\n", buf);
  169 
  170     strcpy(buf, "");
  171     for (a=optind; a<argc; ++a) {
  172         if (a != optind) {
  173             strcat(buf, " ");
  174         }
  175         strcat(buf, argv[a]);
  176     }
  177 
  178     fprintf(stderr, "%s\n", buf);
  179     serv_puts(buf);
  180     serv_gets(buf);
  181     fprintf(stderr, "%s\n", buf);
  182 
  183     xfermode = buf[0];
  184 
  185     if ((xfermode == '4') || (xfermode == '8')) {       /* send text */
  186         while (fgets(buf, sizeof buf, stdin) > 0) {
  187             if (buf[strlen(buf)-1] == '\n') {
  188                 buf[strlen(buf)-1] = 0;
  189             }
  190             serv_puts(buf);
  191         }
  192         serv_puts("000");
  193     }
  194 
  195     if ((xfermode == '1') || (xfermode == '8')) {       /* receive text */
  196         while(serv_gets(buf), strcmp(buf, "000")) {
  197             printf("%s\n", buf);
  198         }
  199     }
  200     
  201     if (xfermode == '6') {                  /* receive binary */
  202         size_t len = atoi(&buf[4]);
  203         size_t bytes_remaining = len;
  204 
  205         while (bytes_remaining > 0) {
  206             size_t this_block = bytes_remaining;
  207             if (this_block > SIZ) this_block = SIZ;
  208             serv_read(buf, this_block);
  209             fwrite(buf, this_block, 1, stdout);
  210             bytes_remaining -= this_block;
  211         }
  212     }
  213 
  214     close(serv_sock);
  215     alarm(0);                       /* cancel the watchdog timer */
  216 
  217     fprintf(stderr, "sendcommand: processing ended.\n");
  218     if (xfermode == '5') {
  219         return(1);
  220     }
  221     return(0);
  222 }