Mercurial > hg > nnchat
comparison nnchat.c @ 268:d04ea4395e9e
Move username and password prompting into the Curses interface, also move Curses initialization to earlier phase.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Fri, 03 Jun 2011 12:48:46 +0300 |
parents | 5175ed15ffa4 |
children | 4d106ad65f26 |
comparison
equal
deleted
inserted
replaced
267:5175ed15ffa4 | 268:d04ea4395e9e |
---|---|
342 } | 342 } |
343 | 343 |
344 return 0; | 344 return 0; |
345 } | 345 } |
346 | 346 |
347 | 347 enum { |
348 void printMsgV(BOOL addStamp, BOOL logOnly, const char *fmt, va_list ap) | 348 LOG_FILE = 1, |
349 LOG_WINDOW = 2, | |
350 LOG_STAMP = 4 | |
351 }; | |
352 | |
353 void printMsgV(int flags, const char *fmt, va_list ap) | |
349 { | 354 { |
350 char tmpStr[128], buf[8192]; | 355 char tmpStr[128], buf[8192]; |
351 | 356 |
352 getTimeStamp(tmpStr, sizeof(tmpStr), "½17½[½11½%H:%M:%S½17½]½0½ "); | 357 getTimeStamp(tmpStr, sizeof(tmpStr), "½17½[½11½%H:%M:%S½17½]½0½ "); |
353 | 358 |
354 vsnprintf(buf, sizeof(buf), fmt, ap); | 359 vsnprintf(buf, sizeof(buf), fmt, ap); |
355 | 360 |
356 if (optLogFile) { | 361 if (optLogFile && (flags & LOG_FILE)) { |
357 if (addStamp) printFile(optLogFile, tmpStr); | 362 if (flags & LOG_STAMP) printFile(optLogFile, tmpStr); |
358 printFile(optLogFile, buf); | 363 printFile(optLogFile, buf); |
359 fflush(optLogFile); | 364 fflush(optLogFile); |
360 } | 365 } |
361 | 366 |
362 if (!optDaemon && !logOnly) { | 367 if (!optDaemon && (flags & LOG_WINDOW)) { |
363 if (addStamp) printWin(mainWin, tmpStr); | 368 if (flags & LOG_STAMP) printWin(mainWin, tmpStr); |
364 printWin(mainWin, buf); | 369 printWin(mainWin, buf); |
365 wrefresh(mainWin); | 370 wrefresh(mainWin); |
366 } | 371 } |
367 } | 372 } |
368 | 373 |
369 void printMsg(const char *fmt, ...) | 374 void printMsg(const char *fmt, ...) |
370 { | 375 { |
371 va_list ap; | 376 va_list ap; |
372 | 377 |
373 va_start(ap, fmt); | 378 va_start(ap, fmt); |
374 printMsgV(TRUE, FALSE, fmt, ap); | 379 printMsgV(LOG_STAMP | LOG_WINDOW | LOG_FILE, fmt, ap); |
375 va_end(ap); | 380 va_end(ap); |
376 } | 381 } |
377 | 382 |
378 void printMsgC(const char *fmt, ...) | 383 void printMsgC(const char *fmt, ...) |
379 { | 384 { |
380 va_list ap; | 385 va_list ap; |
381 | 386 |
382 va_start(ap, fmt); | 387 va_start(ap, fmt); |
383 printMsgV(FALSE, FALSE, fmt, ap); | 388 printMsgV(LOG_WINDOW | LOG_FILE, fmt, ap); |
384 va_end(ap); | 389 va_end(ap); |
385 } | 390 } |
386 | 391 |
387 void printMsgQ(BOOL logOnly, const char *fmt, ...) | 392 void printMsgQ(BOOL logOnly, const char *fmt, ...) |
388 { | 393 { |
389 va_list ap; | 394 va_list ap; |
390 | 395 |
391 va_start(ap, fmt); | 396 va_start(ap, fmt); |
392 printMsgV(TRUE, logOnly, fmt, ap); | 397 printMsgV(logOnly ? (LOG_STAMP | LOG_FILE) : (LOG_STAMP | LOG_WINDOW | LOG_FILE), fmt, ap); |
393 va_end(ap); | 398 va_end(ap); |
394 } | 399 } |
395 | 400 |
396 | 401 |
397 char *errorMessages = NULL; | 402 char *errorMessages = NULL; |
400 { | 405 { |
401 char *tmp; | 406 char *tmp; |
402 va_list ap2; | 407 va_list ap2; |
403 | 408 |
404 va_copy(ap2, ap); | 409 va_copy(ap2, ap); |
405 printMsgV(TRUE, FALSE, fmt, ap); | 410 printMsgV(LOG_STAMP | LOG_WINDOW | LOG_FILE, fmt, ap); |
406 | 411 |
407 tmp = th_strdup_vprintf(fmt, ap2); | 412 tmp = th_strdup_vprintf(fmt, ap2); |
408 | 413 |
409 if (errorMessages != NULL) { | 414 if (errorMessages != NULL) { |
410 char *tmp2 = th_strdup_printf("%s%s", errorMessages, tmp); | 415 char *tmp2 = th_strdup_printf("%s%s", errorMessages, tmp); |
431 } | 436 } |
432 | 437 |
433 void messageFunc(struct _nn_conn_t *conn, const char *fmt, va_list ap) | 438 void messageFunc(struct _nn_conn_t *conn, const char *fmt, va_list ap) |
434 { | 439 { |
435 (void) conn; | 440 (void) conn; |
436 printMsgV(TRUE, FALSE, fmt, ap); | 441 printMsgV(LOG_STAMP | LOG_WINDOW | LOG_FILE, fmt, ap); |
437 } | 442 } |
438 | 443 |
439 | 444 |
440 BOOL checkIgnoreList(const char *name) | 445 BOOL checkIgnoreList(const char *name) |
441 { | 446 { |
1022 fclose(optLogFile); | 1027 fclose(optLogFile); |
1023 optLogFile = NULL; | 1028 optLogFile = NULL; |
1024 } | 1029 } |
1025 } | 1030 } |
1026 | 1031 |
1027 char *promptRequester(const char *info, BOOL allowEmpty) | 1032 char *promptRequester(WINDOW *win, const char *info, BOOL allowEmpty) |
1028 { | 1033 { |
1029 char tmpBuf[512], *ptr; | 1034 char tmpBuf[512], *ptr; |
1030 ssize_t pos; | 1035 ssize_t pos; |
1031 | 1036 |
1032 fputs(info, stdout); | 1037 waddstr(win, info); |
1033 fgets(tmpBuf, sizeof(tmpBuf), stdin); | 1038 wgetnstr(win, tmpBuf, sizeof(tmpBuf) - 1); |
1034 | 1039 |
1035 for (pos = strlen(tmpBuf) - 1; pos > 0 && (tmpBuf[pos] == '\n' || tmpBuf[pos] == '\r' || th_isspace(tmpBuf[pos])); pos--) | 1040 for (pos = strlen(tmpBuf) - 1; pos > 0 && (tmpBuf[pos] == '\n' || tmpBuf[pos] == '\r' || th_isspace(tmpBuf[pos])); pos--) |
1036 tmpBuf[pos] = 0; | 1041 tmpBuf[pos] = 0; |
1037 | 1042 |
1038 ptr = trimLeft(tmpBuf); | 1043 ptr = trimLeft(tmpBuf); |
1139 if (optUserNameCmd != NULL) { | 1144 if (optUserNameCmd != NULL) { |
1140 optUserName = optUserNameCmd; | 1145 optUserName = optUserNameCmd; |
1141 optPassword = optPasswordCmd; | 1146 optPassword = optPasswordCmd; |
1142 } | 1147 } |
1143 | 1148 |
1144 /* Check if we have username and password */ | |
1145 if (optUserName == NULL || optPassword == NULL) { | |
1146 printf("\nYou can avoid this prompt by issuing '/save' after logging in.\n\n"); | |
1147 optUserName = promptRequester("NN username: ", FALSE); | |
1148 optPassword = promptRequester("NN password: ", TRUE); | |
1149 if (optUserName == NULL || optPassword == NULL) { | |
1150 THERR("User/pass not specified, get some --help\n"); | |
1151 return -1; | |
1152 } | |
1153 } | |
1154 | |
1155 if (!argsOK) | 1149 if (!argsOK) |
1156 return -2; | 1150 return -2; |
1157 | 1151 |
1158 /* Allocate userhash */ | 1152 /* Allocate userhash */ |
1159 if ((nnUsers = nn_userhash_new()) == NULL) { | 1153 if ((nnUsers = nn_userhash_new()) == NULL) { |
1174 THERR("Could not initialize network subsystem.\n"); | 1168 THERR("Could not initialize network subsystem.\n"); |
1175 goto err_exit; | 1169 goto err_exit; |
1176 } else | 1170 } else |
1177 networkInit = TRUE; | 1171 networkInit = TRUE; |
1178 | 1172 |
1179 /* Okay ... */ | |
1180 THMSG(1, "Trying to resolve host '%s' ...\n", optServer); | |
1181 tmpHost = gethostbyname(optServer); | |
1182 if (tmpHost == NULL) { | |
1183 THERR("Could not resolve hostname: %s.\n", strerror(h_errno)); | |
1184 goto err_exit; | |
1185 } | |
1186 THMSG(2, "True hostname: %s\n", tmpHost->h_name); | |
1187 | |
1188 /* To emulate the official client, we first make a request for | |
1189 * policy file, even though we don't use it for anything... | |
1190 */ | |
1191 conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, 843); | |
1192 if (!nn_conn_check(conn)) { | |
1193 THERR("Policy file request connection setup failed!\n"); | |
1194 goto err_exit; | |
1195 } | |
1196 | |
1197 tmpStr = "<policy-file-request/>"; | |
1198 if (nn_conn_send_buf(conn, tmpStr, strlen(tmpStr) + 1) == FALSE) { | |
1199 THERR("Failed to send policy file request.\n"); | |
1200 goto err_exit; | |
1201 } else { | |
1202 int cres = nn_conn_pull(conn); | |
1203 if (cres == 0) { | |
1204 THMSG(2, "Probe got: %s\n", conn->buf); | |
1205 } else { | |
1206 THMSG(2, "Could not get policy probe.\n"); | |
1207 } | |
1208 } | |
1209 nn_conn_close(conn); | |
1210 | |
1211 /* Okay, now do the proper connection ... */ | |
1212 conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, optPort); | |
1213 if (!nn_conn_check(conn)) { | |
1214 THERR("Main connection setup failed!\n"); | |
1215 goto err_exit; | |
1216 } | |
1217 | |
1218 conn->errfunc = errorFunc; | |
1219 conn->msgfunc = messageFunc; | |
1220 | |
1221 THMSG(1, "Connected, logging in as '%s', site '%s'.\n", optUserName, optSite); | |
1222 optUserNameEnc = nn_dblencode_str(optUserName); | |
1223 tmpStr = nn_dblencode_str(optSite); | |
1224 nn_conn_send_msg(conn, optUserNameEnc, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); | |
1225 th_free(tmpStr); | |
1226 | |
1227 /* Initialize NCurses */ | 1173 /* Initialize NCurses */ |
1228 if (!optDaemon) { | 1174 if (!optDaemon) { |
1229 if (LINES < 0 || LINES > 1000) LINES = 24; | 1175 if (LINES < 0 || LINES > 1000) LINES = 24; |
1230 if (COLS < 0 || COLS > 1000) COLS = 80; | 1176 if (COLS < 0 || COLS > 1000) COLS = 80; |
1231 initscr(); | 1177 initscr(); |
1232 raw(); | 1178 raw(); |
1233 keypad(stdscr, TRUE); | 1179 keypad(stdscr, TRUE); |
1234 noecho(); | 1180 echo(); |
1235 meta(stdscr, TRUE); | 1181 meta(stdscr, TRUE); |
1236 timeout(SET_DELAY); | 1182 timeout(SET_DELAY); |
1237 curVis = curs_set(0); | 1183 curVis = curs_set(1); |
1238 | 1184 |
1239 if (has_colors()) { | 1185 if (has_colors()) { |
1240 start_color(); | 1186 start_color(); |
1241 | 1187 |
1242 init_pair( 1, COLOR_RED, COLOR_BLACK); | 1188 init_pair( 1, COLOR_RED, COLOR_BLACK); |
1260 cursesInit = TRUE; | 1206 cursesInit = TRUE; |
1261 | 1207 |
1262 if (!initializeWindows()) | 1208 if (!initializeWindows()) |
1263 goto err_exit; | 1209 goto err_exit; |
1264 | 1210 |
1211 updateStatus(insertMode); | |
1212 } | |
1213 | |
1214 /* Check if we have username and password */ | |
1215 if (cursesInit && (optUserName == NULL || optPassword == NULL)) { | |
1216 printWin(editWin, "You can avoid this prompt by issuing '/save' after logging in.\n"); | |
1217 optUserName = promptRequester(editWin, "NN username: ", FALSE); | |
1218 optPassword = promptRequester(editWin, "NN password: ", TRUE); | |
1219 } | |
1220 | |
1221 if (optUserName == NULL || optPassword == NULL) { | |
1222 errorMsg("Username and/or password not specified.\n"); | |
1223 goto err_exit; | |
1224 } | |
1225 | |
1226 /* Okay ... */ | |
1227 printMsg("Trying to resolve host '%s' ...\n", optServer); | |
1228 tmpHost = gethostbyname(optServer); | |
1229 if (tmpHost == NULL) { | |
1230 errorMsg("Could not resolve hostname: %s.\n", strerror(h_errno)); | |
1231 goto err_exit; | |
1232 } | |
1233 printMsg("True hostname: %s\n", tmpHost->h_name); | |
1234 | |
1235 /* To emulate the official client, we first make a request for | |
1236 * policy file, even though we don't use it for anything... | |
1237 */ | |
1238 conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, 843); | |
1239 if (!nn_conn_check(conn)) { | |
1240 errorMsg("Policy file request connection setup failed!\n"); | |
1241 goto err_exit; | |
1242 } | |
1243 | |
1244 tmpStr = "<policy-file-request/>"; | |
1245 if (nn_conn_send_buf(conn, tmpStr, strlen(tmpStr) + 1) == FALSE) { | |
1246 errorMsg("Failed to send policy file request.\n"); | |
1247 goto err_exit; | |
1248 } else { | |
1249 int cres = nn_conn_pull(conn); | |
1250 if (cres == 0) { | |
1251 printMsg("Probe got: %s\n", conn->buf); | |
1252 } else { | |
1253 printMsg("Could not get policy probe.\n"); | |
1254 } | |
1255 } | |
1256 nn_conn_close(conn); | |
1257 | |
1258 /* Okay, now do the proper connection ... */ | |
1259 conn = nn_conn_open((struct in_addr *) tmpHost->h_addr, optPort); | |
1260 if (!nn_conn_check(conn)) { | |
1261 errorMsg("Main connection setup failed!\n"); | |
1262 goto err_exit; | |
1263 } | |
1264 | |
1265 conn->errfunc = errorFunc; | |
1266 conn->msgfunc = messageFunc; | |
1267 | |
1268 /* Log in */ | |
1269 optUserNameEnc = nn_dblencode_str(optUserName); | |
1270 tmpStr = nn_dblencode_str(optSite); | |
1271 nn_conn_send_msg(conn, optUserNameEnc, "%%2Flogin%%20%%2Dsite%%20%s%%20%%2Dpassword%%20%s", tmpStr, optPassword); | |
1272 th_free(tmpStr); | |
1273 | |
1274 /* Initialize random numbers */ | |
1275 prevTime = time(NULL); | |
1276 srandom((int) prevTime); | |
1277 | |
1278 if (cursesInit) { | |
1279 noecho(); | |
1280 curVis = curs_set(0); | |
1265 nn_editbuf_clear(editBuf); | 1281 nn_editbuf_clear(editBuf); |
1266 printEditBuf("", editBuf); | 1282 printEditBuf("", editBuf); |
1267 updateStatus(insertMode); | 1283 updateStatus(insertMode); |
1268 } | 1284 } |
1269 | |
1270 /* Initialize random numbers */ | |
1271 prevTime = time(NULL); | |
1272 srandom((int) prevTime); | |
1273 | 1285 |
1274 /* Enter mainloop */ | 1286 /* Enter mainloop */ |
1275 while (!isError && !exitProg) { | 1287 while (!isError && !exitProg) { |
1276 int cres = nn_conn_pull(conn); | 1288 int cres = nn_conn_pull(conn); |
1277 if (cres == 0) { | 1289 if (cres == 0) { |
1588 nn_ringbuf_free(backBuf); | 1600 nn_ringbuf_free(backBuf); |
1589 nn_editbuf_free(editBuf); | 1601 nn_editbuf_free(editBuf); |
1590 for (histPos = 0; histPos <= SET_MAX_HISTORY; histPos++) | 1602 for (histPos = 0; histPos <= SET_MAX_HISTORY; histPos++) |
1591 nn_editbuf_free(histBuf[histPos]); | 1603 nn_editbuf_free(histBuf[histPos]); |
1592 | 1604 |
1605 #ifdef __WIN32 | |
1606 if (errorMessages || isError) { | |
1607 char *tmp = promptRequester(editWin, "Press enter to quit.\n", FALSE); | |
1608 th_free(tmp); | |
1609 } | |
1610 #endif | |
1611 | |
1593 if (cursesInit) { | 1612 if (cursesInit) { |
1594 if (curVis != ERR) | 1613 if (curVis != ERR) |
1595 curs_set(curVis); | 1614 curs_set(curVis); |
1596 closeWindows(); | 1615 closeWindows(); |
1597 endwin(); | 1616 endwin(); |
1598 THMSG(1, "NCurses deinitialized.\n"); | 1617 THMSG(1, "NCurses deinitialized.\n"); |
1599 } | 1618 } |
1600 | 1619 |
1620 #ifndef __WIN32 | |
1601 if (errorMessages) | 1621 if (errorMessages) |
1602 THERR("%s", errorMessages); | 1622 THERR("%s", errorMessages); |
1603 | |
1604 if (isError) { | |
1605 #ifdef __WIN32 | |
1606 char *tmp = promptRequester("Press enter to quit.\n", FALSE); | |
1607 th_free(tmp); | |
1608 #else | |
1609 THMSG(1, "Error exit.\n"); | |
1610 #endif | 1623 #endif |
1611 } | |
1612 | 1624 |
1613 th_free(optUserNameEnc); | 1625 th_free(optUserNameEnc); |
1614 | 1626 |
1615 nn_conn_close(conn); | 1627 nn_conn_close(conn); |
1616 | 1628 |