2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: fileIo.c /main/4 1996/10/04 17:24:28 drk $ */
24 /**********************************<+>*************************************
25 ***************************************************************************
29 ** Project: DT dtpad, a memo maker type editor based on the Dt Editor
35 *******************************************************************
36 ** (c) Copyright Hewlett-Packard Company, 1991, 1992. All rights are
37 ** reserved. Copying or other reproduction of this program
38 ** except for archival purposes is prohibited without prior
39 ** written consent of Hewlett-Packard Company.
40 ********************************************************************
42 ********************************************************************
43 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
44 ** (c) Copyright 1993, 1994 International Business Machines Corp.
45 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
46 ** (c) Copyright 1993, 1994 Novell, Inc.
47 ********************************************************************
49 ** ToDo: roll in fixes for 10.0 ivepad
52 **************************************************************************
53 **********************************<+>*************************************/
56 #include <sys/types.h>
59 #include <Xm/LabelG.h>
62 /************************************************************************
63 * LoadFile - Opens the specified file and loads its contents to the
66 * The filename is specified either by pPad->fileStuff.fileName or
67 * the 'include' argument. If the filename is specified via include,
68 * the file is inserted at the current cursor location. In both
69 * instances, the filename is assumed to be relative to the local host
70 * where dtpad is running.
72 ************************************************************************/
74 The NOT_SAMPLE warnings/errors need to be added to the message
75 catalog. Removed ifdefs.*/
83 DtEditorErrorCode errorCode;
84 DtEditorContentRec contentRec;
85 Boolean fileLoaded = False;
86 Boolean fileLoadError = False;
89 if (include != (char *)NULL) {
92 localName = pPad->fileStuff.fileName;
93 pPad->fileStuff.readOnly = False;
96 if (localName && *localName) {
97 /* try to load the file to the Dt Editor widget */
98 _DtTurnOnHourGlass(pPad->app_shell);
99 XSync(XtDisplay(pPad->editor), False);
100 if (include != (char *) NULL) {
101 errorCode = DtEditorInsertFromFile(
105 pPad->fileStuff.fileExists = True;
106 errorCode = DtEditorSetContentsFromFile(
110 _DtTurnOffHourGlass(pPad->app_shell);
112 case DtEDITOR_NO_ERRORS: /* file is read/writeable */
115 case DtEDITOR_READ_ONLY_FILE:
117 if (include == (char *) NULL) {
118 pPad->fileStuff.readOnly = True;
119 if (pPad->xrdb.readOnlyWarning &&
120 ! pPad->xrdb.statusLine &&
121 ! pPad->xrdb.viewOnly) {
122 Warning(pPad, (char *) GETMESSAGE(6, 1,
123 "This file has been opened for reading only."),
128 case DtEDITOR_NONEXISTENT_FILE:
129 if (include != (char *) NULL ) {
130 Warning(pPad, (char *) GETMESSAGE(6, 2,
131 "This file does not exist."),
133 fileLoadError = True;
134 } else if (pPad->xrdb.viewOnly) {
135 Warning(pPad, (char *) GETMESSAGE(6, 2,
136 "This file does not exist."),
138 } else if (pPad->xrdb.missingFileWarning) {
139 Warning(pPad, (char *) GETMESSAGE(6, 2,
140 "This file does not exist."),
144 case DtEDITOR_DIRECTORY:
145 Warning(pPad, (char *) GETMESSAGE(6, 3,
146 "Unable to edit a Directory."),
148 fileLoadError = True;
150 case DtEDITOR_CHAR_SPECIAL_FILE:
151 Warning(pPad, (char *) GETMESSAGE(6, 4,
152 "Unable to edit a character special device file."),
154 fileLoadError = True;
156 case DtEDITOR_BLOCK_MODE_FILE:
157 Warning(pPad, (char *) GETMESSAGE(6, 5,
158 "Unable to edit a block mode device file."),
160 fileLoadError = True;
162 case DtEDITOR_NULLS_REMOVED:
163 Warning(pPad, (char *) GETMESSAGE(6, 6,
164 "Embedded Nulls stripped from file."),
168 case DtEDITOR_INSUFFICIENT_MEMORY:
169 Warning(pPad, (char*) GETMESSAGE(6, 7,
170 "Unable to load file (insufficient memory)."),
172 fileLoadError = True;
174 case DtEDITOR_NO_FILE_ACCESS:
175 Warning(pPad, (char *) GETMESSAGE(6, 8,
176 "Unable to access file (can't determine its status)."),
178 fileLoadError = True;
180 case DtEDITOR_UNREADABLE_FILE:
181 Warning(pPad, (char *) GETMESSAGE(6, 9,
182 "Unable to read from the file (probably no read permission)."),
184 fileLoadError = True;
187 Warning(pPad, (char *) GETMESSAGE(6, 12,
188 "Unable to read from the file (unknown reason)."),
190 fileLoadError = True;
192 } /* switch (errorCode) */
193 } /* file name specified */
195 if (include != (char *)NULL)
199 * We only get this far if the current file was to be changed
200 * (i.e. the file was not included)
202 SetStatusLineMsg(pPad); /* set readOnly/viewOnly in status line msg */
205 pPad->fileStuff.fileExists = True;
207 pPad->fileStuff.fileExists = False;
209 /* null out Editor widget */
210 contentRec.type = DtEDITOR_TEXT;
211 contentRec.value.string = "";
212 errorCode = DtEditorSetContents(pPad->editor, &contentRec);
213 if (errorCode != DtEDITOR_NO_ERRORS)
214 Warning(pPad,"Internal Error: Unable to NULL Editor Widget.",XmDIALOG_ERROR);
216 /* clear stale file stuff */
218 if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName)
219 XtFree(pPad->fileStuff.fileName);
220 pPad->fileStuff.fileName = NULL;
221 ChangeMainWindowTitle(pPad);
225 /* set the pathDir and fileName */
226 if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName) {
229 strcpy(pPad->fileStuff.pathDir, pPad->fileStuff.fileName);
230 if ((lastSlash = MbStrrchr(pPad->fileStuff.pathDir, '/')) !=
232 *(lastSlash + 1) = (char)'\0';
235 lastSlash = MbStrrchr(pPad->fileStuff.fileName, '/');
236 if (lastSlash != (char *)NULL) {
239 lastSlash = pPad->fileStuff.fileName;
241 if (*lastSlash == (char)'-' || *lastSlash == (char)'*') {
242 XtFree(pPad->fileStuff.fileName);
243 pPad->fileStuff.fileName = (char *)NULL;
250 /************************************************************************
251 * GetTempFile - generates a file name for a temporary file that can be
253 ************************************************************************/
257 char *tempname = (char *)XtMalloc(L_tmpnam); /* Temporary file name. */
260 (void)tmpnam(tempname);
261 if ((tfp = fopen(tempname, "w")) == NULL)
265 * If tmpnam fails, then try to create our own temp name.
266 * Try a couple of different names if necessary.
269 tempname = XtMalloc(256);
271 sprintf(tempname, "/usr/tmp/editor%ld", (long)pid);
272 if ((tfp = fopen(tempname, "w")) == NULL)
274 sprintf(tempname, "/tmp/editor%ld", (long)pid);
275 if ((tfp = fopen(tempname, "w")) == NULL)
287 extern Editor *pPadList; /* declared/set in main.c */
290 /************************************************************************
291 * AddPound - add a "#" character to the beginning of the base name of
292 * the file name passed in the nameBuf parameter. A pointer to the
293 * new name is returned. The name is constructed in a static buffer.
294 * If nameBuf is empty, it returns the file name "#UNTITLED#".
295 ************************************************************************/
301 static char returnBuf[512];
303 if (nameBuf != (char *)NULL && nameBuf[0] != (char) '\0') {
305 strcpy(tempBuf, nameBuf);
306 baseName = MbStrrchr(tempBuf, '/');
307 if (baseName != (char *)NULL) {
308 strncpy(returnBuf, tempBuf, (baseName - tempBuf) + 1);
309 returnBuf[(baseName - tempBuf) + 1] = (char)'\0';
311 strcat(returnBuf, "#");
312 strcat(returnBuf, baseName);
313 if (returnBuf[strlen(returnBuf) - 1] != (char)'#')
314 strcat(returnBuf, "#");
316 sprintf(returnBuf, "#%s", tempBuf);
317 if(strlen(returnBuf) && returnBuf[strlen(returnBuf) - 1] != (char)'#')
318 strcat(returnBuf, "#");
321 sprintf(returnBuf, "#%s#", GETMESSAGE(5, 21, "UNTITLED"));
327 /************************************************************************
328 * PanicSave - immediately saves the text for each edit session handled
329 * by the text editor to #[#]<filename>.
330 ************************************************************************/
335 struct stat statbuf; /* Information on a file. */
337 DtEditorErrorCode errorCode;
339 for (pPad = pPadList; pPad != (Editor *)NULL; pPad = pPad->pNextPad) {
340 char *fileName = pPad->fileStuff.fileName;
341 if (pPad->inUse != True || pPad->editor == NULL ||
342 (! DtEditorCheckForUnsavedChanges(pPad->editor)))
344 /* -----> Try to cook up a name for a file that doesn't already exist */
345 fileName = AddPound(pPad->fileStuff.fileName);
346 if (stat(fileName, &statbuf) == 0) {
347 fileName = AddPound(fileName);
348 if (stat(fileName, &statbuf) == 0) {
349 fileName = AddPound(fileName);
350 if (stat(fileName, &statbuf) == 0) {
351 /* Give up. We've tried enough names. The user loses. */
356 addNewLines = pPad->xrdb.wordWrap == True &&
357 pPad->fileStuff.saveWithNewlines == True;
358 errorCode = DtEditorSaveContentsToFile(
361 False, /* don't overwrite existing file */
362 addNewLines, /* replace soft line feeds? */
363 False); /* don't mark contents as saved */
365 /* don't really care about errorCode since we're in a hurry and
366 * can't do anything about it anyway */
372 /************************************************************************
373 * SetStatusLineMsg - sets the message (XmTextField) portion of the
374 * DtEditor widget's status line based on whether the pad is in
375 * viewOnly mode or the file being edited/displayed is readOnly.
376 ************************************************************************/
384 if (pPad->xrdb.viewOnly) {
385 message = (char *) GETMESSAGE(6, 10, "View Only");
386 } else if (pPad->fileStuff.readOnly) {
387 message = (char *) GETMESSAGE(6, 11, "Read Only");
390 XmTextFieldSetString(pPad->statusLineMsg, message);