+ /* Now, try application level connection */
+ if (api_exch_init(sock) == -1) {
+ return -1;
+ }
+ if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) {
+ return -1;
+ }
+ while ((i = api_exch_inbyte()) != EXCH_ASSOCIATED) {
+ struct storage_descriptor sd;
+ int passwd_length;
+ char *passwd, *getpass();
+ char buffer[200];
+
+ switch (i) {
+ case EXCH_REJECTED:
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC,
+ sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ sd.length = ntohs(sd.length);
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
+ return -1;
+ }
+ buffer[sd.length] = 0;
+ fprintf(stderr, "%s\n", buffer);
+ if (api_exch_outcommand(EXCH_ASSOCIATE) == -1) {
+ return -1;
+ }
+ break;
+ case EXCH_SEND_AUTH:
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ sd.length = ntohs(sd.length);
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
+ return -1;
+ }
+ buffer[sd.length] = 0;
+ passwd = getpass(buffer); /* Go to terminal */
+ passwd_length = strlen(passwd);
+ if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ sd.length = ntohs(sd.length);
+ if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
+ return -1;
+ }
+ buffer[sd.length] = 0;
+ if (sd.length) {
+ char *ptr;
+
+ ptr = passwd;
+ i = 0;
+ while (*ptr) {
+ *ptr++ ^= buffer[i++];
+ if (i >= sd.length) {
+ i = 0;
+ }
+ }
+ }
+ sd.length = htons(passwd_length);
+ if (api_exch_outcommand(EXCH_AUTH) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
+ return -1;
+ }
+ if (api_exch_outtype(EXCH_TYPE_BYTES, passwd_length, passwd) == -1) {
+ return -1;
+ }
+ break;
+ case -1:
+ return -1;
+ default:
+ fprintf(stderr,
+ "Waiting for connection indicator, received 0x%x.\n", i);
+ break;
+ }
+ }