re-fresh
[nedit-bw.git] / remote-nc.patch
blobc0d2a349e5937b14472636148d1d379e322b2f2b
1 ---
3 source/nc.c | 112 +++++++++++++++++++++++++++++++++++++++----------
4 source/server.c | 42 +++++++++++-------
5 source/server_common.c | 16 +++----
6 source/windowTitle.c | 8 ++-
7 util/utils.c | 101 +++++++++++++++++++++++++++++---------------
8 util/utils.h | 6 +-
9 6 files changed, 202 insertions(+), 83 deletions(-)
11 diff --quilt old/source/nc.c new/source/nc.c
12 --- old/source/nc.c
13 +++ new/source/nc.c
14 @@ -181,7 +181,7 @@ static void setPropertyValue(Atom atom)
17 /* Add another entry to the file entry list, if it doesn't exist yet. */
18 -static void addToFileList(const char *path)
19 +static void addToFileList(long prefixLen, const char *prefix, const char *path)
21 FileListEntry *item;
23 @@ -196,8 +196,9 @@ static void addToFileList(const char *pa
24 item = malloc(sizeof(item[0]));
25 item->waitForFileOpenAtom = None;
26 item->waitForFileClosedAtom = None;
27 - item->path = (char*)malloc(strlen(path)+1);
28 - strcpy(item->path, path);
29 + item->path = (char*)malloc(prefixLen+strlen(path)+1);
30 + strcpy(item->path, prefix);
31 + strcpy(item->path + prefixLen, path);
32 item->next = fileListHead.fileList;
33 fileListHead.fileList = item;
35 @@ -233,6 +234,8 @@ int main(int argc, char **argv)
36 Atom serverExistsAtom, serverRequestAtom;
37 XrmDatabase prefDB;
38 Boolean serverExists;
39 + int xt_argc;
40 + char **xt_argv;
42 /* Initialize toolkit and get an application context */
43 XtToolkitInitialize();
44 @@ -251,21 +254,26 @@ int main(int argc, char **argv)
45 don't support the .nc file anymore) */
46 prefDB = CreatePreferencesDatabase(NULL, APP_CLASS,
47 OpTable, XtNumber(OpTable), (unsigned *)&argc, argv);
49 + /* copy argv/argc because XtOpenDisplay consumes arguments we may need
50 + for the server command line */
51 + xt_argv = (char**)XtMalloc(sizeof(char*) * (argc + 1));
52 + memcpy(xt_argv, argv, sizeof(char*) * (argc + 1));
53 + xt_argc = argc;
55 - /* Process the command line before calling XtOpenDisplay, because the
56 - latter consumes certain command line arguments that we still need
57 - (-icon, -geometry ...) */
58 - commandLine = processCommandLine(argc, argv);
60 /* Open the display and find the root window */
61 TheDisplay = XtOpenDisplay (context, NULL, APP_NAME, APP_CLASS, NULL,
62 - 0, &argc, argv);
63 + 0, &xt_argc, xt_argv);
64 if (!TheDisplay) {
65 XtWarning ("nc: Can't open display\n");
66 exit(EXIT_FAILURE);
68 + XtFree((char*)xt_argv);
69 rootWindow = RootWindow(TheDisplay, DefaultScreen(TheDisplay));
71 + /* Process the command line, with original arguments */
72 + commandLine = processCommandLine(argc, argv);
74 /* Read the application resources into the Preferences data structure */
75 RestorePreferences(prefDB, XtDatabase(TheDisplay), APP_NAME,
76 APP_CLASS, PrefDescrip, XtNumber(PrefDescrip));
77 @@ -503,7 +511,8 @@ static int startServer(const char *messa
79 /* prompt user whether to start server */
80 if (!Preferences.autoStart) {
81 - printf(message);
82 + printf("%s", message);
83 + fflush(stdout);
84 do {
85 c = getc(stdin);
86 } while (c == ' ' || c == '\t');
87 @@ -605,19 +614,34 @@ static CommandLine processCommandLine(in
89 static void parseCommandLine(int argc, char **argv, CommandLine *commandLine)
91 -#define MAX_RECORD_HEADER_LENGTH 38
92 +#define MAX_RECORD_HEADER_LENGTH 64
93 char name[MAXPATHLEN], path[MAXPATHLEN];
94 const char *toDoCommand = "", *langMode = "", *geometry = "";
95 char *commandString, *outPtr;
96 int lineNum = 0, read = 0, create = 0, iconic = 0, tabbed = -1, length = 0;
97 int i, lineArg, nRead, charsWritten, opts = True;
98 int fileCount = 0, group = 0, isTabbed;
99 + int doInNew = False;
101 + char *filePrefix = "";
102 + long filePrefixLen = 0;
103 +#ifndef VMS
104 + if (strcmp(GetNameOfHost(LOCAL_NAME), GetNameOfHost(NEDIT_NAME)))
106 + filePrefixLen = strlen(GetNameOfHost(LOCAL_NAME)) + 1
107 + + strlen(GetUserName(LOCAL_NAME)) + 1;
108 + filePrefix = XtMalloc(filePrefixLen + 1);
109 + sprintf(filePrefix, "%s@%s:",
110 + GetUserName(LOCAL_NAME), GetNameOfHost(LOCAL_NAME));
112 +#endif
114 /* Allocate a string for output, for the maximum possible length. The
115 maximum length is calculated by assuming every argument is a file,
116 and a complete record of maximum length is created for it */
117 for (i=1; i<argc; i++) {
118 - length += MAX_RECORD_HEADER_LENGTH + strlen(argv[i]) + MAXPATHLEN;
119 + length += MAX_RECORD_HEADER_LENGTH + strlen(argv[i]) + MAXPATHLEN
120 + + filePrefixLen;
122 /* In case of no arguments, must still allocate space for one record header */
123 if (length < MAX_RECORD_HEADER_LENGTH)
124 @@ -635,6 +659,10 @@ static void parseCommandLine(int argc, c
125 } else if (opts && !strcmp(argv[i], "-do")) {
126 nextArg(argc, argv, &i);
127 toDoCommand = argv[i];
128 + } else if (opts && !strcmp(argv[i], "-do-in-new")) {
129 + nextArg(argc, argv, &i);
130 + toDoCommand = argv[i];
131 + doInNew = True;
132 } else if (opts && !strcmp(argv[i], "-lm")) {
133 copyCommandLineArg(commandLine, argv[i]);
134 nextArg(argc, argv, &i);
135 @@ -735,16 +763,19 @@ static void parseCommandLine(int argc, c
138 /* See below for casts */
139 - sprintf(outPtr, "%d %d %d %d %d %ld %ld %ld %ld\n%s\n%s\n%s\n%s\n%n",
140 - lineNum, read, create, iconic, tabbed, (long) strlen(path),
141 + sprintf(outPtr, "%d %d %d %d %d %ld %ld %ld %ld\n"
142 + "%s%s\n%s\n%s\n%s\n%n",
143 + lineNum, read, create, iconic, tabbed,
144 + filePrefixLen + (long) strlen(path),
145 (long) strlen(toDoCommand), (long) strlen(langMode),
146 (long) strlen(geometry),
147 - path, toDoCommand, langMode, geometry, &charsWritten);
148 + filePrefix, path, toDoCommand, langMode, geometry,
149 + &charsWritten);
150 outPtr += charsWritten;
151 free(nameList[j]);
153 /* Create the file open atoms for the paths supplied */
154 - addToFileList(path);
155 + addToFileList(filePrefixLen, filePrefix, path);
156 fileCount++;
158 if (nameList != NULL)
159 @@ -778,10 +809,13 @@ static void parseCommandLine(int argc, c
160 is 64 bit on Alphas, and 32-bit on most others. There is
161 no printf format specifier for "size_t", thanx, ANSI. */
162 sprintf(outPtr, "%d %d %d %d %d %ld %ld %ld %ld\n%n", lineNum,
163 - read, create, iconic, isTabbed, (long) strlen(path),
164 + read, create, iconic, isTabbed,
165 + filePrefixLen + (long) strlen(path),
166 (long) strlen(toDoCommand), (long) strlen(langMode),
167 (long) strlen(geometry), &charsWritten);
168 outPtr += charsWritten;
169 + strcpy(outPtr, filePrefix);
170 + outPtr += filePrefixLen;
171 strcpy(outPtr, path);
172 outPtr += strlen(path);
173 *outPtr++ = '\n';
174 @@ -797,9 +831,10 @@ static void parseCommandLine(int argc, c
175 toDoCommand = "";
177 /* Create the file open atoms for the paths supplied */
178 - addToFileList(path);
179 + addToFileList(filePrefixLen, filePrefix, path);
180 fileCount++;
181 #endif /* VMS */
182 + doInNew = False;
185 #ifdef VMS
186 @@ -812,10 +847,42 @@ static void parseCommandLine(int argc, c
187 * iconic state (and optional language mode and geometry).
189 if (toDoCommand[0] != '\0' || fileCount == 0) {
190 - sprintf(outPtr, "0 0 0 %d %d 0 %ld %ld %ld\n\n%n", iconic, tabbed,
191 - (long) strlen(toDoCommand),
192 - (long) strlen(langMode), (long) strlen(geometry), &charsWritten);
193 + char current[MAXPATHLEN];
194 + long length;
195 + strcpy(current, GetCurrentDir());
196 + length = strlen(current);
198 +#ifndef VMS
199 + /* do we have a "/" at the end? if not, add one */
200 + if (0 < length && current[length - 1] != '/' && length < MAXPATHLEN - 1) {
201 + strcpy(&current[length], "/");
202 + length++;
204 +#else /* VMS */
205 + /* A logical name should be followed by a colon so that the filename can
206 + be added to it to make a full file specification; otherwise a directory
207 + path had the form
208 + device_or_logicalname:[dir.dir.dir]
209 + this requires no separator before the file name.
210 + */
211 + if (0 < length && strchr(":]", current[length - 1]) == NULL) {
212 + strcpy(&current[length], ":"); /* could not find a separator at end */
213 + length++;
215 + /* TODO: is this enough for VMS? what of posix emulation? */
216 + /* TODO: what about other platforms? */
217 +#endif /* VMS */
219 + sprintf(outPtr, "0 0 %d %d %d %ld %ld %ld %ld\n%n",
220 + doInNew, iconic, tabbed, -(filePrefixLen + length),
221 + (long) strlen(toDoCommand), (long) strlen(langMode),
222 + (long) strlen(geometry), &charsWritten);
223 outPtr += charsWritten;
224 + strcpy(outPtr, filePrefix);
225 + outPtr += filePrefixLen;
226 + strcpy(outPtr, current);
227 + outPtr += length;
228 + *outPtr++ = '\n';
229 strcpy(outPtr, toDoCommand);
230 outPtr += strlen(toDoCommand);
231 *outPtr++ = '\n';
232 @@ -826,6 +893,9 @@ static void parseCommandLine(int argc, c
233 outPtr += strlen(geometry);
234 *outPtr++ = '\n';
237 + if (filePrefixLen > 0)
238 + XtFree(filePrefix);
240 *outPtr = '\0';
241 commandLine->serverRequest = commandString;
242 diff --quilt old/source/server.c new/source/server.c
243 --- old/source/server.c
244 +++ new/source/server.c
245 @@ -381,10 +381,12 @@ static void processServerCommandString(c
246 if (itemsRead != 9)
247 goto readError;
248 inPtr += charsRead + 1;
249 - if (inPtr - string + fileLen > stringLen)
250 + if (fileLen >= 0 && inPtr - string + fileLen > stringLen)
251 + goto readError;
252 + if (fileLen < 0 && inPtr - string - fileLen > stringLen)
253 goto readError;
254 requestname = inPtr;
255 - inPtr += fileLen;
256 + inPtr += fileLen < 0 ? -fileLen : fileLen;
257 *inPtr++ = '\0';
258 if (inPtr - string + doLen > stringLen)
259 goto readError;
260 @@ -411,13 +413,16 @@ static void processServerCommandString(c
261 if (fileLen <= 0) {
262 for (window=WindowList; window!=NULL; window=window->next)
263 if (!window->filenameSet && !window->fileChanged &&
264 - isLocatedOnDesktop(window, currentDesktop))
265 + isLocatedOnDesktop(window, currentDesktop) &&
266 + (fileLen < 0 ? !strcmp(window->path, fullname) : True))
267 break;
269 - if (*doCommand == '\0') {
270 + if (*doCommand == '\0' || createFlag) {
271 if (window == NULL) {
272 - EditNewFile(findWindowOnDesktop(tabbed, currentDesktop),
273 - NULL, iconicFlag, lmLen==0?NULL:langMode, NULL,
274 + window = EditNewFile(findWindowOnDesktop(tabbed,
275 + currentDesktop),
276 + NULL, iconicFlag, lmLen==0?NULL:langMode,
277 + fileLen < 0 ? fullname : NULL,
278 False);
279 } else {
280 if (iconicFlag)
281 @@ -425,23 +430,28 @@ static void processServerCommandString(c
282 else
283 RaiseDocumentWindow(window);
286 + if (window && *doCommand != '\0')
287 + DoMacro(window, doCommand, "-do-in-new macro");
288 } else {
289 - WindowInfo *win = WindowList;
290 - /* Starting a new command while another one is still running
291 - in the same window is not possible (crashes). */
292 - while (win != NULL && win->macroCmdData != NULL) {
293 - win = win->next;
295 + if (window == NULL || window->macroCmdData != NULL) {
296 + /* Starting a new command while another one is still running
297 + in the same window is not possible (crashes). */
298 + window = WindowList;
299 + while (window != NULL && window->macroCmdData != NULL) {
300 + window = window->next;
304 - if (!win) {
305 + if (!window) {
306 XBell(TheDisplay, 0);
307 } else {
308 /* Raise before -do (macro could close window). */
309 if (iconicFlag)
310 - RaiseDocument(win);
311 + RaiseDocument(window);
312 else
313 - RaiseDocumentWindow(win);
314 - DoMacro(win, doCommand, "-do macro");
315 + RaiseDocumentWindow(window);
316 + DoMacro(window, doCommand, "-do macro");
319 CheckCloseDim();
320 diff --quilt old/util/utils.c new/util/utils.c
321 --- old/util/utils.c
322 +++ new/util/utils.c
323 @@ -119,38 +119,60 @@ const char* GetHomeDir(void)
324 ** allocated string.
326 const char
327 -*GetUserName(void)
328 +*GetUserName(enum nameType name)
330 + static char userName[2][MAXUSERNAMELEN+1];
331 + static int userNameFound = False;
333 + if (!userNameFound) {
334 + const char *user;
336 #ifdef VMS
337 - return cuserid(NULL);
338 + user = cuserid(NULL);
339 #else
340 - /* cuserid has apparently been dropped from the ansi C standard, and if
341 - strict ansi compliance is turned on (on Sun anyhow, maybe others), calls
342 - to cuserid fail to compile. Older versions of nedit try to use the
343 - getlogin call first, then if that fails, use getpwuid and getuid. This
344 - results in the user-name of the original terminal being used, which is
345 - not correct when the user uses the su command. Now, getpwuid only: */
347 - const struct passwd *passwdEntry;
348 - static char *userName=NULL;
350 - if (userName)
351 - return userName;
353 - passwdEntry = getpwuid(getuid());
354 - if (!passwdEntry) {
355 - /* This is really serious, but sometimes username service
356 - is misconfigured through no fault of the user. Be nice
357 - and let the user start nc anyway. */
358 - perror("nedit: getpwuid() failed - reverting to $USER");
359 - return getenv("USER");
361 - else {
362 - userName=malloc(strlen(passwdEntry->pw_name)+1);
363 - strcpy(userName, passwdEntry->pw_name);
364 - return userName;
366 + /* cuserid has apparently been dropped from the ansi C standard,
367 + and if strict ansi compliance is turned on (on Sun anyhow,
368 + maybe others), calls to cuserid fail to compile. Older
369 + versions of nedit try to use the getlogin call first, then if
370 + that fails, use getpwuid and getuid. This results in the
371 + user-name of the original terminal being used, which is not
372 + correct when the user uses the su command. Now, getpwuid only: */
374 + const struct passwd *passwdEntry = getpwuid(getuid());
375 + if (!passwdEntry || !passwdEntry->pw_name) {
376 + /* This is really serious, but sometimes username service
377 + is misconfigured through no fault of the user. Be nice
378 + and let the user start nc anyway. */
379 + perror("nedit: getpwuid() failed - reverting to $USER");
380 + user = getenv("USER");
382 + else {
383 + user = passwdEntry->pw_name;
385 #endif /* VMS */
387 + if (!user) {
388 + fprintf(stderr, "nedit: failed to determine user name.");
389 + exit(EXIT_FAILURE);
391 + if (strlen(user) > MAXUSERNAMELEN)
392 + fprintf(stderr, "nedit: Username to long, need to truncate.\n");
393 + strncpy(userName[LOCAL_NAME], user, MAXUSERNAMELEN);
394 + userName[LOCAL_NAME][MAXUSERNAMELEN] = '\0';
396 + /* set nedit user to $NEDIT_USER,
397 + but only if it fits into the buffer */
398 + if ((user = getenv("NEDIT_USER")) && (strlen(user) <= MAXUSERNAMELEN)) {
399 + strcpy(userName[NEDIT_NAME], user);
400 + } else {
401 + strcpy(userName[NEDIT_NAME], userName[LOCAL_NAME]);
404 + userNameFound = True;
407 + return userName[name];
411 @@ -162,12 +184,13 @@ const char
412 ** VMS links case-insensitively.
414 const char
415 -*GetNameOfHost(void)
416 +*GetNameOfHost(enum nameType name)
418 - static char hostname[MAXNODENAMELEN+1];
419 + static char hostname[2][MAXNODENAMELEN+1];
420 static int hostnameFound = False;
422 if (!hostnameFound) {
423 + const char *host;
424 #ifdef VMS
425 /* This should be simple, but uname is not supported in the DEC C RTL and
426 gethostname on VMS depends either on Multinet or UCX. So use uname
427 @@ -179,12 +202,12 @@ const char
428 unsigned long int unused = 0;
429 unsigned short int hostnameLen = MAXNODENAMELEN+1;
431 - hostnameDesc = NulStrWrtDesc(hostname, MAXNODENAMELEN+1);
432 + hostnameDesc = NulStrWrtDesc(hostname[LOCAL_NAME], MAXNODENAMELEN+1);
433 syi_status = lib$getsyi(&syiItemCode, &unused, hostnameDesc, &hostnameLen,
434 0, 0);
435 if (syi_status != SS$_NORMAL) {
436 fprintf(stderr, "nedit: Error return from lib$getsyi: %d", syi_status);
437 - strcpy(hostname, "VMS");
438 + strcpy(hostname[LOCAL_NAME], "VMS");
439 } else
440 hostname[hostnameLen] = '\0';
441 FreeStrDesc(hostnameDesc);
442 @@ -196,11 +219,23 @@ const char
443 perror("nedit: uname() failed ");
444 exit(EXIT_FAILURE);
446 - strcpy(hostname, nameStruct.nodename);
447 + if (strlen(nameStruct.nodename) > MAXNODENAMELEN)
448 + fprintf(stderr, "nedit: hostname to long, need to truncate.\n");
449 + strcpy(hostname[LOCAL_NAME], nameStruct.nodename);
450 + hostname[LOCAL_NAME][MAXNODENAMELEN] = '\0';
451 #endif /* VMS */
453 + /* set remote hostname to $NEDIT_HOST,
454 + but only if it fits into the buffer */
455 + if ((host = getenv("NEDIT_HOST")) && (strlen(host) <= MAXNODENAMELEN)) {
456 + strcpy(hostname[NEDIT_NAME], host);
457 + } else {
458 + strcpy(hostname[NEDIT_NAME], hostname[LOCAL_NAME]);
461 hostnameFound = True;
463 - return hostname;
464 + return hostname[name];
468 diff --quilt old/source/server_common.c new/source/server_common.c
469 --- old/source/server_common.c
470 +++ new/source/server_common.c
471 @@ -64,8 +64,8 @@ void CreateServerPropertyAtoms(const cha
472 MAXNODENAMELEN+1+
473 MAXUSERNAMELEN+1+
474 MAXSERVERNAMELEN+1];
475 - const char *userName = GetUserName();
476 - const char *hostName = GetNameOfHost();
477 + const char *userName = GetUserName(NEDIT_NAME);
478 + const char *hostName = GetNameOfHost(NEDIT_NAME);
480 sprintf(propName, "NEDIT_%s_SERVER_EXISTS_%s_%s_%s",
481 NEDIT_VERSION_STRING, hostName, userName, serverName);
482 @@ -102,8 +102,8 @@ Atom CreateServerFileOpenAtom(const char
483 MAXSERVERNAMELEN+1+
484 MAXPATHLEN+1+
485 7+1];
486 - const char *userName = GetUserName();
487 - const char *hostName = GetNameOfHost();
488 + const char *userName = GetUserName(NEDIT_NAME);
489 + const char *hostName = GetNameOfHost(NEDIT_NAME);
490 Atom atom;
492 sprintf(propName, "NEDIT_%s_FILE_%s_%s_%s_%s_WF_OPEN",
493 @@ -123,8 +123,8 @@ Atom CreateServerFileClosedAtom(const ch
494 MAXSERVERNAMELEN+1+
495 MAXPATHLEN+1+
496 9+1];
497 - const char *userName = GetUserName();
498 - const char *hostName = GetNameOfHost();
499 + const char *userName = GetUserName(NEDIT_NAME);
500 + const char *hostName = GetNameOfHost(NEDIT_NAME);
501 Atom atom;
503 sprintf(propName, "NEDIT_%s_FILE_%s_%s_%s_%s_WF_CLOSED",
504 @@ -145,8 +145,8 @@ void DeleteServerFileAtoms(const char* s
505 MAXUSERNAMELEN+1+
506 MAXSERVERNAMELEN+1+
508 - const char *userName = GetUserName();
509 - const char *hostName = GetNameOfHost();
510 + const char *userName = GetUserName(NEDIT_NAME);
511 + const char *hostName = GetNameOfHost(NEDIT_NAME);
512 int length = sprintf(propNamePrefix, "NEDIT_%s_FILE_%s_%s_%s_",
513 NEDIT_VERSION_STRING, hostName, userName, serverName);
515 diff --quilt old/util/utils.h new/util/utils.h
516 --- old/util/utils.h
517 +++ new/util/utils.h
518 @@ -37,11 +37,13 @@
519 #include <sys/param.h>
520 #endif /*VMS*/
522 +enum nameType {LOCAL_NAME, NEDIT_NAME};
524 const char *GetCurrentDir(void);
525 const char *GetHomeDir(void);
526 char *PrependHome(const char *filename, char *buf, size_t buflen);
527 -const char *GetUserName(void);
528 -const char *GetNameOfHost(void);
529 +const char *GetUserName(enum nameType name);
530 +const char *GetNameOfHost(enum nameType name);
531 int Min(int i1, int i2);
532 const char* GetRCFileName(int type);
533 const char* GetNEditHome(void);
534 diff --quilt old/source/windowTitle.c new/source/windowTitle.c
535 --- old/source/windowTitle.c
536 +++ new/source/windowTitle.c
537 @@ -352,7 +352,7 @@ char *FormatWindowTitle(const char* file
539 } else if (*titleFormat == 'h') {
540 int comps = c - '0';
541 - char* hostname = strdup(GetNameOfHost());
542 + char* hostname = strdup(GetNameOfHost(NEDIT_NAME));
543 char *p, *n;
544 hostNamePresent = True;
545 titleFormat++; /* delete the argument */
546 @@ -380,7 +380,8 @@ char *FormatWindowTitle(const char* file
548 case 'h': /* host name */
549 hostNamePresent = True;
550 - titlePtr = safeStrCpy(titlePtr, titleEnd, GetNameOfHost());
551 + titlePtr = safeStrCpy(titlePtr, titleEnd,
552 + GetNameOfHost(NEDIT_NAME));
553 break;
555 case 'S': /* file status */
556 @@ -401,7 +402,8 @@ char *FormatWindowTitle(const char* file
558 case 'u': /* user name */
559 userNamePresent = True;
560 - titlePtr = safeStrCpy(titlePtr, titleEnd, GetUserName());
561 + titlePtr = safeStrCpy(titlePtr, titleEnd,
562 + GetUserName(NEDIT_NAME));
563 break;
565 case '%': /* escaped % */