SmCreateDirs.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $TOG: SmCreateDirs.c /main/9 1997/02/24 09:23:16 barstow $ */
  24. /* *
  25. * (c) Copyright 1993, 1994 Hewlett-Packard Company *
  26. * (c) Copyright 1993, 1994 International Business Machines Corp. *
  27. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
  28. * (c) Copyright 1993, 1994 Novell, Inc. *
  29. */
  30. /******************************************************************************
  31. *
  32. * File Name: SmCreateDirs.c
  33. *
  34. *****************************************************************************/
  35. #include <stdio.h>
  36. #include <sys/param.h>
  37. #include <sys/types.h>
  38. #include <sys/stat.h>
  39. #include <sys/wait.h>
  40. #include <stdlib.h>
  41. #include <unistd.h>
  42. #include <X11/Xlib.h>
  43. #include <X11/Xlibint.h>
  44. #include <X11/Intrinsic.h>
  45. #include <Dt/DtNlUtils.h>
  46. #include <Dt/DtPStrings.h>
  47. #include <Dt/WsmP.h>
  48. /******** Private Function Declarations ********/
  49. static int
  50. GetShortHostname (
  51. char*,
  52. unsigned int);
  53. static char *
  54. GetSessionDirProperty (
  55. Display *display);
  56. static char *
  57. GetDisplayName (
  58. Display *display);
  59. /*************************************<->*************************************
  60. *
  61. * _DtCreateDtDirs (display)
  62. *
  63. * 1. Creates ~/.dt, ~/.dt/types, ~/.dt/tmp and either
  64. * ~/.dt/sessions or ~/.dt/<display_name>
  65. *
  66. * 2. Returns the name of the session directory
  67. *
  68. * Outputs:
  69. * -------
  70. * Returns the session directory or NULL if malloc fails or ~/.dt
  71. * cannot be created
  72. *
  73. *************************************<->***********************************/
  74. char *
  75. _DtCreateDtDirs(
  76. Display *display )
  77. {
  78. char *tmpPath = NULL;
  79. Boolean needSessionsDir = False;
  80. Boolean useOldSession = False;
  81. struct stat buf;
  82. int status;
  83. char *home = NULL;
  84. char *sessionDir = NULL;
  85. char *displayName = NULL;
  86. /*
  87. * Sanity check - make sure there's an existing display
  88. */
  89. if(!display)
  90. return(NULL);
  91. if ((home = getenv("HOME")) == NULL)
  92. home = "";
  93. tmpPath = XtCalloc(1, MAXPATHLEN);
  94. if(tmpPath == NULL)
  95. return(NULL);
  96. /*
  97. * If the $HOME/.dt directory does not exist, create it
  98. */
  99. snprintf(tmpPath, MAXPATHLEN, "%s/%s", home, DtPERSONAL_CONFIG_DIRECTORY);
  100. status = stat(tmpPath, &buf);
  101. if (status == -1) {
  102. status = mkdir(tmpPath, 0000);
  103. if (status == -1) {
  104. XtFree(tmpPath);
  105. return(NULL);
  106. }
  107. (void)chmod(tmpPath, 0755);
  108. }
  109. /*
  110. * Create the personal DB directory if it does not exist.
  111. */
  112. snprintf(tmpPath, MAXPATHLEN, "%s/%s", home, DtPERSONAL_DB_DIRECTORY);
  113. if ((status = stat (tmpPath, &buf)) == -1) {
  114. if ((status = mkdir (tmpPath, 0000)) != -1)
  115. (void) chmod (tmpPath, 0755);
  116. }
  117. /*
  118. * Create the personal tmp dir if it does not exist.
  119. */
  120. snprintf(tmpPath, MAXPATHLEN, "%s/%s", home, DtPERSONAL_TMP_DIRECTORY);
  121. if ((status = stat (tmpPath, &buf)) == -1) {
  122. if ((status = mkdir (tmpPath, 0000)) != -1)
  123. (void) chmod (tmpPath, 0755);
  124. }
  125. /*
  126. * The creation of the session directory is tricky:
  127. *
  128. * For CDE 1.0 sessions, if a display-specific directory exists,
  129. * it will take precedence. CDE 1.0 does not support the selection
  130. * of a session.
  131. *
  132. * However, for newer CDE implementations, if a specific session
  133. * was selected, the specified session will be used. If no session
  134. * was selected, the CDE 1.0 mechanism will be used.
  135. *
  136. * If a CDEnext session is being used, the session directory will
  137. * be on a property on the root window.
  138. *
  139. * Must check for this property and use it if is set.
  140. */
  141. if ((sessionDir = GetSessionDirProperty (display)) != NULL) {
  142. if (!strcmp (sessionDir, DtSM_SESSION_DIRECTORY)) {
  143. /*
  144. * Need to create a DtSM_SESSION_DIRECTORY dir if it
  145. * does not exist.
  146. */
  147. needSessionsDir = True;
  148. } else if (!strcmp (sessionDir, DtSM_SESSION_DISPLAY_DIRECTORY)) {
  149. /*
  150. * Create a directory for a display-specific session if necessary
  151. */
  152. if ((displayName = GetDisplayName (display)) != NULL) {
  153. snprintf(tmpPath, MAXPATHLEN, "%s/%s/%s",
  154. home,
  155. DtPERSONAL_CONFIG_DIRECTORY,
  156. displayName);
  157. free(displayName); /* CDExc22771 */
  158. displayName = NULL;
  159. if ((status = stat (tmpPath, &buf)) == -1) {
  160. if ((status = mkdir (tmpPath, 0000)) != -1)
  161. (void) chmod (tmpPath, 0755);
  162. else
  163. useOldSession = True;
  164. }
  165. }
  166. else {
  167. /*
  168. * Something's wrong with the display, use the fallback
  169. */
  170. useOldSession = True;
  171. }
  172. } else {
  173. /*
  174. * The property contains an unrecognized value, fallback to
  175. * other session selection algorithm.
  176. */
  177. useOldSession = True;
  178. }
  179. XFree (sessionDir);
  180. }
  181. else
  182. useOldSession = True;
  183. if (useOldSession) {
  184. /*
  185. * Check for a display dependent directory. If one exists,
  186. * it will be used.
  187. *
  188. * This is done for backward compatibility - THE DISPLAY
  189. * DEPENDENT DIR TAKES PRECEDENT.
  190. */
  191. if ((displayName = GetDisplayName (display)) != NULL) {
  192. snprintf(tmpPath, MAXPATHLEN, "%s/%s/%s",
  193. home,
  194. DtPERSONAL_CONFIG_DIRECTORY,
  195. displayName);
  196. free(displayName); /* CDExc22771 */
  197. displayName = NULL;
  198. if ((status = stat(tmpPath, &buf)) != 0)
  199. /*
  200. * The display directory does not exist
  201. */
  202. needSessionsDir = True;
  203. }
  204. else
  205. needSessionsDir = True;
  206. }
  207. if(needSessionsDir)
  208. {
  209. /*
  210. * If we don't have an old style directory - we check for a sessions
  211. * directory, and create it if it doesn't exist
  212. */
  213. snprintf(tmpPath, MAXPATHLEN, "%s/%s/%s",
  214. home,
  215. DtPERSONAL_CONFIG_DIRECTORY,
  216. DtSM_SESSION_DIRECTORY);
  217. if ((status = stat(tmpPath, &buf)) == -1) {
  218. if ((status = mkdir(tmpPath, 0000)) == -1) {
  219. XtFree(tmpPath);
  220. return(NULL);
  221. }
  222. (void)chmod(tmpPath, 0755);
  223. }
  224. }
  225. return(tmpPath);
  226. }
  227. /*------------------------------------------------------------------------+*/
  228. static int
  229. GetShortHostname(
  230. char *buffer,
  231. unsigned int bufsize )
  232. {
  233. char * ptr;
  234. int status;
  235. if ((status = gethostname(buffer, bufsize)))
  236. return status; /* failed gethostname */
  237. if ((ptr = strstr(buffer, (char *)".")))
  238. *ptr = '\0'; /* delete domain name if there is one */
  239. return 0;
  240. }
  241. /*------------------------------------------------------------------------+*/
  242. /*
  243. * GetSessionDirProperty -
  244. */
  245. static char *
  246. GetSessionDirProperty (
  247. Display *display)
  248. {
  249. int propStatus;
  250. Atom actualType;
  251. int actualFormat;
  252. unsigned long nitems;
  253. unsigned long leftover;
  254. char *property = NULL;
  255. Atom tmpAtom;
  256. tmpAtom = XInternAtom(display, _XA_DT_RESTORE_DIR, False);
  257. propStatus = XGetWindowProperty (display, RootWindow(display, 0),
  258. (Atom) tmpAtom, 0L,
  259. 1000000L, False,
  260. AnyPropertyType, &actualType,
  261. &actualFormat, &nitems, &leftover,
  262. (unsigned char **)&property);
  263. if (propStatus == Success && actualType != None &&
  264. actualFormat == 8 && nitems != 0)
  265. return(property);
  266. if (property)
  267. XFree(property);
  268. return (NULL);
  269. }
  270. /*------------------------------------------------------------------------+*/
  271. /*
  272. * GetDisplayName -
  273. */
  274. static char *
  275. GetDisplayName (
  276. Display *display)
  277. {
  278. char *tmpPath;
  279. char hostName[101], displayName[101];
  280. char *pch, *tmpNumber = NULL;
  281. char *returnPath;
  282. /*
  283. * Create the display name and append it to the current path.
  284. */
  285. snprintf(hostName, sizeof(hostName), "%s", display->display_name);
  286. snprintf(displayName, sizeof(displayName), "%s", display->display_name);
  287. /*
  288. * If this is run to unix or local get the host name - otherwise
  289. * just use what we have
  290. */
  291. /*
  292. * Strip host name to nothing but the unqualified (short) host name
  293. */
  294. if ((pch = DtStrchr(hostName, ':')))
  295. *pch = '\0';
  296. if ((pch = DtStrchr(hostName, '.')))
  297. *pch = '\0';
  298. if((!strcmp(hostName, "unix")) || (!strcmp(hostName, "local"))
  299. || (!strcmp(hostName, "")))
  300. {
  301. /*
  302. * host name is local - get the real name
  303. */
  304. (void) GetShortHostname(hostName, 25);
  305. }
  306. /*
  307. * Strip screen off of display name
  308. */
  309. if ((tmpNumber = DtStrchr(displayName, ':')))
  310. if ((pch = DtStrchr(tmpNumber, '.')))
  311. *pch = '\0';
  312. /*
  313. * Strip it down to 14 chars (actually, 14 bytes or less)
  314. */
  315. if((strlen(tmpNumber) + strlen(hostName)) > (size_t)14)
  316. {
  317. size_t tnLen;
  318. int lastChLen;
  319. char *lastCh;
  320. /* Pare display number to at most 12 bytes */
  321. while ((tnLen = strlen(tmpNumber)) > (size_t)12)
  322. {
  323. /* Remove the last character, an try again */
  324. DtLastChar(tmpNumber, &lastCh, &lastChLen);
  325. *lastCh = '\0';
  326. }
  327. /* Pare down host name, if necessary */
  328. while ((strlen(hostName) + tnLen) > (size_t)14)
  329. {
  330. /* Remove the last character, and try again */
  331. DtLastChar(hostName, &lastCh, &lastChLen);
  332. *lastCh = '\0';
  333. }
  334. }
  335. strcat (hostName, tmpNumber);
  336. returnPath = strdup (hostName);
  337. return (returnPath);
  338. }