Back to index

citadel  8.12
sendcommand.c
Go to the documentation of this file.
00001 /*
00002  * Command-line utility to transmit a server command.
00003  *
00004  * Copyright (c) 1987-2012 by the citadel.org team
00005  *
00006  * This program is open source software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License version 3.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #include <stdlib.h>
00016 #include <unistd.h>
00017 #include <sys/types.h>
00018 #include <sys/wait.h>
00019 #include <string.h>
00020 #include <fcntl.h>
00021 #include <stdio.h>
00022 #include <ctype.h>
00023 #include <signal.h>
00024 #include <errno.h>
00025 #include <limits.h>
00026 #include <sys/socket.h>
00027 #include <sys/un.h>
00028 #include "citadel.h"
00029 #include "include/citadel_dirs.h"
00030 
00031 
00032 
00033 int serv_sock = (-1);
00034 
00035 
00036 int uds_connectsock(char *sockpath)
00037 {
00038        int s;
00039        struct sockaddr_un addr;
00040 
00041        memset(&addr, 0, sizeof(addr));
00042        addr.sun_family = AF_UNIX;
00043        strncpy(addr.sun_path, sockpath, sizeof addr.sun_path);
00044 
00045        s = socket(AF_UNIX, SOCK_STREAM, 0);
00046        if (s < 0) {
00047               fprintf(stderr, "sendcommand: Can't create socket: %s\n", strerror(errno));
00048               exit(3);
00049        }
00050 
00051        if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
00052               fprintf(stderr, "sendcommand: can't connect: %s\n", strerror(errno));
00053               close(s);
00054               exit(3);
00055        }
00056 
00057        return s;
00058 }
00059 
00060 
00061 /*
00062  * input binary data from socket
00063  */
00064 void serv_read(char *buf, int bytes)
00065 {
00066        int len, rlen;
00067 
00068        len = 0;
00069        while (len < bytes) {
00070               rlen = read(serv_sock, &buf[len], bytes - len);
00071               if (rlen < 1) {
00072                      return;
00073               }
00074               len = len + rlen;
00075        }
00076 }
00077 
00078 
00079 /*
00080  * send binary to server
00081  */
00082 void serv_write(char *buf, int nbytes)
00083 {
00084        int bytes_written = 0;
00085        int retval;
00086        while (bytes_written < nbytes) {
00087               retval = write(serv_sock, &buf[bytes_written], nbytes - bytes_written);
00088               if (retval < 1) {
00089                      return;
00090               }
00091               bytes_written = bytes_written + retval;
00092        }
00093 }
00094 
00095 
00096 
00097 /*
00098  * input string from socket - implemented in terms of serv_read()
00099  */
00100 void serv_gets(char *buf)
00101 {
00102        int i;
00103 
00104        /* Read one character at a time.
00105         */
00106        for (i = 0;; i++) {
00107               serv_read(&buf[i], 1);
00108               if (buf[i] == '\n' || i == (SIZ-1))
00109                      break;
00110        }
00111 
00112        /* If we got a long line, discard characters until the newline.
00113         */
00114        if (i == (SIZ-1)) {
00115               while (buf[i] != '\n') {
00116                      serv_read(&buf[i], 1);
00117               }
00118        }
00119 
00120        /* Strip all trailing nonprintables (crlf)
00121         */
00122        buf[i] = 0;
00123 }
00124 
00125 
00126 /*
00127  * send line to server - implemented in terms of serv_write()
00128  */
00129 void serv_puts(char *buf)
00130 {
00131        serv_write(buf, strlen(buf));
00132        serv_write("\n", 1);
00133 }
00134 
00135 
00136 
00137 
00138 /*
00139  * Main loop.  Do things and have fun.
00140  */
00141 int main(int argc, char **argv)
00142 {
00143        int a;
00144        int watchdog = 60;
00145        char buf[SIZ];
00146        int xfermode = 0;
00147        int relh=0;
00148        int home=0;
00149        char relhome[PATH_MAX]="";
00150        char ctdldir[PATH_MAX]=CTDLDIR;
00151 
00152        /* Parse command line */
00153        while ((a = getopt(argc, argv, "h:w:")) != EOF) {
00154               switch (a) {
00155               case 'h':
00156                      relh=optarg[0]!='/';
00157                      if (!relh) {
00158                             strncpy(ctdl_home_directory, optarg, sizeof ctdl_home_directory);
00159                      } else {
00160                             strncpy(relhome, optarg, sizeof relhome);
00161                      }
00162                      home = 1;
00163                      break;
00164               case 'w':
00165                      watchdog = atoi(optarg);
00166               default:
00167                      fprintf(stderr, "sendcommand: usage: sendcommand [-h server_dir] [-w watchdog_timeout]\n");
00168                      return(1);
00169               }
00170        }
00171 
00172        calc_dirs_n_files(relh, home, relhome, ctdldir, 0);
00173 
00174        fprintf(stderr, "sendcommand: started (pid=%d) connecting to Citadel server at %s\n",
00175               (int) getpid(),
00176               file_citadel_admin_socket
00177        );
00178        fflush(stderr);
00179 
00180        alarm(watchdog);
00181        serv_sock = uds_connectsock(file_citadel_admin_socket);
00182 
00183        serv_gets(buf);
00184        fprintf(stderr, "%s\n", buf);
00185 
00186        strcpy(buf, "");
00187        for (a=optind; a<argc; ++a) {
00188               if (a != optind) {
00189                      strcat(buf, " ");
00190               }
00191               strcat(buf, argv[a]);
00192        }
00193 
00194        fprintf(stderr, "%s\n", buf);
00195        serv_puts(buf);
00196        serv_gets(buf);
00197        fprintf(stderr, "%s\n", buf);
00198 
00199        xfermode = buf[0];
00200 
00201        if ((xfermode == '4') || (xfermode == '8')) {           /* send text */
00202               while (fgets(buf, sizeof buf, stdin)) {
00203                      buf[strlen(buf)-1] = 0;
00204                      serv_puts(buf);
00205                      alarm(watchdog);                   /* reset the watchdog timer */
00206               }
00207               serv_puts("000");
00208        }
00209 
00210        if ((xfermode == '1') || (xfermode == '8')) {           /* receive text */
00211               while (serv_gets(buf), strcmp(buf, "000")) {
00212                      printf("%s\n", buf);
00213                      alarm(watchdog);                   /* reset the watchdog timer */
00214               }
00215        }
00216        
00217        if (xfermode == '6') {                                  /* receive binary */
00218               size_t len = atoi(&buf[4]);
00219               size_t bytes_remaining = len;
00220 
00221               while (bytes_remaining > 0) {
00222                      size_t this_block = bytes_remaining;
00223                      if (this_block > SIZ) this_block = SIZ;
00224                      serv_read(buf, this_block);
00225                      fwrite(buf, this_block, 1, stdout);
00226                      bytes_remaining -= this_block;
00227               }
00228        }
00229 
00230        close(serv_sock);
00231        alarm(0);                                        /* cancel the watchdog timer */
00232        fprintf(stderr, "sendcommand: processing ended.\n");
00233        if (xfermode == '5') {
00234               return(1);
00235        }
00236        return(0);
00237 }
00238 
00239 
00240 
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 
00250 
00251