Annotation of researchv10no/cmd/asd++/domach.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  *     domach - install a file on a (single) machine.
                      3:  *
                      4:  *     Output from the installation is appended to the
                      5:  *     "output" list.  The result is a null string on success,
                      6:  *     non-null on failure.
                      7:  */
                      8: 
                      9: #include "decl.h"
                     10: #include <signal.h>
                     11: #include <errno.h>
                     12: #include <ipc.h>
                     13: 
                     14: static const int bufsize = 4096;
                     15: static const int timeout = 60*10;
                     16: 
                     17: static void
                     18: alarmcatch (int)
                     19: {
                     20:        signal (SIGALRM, alarmcatch);
                     21: }
                     22: 
                     23: static void
                     24: pipecatch (int)
                     25: {
                     26:        signal (SIGPIPE, pipecatch);
                     27: }
                     28: 
                     29: static int
                     30: twrite (int fd, char* buf, int n)
                     31: {
                     32:        SIG_TYP pipesave = signal (SIGPIPE, pipecatch);
                     33:        alarm (timeout);
                     34:        int r = write (fd, buf, n);
                     35:        alarm (0);
                     36:        signal (SIGPIPE, pipesave);
                     37:        return r;
                     38: }
                     39: 
                     40: static int
                     41: tread (int fd, char* buf, int n)
                     42: {
                     43:        alarm (timeout);
                     44:        int r = read (fd, buf, n);
                     45:        alarm (0);
                     46:        return r;
                     47: }
                     48: 
                     49: String
                     50: domach (String machname, Path file, String_list& output)
                     51: {
                     52:        checksum cs;
                     53:        signal (SIGALRM, alarmcatch);
                     54: 
                     55:        /* Open the input file */
                     56:        int infd = open (file, 0);
                     57:        if (infd < 0) {
                     58:                output += "cannot open package";
                     59:                return "";
                     60:        }
                     61: 
                     62:        /* Establish a connection to the remote machine */
                     63:        errno = 0;
                     64:        int remfd = ipcopen(ipcpath(charstr(machname),"dk","asd"), "heavy delim");
                     65:        if (remfd < 0) {
                     66:                close (infd);
                     67: 
                     68:                switch (errno) {
                     69: 
                     70:                /* permanent errors */
                     71:                case ENOENT:            /* illegal destination name */
                     72:                case EACCES:            /* permission denied */
                     73:                        if (errstr)
                     74:                                output += errstr;
                     75:                        return "";
                     76: 
                     77:                default:
                     78:                        if (errstr)
                     79:                                return errstr;
                     80:                        return "cannot connect";
                     81: 
                     82:                case 0:
                     83:                        ;
                     84:                }
                     85:        }
                     86: 
                     87:        char buf[bufsize];
                     88:        int n, w;
                     89: 
                     90:        /* verify that we are talking to a dkinstall process */
                     91:        n = tread (remfd, buf, bufsize);
                     92:        if (n != 4 || strncmp (buf, "asd\n", 4) != 0) {
                     93:                close (infd);
                     94:                close (remfd);
                     95:                output += "cannot ship to this destination";
                     96:                output += dec(n) + (": " + String(buf,n>0?n-1:0));
                     97:                return "";
                     98:        }
                     99: 
                    100:        /* copy the file data to the remote system */
                    101:        while ((n = read (infd, buf, bufsize)) > 0) {
                    102:                cs.combine (buf, n);
                    103:                w = twrite (remfd, buf, n);
                    104:                if (w != n) {
                    105:                        close (infd);
                    106:                        close (remfd);
                    107:                        return "error while writing to remote";
                    108:                }
                    109:        }
                    110: 
                    111:        close (infd);
                    112:        if (n != 0) {
                    113:                close (remfd);
                    114:                return "input error";
                    115:        }
                    116: 
                    117:        /* Indicate end of file */
                    118:        if (twrite (remfd, "", 0) != 0) {
                    119:                close (remfd);
                    120:                return "cannot write eof";
                    121:        }
                    122: 
                    123:        /* Send the checksum */
                    124:        SIG_TYP pipesave = signal (SIGPIPE, pipecatch);
                    125:        alarm (timeout);
                    126:        n = write (remfd, cs);
                    127:        alarm (0);
                    128:        signal (SIGPIPE, pipesave);
                    129:        if (n != cksize) {
                    130:                close (remfd);
                    131:                return "cannot send checksum";
                    132:        }
                    133: 
                    134:        /*
                    135:         * Read the acknowledgment.  If the acknowledgment begins
                    136:         * with a null record, it indicates success or permanent
                    137:         * failure.  Otherwise it is a temporary failure.
                    138:         */
                    139: 
                    140:        if ((n = tread (remfd, buf, bufsize)) != 0) {
                    141:                close (remfd);
                    142:                if (n < 0)
                    143:                        return "error reading ack";
                    144:                String msg (buf, n);
                    145:                if ((n = msg.strchr('\n')) >= 0)
                    146:                        msg = msg (0, n);
                    147:                return msg;
                    148:        }
                    149: 
                    150:        /*
                    151:         * We got here only if we saw a null record from the remote.
                    152:         *
                    153:         * Read and handle the stuff coming in from the remote.
                    154:         * Discard leading null lines, which are probably
                    155:         * keep-alive messages but are good to remove even
                    156:         * even if they aren't.
                    157:         */
                    158:        String remnant;
                    159:        int gotdata = 0;
                    160:        while ((n = tread (remfd, buf, bufsize)) > 0) {
                    161:                register char *p = buf;
                    162:                char *lastp = p, *lim = p + n;
                    163:                while (p < lim) {
                    164:                        if (*p == '\n') {
                    165:                                String line = remnant +
                    166:                                        String (lastp, p - lastp);
                    167:                                if (gotdata || line.length() != 0) {
                    168:                                        output += line;
                    169:                                        gotdata = 1;
                    170:                                }
                    171:                                remnant = "";
                    172:                                lastp = p + 1;
                    173:                        }
                    174:                        p++;
                    175:                }
                    176:                remnant += String (lastp, p - lastp);
                    177:        }
                    178: 
                    179:        if (remnant.length() != 0)
                    180:                output += remnant;
                    181: 
                    182:        /* remove trailing normal status message */
                    183:        String s;
                    184:        if (output.lastX (s)) {
                    185:                if (s == "return code 0")
                    186:                        output.unput();
                    187:        }
                    188: 
                    189:        close (remfd);
                    190: 
                    191:        if (n < 0)
                    192:                return "error reading return status";
                    193: 
                    194:        return "";
                    195: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.