release client: fix race between menu building and IsServer
[nedit-bw.git] / remote-nc.patch
blob3e6ec9501590a8db427340dbc18ddbf2fc2042f0
1 ---
3 source/nc.c | 86 +++++++++++++++++++++++++++++++----------
4 source/server.c | 25 ++++++++----
5 source/server_common.c | 22 +++++-----
6 source/windowTitle.c | 8 ++-
7 util/utils.c | 101 ++++++++++++++++++++++++++++++++-----------------
8 util/utils.h | 6 +-
9 6 files changed, 170 insertions(+), 78 deletions(-)
11 diff --quilt old/source/nc.c new/source/nc.c
12 --- old/source/nc.c
13 +++ new/source/nc.c
14 @@ -36,6 +36,7 @@ static const char CVSID[] = "$Id: nc.c,v
15 #include "../util/utils.h"
16 #include "../util/prefFile.h"
17 #include "../util/system.h"
18 +#include "../util/misc.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 @@ -181,7 +182,7 @@ static void setPropertyValue(Atom atom)
25 /* Add another entry to the file entry list, if it doesn't exist yet. */
26 -static void addToFileList(const char *path)
27 +static void addToFileList(long prefixLen, const char *prefix, const char *path)
29 FileListEntry *item;
31 @@ -196,8 +197,9 @@ static void addToFileList(const char *pa
32 item = malloc(sizeof(item[0]));
33 item->waitForFileOpenAtom = None;
34 item->waitForFileClosedAtom = None;
35 - item->path = (char*)malloc(strlen(path)+1);
36 - strcpy(item->path, path);
37 + item->path = (char*)malloc(prefixLen+strlen(path)+1);
38 + strcpy(item->path, prefix);
39 + strcpy(item->path + prefixLen, path);
40 item->next = fileListHead.fileList;
41 fileListHead.fileList = item;
43 @@ -233,6 +235,8 @@ int main(int argc, char **argv)
44 Atom serverExistsAtom, serverRequestAtom;
45 XrmDatabase prefDB;
46 Boolean serverExists;
47 + int xt_argc;
48 + char **xt_argv;
50 /* Initialize toolkit and get an application context */
51 XtToolkitInitialize();
52 @@ -251,21 +255,26 @@ int main(int argc, char **argv)
53 don't support the .nc file anymore) */
54 prefDB = CreatePreferencesDatabase(NULL, APP_CLASS,
55 OpTable, XtNumber(OpTable), (unsigned *)&argc, argv);
57 + /* copy argv/argc because XtOpenDisplay consumes arguments we may need
58 + for the server command line */
59 + xt_argv = (char**)XtMalloc(sizeof(char*) * (argc + 1));
60 + memcpy(xt_argv, argv, sizeof(char*) * (argc + 1));
61 + xt_argc = argc;
63 - /* Process the command line before calling XtOpenDisplay, because the
64 - latter consumes certain command line arguments that we still need
65 - (-icon, -geometry ...) */
66 - commandLine = processCommandLine(argc, argv);
68 /* Open the display and find the root window */
69 TheDisplay = XtOpenDisplay (context, NULL, APP_NAME, APP_CLASS, NULL,
70 - 0, &argc, argv);
71 + 0, &xt_argc, xt_argv);
72 if (!TheDisplay) {
73 XtWarning ("nc: Can't open display\n");
74 exit(EXIT_FAILURE);
76 + XtFree((char*)xt_argv);
77 rootWindow = RootWindow(TheDisplay, DefaultScreen(TheDisplay));
79 + /* Process the command line, with original arguments */
80 + commandLine = processCommandLine(argc, argv);
82 /* Read the application resources into the Preferences data structure */
83 RestorePreferences(prefDB, XtDatabase(TheDisplay), APP_NAME,
84 APP_CLASS, PrefDescrip, XtNumber(PrefDescrip));
85 @@ -503,7 +512,8 @@ static int startServer(const char *messa
87 /* prompt user whether to start server */
88 if (!Preferences.autoStart) {
89 - printf(message);
90 + printf("%s", message);
91 + fflush(stdout);
92 do {
93 c = getc(stdin);
94 } while (c == ' ' || c == '\t');
95 @@ -605,19 +615,35 @@ static CommandLine processCommandLine(in
97 static void parseCommandLine(int argc, char **argv, CommandLine *commandLine)
99 -#define MAX_RECORD_HEADER_LENGTH 38
100 +#define MAX_RECORD_HEADER_LENGTH 64
101 char name[MAXPATHLEN], path[MAXPATHLEN];
102 const char *toDoCommand = "", *langMode = "", *geometry = "";
103 char *commandString, *outPtr;
104 int lineNum = 0, read = 0, create = 0, iconic = 0, tabbed = -1, length = 0;
105 int i, lineArg, nRead, charsWritten, opts = True;
106 int fileCount = 0, group = 0, isTabbed;
107 + long currentDesktop = QueryCurrentDesktop(TheDisplay,
108 + RootWindow(TheDisplay, DefaultScreen(TheDisplay)));
110 + char *filePrefix = "";
111 + long filePrefixLen = 0;
112 +#ifndef VMS
113 + if (strcmp(GetNameOfHost(LOCAL_NAME), GetNameOfHost(NEDIT_NAME)))
115 + filePrefixLen = strlen(GetNameOfHost(LOCAL_NAME)) + 1
116 + + strlen(GetUserName(LOCAL_NAME)) + 1;
117 + filePrefix = XtMalloc(filePrefixLen + 1);
118 + sprintf(filePrefix, "%s@%s:",
119 + GetUserName(LOCAL_NAME), GetNameOfHost(LOCAL_NAME));
121 +#endif
123 /* Allocate a string for output, for the maximum possible length. The
124 maximum length is calculated by assuming every argument is a file,
125 and a complete record of maximum length is created for it */
126 for (i=1; i<argc; i++) {
127 - length += MAX_RECORD_HEADER_LENGTH + strlen(argv[i]) + MAXPATHLEN;
128 + length += MAX_RECORD_HEADER_LENGTH + strlen(argv[i]) + MAXPATHLEN
129 + + filePrefixLen;
131 /* In case of no arguments, must still allocate space for one record header */
132 if (length < MAX_RECORD_HEADER_LENGTH)
133 @@ -735,16 +761,19 @@ static void parseCommandLine(int argc, c
136 /* See below for casts */
137 - sprintf(outPtr, "%d %d %d %d %d %ld %ld %ld %ld\n%s\n%s\n%s\n%s\n%n",
138 - lineNum, read, create, iconic, tabbed, (long) strlen(path),
139 + sprintf(outPtr, "%d %d %d %d %d %ld %ld %ld %ld %ld\n"
140 + "%s%s\n%s\n%s\n%s\n%n",
141 + lineNum, read, create, iconic, tabbed, currentDesktop,
142 + filePrefixLen + (long) strlen(path),
143 (long) strlen(toDoCommand), (long) strlen(langMode),
144 (long) strlen(geometry),
145 - path, toDoCommand, langMode, geometry, &charsWritten);
146 + filePrefix, path, toDoCommand, langMode, geometry,
147 + &charsWritten);
148 outPtr += charsWritten;
149 free(nameList[j]);
151 /* Create the file open atoms for the paths supplied */
152 - addToFileList(path);
153 + addToFileList(filePrefixLen, filePrefix, path);
154 fileCount++;
156 if (nameList != NULL)
157 @@ -777,11 +806,14 @@ static void parseCommandLine(int argc, c
158 The "long" cast on strlen() is necessary because size_t
159 is 64 bit on Alphas, and 32-bit on most others. There is
160 no printf format specifier for "size_t", thanx, ANSI. */
161 - sprintf(outPtr, "%d %d %d %d %d %ld %ld %ld %ld\n%n", lineNum,
162 - read, create, iconic, isTabbed, (long) strlen(path),
163 + sprintf(outPtr, "%d %d %d %d %d %ld %ld %ld %ld %ld\n%n", lineNum,
164 + read, create, iconic, isTabbed, currentDesktop,
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,7 +829,7 @@ 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 */
183 @@ -812,10 +844,17 @@ static void parseCommandLine(int argc, c
184 * iconic state (and optional language mode and geometry).
186 if (toDoCommand[0] != '\0' || fileCount == 0) {
187 - sprintf(outPtr, "0 0 0 %d %d 0 %ld %ld %ld\n\n%n", iconic, tabbed,
188 - (long) strlen(toDoCommand),
189 - (long) strlen(langMode), (long) strlen(geometry), &charsWritten);
190 + const char *current = GetCurrentDir();
191 + sprintf(outPtr, "0 0 0 %d %d %ld %ld %ld %ld %ld\n%n", iconic, tabbed,
192 + currentDesktop, -(filePrefixLen + (long) strlen(current)),
193 + (long) strlen(toDoCommand), (long) strlen(langMode),
194 + (long) strlen(geometry), &charsWritten);
195 outPtr += charsWritten;
196 + strcpy(outPtr, filePrefix);
197 + outPtr += filePrefixLen;
198 + strcpy(outPtr, current);
199 + outPtr += strlen(current);
200 + *outPtr++ = '\n';
201 strcpy(outPtr, toDoCommand);
202 outPtr += strlen(toDoCommand);
203 *outPtr++ = '\n';
204 @@ -826,6 +865,9 @@ static void parseCommandLine(int argc, c
205 outPtr += strlen(geometry);
206 *outPtr++ = '\n';
209 + if (filePrefixLen > 0)
210 + XtFree(filePrefix);
212 *outPtr = '\0';
213 commandLine->serverRequest = commandString;
214 diff --quilt old/source/server.c new/source/server.c
215 --- old/source/server.c
216 +++ new/source/server.c
217 @@ -374,16 +374,26 @@ static void processServerCommandString(c
218 command both followed by newlines. This bit of code reads the
219 header, and converts the newlines following the filename and do
220 command to nulls to terminate the filename and doCommand strings */
221 - itemsRead = sscanf(inPtr, "%d %d %d %d %d %d %d %d %d%n", &lineNum,
222 - &readFlag, &createFlag, &iconicFlag, &tabbed, &fileLen,
223 - &doLen, &lmLen, &geomLen, &charsRead);
224 - if (itemsRead != 9)
225 + itemsRead = sscanf(inPtr, "%d %d %d %d %d %ld %d %d %d %d%n", &lineNum,
226 + &readFlag, &createFlag, &iconicFlag, &tabbed, &currentDesktop,
227 + &fileLen, &doLen, &lmLen, &geomLen, &charsRead);
228 + if (itemsRead == 9) {
229 + /* backward compatibility, without currentDesktop */
230 + geomLen = lmLen;
231 + lmLen = doLen;
232 + doLen = fileLen;
233 + fileLen = currentDesktop;
234 + currentDesktop = QueryCurrentDesktop(TheDisplay,
235 + RootWindow(TheDisplay, DefaultScreen(TheDisplay)));
236 + } else if (itemsRead != 10)
237 goto readError;
238 inPtr += charsRead + 1;
239 - if (inPtr - string + fileLen > stringLen)
240 + if (fileLen >= 0 && inPtr - string + fileLen > stringLen)
241 + goto readError;
242 + if (fileLen < 0 && inPtr - string - fileLen > stringLen)
243 goto readError;
244 requestname = inPtr;
245 - inPtr += fileLen;
246 + inPtr += fileLen < 0 ? -fileLen : fileLen;
247 *inPtr++ = '\0';
248 if (inPtr - string + doLen > stringLen)
249 goto readError;
250 @@ -416,7 +426,8 @@ static void processServerCommandString(c
251 if (*doCommand == '\0') {
252 if (window == NULL) {
253 EditNewFile(findWindowOnDesktop(tabbed, currentDesktop),
254 - NULL, iconicFlag, lmLen==0?NULL:langMode, NULL,
255 + NULL, iconicFlag, lmLen==0?NULL:langMode,
256 + fileLen < 0 ? fullname : NULL,
257 False);
258 } else {
259 if (iconicFlag)
260 diff --quilt old/util/utils.c new/util/utils.c
261 --- old/util/utils.c
262 +++ new/util/utils.c
263 @@ -119,38 +119,60 @@ const char* GetHomeDir(void)
264 ** allocated string.
266 const char
267 -*GetUserName(void)
268 +*GetUserName(enum nameType name)
270 + static char userName[2][MAXUSERNAMELEN+1];
271 + static int userNameFound = False;
273 + if (!userNameFound) {
274 + const char *user;
276 #ifdef VMS
277 - return cuserid(NULL);
278 + user = cuserid(NULL);
279 #else
280 - /* cuserid has apparently been dropped from the ansi C standard, and if
281 - strict ansi compliance is turned on (on Sun anyhow, maybe others), calls
282 - to cuserid fail to compile. Older versions of nedit try to use the
283 - getlogin call first, then if that fails, use getpwuid and getuid. This
284 - results in the user-name of the original terminal being used, which is
285 - not correct when the user uses the su command. Now, getpwuid only: */
287 - const struct passwd *passwdEntry;
288 - static char *userName=NULL;
290 - if (userName)
291 - return userName;
293 - passwdEntry = getpwuid(getuid());
294 - if (!passwdEntry) {
295 - /* This is really serious, but sometimes username service
296 - is misconfigured through no fault of the user. Be nice
297 - and let the user start nc anyway. */
298 - perror("nedit: getpwuid() failed - reverting to $USER");
299 - return getenv("USER");
301 - else {
302 - userName=malloc(strlen(passwdEntry->pw_name)+1);
303 - strcpy(userName, passwdEntry->pw_name);
304 - return userName;
306 + /* cuserid has apparently been dropped from the ansi C standard,
307 + and if strict ansi compliance is turned on (on Sun anyhow,
308 + maybe others), calls to cuserid fail to compile. Older
309 + versions of nedit try to use the getlogin call first, then if
310 + that fails, use getpwuid and getuid. This results in the
311 + user-name of the original terminal being used, which is not
312 + correct when the user uses the su command. Now, getpwuid only: */
314 + const struct passwd *passwdEntry = getpwuid(getuid());
315 + if (!passwdEntry || !passwdEntry->pw_name) {
316 + /* This is really serious, but sometimes username service
317 + is misconfigured through no fault of the user. Be nice
318 + and let the user start nc anyway. */
319 + perror("nedit: getpwuid() failed - reverting to $USER");
320 + user = getenv("USER");
322 + else {
323 + user = passwdEntry->pw_name;
325 #endif /* VMS */
327 + if (!user) {
328 + fprintf(stderr, "nedit: failed to determine user name.");
329 + exit(EXIT_FAILURE);
331 + if (strlen(user) > MAXUSERNAMELEN)
332 + fprintf(stderr, "nedit: Username to long, need to truncate.\n");
333 + strncpy(userName[LOCAL_NAME], user, MAXUSERNAMELEN);
334 + userName[LOCAL_NAME][MAXUSERNAMELEN] = '\0';
336 + /* set nedit user to $NEDIT_USER,
337 + but only if it fits into the buffer */
338 + if ((user = getenv("NEDIT_USER")) && (strlen(user) <= MAXUSERNAMELEN)) {
339 + strcpy(userName[NEDIT_NAME], user);
340 + } else {
341 + strcpy(userName[NEDIT_NAME], userName[LOCAL_NAME]);
344 + userNameFound = True;
347 + return userName[name];
351 @@ -162,12 +184,13 @@ const char
352 ** VMS links case-insensitively.
354 const char
355 -*GetNameOfHost(void)
356 +*GetNameOfHost(enum nameType name)
358 - static char hostname[MAXNODENAMELEN+1];
359 + static char hostname[2][MAXNODENAMELEN+1];
360 static int hostnameFound = False;
362 if (!hostnameFound) {
363 + const char *host;
364 #ifdef VMS
365 /* This should be simple, but uname is not supported in the DEC C RTL and
366 gethostname on VMS depends either on Multinet or UCX. So use uname
367 @@ -179,12 +202,12 @@ const char
368 unsigned long int unused = 0;
369 unsigned short int hostnameLen = MAXNODENAMELEN+1;
371 - hostnameDesc = NulStrWrtDesc(hostname, MAXNODENAMELEN+1);
372 + hostnameDesc = NulStrWrtDesc(hostname[LOCAL_NAME], MAXNODENAMELEN+1);
373 syi_status = lib$getsyi(&syiItemCode, &unused, hostnameDesc, &hostnameLen,
374 0, 0);
375 if (syi_status != SS$_NORMAL) {
376 fprintf(stderr, "nedit: Error return from lib$getsyi: %d", syi_status);
377 - strcpy(hostname, "VMS");
378 + strcpy(hostname[LOCAL_NAME], "VMS");
379 } else
380 hostname[hostnameLen] = '\0';
381 FreeStrDesc(hostnameDesc);
382 @@ -196,11 +219,23 @@ const char
383 perror("nedit: uname() failed ");
384 exit(EXIT_FAILURE);
386 - strcpy(hostname, nameStruct.nodename);
387 + if (strlen(nameStruct.nodename) > MAXNODENAMELEN)
388 + fprintf(stderr, "nedit: hostname to long, need to truncate.\n");
389 + strcpy(hostname[LOCAL_NAME], nameStruct.nodename);
390 + hostname[LOCAL_NAME][MAXNODENAMELEN] = '\0';
391 #endif /* VMS */
393 + /* set remote hostname to $NEDIT_HOST,
394 + but only if it fits into the buffer */
395 + if ((host = getenv("NEDIT_HOST")) && (strlen(host) <= MAXNODENAMELEN)) {
396 + strcpy(hostname[NEDIT_NAME], host);
397 + } else {
398 + strcpy(hostname[NEDIT_NAME], hostname[LOCAL_NAME]);
401 hostnameFound = True;
403 - return hostname;
404 + return hostname[name];
408 diff --quilt old/source/server_common.c new/source/server_common.c
409 --- old/source/server_common.c
410 +++ new/source/server_common.c
411 @@ -57,8 +57,8 @@ void CreateServerPropertyAtoms(const cha
412 Atom *serverRequestAtomReturn)
414 char propName[24+1+MAXNODENAMELEN+1+MAXUSERNAMELEN+1+MAXSERVERNAMELEN];
415 - const char *userName = GetUserName();
416 - const char *hostName = GetNameOfHost();
417 + const char *userName = GetUserName(NEDIT_NAME);
418 + const char *hostName = GetNameOfHost(NEDIT_NAME);
420 sprintf(propName, "NEDIT_5.7_SERVER_EXISTS_%s_%s_%s", hostName, userName, serverName);
421 *serverExistsAtomReturn = XInternAtom(TheDisplay, propName, False);
422 @@ -86,9 +86,9 @@ void CreateServerPropertyAtoms(const cha
423 Atom CreateServerFileOpenAtom(const char *serverName,
424 const char *path)
426 - char propName[14+1+MAXNODENAMELEN+1+MAXUSERNAMELEN+1+MAXSERVERNAMELEN+1+MAXPATHLEN+1+7];
427 - const char *userName = GetUserName();
428 - const char *hostName = GetNameOfHost();
429 + char propName[14+1+MAXNODENAMELEN+1+MAXUSERNAMELEN+1+MAXSERVERNAMELEN+1+MAXPATHLEN+1+7+1];
430 + const char *userName = GetUserName(NEDIT_NAME);
431 + const char *hostName = GetNameOfHost(NEDIT_NAME);
432 Atom atom;
434 sprintf(propName, "NEDIT_5.7_FILE_%s_%s_%s_%s_WF_OPEN", hostName, userName, serverName, path);
435 @@ -100,9 +100,9 @@ Atom CreateServerFileClosedAtom(const ch
436 const char *path,
437 Bool only_if_exist)
439 - char propName[14+1+MAXNODENAMELEN+1+MAXUSERNAMELEN+1+MAXSERVERNAMELEN+1+MAXPATHLEN+1+9];
440 - const char *userName = GetUserName();
441 - const char *hostName = GetNameOfHost();
442 + char propName[14+1+MAXNODENAMELEN+1+MAXUSERNAMELEN+1+MAXSERVERNAMELEN+1+MAXPATHLEN+1+9+1];
443 + const char *userName = GetUserName(NEDIT_NAME);
444 + const char *hostName = GetNameOfHost(NEDIT_NAME);
445 Atom atom;
447 sprintf(propName, "NEDIT_5.7_FILE_%s_%s_%s_%s_WF_CLOSED", hostName, userName, serverName, path);
448 @@ -116,9 +116,9 @@ Atom CreateServerFileClosedAtom(const ch
450 void DeleteServerFileAtoms(const char* serverName, Window rootWindow)
452 - char propNamePrefix[14+1+MAXNODENAMELEN+1+MAXUSERNAMELEN+1+MAXSERVERNAMELEN+1];
453 - const char *userName = GetUserName();
454 - const char *hostName = GetNameOfHost();
455 + char propNamePrefix[14+1+MAXNODENAMELEN+1+MAXUSERNAMELEN+1+MAXSERVERNAMELEN+1+1];
456 + const char *userName = GetUserName(NEDIT_NAME);
457 + const char *hostName = GetNameOfHost(NEDIT_NAME);
458 int length = sprintf(propNamePrefix, "NEDIT_5.7_FILE_%s_%s_%s_", hostName, userName, serverName);
460 int nProperties;
461 diff --quilt old/util/utils.h new/util/utils.h
462 --- old/util/utils.h
463 +++ new/util/utils.h
464 @@ -37,11 +37,13 @@
465 #include <sys/param.h>
466 #endif /*VMS*/
468 +enum nameType {LOCAL_NAME, NEDIT_NAME};
470 const char *GetCurrentDir(void);
471 const char *GetHomeDir(void);
472 char *PrependHome(const char *filename, char *buf, size_t buflen);
473 -const char *GetUserName(void);
474 -const char *GetNameOfHost(void);
475 +const char *GetUserName(enum nameType name);
476 +const char *GetNameOfHost(enum nameType name);
477 int Min(int i1, int i2);
478 const char* GetRCFileName(int type);
479 const char* GetNEditHome(void);
480 diff --quilt old/source/windowTitle.c new/source/windowTitle.c
481 --- old/source/windowTitle.c
482 +++ new/source/windowTitle.c
483 @@ -352,7 +352,7 @@ char *FormatWindowTitle(const char* file
485 } else if (*titleFormat == 'h') {
486 int comps = c - '0';
487 - char* hostname = strdup(GetNameOfHost());
488 + char* hostname = strdup(GetNameOfHost(NEDIT_NAME));
489 char *p, *n;
490 hostNamePresent = True;
491 titleFormat++; /* delete the argument */
492 @@ -380,7 +380,8 @@ char *FormatWindowTitle(const char* file
494 case 'h': /* host name */
495 hostNamePresent = True;
496 - titlePtr = safeStrCpy(titlePtr, titleEnd, GetNameOfHost());
497 + titlePtr = safeStrCpy(titlePtr, titleEnd,
498 + GetNameOfHost(NEDIT_NAME));
499 break;
501 case 'S': /* file status */
502 @@ -401,7 +402,8 @@ char *FormatWindowTitle(const char* file
504 case 'u': /* user name */
505 userNamePresent = True;
506 - titlePtr = safeStrCpy(titlePtr, titleEnd, GetUserName());
507 + titlePtr = safeStrCpy(titlePtr, titleEnd,
508 + GetUserName(NEDIT_NAME));
509 break;
511 case '%': /* escaped % */