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

unix.superglobalmegacorp.com

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