📄 file.c
字号:
window->fileMissing = FALSE; } else { /* This needs to produce an error message -- the file can't be accessed! */ window->lastModTime = 0; window->fileMissing = TRUE; } return TRUE;}/*** Create a backup file for the current window. The name for the backup file** is generated using the name and path stored in the window and adding a** tilde (~) on UNIX and underscore (_) on VMS to the beginning of the name. */int WriteBackupFile(WindowInfo *window){ char *fileString = NULL; char name[MAXPATHLEN]; FILE *fp; int fd, fileLen; /* Generate a name for the autoSave file */ backupFileName(window, name, sizeof(name)); /* remove the old backup file. Well, this might fail - we'll notice later however. */ remove(name); /* open the file, set more restrictive permissions (using default permissions was somewhat of a security hole, because permissions were independent of those of the original file being edited */#ifdef VMS if ((fp = fopen(name, "w", "rfm = stmlf")) == NULL)#else if ((fd = open(name, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR | S_IWUSR)) < 0 || (fp = fdopen(fd, "w")) == NULL)#endif /* VMS */ { DialogF(DF_WARN, window->shell, 1, "Error writing Backup", "Unable to save backup for %s:\n%s\n" "Automatic backup is now off", "Dismiss", window->filename, errorString()); window->autoSave = FALSE; XmToggleButtonSetState(window->autoSaveItem, FALSE, FALSE); return FALSE; } /* Set VMS permissions */#ifdef VMS chmod(name, S_IRUSR | S_IWUSR);#endif /* get the text buffer contents and its length */ fileString = BufGetAll(window->buffer); fileLen = window->buffer->length; /* If null characters are substituted for, put them back */ BufUnsubstituteNullChars(fileString, window->buffer); /* add a terminating newline if the file doesn't already have one */ if (fileLen != 0 && fileString[fileLen-1] != '\n') fileString[fileLen++] = '\n'; /* null terminator no longer needed */ /* write out the file */#ifdef IBM_FWRITE_BUG write(fileno(fp), fileString, fileLen);#else fwrite(fileString, sizeof(char), fileLen, fp);#endif if (ferror(fp)) { DialogF(DF_ERR, window->shell, 1, "Error saving Backup", "Error while saving backup for %s:\n%s\n" "Automatic backup is now off", "Dismiss", window->filename, errorString()); fclose(fp); remove(name); XtFree(fileString); window->autoSave = FALSE; return FALSE; } /* close the backup file */ if (fclose(fp) != 0) { XtFree(fileString); return FALSE; } /* Free the text buffer copy returned from XmTextGetString */ XtFree(fileString); return TRUE;}/*** Remove the backup file associated with this window*/void RemoveBackupFile(WindowInfo *window){ char name[MAXPATHLEN]; backupFileName(window, name, sizeof(name)); remove(name);}/*** Generate the name of the backup file for this window from the filename** and path in the window data structure & write into name*/static void backupFileName(WindowInfo *window, char *name, int len){ char bckname[MAXPATHLEN];#ifdef VMS if (window->filenameSet) sprintf(name, "%s_%s", window->path, window->filename); else sprintf(name, "%s_%s", "SYS$LOGIN:", window->filename);#else strcpy(bckname, "~"); strcat(bckname, window->filename); if (window->filenameSet) sprintf(name, "%s~%s", window->path, window->filename); else PrependHome(bckname, name, len);#endif /*VMS*/}/*** If saveOldVersion is on, copies the existing version of the file to** <filename>.bck in anticipation of a new version being saved. Returns** True if backup fails and user requests that the new file not be written.*/static int writeBckVersion(WindowInfo *window){#ifndef VMS char fullname[MAXPATHLEN], bckname[MAXPATHLEN]; struct stat statbuf; FILE *inFP, *outFP; int fd, fileLen; char *fileString; /* Do only if version backups are turned on */ if (!window->saveOldVersion) { return False; } /* Get the full name of the file */ strcpy(fullname, window->path); strcat(fullname, window->filename); /* Generate name for old version */ { if ((int)(strlen(fullname) + 5) > (int)MAXPATHLEN) return bckError(window, "file name too long", window->filename); } sprintf(bckname, "%s.bck", fullname); /* Delete the old backup file */ /* Errors are ignored; we'll notice them later. */ unlink(bckname); /* open the file being edited. If there are problems with the old file, don't bother the user, just skip the backup */ inFP = fopen(fullname, "rb"); if (inFP == NULL) { return FALSE; } /* find the length of the file */ if (fstat(fileno(inFP), &statbuf) != 0) { return FALSE; } fileLen = statbuf.st_size; /* open the file exclusive and with restrictive permissions. */#ifdef VMS if ((outFP = fopen(bckname, "w", "rfm = stmlf")) == NULL) {#else if ((fd = open(bckname, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR | S_IWUSR)) < 0 || (outFP = fdopen(fd, "wb")) == NULL) {#endif /* VMS */ fclose(inFP); return bckError(window, "Error open backup file", bckname); }#ifdef VMS chmod(bckname, S_IRUSR | S_IWUSR); #endif /* Allocate space for the whole contents of the file */ fileString = (char *)malloc(fileLen); if (fileString == NULL) { fclose(inFP); fclose(outFP); return bckError(window, "out of memory", bckname); } /* read the file into fileString */ fread(fileString, sizeof(char), fileLen, inFP); if (ferror(inFP)) { fclose(inFP); fclose(outFP); free(fileString); return FALSE; } /* close the input file, ignore any errors */ fclose(inFP); /* write to the file */#ifdef IBM_FWRITE_BUG write(fileno(outFP), fileString, fileLen);#else fwrite(fileString, sizeof(char), fileLen, outFP);#endif if (ferror(outFP)) { fclose(outFP); remove(bckname); free(fileString); return bckError(window, errorString(), bckname); } free(fileString); /* close the file */ if (fclose(outFP) != 0) return bckError(window, errorString(), bckname);#endif /* VMS */ return FALSE;}/*** Error processing for writeBckVersion, gives the user option to cancel** the subsequent save, or continue and optionally turn off versioning*/static int bckError(WindowInfo *window, const char *errString, const char *file){ int resp; resp = DialogF(DF_ERR, window->shell, 3, "Error writing Backup", "Couldn't write .bck (last version) file.\n%s: %s", "Cancel Save", "Turn off Backups", "Continue", file, errString); if (resp == 1) return TRUE; if (resp == 2) { window->saveOldVersion = FALSE; XmToggleButtonSetState(window->saveLastItem, FALSE, FALSE); } return FALSE;}void PrintWindow(WindowInfo *window, int selectedOnly){ textBuffer *buf = window->buffer; selection *sel = &buf->primary; char *fileString = NULL; int fileLen; /* get the contents of the text buffer from the text area widget. Add wrapping newlines if necessary to make it match the displayed text */ if (selectedOnly) { if (!sel->selected) { XBell(TheDisplay, 0); return; } if (sel->rectangular) { fileString = BufGetSelectionText(buf); fileLen = strlen(fileString); } else fileString = TextGetWrapped(window->textArea, sel->start, sel->end, &fileLen); } else fileString = TextGetWrapped(window->textArea, 0, buf->length, &fileLen); /* If null characters are substituted for, put them back */ BufUnsubstituteNullChars(fileString, buf); /* add a terminating newline if the file doesn't already have one */ if (fileLen != 0 && fileString[fileLen-1] != '\n') fileString[fileLen++] = '\n'; /* null terminator no longer needed */ /* Print the string */ PrintString(fileString, fileLen, window->shell, window->filename); /* Free the text buffer copy returned from XmTextGetString */ XtFree(fileString);}/*** Print a string (length is required). parent is the dialog parent, for** error dialogs, and jobName is the print title.*/void PrintString(const char *string, int length, Widget parent, const char *jobName){ char tmpFileName[L_tmpnam]; /* L_tmpnam defined in stdio.h */ FILE *fp; int fd; /* Generate a temporary file name */ /* If the glibc is used, the linker issues a warning at this point. This is very thoughtful of him, but does not apply to NEdit. The recommended replacement mkstemp(3) uses the same algorithm as NEdit, namely 1. Create a filename 2. Open the file with the O_CREAT|O_EXCL flags So all an attacker can do is a DoS on the print function. */ tmpnam(tmpFileName); /* open the temporary file */#ifdef VMS if ((fp = fopen(tmpFileName, "w", "rfm = stmlf")) == NULL)#else if ((fd = open(tmpFileName, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR | S_IWUSR)) < 0 || (fp = fdopen(fd, "w")) == NULL)#endif /* VMS */ { DialogF(DF_WARN, parent, 1, "Error while Printing", "Unable to write file for printing:\n%s", "Dismiss", errorString()); return; }#ifdef VMS chmod(tmpFileName, S_IRUSR | S_IWUSR); #endif /* write to the file */#ifdef IBM_FWRITE_BUG write(fileno(fp), string, length);#else fwrite(string, sizeof(char), length, fp);#endif if (ferror(fp)) { DialogF(DF_ERR, parent, 1, "Error while Printing", "%s not printed:\n%s", "Dismiss", jobName, errorString()); fclose(fp); /* should call close(fd) in turn! */ remove(tmpFileName); return; } /* close the temporary file */ if (fclose(fp) != 0) { DialogF(DF_ERR, parent, 1, "Error while Printing", "Error closing temp. print file:\n%s", "Dismiss", errorString()); remove(tmpFileName); return; } /* Print the temporary file, then delete it and return success */#ifdef VMS strcat(tmpFileName, "."); PrintFile(parent, tmpFileName, jobName, True);#else PrintFile(parent, tmpFileName, jobName); remove(tmpFileName);#endif /*VMS*/ return;}/*** Wrapper for GetExistingFilename which uses the current window's path** (if set) as the default directory.*/int PromptForExistingFile(WindowInfo *window, char *prompt, char *fullname){ char *savedDefaultDir; int retVal; /* Temporarily set default directory to window->path, prompt for file, then, if the call was unsuccessful, restore the original default directory */ savedDefaultDir = GetFileDialogDefaultDirectory(); if (*window->path != '\0') SetFileDialogDefaultDirectory(window->path); retVal = GetExistingFilename(window->shell, prompt, fullname); if (retVal != GFN_OK) SetFileDialogDefaultDirectory(savedDefaultDir); if (savedDefaultDir != NULL) XtFree(savedDefaultDir); return retVal;}/*** Wrapper for HandleCustomNewFileSB which uses the current window's path** (if set) as the default directory, and asks about embedding newlines** to make wrapping permanent.*/int PromptForNewFile(WindowInfo *window, char *prompt, char *fullname, int *fileFormat, int *addWrap){ int n, retVal; Arg args[20]; XmString s1, s2; Widget fileSB, wrapToggle; Widget formatForm, formatBtns, unixFormat, dosFormat, macFormat; char *savedDefaultDir; *fileFormat = window->fileFormat; /* Temporarily set default directory to window->path, prompt for file, then, if the call was unsuccessful, restore the original default directory */ savedDefaultDir = GetFileDialogDefaultDirectory(); if (*window->path != '\0') SetFileDialogDefaultDirectory(window->path); /* Present a file selection dialog with an added field for requesting long line wrapping to become permanent via inserted newlines */ n = 0; XtSetArg(args[n], XmNselectionLabelString, s1 = XmStringCreateLocalized("New File Name:")); n++; XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++; XtSetArg(args[n], XmNdialogTitle, s2 = XmStringCreateSimple(prompt)); n++; fileSB = CreateFileSelectionDialog(window->shell,"FileSelect",args,n); XmStringFree(s1); XmStringFree(s2); formatForm = XtVaCreateManagedWidget("formatBtns", xmFormWidgetClass, fileSB, NULL); formatBtns = XtVaCreateManagedWidget("formatBtns", xmRowColumnWidgetClass, formatForm, XmNradioBehavior, XmONE_OF_MANY, XmNorientation, XmHORIZONTAL, XmNpacking, XmPACK_TIGHT, XmNtopAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, NULL); XtVaCreateManagedWidget("formatBtns", xmLabelWidgetClass, formatBtns, XmNlabelString, s1=XmStringCreateSimple("Format:"), NULL); XmStringFree(s1); unixFormat = XtVaCreateManagedWidget("unixFormat", xmToggleButtonWidgetClass, formatBtns, XmNlabelString, s1=XmStringCreateSimple("Unix"), XmNset, *fileFormat == UNIX_FILE_FORMAT, XmNuserData, UNIX_FILE_FORMAT, XmNmarginHeight, 0, XmNalignment, XmALIGNMENT_BEGINNING, XmNmnemonic, 'U', NULL); XmStringFree(s1); XtAddCallback(unixFormat, XmNvalueChangedCallback, setFormatCB, fileFormat); dosFormat = XtVaCreateManagedWidget("dosFormat", xmToggleButtonWidgetClass, formatBtns, XmNlabelString, s1=XmStringCreateSimple("DOS"), XmNset, *fileFormat == DOS_FILE_FORMAT, XmNuserData, DOS_FILE_FORMAT, XmNmarginHeight, 0, XmNalignment, XmALIGNMENT_BEGINNING, XmNmnemonic, 'O', NULL); XmStringFree(s1); XtAddCallback(dosFormat, XmNvalueChangedCallback, setFormatCB, fileFormat); macFormat = XtVaCreateManagedWidget("macFormat", xmToggleButtonWidgetClass, formatBtns, XmNlabelString, s1=XmStringCreateSimple("Macintosh"), XmNset, *fileFormat == MAC_FILE_FORMAT, XmNuserData, MAC_FILE_FORMAT, XmNmarginHeight, 0, XmNalignment, XmALIGNMENT_BEGINNING, XmNmnemonic, 'M', NULL); XmStringFree(s1); XtAddCallback(macFormat, XmNvalueChangedCallback, setFormatCB, fileFormat); if (window->wrapMode == CONTINUOUS_WRAP) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -