|
|
1.1 root 1: #include "../chunix/chsys.h"
2: #include "../chunix/chconf.h"
3: #define CHDEFINE
4: #include "../chaos/chaos.h"
5: #undef CHDEFINE
6:
7: /*
8: * Miscellaneous utility routines - notice the CHDEFINE is turned on here
9: * and only here.
10: */
11:
12: /*
13: * Allocate a connection and return it, also allocating a slot in Chconntab
14: */
15: struct connection *
16: allconn()
17: {
18: register struct connection *conn;
19: register struct connection **cptr;
20: static int uniq;
21:
22: if ((conn = connalloc()) == NOCONN) {
23: debug(DCONN|DABNOR,printf("Conn: alloc failed (packet)\n"));
24: Chaos_error = CHNOPKT;
25: return(NOCONN);
26: }
27: for(cptr = &Chconntab[0]; cptr != &Chconntab[CHNCONNS]; cptr++) {
28: if(*cptr != NOCONN) continue;
29: *cptr = conn;
30: clear((char *)conn, sizeof(struct connection));
31: conn->cn_ltidx = cptr - &Chconntab[0];
32: if (++uniq == 0)
33: uniq = 1;
34: conn->cn_luniq = uniq;
35: debug(DCONN,printf("Conn: alloc #%x\n", conn->cn_lidx));
36: return(conn);
37: }
38: ch_free((char *)conn);
39: Chaos_error = CHNOCONN;
40: debug(DCONN|DABNOR,printf("Conn: alloc failed (table)\n"));
41: return(NOCONN);
42: }
43: /*
44: * Make a connection closed with given state, at interrupt time.
45: * Queue the given packet on the input queue for the user.
46: */
47: clsconn(conn, state, pkt)
48: register struct connection *conn;
49: register struct packet *pkt;
50: {
51: freelist(conn->cn_thead);
52: conn->cn_thead = conn->cn_ttail = NOPKT;
53: conn->cn_state = state;
54: debug(DCONN|DABNOR, printf("Conn #%x: CLOSED: state: %d\n",
55: conn->cn_lidx, state));
56: if (pkt != NOPKT) {
57: pkt->pk_next = NOPKT;
58: if (conn->cn_rhead != NOPKT)
59: conn->cn_rtail->pk_next = pkt;
60: else
61: conn->cn_rhead = pkt;
62: conn->cn_rtail = pkt;
63: }
64: NEWSTATE(conn);
65: }
66:
67: /*
68: * Release a connection - freeing all associated storage.
69: * This removes all trace of the connection.
70: * Always called from top level at low priority.
71: */
72: rlsconn(conn)
73: register struct connection *conn;
74: {
75: Chconntab[conn->cn_ltidx] = NOCONN;
76: freelist(conn->cn_routorder);
77: freelist(conn->cn_rhead);
78: freelist(conn->cn_thead);
79: #ifdef CHSTRCODE
80: if (conn->cn_toutput != NOPKT)
81: ch_free((char *)conn->cn_toutput);
82: #endif
83: debug(DCONN,printf("Conn: release #%x\n", conn->cn_lidx));
84: ch_free((char *)conn);
85: }
86: /*
87: * Free a list of packets
88: */
89: freelist(pkt)
90: register struct packet *pkt;
91: {
92: register struct packet *opkt;
93:
94: while ((opkt = pkt) != NOPKT) {
95: pkt = pkt->pk_next;
96: ch_free((char *)opkt);
97: }
98: }
99:
100: /*
101: * Fill a packet with a string, returning packet because it may reallocate
102: * Assumes we are called from interrupt level (high priority).
103: * If the pkt argument is NOPKT then allocate a packet here.
104: * The string is null terminated and may be shorter than "len".
105: */
106: struct packet *
107: pktstr(pkt, str, len)
108: struct packet *pkt;
109: register char *str;
110: register len;
111: {
112: struct packet *npkt;
113: register char *odata;
114:
115: if (pkt == NOPKT || ch_size((char *)pkt) < CHHEADSIZE + len ) {
116: if ((npkt = pkalloc(len, 1)) == NOPKT)
117: return(NOPKT);
118: if (pkt != NOPKT) {
119: pkt->pk_len = 0;
120: movepkt(pkt, npkt);
121: ch_free((char *)pkt);
122: }
123: pkt = npkt;
124: }
125: odata = pkt->pk_cdata;
126: pkt->pk_len = len;
127: if (len) do *odata++ = *str; while (*str++ && --len);
128: return(pkt);
129: }
130: /*
131: * Zero out n bytes - this should be somewhere else, probably provided
132: * by the implementation.
133: */
134: clear(ptr, n)
135: register char *ptr;
136: register int n;
137: {
138: if (n)
139: do {
140: *ptr++ = 0;
141: } while (--n);
142: }
143: /*
144: * Move contents of opkt to npkt
145: */
146: movepkt(opkt, npkt)
147: struct packet *opkt, *npkt;
148: {
149: register short *nptr, *optr, n;
150:
151: n = (CHHEADSIZE + opkt->pk_len + sizeof(short) - 1) / sizeof(short);
152: nptr = (short *)npkt;
153: optr = (short *)opkt;
154: do {
155: *nptr++ = *optr++;
156: } while (--n);
157: }
158: /*
159: * Move n bytes - should probably be elsewhere.
160: * Can we replace this with a movc3?
161: */
162: chmove(from, to, n)
163: register char *from, *to;
164: register int n;
165: {
166: if (n)
167: do *to++ = *from++; while(--n);
168: }
169: /*
170: * Set packet fields from connection, many routines count on the fact that
171: * this routine clears pk_type and pk_next
172: */
173: setpkt(conn, pkt)
174: register struct connection *conn;
175: register struct packet *pkt;
176: {
177: pkt->pk_daddr = conn->cn_faddr;
178: pkt->pk_didx = conn->cn_fidx;
179: pkt->pk_saddr = Chmyaddr;
180: pkt->pk_sidx = conn->cn_lidx;
181: pkt->pk_type = 0;
182: pkt->pk_next = NOPKT;
183: pkt->pk_fc = 0;
184: }
185: #ifdef pdp11
186: /*
187: * Swap the word of n longs.
188: */
189: swaplong(lp, n)
190: register short *lp;
191: register int n;
192: {
193: register short temp;
194:
195: if (n)
196: do {
197: temp = *lp++;
198: lp[-1] = *lp;
199: *lp++ = temp;
200: } while (--n);
201: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.