1 /* $XConsortium: fileIo.c /main/4 1996/10/04 17:24:28 drk $ */
2 /**********************************<+>*************************************
3 ***************************************************************************
7 ** Project: DT dtpad, a memo maker type editor based on the Dt Editor
13 *******************************************************************
14 ** (c) Copyright Hewlett-Packard Company, 1991, 1992. All rights are
15 ** reserved. Copying or other reproduction of this program
16 ** except for archival purposes is prohibited without prior
17 ** written consent of Hewlett-Packard Company.
18 ********************************************************************
20 ********************************************************************
21 ** (c) Copyright 1993, 1994 Hewlett-Packard Company
22 ** (c) Copyright 1993, 1994 International Business Machines Corp.
23 ** (c) Copyright 1993, 1994 Sun Microsystems, Inc.
24 ** (c) Copyright 1993, 1994 Novell, Inc.
25 ********************************************************************
27 ** ToDo: roll in fixes for 10.0 ivepad
30 **************************************************************************
31 **********************************<+>*************************************/
34 #include <sys/types.h>
37 #include <Xm/LabelG.h>
40 /************************************************************************
41 * LoadFile - Opens the specified file and loads its contents to the
44 * The filename is specified either by pPad->fileStuff.fileName or
45 * the 'include' argument. If the filename is specified via include,
46 * the file is inserted at the current cursor location. In both
47 * instances, the filename is assumed to be relative to the local host
48 * where dtpad is running.
50 ************************************************************************/
52 The NOT_SAMPLE warnings/errors need to be added to the message
53 catalog. Removed ifdefs.*/
61 DtEditorErrorCode errorCode;
62 DtEditorContentRec contentRec;
63 Boolean fileLoaded = False;
64 Boolean fileLoadError = False;
67 if (include != (char *)NULL) {
70 localName = pPad->fileStuff.fileName;
71 pPad->fileStuff.readOnly = False;
74 if (localName && *localName) {
75 /* try to load the file to the Dt Editor widget */
76 _DtTurnOnHourGlass(pPad->app_shell);
77 XSync(XtDisplay(pPad->editor), False);
78 if (include != (char *) NULL) {
79 errorCode = DtEditorInsertFromFile(
83 pPad->fileStuff.fileExists = True;
84 errorCode = DtEditorSetContentsFromFile(
88 _DtTurnOffHourGlass(pPad->app_shell);
90 case DtEDITOR_NO_ERRORS: /* file is read/writeable */
93 case DtEDITOR_READ_ONLY_FILE:
95 if (include == (char *) NULL) {
96 pPad->fileStuff.readOnly = True;
97 if (pPad->xrdb.readOnlyWarning &&
98 ! pPad->xrdb.statusLine &&
99 ! pPad->xrdb.viewOnly) {
100 Warning(pPad, (char *) GETMESSAGE(6, 1,
101 "This file has been opened for reading only."),
106 case DtEDITOR_NONEXISTENT_FILE:
107 if (include != (char *) NULL ) {
108 Warning(pPad, (char *) GETMESSAGE(6, 2,
109 "This file does not exist."),
111 fileLoadError = True;
112 } else if (pPad->xrdb.viewOnly) {
113 Warning(pPad, (char *) GETMESSAGE(6, 2,
114 "This file does not exist."),
116 } else if (pPad->xrdb.missingFileWarning) {
117 Warning(pPad, (char *) GETMESSAGE(6, 2,
118 "This file does not exist."),
122 case DtEDITOR_DIRECTORY:
123 Warning(pPad, (char *) GETMESSAGE(6, 3,
124 "Unable to edit a Directory."),
126 fileLoadError = True;
128 case DtEDITOR_CHAR_SPECIAL_FILE:
129 Warning(pPad, (char *) GETMESSAGE(6, 4,
130 "Unable to edit a character special device file."),
132 fileLoadError = True;
134 case DtEDITOR_BLOCK_MODE_FILE:
135 Warning(pPad, (char *) GETMESSAGE(6, 5,
136 "Unable to edit a block mode device file."),
138 fileLoadError = True;
140 case DtEDITOR_NULLS_REMOVED:
141 Warning(pPad, (char *) GETMESSAGE(6, 6,
142 "Embedded Nulls stripped from file."),
146 case DtEDITOR_INSUFFICIENT_MEMORY:
147 Warning(pPad, (char*) GETMESSAGE(6, 7,
148 "Unable to load file (insufficient memory)."),
150 fileLoadError = True;
152 case DtEDITOR_NO_FILE_ACCESS:
153 Warning(pPad, (char *) GETMESSAGE(6, 8,
154 "Unable to access file (can't determine its status)."),
156 fileLoadError = True;
158 case DtEDITOR_UNREADABLE_FILE:
159 Warning(pPad, (char *) GETMESSAGE(6, 9,
160 "Unable to read from the file (probably no read permission)."),
162 fileLoadError = True;
165 Warning(pPad, (char *) GETMESSAGE(6, 12,
166 "Unable to read from the file (unknown reason)."),
168 fileLoadError = True;
170 } /* switch (errorCode) */
171 } /* file name specified */
173 if (include != (char *)NULL)
177 * We only get this far if the current file was to be changed
178 * (i.e. the file was not included)
180 SetStatusLineMsg(pPad); /* set readOnly/viewOnly in status line msg */
183 pPad->fileStuff.fileExists = True;
185 pPad->fileStuff.fileExists = False;
187 /* null out Editor widget */
188 contentRec.type = DtEDITOR_TEXT;
189 contentRec.value.string = "";
190 errorCode = DtEditorSetContents(pPad->editor, &contentRec);
191 if (errorCode != DtEDITOR_NO_ERRORS)
192 Warning(pPad,"Internal Error: Unable to NULL Editor Widget.",XmDIALOG_ERROR);
194 /* clear stale file stuff */
196 if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName)
197 XtFree(pPad->fileStuff.fileName);
198 pPad->fileStuff.fileName = NULL;
199 ChangeMainWindowTitle(pPad);
203 /* set the pathDir and fileName */
204 if (pPad->fileStuff.fileName && *pPad->fileStuff.fileName) {
207 strcpy(pPad->fileStuff.pathDir, pPad->fileStuff.fileName);
208 if ((lastSlash = MbStrrchr(pPad->fileStuff.pathDir, '/')) !=
210 *(lastSlash + 1) = (char)'\0';
213 lastSlash = MbStrrchr(pPad->fileStuff.fileName, '/');
214 if (lastSlash != (char *)NULL) {
217 lastSlash = pPad->fileStuff.fileName;
219 if (*lastSlash == (char)'-' || *lastSlash == (char)'*') {
220 XtFree(pPad->fileStuff.fileName);
221 pPad->fileStuff.fileName = (char *)NULL;
228 /************************************************************************
229 * GetTempFile - generates a file name for a temporary file that can be
231 ************************************************************************/
235 char *tempname = (char *)XtMalloc(L_tmpnam); /* Temporary file name. */
238 (void)tmpnam(tempname);
239 if ((tfp = fopen(tempname, "w")) == NULL)
243 * If tmpnam fails, then try to create our own temp name.
244 * Try a couple of different names if necessary.
247 tempname = XtMalloc(256);
249 sprintf(tempname, "/usr/tmp/editor%ld", (long)pid);
250 if ((tfp = fopen(tempname, "w")) == NULL)
252 sprintf(tempname, "/tmp/editor%ld", (long)pid);
253 if ((tfp = fopen(tempname, "w")) == NULL)
265 extern Editor *pPadList; /* declared/set in main.c */
268 /************************************************************************
269 * AddPound - add a "#" character to the beginning of the base name of
270 * the file name passed in the nameBuf parameter. A pointer to the
271 * new name is returned. The name is constructed in a static buffer.
272 * If nameBuf is empty, it returns the file name "#UNTITLED#".
273 ************************************************************************/
279 static char returnBuf[512];
281 if (nameBuf != (char *)NULL && nameBuf[0] != (char) '\0') {
283 strcpy(tempBuf, nameBuf);
284 baseName = MbStrrchr(tempBuf, '/');
285 if (baseName != (char *)NULL) {
286 strncpy(returnBuf, tempBuf, (baseName - tempBuf) + 1);
287 returnBuf[(baseName - tempBuf) + 1] = (char)'\0';
289 strcat(returnBuf, "#");
290 strcat(returnBuf, baseName);
291 if (returnBuf[strlen(returnBuf) - 1] != (char)'#')
292 strcat(returnBuf, "#");
294 sprintf(returnBuf, "#%s", tempBuf);
295 if(returnBuf[strlen(returnBuf) - 1] != (char)'#')
296 strcat(returnBuf, "#");
299 sprintf(returnBuf, "#%s#", GETMESSAGE(5, 21, "UNTITLED"));
305 /************************************************************************
306 * PanicSave - immediately saves the text for each edit session handled
307 * by the text editor to #[#]<filename>.
308 ************************************************************************/
313 struct stat statbuf; /* Information on a file. */
315 DtEditorErrorCode errorCode;
317 for (pPad = pPadList; pPad != (Editor *)NULL; pPad = pPad->pNextPad) {
318 char *fileName = pPad->fileStuff.fileName;
319 if (pPad->inUse != True || pPad->editor == NULL ||
320 (! DtEditorCheckForUnsavedChanges(pPad->editor)))
322 /* -----> Try to cook up a name for a file that doesn't already exist */
323 fileName = AddPound(pPad->fileStuff.fileName);
324 if (stat(fileName, &statbuf) == 0) {
325 fileName = AddPound(fileName);
326 if (stat(fileName, &statbuf) == 0) {
327 fileName = AddPound(fileName);
328 if (stat(fileName, &statbuf) == 0) {
329 /* Give up. We've tried enough names. The user loses. */
334 addNewLines = pPad->xrdb.wordWrap == True &&
335 pPad->fileStuff.saveWithNewlines == True;
336 errorCode = DtEditorSaveContentsToFile(
339 False, /* don't overwrite existing file */
340 addNewLines, /* replace soft line feeds? */
341 False); /* don't mark contents as saved */
343 /* don't really care about errorCode since we're in a hurry and
344 * can't do anything about it anyway */
350 /************************************************************************
351 * SetStatusLineMsg - sets the message (XmTextField) portion of the
352 * DtEditor widget's status line based on whether the pad is in
353 * viewOnly mode or the file being edited/displayed is readOnly.
354 ************************************************************************/
362 if (pPad->xrdb.viewOnly) {
363 message = (char *) GETMESSAGE(6, 10, "View Only");
364 } else if (pPad->fileStuff.readOnly) {
365 message = (char *) GETMESSAGE(6, 11, "Read Only");
368 XmTextFieldSetString(pPad->statusLineMsg, message);