diff --git a/.gitignore b/.gitignore deleted file mode 100644 index b1dd607..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -onefilecms2.esproj \ No newline at end of file diff --git a/extras/OneFileCMS.config.SAMPLE.php b/extras/OneFileCMS.config.SAMPLE.php new file mode 100755 index 0000000..7fc9738 --- /dev/null +++ b/extras/OneFileCMS.config.SAMPLE.php @@ -0,0 +1,98 @@ + defining page layout. Can be px, pt, em, or %. Assumes px otherwise. +$WIDE_VIEW_WIDTH = '97%'; //Width to set Edit page if [Wide View] is clicked. Can be px, pt, em, or %. Assumes px otherwise. + +$LINE_WRAP = "on"; //"on", anything else = "off". Default for edit page. Once on page, line-wrap can toggle on/off. +$TAB_SIZE = 8; //Some browsers recognize a css tab-size. Some don't (IE/Edge, as of mid-2016). + +$MAX_EDIT_SIZE = 250000; // Edit gets flaky with large files in some browsers. Trial and error your's. +$MAX_VIEW_SIZE = 1000000; // If file > $MAX_EDIT_SIZE, don't even view in OneFileCMS. + // The default max view size is completely arbitrary. Basically, it was 2am, and seemed like a good idea at the time. + +$MAX_IMG_W = 810; //Max width (in px) to display images. (main width is 810) +$MAX_IMG_H = 1000; //Max height (in px). I don't know, it just looks reasonable. + +$UPLOAD_FIELDS = 10; //Number of upload fields on Upload File(s) page. Max value is ini_get('max_file_uploads'). + +$FAVICON = "favicon.ico"; //Path is relative to root of website. + +$EXCLUDED_FILES = ""; //csv list of filenames to exclude from directory listings- CaSe sEnsiTive! + +$EDIT_FILES = "svg,asp,cfg,conf,csv,css,dtd,htm,html,xhtml,htaccess,ini,js,log,markdown,md,php,pl,txt,text"; //Editable file types. +$SHOW_FILES = "*"; // Shown types; only files of the given types should show up in the file-listing + // Use $SHOW_FILES exactly like $EDIT_FILES: a list of extensions separated by commas. + // If $SHOW_FILES is set to null - by intention or by error - only folders will be shown. + // If $SHOW_FILES is set to the *-wildcard (the default), all files will show up. + // If $SHOW_FILES is set to "html,htm" for example, only file with the extension "html" or "htm" will get listed. + +$SHOW_IMGS = "jpg,gif,png,bmp,ico"; //image types to display on edit page. +//File types (extensions). _ftypes & _fclass must have the same number of values. bin is default. +$FILE_TYPES = "bin,z,gz,7z,zip,jpg,gif,png,bmp,ico,svg,asp,cfg,conf,csv,css,dtd,htm,html,xhtml,htaccess,ini,js,log,markdown,md,php,pl,txt,text"; +//Cooresponding file classes to _ftypes - used to determine icons for directory listing. +$FILE_CLASSES = "bin,z,z ,z ,z ,img,img,img,img,img,svg,txt,txt,cfg ,txt,css,txt,htm,htm ,htm ,txt ,txt,txt,txt,txt ,txt,php,php,txt,txt"; + +$EX = '( ! ) '; //EXclaimation point "icon" Used in $MESSAGE's + +$PAGEUPDOWN = 10; //Number of rows to jump using Page Up/Page Down keys on directory listing. + +$SESSION_NAME = 'OFCMS'; //Name of session cookie. Change if using multiple copies of OneFileCMS concurrently. + +//Optional: restrict access to a particular sub folder from root. +//$ACCESS_ROOT = '/some/path'; +//If blank or invalid, default is $_SERVER['DOCUMENT_ROOT']. +//$ACCESS_ROOT = '/home/user'; + + +//Optional: specify a default start path on login. +//$DEFAULT_PATH = 'some/path/deeper/' +//Must be a decendant of $ACCESS_ROOT. +//If blank or invalid, defaults to $ACCESS_ROOT. +//$DEFAULT_PATH = '/home/user/public_html'; + + +//URL of optional external style sheet. Used as an href in +//If file is not found, or is incomplete, built-in defaults will be used. +//$CSS_FILE = 'OneFileCMS.css'; + + +//Notes for $LANGUAGE_FILE, $WYSIWYG_PLUGIN, and $CONFIG_FILE: +// +// Filename path examples: +// 1) $SOME_FILE = "/some/path/from/system/root/somefile.php" //Absolue to filesystem. +// 2) $SOME_FILE = $_SERVER['DOCUMENT_ROOT']."/some/path/from/web/root/somefile.php" //Relative to root of web site. + +//Name of optional external language file. If file is not found, the built-in defaults will be used. +//$LANGUAGE_FILE = "/home/user/public_html/OneFileCMS.LANG.EN.php"; + +//Init file for optional external wysiwyg editor. +//Sample init files are availble in the "extras\" folder of the OneFileCMS repo, but the actual editors are not. +//$WYSIWYG_PLUGIN = '/home/user/public_html/plugins/plugin-tinymce_init.php'; +//$WYSIWYG_PLUGIN = '/home/user/public_html/plugins/plugin-ckeditor_init.php'; + +//Name of optional external config file. Any settings it contains will supersede those above. +//See the sample file in the OneFileCMS github repo for format example. +//Basically, it is just a php file with a copy/paste of this configuration section. +//$CONFIG_FILE = '/home/user/public_html/extras/OneFileCMS.config.SAMPLE.php'; + +//end CONFIGURABLE OPTIoNS ***************************************************** diff --git a/extras/OneFileCMS.css b/extras/OneFileCMS.css new file mode 100755 index 0000000..049f47d --- /dev/null +++ b/extras/OneFileCMS.css @@ -0,0 +1,555 @@ +/******************************************************************************* +Sample, OPTIONAL, external style sheet, as of OneFileCMS v3.6.08 + +This is just a copy of the primary section in OneFileCMS +*******************************************************************************/ + +/* --- reset --- */ +* { border : 0; outline: 0; margin: 0; padding: 0; + font-family: inherit; font-weight: inherit; font-style : inherit; + font-size : 100%; vertical-align: baseline; box-sizing: border-box; } + +:before, :after { box-sizing: border-box; } /*not currently used anywhere, but you never know...*/ + +/* --- general formatting --- */ + +html { background: linear-gradient(170deg, white, rgb(50, 120, 250)); background-attachment: fixed;} + +body { height: 100%; font-size: 1em; font-family: sans-serif; overflow-y: scroll; } + +svg { position: relative; top: 2px; } + +p, table, ol { margin-bottom: .6em;} + +h1,h2,h3,h4,h5,h6 { font-weight: bold; } +h2, h3 { font-size: 1.2em; margin: .4em 0 .4em 0; } /*TRBL*/ + +li { margin-left: 2em } + +i, em { font-style : italic; } +b, strong { font-weight: bold; } + +:focus {outline:0;} +:hover {border-color: #333;} + +table { border-collapse:separate; border-spacing:0; } +th,td { text-align:left; font-weight:400; } + +label { font-size : 1em; font-weight: bold; } + +pre { background: white; border: 1px solid #777; padding: .2em; margin: 0; } + +input[type="text"] { width: 100%; border: 1px solid #777; padding: 1px; font : 1em Courier; } +input[type="password"] { width: 100%; border: 1px solid #777; padding: 1px 1px 0px 1px; } +input[type="file"] { width: 100%; border: 1px solid #777; background-color: white; margin: 0; } +input[type="radio"] { margin: 0 1px 2px 3px; vertical-align: middle; cursor : pointer; } + +input[readonly] { color: #333; background-color: #EEE; } +input[disabled] { color: #555; background-color: #EEE; } + +input:focus { background-color: rgb(255,250,150); border: 1px solid #333; } +input:hover { background-color: rgb(255,250,150); } + +/*-- Must be after input:focus, as it alters border --*/ +input[type="checkbox"] { cursor: pointer; border: none;} + +button, .button {border-radius: 5px;} + +button:hover { background-color: rgb(255,250,150); border-color: #333;} +button:focus { background-color: rgb(255,250,150); border-color: #333;} +button:active { background-color: rgb(245,245,50); border-color: #333;} + +button:active, .button:active{ position:relative; top :1px; left:1px; } + +/* --- layout --- */ + +#main { + border : 0px solid #777; + width : 810px; /*Adjusted by $MAIN_WIDTH config variable*/ + margin : 0 auto 2em auto; + } + + +#header { + border-bottom : 1px solid #777; + padding: 4px 0px 1px 0px; + margin : 0 0 0 0; + } + + +#logo { + font-family: 'Trebuchet MS', sans-serif; + font-size:2em; + font-weight: bold; + color: black; + padding: .1em; + } + + +.h2_filename { + border: 1px solid #777; + padding: .1em .2em .1em .2em; + font-weight: 700; + font-family: courier; + background-color: #EEE; + } + + +#message_box { border: none; margin: .2em 0 .1em 0; padding: 0; min-height: 3em; } + +.message_box_contents { border: 1px solid gray; padding: 3px 2px 2px 4px; background: #FFF000; } + +#message_box #message_left {float: left; margin: 0; padding: 0; border: none; font-weight: 900; } + +#message_box #X_box { + display: block; + float : right; + margin : 0; + padding: 0px 0px 0 1px; + border : 1px solid gray; + font-size : 20px; + line-height: 16px; + background : #EEE; + } + +#message_box #X_box:hover {background-color: rgb(255,250,150); border-color: #333} +#message_box #X_box:focus {background-color: rgb(255,250,150); border-color: #333} +#message_box #X_box:active {background-color: rgb(245,245,50); } + +.filename { font-family: courier; } + +#submitty { margin-left: 1em; } +#hr_bottom { border-color: white; } + + +/* ------ INDEX Page ------ */ + +#index_page_buttons { margin: 0; } +#index_page_buttons div { display: inline-block; vertical-align: bottom; } + + +/*** Select All [x] ***/ +#select_all_label { + font : 400 .84em arial; + color : #333; + display: inline-block; + padding: 4px 0 3px 0; + cursor : pointer; + width : 72px; /*Adjusted by langauge files*/ + border-right: solid transparent 1px; + } + +#select_all_label:hover { background-color: rgb(255,250,150); } +#select_all_label:active { background-color: rgb(245,245, 50); } + +label.ckbox_label_focus { background-color: rgb(255,250,150) } +.ckbox.ckbox_label_focus { background-color: rgb(255,250,150) } + + +/*** Directory list file select boxes ***/ +/*ckbox is assigned to
that contain */ +.ckbox {padding: 3px 3px 1px 3px; display: inline-block; border: solid 1px transparent; } +.ckbox:hover {background-color: rgb(255,240,140);} +.ckbox:active {background-color: rgb(245,245, 50);} + +.ckbox.ckbox_parent_focus { background-color: rgb(255,235,90); border: solid 1px rgb(220,190,0); } + + +/* Slightly darker colors for [m][c][d] file options since they are small & less noticable*/ +.index_T a.MCD:hover {background-color: rgb(255,240,140);} +.index_T a.MCD:focus {background-color: rgb(255,240,140);} +.index_T a.MCD:active {background-color: rgb(245,245, 50);} + +.index_T a.MCD { border: solid 1px transparent; } +.index_T a.MCD:focus { border: solid 1px rgb(220,190,0); } + + +input.perms { + display: inline-block; + width: 2.4rem; + padding: 2px 2px; + border: solid 1px transparent; + background-color: transparent; + text-align: right; +} + + +td.perms { padding: 0; } + +input.perms {height: 1.42rem;} + +input.perms.edit_perms { background-color: rgb(255,240,140); box-shadow: 0 0 10px 2px #F44; } + +.perms:focus { border: solid 1px rgb(190,160,0); background-color: #EEE } + +.perms:hover { cursor : pointer; } + + + + +/*** [x] (folders first) ***/ + +#ff_ckbox_div {float: left;} + +#folders_first_label { + display: inline-block; + float: left; + font-size : .9em; + font-weight: normal; + border : solid 1px transparent; + color : #333; + margin : 0 0 0 0; + padding: 4px 3px 2px 0; + cursor : pointer; + } + +#folders_first_label:hover { + background-color : rgb(255,250,150); + border-left-color : silver; + border-right-color: silver; + } + +#folders_first_label:active {background-color : rgb(245,245, 50);} + + +/* --- Directory Listing --- */ + +table.index_T { + min-width: 30em; + font-size: .95em; + border : 1px solid #777; + border-collapse: collapse; + margin: .5em 0 .5em 0; + background-color: #FFF; + } + +table.index_T tr:hover {border: 1px solid #777; background-color: #EEE} +table.index_T th { border: 1px inset silver; vertical-align: middle; text-align: center; padding: 0 ;} +table.index_T td { border: 1px inset silver; vertical-align: middle; white-space: nowrap; } +table.index_T th:hover { background-color: white;} + +.index_T td a { display: block; height: 1.42rem; border: none; padding: 2px 4px 2px 4px; overflow : hidden; } +.index_T th a { padding: 1px 0 1px 0; border-width: 0px;} + +th.file_name {min-width: 15em} + +.index_T th.file_name a { + display: inline-block; + padding: 4px 1em 3px 1em; + border-top-width: 0px; + border-bottom-width: 0px; + text-align: center; + } + +#header_filename {border-width: 0 1px 0 1px; display: block; overflow: auto;} +#header_filename:hover {border-color: silver;} +#header_filename:focus {border-color: silver;} + +.index_T th.file_size a { display : block; padding: 4px 0 3px 0; } +.index_T th.file_time a { display : block; padding: 4px 0 3px 0; } + +#header_sorttype {float: right; padding: 4px 5px 3px 4px; border-width: 0px 0 0 1px;} +#header_sorttype:hover {border-color: silver;} +#header_sorttype:focus {border-color: silver;} + +.file_name { max-width: 26em; } +.file_size { min-width: 6em; } +.file_time { min-width: 10em; } + +.meta_T { padding: 0 .5em; text-align: right; font: bold .9rem courier; color: #333} +.meta_T2 { border: solid 1px black; background-color: white; font-size: 1rem; } + + +#DIRECTORY_FOOTER {text-align: center; font-size: .9em; color: #333; padding: 3px 0 0 0; } + + +/*** front_links: [New File] [New Folder] [Upload File] ***/ +.front_links { float: right; } + +.front_links a { + display : inline-block; + border : 1px solid #777; + font-size : 1em; /*Adjusted by langauge files*/ + margin-left : 1em; /*Adjusted by langauge files*/ + padding : 3px 5px 2px 4px; /*TRBL*/ + background-color: #EEE; + border-radius: 5px; + } + +.front_links svg { position: relative; top: 1px; margin-right: 5px; } + +/*These must go after .front_links and other style that affect tags*/ +a { border: 1px solid transparent; text-decoration: none; } +a:focus { border: 1px solid #333; background-color: rgb(255,250,150); } +a:hover { border: 1px solid #333; background-color: rgb(255,250,150); } +a:active { border: 1px solid #333; background-color: rgb(245,245,50); } + + +/*** [Move] [Copy] [Delete] ***/ + +#mcd_submit { margin: 0; } + +#mcd_submit button { + height : 1.75em; + cursor : pointer; + border : 1px solid #777; + padding : 0px 3px 0px 2px; /*TRBL*/ + margin-right: 1.0em; /* Adjusted by language files */ + font-size: .9em; + color : rgb(100,45,0); + background-color: #EEE; + } + +#mcd_submit svg { margin-right: 5px; } + +#mcd_submit button:focus { border: 1px solid #333; background-color: rgb(255,250,150); } +#mcd_submit button:hover { border: 1px solid #333; background-color: rgb(255,250,150); } +#mcd_submit button:active { border: 1px solid #333; background-color: rgb(245,245, 50); } + +.buttons_right { float: right; } +.buttons_right .button { margin-left: .5em; } + +.button { + cursor : pointer; + border : 1px solid #777; + color : black; + padding : 4px 7px 4px 7px; /*Adjusted by langauge files*/ + font-size : .9em; /*Adjusted by langauge files*/ + font-family: sans-serif; + background-color: #EEE; + } + +.button:hover { border: 1px solid #333; background-color: rgb(255,250,150); } +.button:focus { border: 1px solid #333; background-color: rgb(255,250,150); } +.button:active { background-color: rgb(245,245,50); } /*first */ +.button[disabled] { color: #777; background-color: #EEE; cursor: default} /*second - order matters*/ + +#renamefile_btn {padding: 2px 7px 4px 7px;} + + +/* --- header --- */ + +.nav { float: right; display: inline-block; margin-top: 1.35em; font-size : 1em; } +.nav a { border: 1px solid transparent; font-weight: bold; padding: .2em .6em .1em .6em; } +.nav a:hover { border: 1px solid #333; } +.nav a:focus { border: 1px solid #333; } + + +/* --- edit --- */ + +#edit_header {margin: .5em 0 0 0;} +#edit_header a:hover { border: 1px solid #000; } + +#edit_form {margin: 0;} + +.edit_disabled { + border : 1px solid #777; + width : 99%; + height : 35em; + padding: .2em; + margin : .5em 0 .6em 0; + color : #222; + background-color: #FFF000; + line-height: 1.4em; + white-space: pre-wrap; + word-wrap: break-word; + overflow: auto; + } + +.view_file { font: .9em Courier; background-color: #F8F8F8; } + + + +#wrapper_linenums_editor { + vertical-align : top; + white-space : nowrap; + padding : 0px; + border : none; + width : 100%; +} + +#line_numbers, #file_editor { + vertical-align : top; + display : inline-block; + height : 40em; + white-space : pre; + margin : 0; + font : normal .9em courier; +} + + +#line_numbers { + min-width : 3.1em; /* Must be wider than scroll-bar left-right arrows, or no scrollbar appears. */ + padding : 1px .3em 0 .2em; + border : 1px solid #777; + background : #ccc; + color : #444; + overflow-y : hidden; + overflow-x : scroll; /*This may be grayed out, but provides visual consistancy with #file_editor.*/ + text-align : right; + float : left; /*only needed to help eliminate whitespace between #line_numbers & #file_editor*/ +} + +#line_0, #line_1 {margin: 0; display: inline-block; } + +#file_editor { + font : .9em Courier; + border : 1px solid #777; + width : 96%; /* Dynamically set by Set_File_Textarea_Width(), base on Normal or Wide view. */ + margin : 0 0 .7em 2px; + padding : 1px 0 0 3px; + overflow : scroll; + word-wrap : normal; + word-break : break-all; + white-space: pre-wrap; + resize : none; + + color : black; /* Default. May make themeable, along with background-color. Someday... */ + background-color: white; /* Set in Reset_file_status_indicators() and Check_for_changes() */ + } + + +#file_editor:focus { border-color: #000; } + +.tab_size { tab-size: 8; -o-tab-size: 8; -moz-tab-size: 8; } + + +.file_meta { float: left; margin-top: .6em; font-size: .95em; color: #222; } + +#edit_notes { font-size: .8em; color: #222 ;margin-top: 1em; clear:both; } + +.notes { margin-bottom: .4em; } + + + + + +/* --- log in --- */ + +#login_page { + border : 1px solid #777; + width : 370px; + margin : 5em auto; + padding : .5em 1.2em .1em 1em; + } + +#login_page .nav { margin-top: .5em; } + +#login_page input {margin: 0 0 .7em 0;} + + +hr { /*-- -- -- -- -- -- --*/ + line-height : 0; + Xfont-size : 1px; + display : block; + position: relative; + padding : 0; + margin : .6em auto; + width : 100%; + clear : both; + border : none; + border-top : 1px solid #777; + Xborder-bottom: 1px solid #eee; + overflow: visible; + } + + +.verify { + min-width : 50%; + font : 1em Courier; + border : 1px solid gray; + border-collapse : collapse; + background-color: white; + } + +.verify th { + border : 1px solid gray; + padding : 0 1em 0 1em; + text-align : center; + font-weight : 900; + font-family : arial; + background-color: #EEE; + } + +.verify td { + border : 1px inset silver; + padding: .1em 1em .1em .5em; + vertical-align: middle; + } + +.verify_del { + font : 1em Courier; + border: 1px solid #F00; + padding: .2em .4em; + color : #222; + background-color: #FDD; + } + +.verify_del td { border: 1px solid #F44; } + + +#admin {padding: 3px 5px;} + +.admin_buttons .button {margin-right: .5em;} + +.clear {clear:both; padding: 0; margin: 0; border: none} + +.web_root { border: 1px solid #777; border-right: none; font: 1em Courier; padding: 1px; background-color: #EEE;} + +.mono {font-family: courier;} + +.info {margin: .7em 0 .5em 0; background: #f9f9f9; padding: .2em .5em;} + +.path {padding: 1px 5px 1px 5px} /*TRBL*/ + +.timer {border: 1px solid #eee; padding: 3px .5em 4px .5em;} + +.timeout {float:right; font-size: .95em; color: #111; padding-right: .3em;} + +.edit_btns_top {margin: .2em 0 .5em 0;} + +.image_info { + color: #222; + font-size: 1em ; /*Adjusted by langauge files*/ + margin: .7em 0 1em 0; + } + +.edit_btns_bottom {float: right;} +.edit_btns_bottom .button { margin-left: .7em; } /*Adjusted by langauge files*/ + +input[type="text"]#new_name {width : 50%; margin-bottom: .2em;} +#new_location {border-left: none;} + +#del_backup { margin: 0; padding: 2px 5px; border: 1px solid transparent;} + +/*** For old IE only: text "icons" for Rename, Copy, and Delete ***/ +.RCD1 {font: 900 7pt arial; padding: 0px 3px 0px 3px; margin: 0px; float: left} +.R {color: #00a; border: 1px solid #804000} +.C {color: #006400; border: 1px solid #008400} +.D {color: #b00; border: 1px solid #b00} + +.action {display: inline-block} +.ren_over {display: inline-block} +.ren_over input {margin: 0 0 0 2em} +.ren_over label {font-weight: normal} + +#path_header{ + display: inline-block; + background-color:white; + border: solid 1px #777; + font-weight: normal; + padding: 0 .5em 0 0; + margin: .5em 0 0 0; + } + +#path_header a { + outline: none; + border: none; + border-left : solid 1px transparent; + border-right: solid 1px transparent; + display: inline-block; + padding: 1px 5px 0 5px; + } + +#path_header a:hover { border-left : solid 1px #777; border-right: solid 1px #777; } +#path_header a:focus { border-left : solid 1px #777; border-right: solid 1px #777; } diff --git a/extras/plugin-ckeditor_init.php b/extras/plugin-ckeditor_init.php new file mode 100755 index 0000000..d070d68 --- /dev/null +++ b/extras/plugin-ckeditor_init.php @@ -0,0 +1,39 @@ + tag.* + 2) specify the id of the OneFileCMS textarea, "file_editor", in the CKEDITOR.replace() call + + *Note: In the + + diff --git a/extras/plugin-tinymce_init.php b/extras/plugin-tinymce_init.php new file mode 100755 index 0000000..ce65102 --- /dev/null +++ b/extras/plugin-tinymce_init.php @@ -0,0 +1,82 @@ + tag.* + + + *Note: In the + diff --git a/info/OneFileCMS.License.BSD.txt b/info/OneFileCMS.License.BSD.txt new file mode 100755 index 0000000..c33a683 --- /dev/null +++ b/info/OneFileCMS.License.BSD.txt @@ -0,0 +1,29 @@ +OneFileCMS + +Copyright 2009-2012 https://github.com/rocktronica +Copyright 2012- https://github.com/Self-Evident David W. Gay + +(Based on the BSD new/3-clause license) + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the author or copyright holder, nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/info/OneFileCMS.License.MIT.txt b/info/OneFileCMS.License.MIT.txt new file mode 100755 index 0000000..d9e8e69 --- /dev/null +++ b/info/OneFileCMS.License.MIT.txt @@ -0,0 +1,22 @@ +OneFileCMS + +Copyright © 2009-2012 https://github.com/rocktronica +Copyright © 2012- https://github.com/Self-Evident David W. Gay + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/info/OneFileCMS_structure.txt b/info/OneFileCMS_structure.txt new file mode 100644 index 0000000..ad7a9e7 --- /dev/null +++ b/info/OneFileCMS_structure.txt @@ -0,0 +1,157 @@ +OneFileCMS Version 3.5.21 structure/layout + +LICENSE + +SOME BASIC SECURITY & ERROR LOG SETTINGS + +CONFIGURATION SECTION + +MISC FUNCTIONS: + System_setup() + Default_Language() + validate_units() + hsc() + Convert_encoding() + Session_Startup() + Verify_IDLE_POST_etc() + hashit() + Error_reporting_and_early_output() + Update_Recent_Pages() + undo_magic_quotes() + strip_array() + Validate_params() + Valid_Path() + Get_GET() + Verify_Page_Conditions() + has_invalid_char() + URLencode_path() + dir_name() + Check_path() + Sort_Seperate() + add_serial_num() + supports_svg() + rCopy() + rDel() + +MISC PAGE SECTIONS/FUNCTIONS + Current_Path_Header() + Page_Header() + Cancel_Submit_Buttons() + show_image() + Timeout_Timer() + + Init_Macros() + +SVG ICONS + Init_ICONS() + svg_icon_txt() + svg_icon_folder() + +PAGE & RESPONSE FUNCTIONS: + List_File() + List_Backups_and_Logs() + Admin_Page() + Hash_Page() + Hash_response() + Change_PWUN_Page() + Update_config() + Change_PWUN_response() + Logout() + Login_Page() + Login_response() + Create_Table_for_Listing() + Get_DIRECTORY_DATA() + Send_data_to_js_and_display() + Index_Page_buttons_top() + Index_Page() + Edit_Page_buttons_top() + Edit_Page_buttons() + RCD_buttons() + Edit_Page_form() + Edit_Page_Notes() + Edit_Page() + Edit_response() + Upload_Page() + Upload_response() + New_Page() + New_response() + Set_Input_width() + CRM_Page() + CRM_response() + Delete_response() + MCD_Page() + MCD_response() + Page_Title() + Load_Selected_Page() + Respond_to_POST() + +JAVASCRIPT FUNCTIONS: + init_ICONS_js() + common_scripts() + pad() + hsc() + trim() + FormatTime() + format_number() + Countdown() + Start_Countdown() + FileTimeStamp() + Display_Messages() + Index_Page_events() + (various onclicks) + document.onmousedown() + on_Tab_down() + document.onkeydown + Index_Page_scripts() + Sort_FOlder_First() + sort_DIRECTORY() + Init_Dir_table_rows() + Assemble_row() + Build_Directory + Directory_Summary() + Sort_and_Show() + Select_All() + Confirm_Submit() + Edit_Page_scripts() + Set_File_Textarea_Width() + Correct_Word_Wrapping() + Wide_View() + Toggle_Line_Wrap() + Reset_file_status_indicators() + Check_for_changes() + Reset_File() + Line_Numbering() + Display_Width_Chars() + Line_Count() + Effective_Line_Length() + Create_Line_Numbers() + Set_Line_Numbers() + Global variables + Event assignments + pwun_event_scripts() + events_down() + events_up() + pre_validate_pwun() + js_hash_scripts() + hex_sha256() (& related...) + hash() + +STYLESHEET FUNCTIONS: + style_sheet() + Language_and_config_adjusted_styles() + Load_style_sheet() + +LOGIC TO DETERMINE PAGE ACTION + Load Default_Language() + System_setup() + Session_Startup() + Init_Icons() + Get_GET() + Valid_Path() + Validate_params() + Init_Macros() + Respond_to_POST() + Verify_page_conditions() + Update_Recent_Pages(); + +OUTPUT ... diff --git a/info/changelog.markdown b/info/changelog.markdown new file mode 100755 index 0000000..f13248b --- /dev/null +++ b/info/changelog.markdown @@ -0,0 +1,621 @@ +# OneFileCMS Change Log + +### v3.6.12 (2017-10-08) + +- Admin page now shows username OneFileCMS is running as. +- Index & Edit pages now indicate files that are not writable (rather than just responding with an error message after trying to edit/delete said files). +- When editing file permissions, message box shows current expanded perms [rwxrwxrwx] owner group :current user: + (But, can still only edit the octal form by the file name.) + +### v3.6.11 (2017-10-06) + +- Switched to php short tags: ``    (from ``)     Because I felt like it. I wanted to years ago, in my beginning of this project, but my web host was still on some 5.3 version of php, and didn't always have 'em enabled. But now, as php is up to v7.something, and most hosts have, at least, php 5.4, it seems like a safe move at this point. If not, oh well! + +### v3.6.10 (2017-10-06) + +- Fixed a minor bug introduced by prior commit's code "improvements". +- Directory list now shows link targets: some\_symlink -> /target/of/symlink +- Reworked keyboard nav a bit. +- Some misc code improvements. + +### v3.6.09 (2017-10-04) + +- Some minor keyboard nav improvements on index page. +- Some misc code improvements. + +### v3.6.08 (2017-09-30) + +- [Mov], [Del], & [X] are unavailable if file is readonly. +- Fixed minor issue where if perms changed, new value not always displayed. +- A bit of restructure/refactor of perm & Assemble\_Insert\_Row() related functions. +- "(on php 5.x.x)" version, and link to phpinfo, now only shows on Admin page. +- Andd some css... + +### v3.6.07 (2017-09-29) + +- Mostly some code improvements. +- And some css... + +### v3.6.06 (2017-09-27) + +- Added ability to edit file permissions. + +### v3.6.05 (2017-09-24) + +- Fixed a couple bugs in keyboard navigation when there's only one item in current diretory. + (Couldn't "arrow up" when in the file row [M][C][D][x][perms] [Filename]) + (It was submitting on enter when on checkboxes.) + +### v3.6.04 (2017-09-20) + +- A _little_ bit of code improvement/cleanup - using onfocus/blur in lieu of the prior scatter gun approach. + + +### v3.6.03 (2017-09-20) + +- Removed Rename/Delete/Edit options for readonly files. + (previously would simple have generated an error.) +- Some more prep work for eventual option to edit file perms. + +### v3.6.02 (2017-09-18) + +- Fixed a minor bug with tabindex on directory listing page. +- Increased default $PRE\_ITERATIONS from 1000 to 10000. Had kept low as IE8 was slow. +- Now attempts to set a session\_save\_path() based on username. (default is /tmp, or /var/lib/php5/, etc) + +### v3.6.01 (2017-09-18) + +- Fixed a couple of minor display bugs. + +### v3.6 (2017-09-17) + +- Fixed a minor bug in $ACCESS\_ROOT. +- Did some prep work for editing of file permissions. Not yet editable. + + +### v3.5.23 (2017-09-08) + +- OneFileCMS is no longer restricted to just public_html. +- Increased $MAX\_EDIT\_SIZE to 250000. (It could probably go higher.) + +### v3.5.22 (2017-09-05) + +- Added file permissions to directory list. +- A couple of minor bug-fixes. +- Some minor code improvements. + +### v3.5.21 (2016-06-26) + +- Some code cleanup & a little local js re-org. +- Some minor static & active css improvements. +- Added some basic validation to a config value. + +### v3.5.20 (2016-06-21) + +- Fixed sporadic directory-won't-display issue. +- Fixed wrapping & line-numbering issue when toggling between wrap on & wrap off. +- Added line-numbers to read-only files also. + +### v3.5.19 (2016-06-16) + +- Added line numbers to left of edit window. A current side effect is wrapping is now break-word, instead of word-break. That is, lines may wrap in the midddle of words, not just on white-space. +- Added a word-wrap toggle option on the edit page. Only works on editable files. Files with edit disabled still just word-wrap normally as appropriate. +- And some code cleanup etc. + +### v3.5.18 (2016-06-09) + +- And a few more improvements to arrow key handling. +- A couple minor bug fixes +- Some code cleanup etc. + +### v3.5.17 (2014-04-20) + +- Additional improvments to arrow key handling, particularly in regards to $message box. + +### v3.5.16 (2014-04-04) + +- Improved logic for handling Left & Rigth arrow keys in Index\_Page\_events() +- Left some //##### comments in as reminders for potential improvements. + +### v3.5.15 (2014-04-03) + +- Fixed a minor keyboard navigation bug on Index page if active copy of OnefileCMS is listed. +- Fixed css "glitch" that ony affected IE - removed borders on checkboxes. + +### v3.5.14 (2014-04-02) + +- Improved keyboard navigation of directory listings (Arrows, Page Up/Down, etc...) +- Asked "how hard can it be?" - and found out... +- Fixed a minor bug on the Edit page (affected IE only). +- Some css adjustments/cleanup (needs lots more). + +### v3.5.13 (2014-03-30) + +- Added basic keyboard navigation on directory listings. +- Removed [View Raw] button when viewing images. +- And tweaked some css... + +### v3.5.12 (2014-03-25) + +- Fixed a minor glitch in the countdown used in login delays. +- Associated/misc code tweaks & imrovements. +- Added the countdown timer to the two-minute time-out "Warning..." message. + +### v3.5.11 (2014-03-24) + +- Improved some $message handling & focus() responses. +- Some minor readme updates. +- some css... + +### v3.5.10 (2014-03-23) + +- Just a quick fix to a minor issue: needed to urlencode an onclick parameter. +- Also a few minor updates to the readme. + +### v3.5.09 (2014-03-22) + +- Restored IE 8+ support. +- And, you know, tweaked some css... + +### v3.5.08 (2014-03-21) + +- Mostly just some code improvements/cleanup. +- ...and css... + + +### v3.5.07 (2014-03-15) + +- Removed ability for OneFileCMS to edit itself - it is too risky an option. If needed, make a copy & edit it. +- Added a [View Raw] button on the Edit/View page. It displays the raw/plain text of the current file. +- Fixed issue using Chrome & editing some files containing javascript. +- Some changes to "file changed" visual feedback (textarea & [Save] button styles). +- Some general code improvements to Edit\_Page\_... functions. +- Some other general code improvements. +- And, a bit of css tweakin... + +### v3.5.06 (2014-03-11) + +- Added optional logging of login attempts, both successful & failed. + +### v3.5.05 (2014-03-09) + +- Copy & Rename pages ignore blank "New Name" fields. +- Some minor improvemnts & css tweaks. + +### v3.5.04 (2014-03-08) + +- Fixed "minor" bug - editor not saving changes (introduced in 3.5.02, but just noticed) +- Some general code improvements & shuffling +- Some CSS shuffling & tweaks. + +### v3.5.03 (2014-03-06) + +- Minor update to Get\_DIRECTORY\_DATA(). Didn't seem to affect all php versions. + +### v3.5.02 (2014-03-06) + +- OneFileCMS can now work with non-ASCII filenames. +- (But, OneFileCMS itself can not be named with non-ASCII characters. I don't know why.) +- Increased $PRE_ITERATIONS from 200 to 1000. This will affect, at least, older IE's, and maybe other browsers as well. For instance, it takes IE8 37 times longer to perform the "pre-iterations" than Firefox. In anycase, it can, of course, be changed back if needed. + (However, OneFileCMS does not currenly work in IE, so it's kinda academic for now.) +- Some css tweaks & improvements. + +### v3.5.01 (2014-02-22) + +- Mostly behind the scenes stuff... +- Replaced use of htmlentities() with htmlspecialchars(). With UTF-8, htmlentites() is superfluous. +- Added hsc() to a number of strings where should have already been. +- Changed directory sort function a bit. Note: when selecting/deselecting the 'folders first' option, the primary sort will be the last sorted column. +- Split out a new function, Send\_data\_to\_js(), from Index\_Page(). +- Also, in prep for an upcoming update, tagged several places (with //##### ) where file system calls are made. The $filename strings used in the calls may need to be encoded with something other than UTF-8, depending on the underlying OS's filesystem. (such as NTFS, which uses UTF-16) + +### v3.5 (2014-02-19) + +- The directory list can now be sorted by column: name, .ext, size, date. +- Also has an option to list folders first, or to sort without regard to file or folder. +- In accomplishing the above, most sorting moved client side. This permits resorts without another server hit. +- Added & tweaked some css... +- Slight restructure of the repo (ie: move a few "extras" files around). +- NOTE: versions 3.4.23 and later DO NOT WORK IN IE! I don't know why yet, mostly likely js related. + +### v3.4.23 (2014-02-12) + +- More changes in prep for sort by column +- Directory list is now built & displayed client side via javascript. + +### v3.4.22 (2014-02-10) + +- Mostly some changes to prep for sort by column (name, size, or date) feature. + +### v3.4.21 (2014-02-08) + +- Added back the option for external style sheets +- Cooresponding updates to sample external config file. +- In addition to specific file names, specific folder names may now be excluded from directory listings. +- Fixed minor missing page title on Copy Folder page +- Tweaked a couple css defaults + + +### (2013-01-19) + +- Just some minor updates/wording changes to the readme & plugin/*.init files. + +### v3.4.20 (2012-12-19) + +- The $ACCESS_ROOT option has been reimplemented and is now fully functional\*. This option limits access to a specified folder (and it's sub-folders). To use, just specify a valid path relative to the root of the website (no leading slash). +(*Well, as best as I can tell...) + +- All OneFileCMS configuration variables that reference external files ($CONFIG\_file, $LANGUAGE\_FILE, $WYSIWYG\_PLUGIN) must be specified in one of two ways: + 1. Relative to the root of the website - with NO leading slash: "some/path/from/webroot/somefile.php" + 2. Absolute to the file system - WITH a leading slash: "/some/path/from/system/root/somefile.php" + (On Windows, the drive letter may also be used, but it is not required if all is on same drive.) + +### v3.4.19 (2012-12-12) + +- Slightly adjusted how wysiwyg plugins are implemented - removed $WYSIWIG\_SOURCE config variable. + (It's value is now specified directly in the "init" file specified by $WYSIWYG\_PLUGIN.) + +- Two steps forward, one step back... + Just for now - removed the $ACCESS_ROOT option. I was coding in circles and getting no where while trying to reconcile various issues: + + - With OneFileCMS in any folder other than the web root, + - With OneFileCMS in a folder other than $ACCESS_ROOT + - Depending on the above, can't delete the backup copy of OneFileCMS created by a p/w or u/n change). + - External file references (config, language, plugins) affected by the above. + - Should $ACCESS_ROOT also restrict access to OneFileCMS itself? That would prevent p/w & u/n changes. + - Display of the current/path/header/ varies depending on $ACESS_ROOT. + - Combining the above. + + A solution is in the works, but I'm going to take some time to make sure no new problems are introduced by the eventual fix. (hahaha...) It will probably end up being simple, but it's not yet... + +- Just a general note on security: due to the fundamental structure of OneFileCMS - primarily that it's one file, and that there is no seperate database for authentication - there are certain inherent security limitations that should be kept in mind: + - The first is that all OneFileCMS users are "admins", with the ability to upload and edit files with any type of code. + - Next, as a direct consequence of the prior point, is that any restriction imposed by some potential feature, such as the $ACCESS_ROOT option that limited access to a specific folder, is only - at most - a guard against accidental access and modification of files outside of the "accessible" folder. This is not to say that such features are not useful - this is simply meant to provide a realistic expectation of security, and that OneFileCMS should only be used with trusted users. + +### v3.4.18 (2012-12-03) + +Of course, everything comes with a price (exacerbated by my apparent lack of testing...) + +- Anyway, the current release partly fixes an issue when trying to use a wysiwyg editor with onefilecms.php installed in a sub-folder of a site. The issue is - it didn't work. Now it does - mostly. However, there is still an issue using wysiwyg editors if the $ACCESS_ROOT variable is set to anything but blank (root). + +### 2012-12-03 + +- Just a note: there is an issue using a wysiwyg editor when onefilecm.php is in a sub-folder, or related to using the $ACCESS_ROOT option (restricting onefilecms access to a folder). WYSIWYG seems to otherwise work fine when onefilecms.php is in the root folder of a site. + +### v3.4.17 (2012-11-29) + +- WYSIWYG is here! +Due to popular demand (ie: it has been requested more than once), WYSYWIG editors can now be "plugged in" and used with OneFileCMS. Currently, only [TinyMCE](http://tinymce.moxiecode.com/) and [CKEditor](http://ckeditor.com/) have been tested (and on a very limited scale). Others may work - but I don't know yet. And, naturally, the use or inclusion of such editors is completely optional, of course. + + **No actual WYSIWYG editors are included with OneFileCMS** - any desired editor must be obtained seperately. + + A brief how-to on using either editor can be found in their respective sample "init" files included in the plugins folder of the OneFileCMS repo. Any suitable init file for a given editor may be used, as long as the correct path to the editor's javascript source file is specified, and - for CKEditor - the id of the OneFileCMS textarea, "file_editor", is also be specified. + + Now, while everything seems to work, I have little to no experience using TinyMCE, CKEditor, or any other such application. So, if there is something missing or not working as expected, please let me know (open an "issue" on the Issues page). + + Notes: + + - These editors have their own, extensive, event controls (responses to keyboard & mouse input), so the OneFileCMS edit page event scripts are not loaded when an editor is in use. The primary effect is the loss of incidental file status indicators - [Save] will not change to [SAVE CHANGES!], background color will not change, etc., and any "unsaved changes" alerts should be handled by the active editor. Also, the [Wide View] button will be unavailable. + + - The TinyMCE "init" file included in the OneFileCMS repo specifies the use of the TinyMCE "fullpage" plugin, which produces an "unsaved changes" alert every time you exit the Edit page - even if no changes have been made to the file in the editor. + + - The CKEditor, on the other hand, does not seem to present an alert at all when you leave the editor page - even with unsaved changes. + +### v3.4.16 (2012-11-23) + +- Added icons to lower buttons on edit page. +- And a few code tweaks & improvements. + +### v3.4.15 (2012-11-18) + +- Added client-side hashing of passwords. + This is primarily a benefit for the user, as it does not really add any security to the server side application that uses it (such as OneFileCMS). The reason is that this "pre-hash" simply becomes the actual password as far as the server is concerned, and is just as vulnerable to exposure while in transit. However, it does help to protect the user's plain-text password, which may be used elsewhere. + +- Also added a "please wait..." message while computing the client-side hashes - primarily for IE versions < 9, which are MUCH slower than FF or Chrome (by a factor of 37 or more). Subsequently, the number of iterations for the client-side hashing is quite low (compared to the server side), but still causes a 1 - 2 second delay on the login screen, and a 3 - 6 second delay on the Change Password screen. On FF and Chrome, however, the delay is much shorter, almost unnoticable. + +- I want to thank [fermuch](http://github.com/fermuch) for the client-side hashing suggestion. While a somewhat different approach was ultlimately employed, his original solution provided the insight needed to approach the idea in general. + +### 3.4.14 (2012-11-12) + +- Courtesy of [Fuchur777](github.com/Fuchur777), added option to restrict OneFileCMS to a specified folder (and it's sub-folders). +- Fixed issue on Upload page if using PHP v3.2.12 or earlier. +- A few miscellaneous code improvements. + +### (2012-11-11) + +- Thanks to [zaykin](https://github.com/zaykin) for the Russion language file! + +### 3.4.13 (2012-11-05) + +- Thanks to [symsec](http://github.com/symsec) for the Dutch (Nederlands) language file! +- Otherwise, mostly some incidental code improvements and cleanup. + +### 3.4.12 (2012-10-21) + +- On the Upload Page, added an option to select either automatic rename or overwrite of pre-existing files. + +### 3.4.11 (2012-10-16) + +- Just a few code tweaks and improvements. + +### 3.4.10 (2012-10-08) + +- Folders are now listed ahead of files in main file list. +- Quite of bit of code consolidation and improvement. +- Converted svg icons from functions into an array of $ICONS[] + +### 3.4.09 + +- Can now recursively copy folders. +- Consolidated some functions. +- Removed some svg icons no longer used. +- The usual "code cleanup" and "tweaked some css"... + +### 3.4.07 + +- Can now recursively delete non-empty folders (just be careful!) +- Consolidated some functions. +- Minor bug fix & a few misc code improvements. +- Darkened folder icons. +- Removed & changed a few $_[] language strings. + +### 3.4.06 + +- Minor bug fix: Index page would not display folders that started with a period ("hidden" folders on *nix) + +### 3.4.05 + +- Consolidated index page radio & submit buttons (for Move, Copy, Delete) into just three standard buttons. +- Added multi-file upload ability. +- Index page: removed extra Upload/New/Rename/Delete buttons from bottom of page. +- Subsequent to the above, a bit of code cleanup & improvement. + +### 3.4.04 + +- Minor bug fix. + +### 3.4.02-3.4.03 + +- Primary user noticable change: on rename/move/copy pages, split "New Name" from "New Location". +- A couple minor bug fixes. +- Consolidated four functions into two. +- Other general code cleanup & improvements. +- Numerous new, changed, and removed langauge settings. + +### 3.4.01 + +- A couple of minor bug fixes. +- Some code cleanup & improvements. + +### 3.3.17 - 3.4.0 (2012-08-29) + +- Added option to select and move, copy, or delete multiple files. +- And other general code tweaks and improvements. + +### 3.3.11 - 3.3.16 + +- Added screens for changing username and password. +- Plaintext $PASSWORD option is no longer available. +- Added options to Rename, Copy, or Delete files from Index screen. +- Improved validation of $_GET parameters & other general code improvements. + +### 3.3.10 + +- Created an actual "Admin" page that has links to admin functions: Hash Page, Edit OneFileCMS, and (soon) Change Password. + +### 3.3.09 + +- Minor code improvements & cleanup. + +### 3.3.08 + +- Added some basic error handling and now using buffering to capture errant early output. +- Seperate function to handle dynamic css values. + +### 3.3.07 + +- Language file formats are now php instead of ini. +- Minor improvement to version checking. + +### 3.3.06 + +- Increased hash iterations from 1000 to 10000. (I've read that lots of iterations help slow down brute force p/w recovery) +- Format for external config files is now just php (instead of ini). +- Some miscellaneous code & css improvements. + +### 3.3.05a + +- Just removed some trouble-shooting code that was left in unintentionally. + +### 3.3.05 + +- Added a few settings to the language files to adjust certain css values if needed. In some instances, some langauges may use significantly longer words or phrases than others. So, a smaller font or less spacing may be desirable in those places to preserve page layout. +- And, of course, some minor code improvements hear and there. + +### 3.3.04 + +- Added Spanish language file courtesy of [fermuch](https//github.com/fermuch). +- Some misc code improvements. +- Added notes regarding using .ini file for password storage. + +### 3.3.03 + +- "Wide View" option on Edit page now persists across saves. +- Improved handling of language files. However, kinda' like "online security", "multi-language support" is nebulous and a bit finicky. + +### 3.3.02 + +- Added German language file courtesy of [codeless](http://github.com/codeless). + +### 3.3.01 + +- Fixed a "minor" issue after adding multi-language support- OneFileCMS stopped working altogether on versions of PHP < 5.3. + +### 3.3.0 + +- Added support for optional external language files. Now to get some translations... +- The default, English, is included directly in OneFileCMS, of course. +- A sample language file (English) is included in the repo for reference for anyone that may be interested. + + +### 3.2.3 + +- Thanks to github.com/codeless: added the ability to process a seperate config file. + (This is just an option for flexibility, and is not required) +- Added a [Wide View] button to Edit page. +- Some minor code improvement & css tweaking. + +### 3.2.2 + +- Thanks to github.com/codeless: added a configurable whitelist of files to show. +- Fixed minor issue on hash page (needed htmlspecialchars) +- And, of course, various style & code tweaks. + + +### 3.2.1 + +- Added timer to "Please wait..." message after too many invalid login attempts. +- Mostly some misc code cleanup & improvement. + +### 3.2.0 + +- Added a few security improvements. +- Added "timeout" timer as a warning to save edits before they're lost. + + +### 3.1.9 + +- Password may now be stored as an encrypted hash, instead of in plain text. +- Added an "Admin" page to generate password hashes. +- A bunch of other code tweakin' & improvements. + +### 3.1.6 thru 3.1.8 + +- Converted bulk of rest of code into functions (easier to work with). +- Resolved issue (I hope) with differing versions of PHP and how magic_quotes & stripslashes are handled. + +### 3.1.2 thru 3.1.5 + +- Added file size limits to the Edit/View page. (Some browsers don't like large files in an HTML textarea.) +- Added some data validation to $_GET parameters +- Some misc code cleanup & organization etc. +- And other misc stuff... + +### 3.1.1 + +- Fixed minor issue with data encoding of file for editting in a <textarea> + +### 3.1 + +- (Very) moderate data validation improvements. +- Reorganized & funcionalized() most of the code. + +### 3.0 + +- Implemented svg icons + +### 2.0 + +- OneFileCMS is now actually ONE FILE! No external style sheets or icons. + (Of course, external style sheets & icons can be added back in, if you like.) + +- This is OneFileCMS "Lite", and will be maintained along with v3.0 + +### 1.5 + +- Style sheet is now part of onfilecms.php file, but still uses external icons. +- Some minor logic improvements on Edit & Index pages. + +### 1.4.0 + +- Substantial code reorganization & updates. + + +### 1.2.4 - 1.3.0 + +- DO NOT USE THESE VERSIONS! +- Mostly just a bunch of code modifications. +- These versions have issues, primarily when on the home/root page your site. + +### 1.2.3 + +- Fixed check for local css. If not found, loads hosted copy. + (This will soon be a moot point...) + +### 1.2.2 + +- On "Edit" page, images are now displayed directly, instead of a disabled textarea. +- Logout page replaced with standard "alert" message on login screen. + +### 1.2.1 + +- Fixed security hole that affected versions 1.1.7 - 1.2.0. + +### 1.2.0 + +- List of files now sorted alphabetically, without regard to case. +- Further improved Edit page & screen feedback of file state (changed/unchanged). +- Added [X] dismiss button on message box +- File dates shown on Index & Edit pages are now in user's local time. +- Moved from xhtml to html syntax & doctype. + +### 1.1.9 + +- Improved Edit page & screen feedback of file state (changed/unchanged). +- Removed use of jquery in move towards a true "OneFileCMS". + +### 1.1.8 + +- Added a table list view option (default). Either List or original "Block" view selectable with $VIEW_MODE variable. (On screen selection in the works) +- (And, of course, numerous other code tweaks/improvements. + +### 1.1.7 + +- Added [Cancel] button to most screens. Numerous minor UI & code tweaks/improvements. Changed where .css is hosted (may change back later). Removed "Rendered in (microseconds)...". Added license info & copyright notice. + +### 1.1.6 + +- Breadcrumb navigation (courtesy of [Self-Evident](https://github.com/Self-Evident/)), CSS file and some minor changes to it +- Installation is still as usual, but now, if you have _onefilecms.css_ in the same folder as _onefilecms.php_, it'll be linked instead of the normal [http://onefilecms.com/style.css](http://onefilecms.com/style.css). + +### 1.1.5 + +- Fixed a disallowed redirect vulnerability +Many thanks to Abhi M Balakrishnan from [OWASP Mantra Team](http://www.getmantra.com/) for his help + +### 1.1.4 + +- JavaScript cleanup and jQuery upgrade +- Visit Site = / +- Now on GitHub! + +### 1.1.3 (1/10/2012) + +- Fixed a upload bug leftover from 1.1.2's CSRF protection + +### 1.1.2 (9/21/11) + +- More CSRF protection for logged-in users + +### 1.1.1 (1/9/10) + +- CSRF protection (thanks Steve and Rene) +- Support for storing password as an MD5 hash (thanks, durilka!) + +### 1.1.0 (10/18/09) + +- config_footer variable for branding or analytics code +- config_disabled variable to disallow editing of files like images, zips, icons, etc +- config_excluded variable to exclude specific files (or filetypes) from being shown in the index +- Shows hidden files (files that start with a "." like ".htaccess") on index listing +- "noindex" meta tag so Google doesn't crawl your backend +- Fixed a couple minor CSS and link bugs in the example site. +- Updated license page to clarify commercial license usage per domain and upgrade. + +### 1.0.1 (9/24/09) + +- Relative CSS links and navigation in example site to work better with the demo (No change to OneFileCMS itself) + +### 1.0 (9/5/09) + +- Launch! diff --git a/languages/OneFileCMS.LANG.DE.php b/languages/OneFileCMS.LANG.DE.php new file mode 100755 index 0000000..fd0e142 --- /dev/null +++ b/languages/OneFileCMS.LANG.DE.php @@ -0,0 +1,272 @@ +'; +$_['too_large_to_edit_02'] = 'Einige Browser (wie zum Beispiel der Internet Explorer) bleiben stecken oder werden instabil, sobald größere Textmengen in einer HTML -

-

- - -

- - -

-

- - - ?r='" /> - ?d='" /> - ?c='" /> -

-
-

File Size: kb - - Last Updated:

-
- -
- -

'.$path_levels[0].' / '; - } - $current_path = ""; - for ($x=1; $x < $levels-1; $x++) { - if ($x !== 1){ $current_path .= ' / '; } - $current_path = $current_path.$path_levels[$x]; - echo ''; - echo $path_levels[$x], ' / '; - } - echo $path_levels[$x].' /'; // last item is current dir. No link needed. - ?>

- -

- - ?i=" class="folder"> - -

-
- - - -

Log In

-
"> -

- - -

-

- - -

-

Hint:

-

-
- -

Log Out

-

You have successfully been logged out and may close this window.

- -

New File

-

Existing files with the same name will not be overwritten.

-
"> - -

- - " /> -

-

-
- -

New Folder

-

Existing folders with the same name will not be overwritten.

-
"> - -

- - " /> -

-

-
- -

Other

-

Check for Updates

-

Future versions of OneFileCMS will have a one-click upgrade process. For now, though, you have to click this link. You are using version .

-

Want some good Karma?

-

Let people know you use OneFileCMS by putting this in your footer:

-
This site powered by <a href="http://onefilecms.com/">OneFileCMS</a>.
-

Admin Link

-

Add this to your footer (or something) for lazy/forgetful admins. They'll still have to know the username and password, of course.

-
[<a href="">Admin</a>]
- -

Password Hash

-

By the way, MD5 hash of your currently configured password is: - - -

Rename “

-

Existing files with the same filename are automatically overwritten... Be - careful!

-

To move a file, preface its name with the folder's name, as in - "foldername/filename.txt." The folder must already exist.

-
"> - -

- - - -

-

- - -

-

-
- -

Rename Folder “

-
"> - -

- " /> - " class="textinput" disabled="disabled" /> -

-

- - " /> -

-

-
- -

Upload

-
" method="post"> - - -

- - " class="textinput" /> -

-

- - -

-

-
- + //Only need 3 most recent pages (increase if needed) + if ($pages > 3) { array_pop($_SESSION['recent_pages']); } + +}//end Update_Recent_Pages() //************************************************* + + - -
+function undo_magic_quotes() {//************************************************ - - - - \ No newline at end of file + + +function Validate_params() {//************************************************** + global $_, $ipath, $filename, $page, $param1, $param2, $param3, $IS_OFCMS, $EX, $MESSAGE; + + //Pages that require a valid $filename + $file_pages = array("edit", "renamefile", "copyfile", "deletefile"); + + //Make sure $filename & $page go together + if ( ($filename != "") && !in_array($page, $file_pages) ) { $filename = ""; } + if ( ($filename == "") && in_array($page, $file_pages) ) { $page = "index"; } + + //Init $param's used in href's &
actions + $param1 = '?i='.URLencode_path($ipath); //$param1 must not be blank. + if ($filename == "") { $param2 = ""; } else { $param2 = '&f='.rawurlencode(basename($filename)); } + if ($page == "" ) { $param3 = ""; } else { $param3 = '&p='.$page; } + + //Used to restrict edit/del/etc. on active copy of OneFileCMS. + $IS_OFCMS = Set_IS_OFCMS($filename); + +}//end Validate_params() //***************************************************** + + + + +function Valid_Path($path, $gotoroot=true) {//********************************** + //$gotoroot: if true, return to index page of $ACCESS_ROOT. + global $ipath, $ipath_OS, $filename, $param1, $param2, $param3, $ACCESS_ROOT, $ACCESS_ROOT_len, $MESSAGE; + + //Limit access to the folder $ACCESS_ROOT: + //$ACCESS_ROOT = some/root/path/ + //$path = some/root/path/...(or deeper) : good + //$path = some/root/ : bad + //$path = some/other/path/ : bad + + $path_len = mb_strlen($path); + $path_root = mb_substr($path, 0, $ACCESS_ROOT_len); + $good_path = false; + + + if (isset($_SESSION['admin_page']) && $_SESSION['admin_page']) { + //Permit Admin actions: changing p/w, u/n, viewing OneFile... + $ACCESS_ROOT == ''; + return true; + } + elseif ( $path_len < $ACCESS_ROOT_len ) { $good_path = false; } + else { $good_path = ($path_root == $ACCESS_ROOT); } + + if (!$good_path && $gotoroot) { + $ipath = $ACCESS_ROOT; + $ipath_OS = Convert_encoding($ipath); + $filename = ''; + //$page = 'index'; //#### If set to index here, can't logout. + $param1 = '?i='.$ipath; + $param2 = ''; + $param3 = ''; + $_GET = ''; + $_POST = ''; + } + + return $good_path; +}//end Valid_Path() //********************************************************** + + + + +function Get_GET() {//**** Get URL passed parameters *************************** + global $_, $ipath, $ipath_OS, $filename, $filename_OS, $page, $VALID_PAGES, $EX, $MESSAGE, $DEFAULT_PATH; + // i=some/path/, f=somefile.xyz, p=somepage, m=somemessage + // $ipath = i , $filename = $ipath.f , $page = p , $MESSAGE + // (NOTE: in some functions $filename = just the file's name, ie: $_GET['f'], with no path/) + //##### (Normalize $filename usage program-wide??) + // Perform initial, basic, validation. + // Get_GET() should not be called unless $_SESSION['valid'] == 1 (or true) + + + //Initialize & validate $ipath + if (isset($_GET["i"])) { + $ipath = Check_path($_GET["i"],1); + $ipath_OS = Convert_encoding($ipath); + + if ( $ipath === "") {;} //root, aka '/', is valid. + else if ( $ipath === false || !is_dir($ipath_OS)) { $ipath = $DEFAULT_PATH; } //not root & not valid + } + else { + $ipath = $DEFAULT_PATH; + } + $ipath_OS = Convert_encoding($ipath); + + + //Initialize & validate $filename + if (isset($_GET["f"])) { $filename = $ipath.$_GET["f"]; } else { $filename = ""; } + + $filename_OS = Convert_encoding($filename); + if ( ($filename != "") && !is_file($filename_OS) ) { + $MESSAGE .= $EX.''.hsc($_['get_get_msg_01']).' '; + $MESSAGE .= hsc(dir_name($filename)).''.hsc(basename($filename)).'
'; + $filename = $filename_OS = ""; + } + + + //Initialize & validate $page + if (isset($_GET["p"])) { $page = $_GET["p"]; } else { $page = "index"; } + if (!in_array($page, $VALID_PAGES)) { + $MESSAGE .= $EX.hsc($_['get_get_msg_02']).' '.hsc($page).'
'; + $page = "index"; //If invalid $_GET["p"] + } + + + //Sanitize any message. Initialized on line 1 / top of this file. + if (isset($_GET["m"])) { $MESSAGE .= hsc($_GET["m"]); } +}//end Get_GET() //************************************************************* + + + + +function Verify_Page_Conditions() {//******************************************* + global $_, $ONESCRIPT_file, $ipath, $ipath_OS, $param1, $filename, $filename_OS, $page, $EX, $MESSAGE, + $VALID_POST, $IS_OFCMS; + + //If exited admin pages, restore $ipath + if ( ($page == "index") && $_SESSION['admin_page'] ) { + //...unless clicked www/some/path/ from edit or copy page while in admin pages. + if ( ($_SESSION['recent_pages'][0] != 'edit') && ($_SESSION['recent_pages'][0] != 'copyfile') ){ + $ipath = $_SESSION['admin_ipath']; + $param1 = '?i='.URLencode_path($ipath); + } + $_SESSION['admin_page'] = false; + $_SESSION['admin_ipath'] = ''; + } + //Don't load login screen when already in a valid session. + //$_SESSION['valid'] may be false after Respond_to_POST() + elseif ( ($page == "login") && $_SESSION['valid'] ) { $page = "index"; } + + elseif ( $page == "logout" ) { + Logout(); + $MESSAGE .= hsc($_['logout_msg']); + } + //Don't load rename or delete folder pages at webroot. //##### is this still needed? + elseif ( ($page == "deletefolder" || $page == "renamefolder") && ($ipath == "") ) { + $page = "index"; + } + //Prep MCD_Page() to delete a single folder selected via (x) icon on index page. + elseif ($page == "deletefolder") { + $_POST['files'][1] = basename($ipath); //Must precede next line (change of $ipath). + $ipath = dir_name($ipath); + $ipath_OS = Convert_encoding($ipath); + $param1 = '?i='.$ipath; + } + //There must be at least one 'file', and 'mcdaction' must = "move", "copy", or "delete" + elseif ($page == "mcdaction") { + if (!isset($_POST['mcdaction'] )) { $page = "index"; } + elseif (!isset($_POST['files']) ) { $page = "index"; } + elseif ( ($_POST['mcdaction'] != "move") && ($_POST['mcdaction'] != "copy") && ($_POST['mcdaction'] != "delete") ) { + $page = "index"; + } + } + //if size of $_POST > post_max_size, PHP only returns empty $_POST & $_FILE arrays. + elseif ( ($page == "uploaded") && !$VALID_POST ) { + $MESSAGE .= $EX.' '.hsc($_['upload_error_01a']).' '.ini_get('post_max_size').' '.hsc($_['upload_error_01b']).'
'; + $page = "index"; + } + + //[View Raw] file contents in a browser window (in plain text, NOT HTML). + if ($page == "raw_view"){ + ob_start(); + $raw_contents = file_get_contents($filename_OS); + $file_ENC = mb_detect_encoding($raw_contents); //ASCII, UTF-8, etc... + header('Content-type: text/plain; charset=utf-8'); + echo mb_convert_encoding($raw_contents, 'UTF-8', $file_ENC); + die; + } +}//end Verify_Page_Conditions() //********************************************** + + + + +function has_invalid_char($string) {//****************************************** + global $INVALID_CHARS; + $INVALID_CHARS_array = explode(' ', $INVALID_CHARS); + foreach ($INVALID_CHARS_array as $bad_char) { + if (mb_strpos($string, $bad_char) !== false) { return true; } + } + return false; +}//end has_invalid_char() //**************************************************** + + + + +function URLencode_path($path){ // don't encode the forward slashes ************ + $path = str_replace('\\','/',$path); //Make sure all forward slashes. + $TS = ''; // Trailing Slash/ + if (mb_substr($path, -1) == '/' ) { $TS = '/'; } //start with a $TS? + $path_array = explode('/',$path); + $path = ""; + foreach ($path_array as $level) { $path .= rawurlencode($level).'/'; } + $path = rtrim($path,'/').$TS; //end with $TS only if started with one + return $path; +}//end URLencode_path() //****************************************************** + + + + +function dir_name($path) {//**************************************************** + //Modified dirname(). + $parent = dirname($path); + if ($parent == "." || $parent == "/" || $parent == '\\' || $parent == "") { return ""; } + else { return $parent.'/'; } +}//end dir_name() //************************************************************ + + + + +function Check_path($path, $show_msg = false) {//******************************* + // check for invalid characters & "dot" or "dot dot" path segments. + // Does NOT check if exists - only if of valid construction. + global $_, $MESSAGE, $EX, $INVALID_CHARS, $WHSPC_SLASH; + + $path = str_replace('\\','/',$path); //Make sure all forward slashes. + $path = trim($path, $WHSPC_SLASH); // trim whitespace & slashes + + if ( ($path == "") || ($path == ".") ){ return ""; } // At root. + + $err_msg = ""; + $errors = 0; + + $pathparts = explode( '/', $path); + + foreach ($pathparts as $part) { + + //Check for any '.' and '..' parts of the path to protect directories outside webroot. + //They also cause issues in

www / current / path /

+ if ( ($part == '.') || ($part == '..') ) { + $err_msg .= $EX.' '.hsc($_['check_path_msg_02']).'
'; + $errors++; + break; + } + + //Check for invalid characters + $invalid_chars = str_replace(' /','',$INVALID_CHARS); //The forward slash is not present, or invalid, at this point. + if ( has_invalid_char($part) ) { + $err_msg .= $EX.' '.hsc($_['check_path_msg_03']).'   '.$invalid_chars.'
'; + $errors++; + break; + } + } + + if ($errors > 0) { + if ($show_msg) { $MESSAGE .= $err_msg; } + return false; + } + + return $path.'/'; +}//end Check_path() //********************************************************** + + + + +function Sort_Seperate($path, $full_list) {//*********************************** + //Sort list, then seperate folders & files + + natcasesort($full_list); + $files= array(); + $folders= array(); + $F=1; $D=1; //indexes + foreach ( $full_list as $item ) { + if ( ($item == '.') || ($item == '..') || ($item == "")){ continue; } + $fullpath_OS = Convert_encoding($path.$item); + if (is_dir($fullpath_OS)) { $folders[$D++] = $item; } + else { $files[$F++] = $item; } + } + + return array_merge($folders, $files); +}//end Sort_Seperate() //******************************************************* + + + + +function add_serial_num($filename, &$msg) {//*********************************** + //if file_exists(file.txt), add serial# to filename until it doesn't + //ie: file.txt.001, file.txt.002, file.txt.003 etc... + global $_, $EX; + + $ordinal = 0; + + //Convert $filename to server's File Syetem encoding + $savefile = $filename; + $savefile_OS = Convert_encoding($savefile); + + if (file_exists($savefile_OS)) { + + $msg .= $EX.hsc($_['ord_msg_01']).'
'; + + while (file_exists($savefile_OS)) { + $ordinal = sprintf("%03d", ++$ordinal); // 001, 002, 003, etc... + $savefile = $filename.'.'.$ordinal; + $savefile_OS = Convert_encoding($savefile); + } + $msg .= ''.hsc($_['ord_msg_02']).': '.hsc(basename($savefile)).''; + } + return $savefile; +}//end add_serial_num() //****************************************************** + + + + +function supports_svg() {//***************************************************** + //IE < 9 is the only browser checked for currently. + //EX: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0) + $USER_AGENT = $_SERVER['HTTP_USER_AGENT']; + $pos_MSIE = mb_strpos($USER_AGENT, 'MSIE '); + $old_ie = false; + if ($pos_MSIE !== false) { + $ie_ver = mb_substr($USER_AGENT, ($pos_MSIE+5), 1); + $old_ie = ( $ie_ver < 9 ); + } + return !$old_ie; +}//end supports_svg() //******************************************************** + + + + +function rCopy( $old_path, $new_path ) {//************************************** + global $_, $WHSPC_SLASH, $EX, $MESSAGE; + //Recursively copy $old_path to $new_path + //Both $old_ & $new_path must ALREADY be in OS/file system's encoding. + //(ie: usually UTF-8, but often ISO-8859-1 for Windows.) + //Return number of successful copy's + mkdir's, or 0 on error. + + //$old_path & $new_path must already be in OS/filesystem's file name encoding + + //Avoid a bottomless pit of sub-directories: + // ok: copy root/1/ to root/1/Copy_of_1/ + //NOT OK: copy root/1/ to root/1/2/Copy_of_1/ + // + + $error_code = 0; + + //First, trim / and white-space that will mess up strlen() check. + $old_path = trim($old_path,$WHSPC_SLASH); + $new_path = trim($new_path,$WHSPC_SLASH); + // + $test_path = dirname($new_path); + while (mb_strlen($test_path) >= mb_strlen($old_path)) { + $test_path = dirname($test_path); + if ( $test_path == $old_path ) { + $MESSAGE .= $EX.' '.hsc($_['rCopy_msg_01']).'
'; + return 0; + } + } + + if ( is_file($old_path) ) { return (copy($old_path, $new_path)*1); } + + if ( is_dir($old_path) ) { + + $dir_list = scandir($old_path); //MUST come before mkdir(). + $error_code = (mkdir($new_path, 0755)*1); + + if ( sizeof($dir_list) > 0 ) { + foreach ( $dir_list as $file ) { + if ( $file == "." || $file == ".." ) { continue; } + + $error_code += rCopy( $old_path.'/'.$file, $new_path.'/'.$file); + } + } + return $error_code; + } + + return 0; //$old_path doesn't exist, or, I don't know what it is. +}//end rCopy() //*************************************************************** + + + + +function rDel($path) {//******************************************************** + //Recursively delete $path & all sub-folders & files. + //Returns number of successful unlinks & rmdirs. + + $path = trim($path, '/'); //Protect against deleting files outside of webroot. + if ($path == "") { $path = '.'; } + + $path_OS = Convert_encoding($path); + + $count = 0; + + if ( is_file($path_OS) ) { return (unlink($path_OS)*1); } + if ( is_dir($path_OS) ) { + + $dir_list = scandir($path_OS); + foreach ( $dir_list as $dir_item ) { + $dir_item_OS = Convert_encoding($dir_item); + if ( ($dir_item == '.') || ($dir_item =='..') ) {continue;} + $count += rDel($path.'/'.$dir_item); + } + + $count += rmdir($path_OS); + return $count; + } + return false; //$path doesn't exists, or, I don't know what it is... +}//end rDel() //**************************************************************** + + + + +function Current_Path_Header() {//********************************************** + // Current path. ie: webroot/current/path/ + // Each level is a link to that level. + global $ONESCRIPT, $ipath, $ACCESS_ROOT, $ACCESS_ROOT_len, $TABINDEX, $MESSAGE; + + $unaccessable = ''; + $_1st_accessable = ''; + $remaining_path = trim(mb_substr($ipath, $ACCESS_ROOT_len), ' /'); + + if ($ACCESS_ROOT != '') { + $unaccessable = dirname($ACCESS_ROOT); + $_1st_accessable = basename($ACCESS_ROOT); + + if ($unaccessable == '.') { $unaccessable = '/'; } + else { $unaccessable = '/'.dirname($ACCESS_ROOT).'/'; } + $unaccessable = ' '.hsc(trim(str_replace('/', ' / ',$unaccessable))); + } + + echo '

'; + //Root (or $ACCESS_ROOT) folder of web site. + $p1 = '?i='.URLencode_path($ACCESS_ROOT); + + if ($_1st_accessable == "") { + echo ' /'; + } else { + echo $unaccessable.''.hsc($_1st_accessable).'/'; + } + + if ($remaining_path != "" ) { //if not at root, show the rest + $path_levels = explode("/",trim($remaining_path,'/') ); + + $levels = count($path_levels); //If levels=3, indexes = 0, 1, 2 etc... + $current_path = ""; + + for ($x=0; $x < $levels; $x++) { + $current_path .= $path_levels[$x].'/'; + $p1 = '?i='.URLencode_path($ACCESS_ROOT.$current_path); + echo ''; + echo hsc($path_levels[$x]).'/'; + } + }//end if(not at root) + echo '

'; +}//end Current_Path_Header() //************************************************* + + + + +function Page_Header() {//****************************************************** + global $_, $ONESCRIPT, $page, $WEBSITE, $MAIN_TITLE, $OFCMS_version, $FAVICON, $TABINDEX, $MESSAGE; + + $TABINDEX = 1; //Initial tabindex + + $FAVICON = trim($FAVICON,' /'); + + $favicon_img = ''; + if (file_exists($_SERVER['DOCUMENT_ROOT']."/".$FAVICON)) { + $favicon_img = '[favicon]'; + } + + echo '';// +}//end Page_Header() //********************************************************* + + + + +function Cancel_Submit_Buttons($submit_label) {//******************************* + //$submit_label = Rename, Copy, Delete, etc... + global $_, $ONESCRIPT, $ipath, $param1, $param2, $page; + + $params = $param1.$param2.'&p='. $_SESSION['recent_pages'][1]; //.'&m='.hsc($_['cancelled']) not sure I like this. +?> +

+ + + + $MAX_IMG_W) { $SCALE_W = ( $MAX_IMG_W/$img_info[$W] );} + if ($img_info[$H] > $MAX_IMG_H) { $SCALE_H = ( $MAX_IMG_H/$img_info[$H] );} + + //Set $SCALE to the more restrictive scale. + if ( $SCALE_W > $SCALE_H ) { $SCALE = $SCALE_H; } //ex: if (.90 > .50) + else { $SCALE = $SCALE_W; } //If _H >= _W, or both are 1 + + //For languages with longer words that don't fit next to [Wide] & [Close] buttons. + if ($_['image_info_pos']){ echo '

'."\n"; } + + echo '

'; + echo hsc($_['show_img_msg_01']).round($SCALE*100). + hsc($_['show_img_msg_02']).' '.$img_info[0].' x '.$img_info[1].').

'; + echo '
'."\n"; + echo ''."\n"; + echo ''."\n"; +}//end Show_Image() //********************************************************** + + + + +function Timeout_Timer($COUNT, $ID, $ACTION="") {//***************************** + global $DELAY_Start_Countdown; + + //These represent strings that need to be "quoted". + $ID = '"'.$ID.'"'; + $ACTION = '"'.$ACTION.'"'; + + return "\n"; + +}//end Timeout_Timer() //******************************************************* + + + + +function Init_Macros() {//**** ($varibale="some reusable chunk of code")******** + global $_, $ONESCRIPT, $param1, $param2, $INPUT_NUONCE, $FORM_COMMON, $PWUN_RULES; + + $INPUT_NUONCE = ''."\n"; + $FORM_COMMON = ''."\n".$INPUT_NUONCE."\n"; + + $PWUN_RULES = '

'.hsc($_['pw_txt_02']); + $PWUN_RULES .= '

  1. '.hsc($_['pw_txt_04']).'
  2. '.hsc($_['pw_txt_06']); + $PWUN_RULES .= '
  3. '.hsc($_['pw_txt_10']).'
  4. '.hsc($_['pw_txt_08']).'
'; +}//end Init_Macros() //********************************************************* + + + + +function Init_ICONS() {//******************************************************** + global $ICONS; + + //********************************************************************* + function icon_txt($border='#333', $lines='#000', $fill='#FFF', $extra1="", $extra2=""){ + return ''. + ''.$extra2. + ''. + ''. + ''. + ''.$extra1.''; + }//end icon_txt() //*************************************************** + + + function icon_folder($extra = "") {//********************************** + return ''. + ''. + ''. + ''. + $extra.''; + }//end icon_folder() //************************************************ + + + //Some common components + $circle_x = ''. + ''. + ''; + + $circle_plus = ''. + ''. + ''; + + $circle_plus_rev = ''. + ''. + ''; + + $pencil = ''. + ''. + ''. + ''. + ''; + + $img_0 = ''. + ''. + ''. + ''; + + $arc_arrow = ''; + + $up_arrow = ''; + + $zero = ''; + $one = ''; + + $extra_up = ''.$up_arrow.''; + $extra_new = ''.$circle_plus.''; + $extra_z = 'z'; + + //The icons + $ICONS['bin'] = ''. + ''.$one .''. + ''.$zero.''.''.$one .''. + ''.$one .''.''.$zero.''. + ''.$one .''.''.$zero.''. + ''; + $ICONS['z'] = icon_txt('#333','#FFF','#FFF',$extra_z); + $ICONS['img'] = ''.$img_0.''; + $ICONS['svg'] = icon_txt('#333', '#444', '#FFF', "", $img_0); + $ICONS['txt'] = icon_txt('#333', '#000', '#FFF'); + $ICONS['htm'] = icon_txt('#444', '#222', '#FABEAA'); //rgb(250,190,170) + $ICONS['php'] = icon_txt('#333', '#111', '#C3C3FF'); //rgb(195,195,225) + $ICONS['css'] = icon_txt('#333', '#111', '#FFE1A5'); //rgb(255,225,165) + $ICONS['cfg'] = icon_txt('#444', '#111', '#DDD'); + $ICONS['dir'] = icon_folder(); + $ICONS['folder'] = icon_folder(); + $ICONS['folder_new'] = icon_folder(''.$circle_plus.''); + $ICONS['upload'] = icon_txt('#333', 'black', 'white', $extra_up); + $ICONS['file_new'] = icon_txt('#444', 'black', 'white', $extra_new); + $ICONS['ren_mov'] = icon_folder(''.$pencil.''.$arc_arrow); + $ICONS['move'] = icon_folder($arc_arrow); + $ICONS['copy'] = ''.$circle_plus_rev.''; + $ICONS['delete'] = ''.$circle_x.''; + $ICONS['up_dir'] = icon_folder(''.$up_arrow.''); + + if (!supports_svg()) { //Text "icons" if SVG not supported. Mostly for IE < 9 + foreach ($ICONS as $key=> $value) { $ICONS[$key] = ""; } + $ICONS['up_dir'] = '[<]'; + $ICONS['dir'] = '[+]'; + $ICONS['folder'] = '[+]'; + $ICONS['ren_mov'] = '>'; + $ICONS['move'] = '>'; + $ICONS['copy'] = '+'; + $ICONS['delete'] = 'x'; + } +}//end Init_ICONS() {//********************************************************* + + + + +function List_File($file, $file_url) {//**************************************** + global $_, $DOC_ROOT, $ONESCRIPT, $ICONS, $MESSAGE; + + $file_OS = Convert_encoding($file); + clearstatcache(); + $ipath = trim($DOC_ROOT,'/').dir_name($file_url); + + $href = $ONESCRIPT.'?i='.$ipath.'&f='.basename($file_url); + $edit_link = ''.hsc(basename($file)).''; +?> + + + + +   B +   + +'; + if ($log_found) { List_File($LOGIN_LOG_file, $LOGIN_LOG_url); } + if (is_file($ONESCRIPT_file_backup_OS)) { List_File($ONESCRIPT_file_backup, $ONESCRIPT_backup); } + if (is_file($CONFIG_FILE_backup_OS)) { List_File($CONFIG_FILE_backup, $CONFIG_backup); } + echo ''; + + if ($backup_found) { + echo '

'.hsc($_['admin_txt_00']).'

'; + echo '

'.hsc($_['admin_txt_01']); + } + echo '


'; + }//end of check for backup +}//end List_Backups_and_Logs() //*********************************************** + + + + +function Admin_Page() {//******************************************************* + global $_, $DOC_ROOT, $ONESCRIPT, $ipath, $filename, $param1, $param2, $MAIN_TITLE, $MESSAGE; + + // Restore/Preserve $ipath prior to admin page in case OneFileCMS is edited (which would change $ipath). + if ( $_SESSION['admin_page'] ) { $ipath = $_SESSION['admin_ipath']; + $param1 = '?i='.URLencode_path($ipath); } + else { $_SESSION['admin_page'] = true; + $_SESSION['admin_ipath'] = $ipath; } + + // [Close] returns to either the index or edit page. + $params = ""; + if ($filename != "") { $params = $param2.'&p=edit'; } + + $button_attribs = ''; + echo $button_attribs.$param1.'&p=changepw\'">'.hsc($_['pw_change']).''; + echo $button_attribs.$param1.'&p=changeun\'">'.hsc($_['un_change']).''; + echo $button_attribs.$param1.'&p=hash\'">'.hsc($_['Generate_Hash']).''; + echo $button_attribs.$edit_params.'\'">'.hsc($_['View'].' '.$MAIN_TITLE).''; + echo ''; + + echo '
'; + + List_Backups_and_Logs(); + + echo '

'.hsc($_['Username']).': '; + echo ''.get_current_user()."
\n"; + + echo '

'.hsc($_['admin_txt_03']).': '; + echo ''.session_save_path()."
\n"; + + echo '

'.hsc($_['admin_txt_04']).': '; + echo ''.php_uname('n')."


\n"; + + echo '

'.hsc($_['admin_txt_02']).''; + echo '

' .hsc($_['admin_txt_16']); + echo '

'.hsc($_['admin_txt_14']); + echo '

'; //end class=info + + echo ''; +}//end Admin_Page() //********************************************************** + + + + +function Hash_Page() {//******************************************************** + global $_, $ONESCRIPT, $param1, $param3, $INPUT_NUONCE, $PWUN_RULES; + + if (!isset($_POST['whattohash'])) { $_POST['whattohash'] = ''; } +?> + + +

+ + + + + +

+ +

+ +
+


+


  1. + +

  2. +
    +
    +
  3. +
+ +
+'; + $MESSAGE .= hsc($_['Hash']).': '.hashit($_POST['whattohash'], 1).'
'; +}//end Hash_response() //******************************************************* + + + + +//****************************************************************************** +function Change_PWUN_Page($pwun, $type, $page_title, $label_new, $label_confirm) { + //$pwun must = "pw" or "un" + global $_, $EX, $ONESCRIPT, $param1, $param2, $param3, $INPUT_NUONCE, $PWUN_RULES; + + $params = $param1.$param2.'&p='. $_SESSION['recent_pages'][1]; +?> + + + +

+ +
+ + + + +


+ + +


+ + +


+ + +

+ + + +

+ +
+ +

+

+

+'.hsc($_['Not_found']).': '.hsc($search_file).'
'; + return false; + } + + //Read file into an array for searching. + $search_lines = file($search_file_OS, FILE_IGNORE_NEW_LINES); + + //Search start of each $line in (array)$search_lines for (string)$search_for. + //If match found, replace $line with $replace_with, end search. + $search_len = mb_strlen($search_for); + $found = false; + foreach ($search_lines as $key => $line) { + if ( mb_substr($line,0,$search_len) == $search_for ) { + $found = true; + $search_lines[$key] = $replace_with; + break 1; //only replace first occurrance of $search_for + } + } + + //This should not happen, but just in case... + if (!$found){ $MESSAGE .= $EX.' '.hsc($_['Not_found']).': '.hsc($search_for).'
'; return false; } + + copy($search_file_OS, $backup_file_OS); // Just in case... + + $updated_contents = implode("\n", $search_lines); + + if (file_put_contents($search_file_OS, $updated_contents, LOCK_EX) === false) { + $MESSAGE .= $EX.''.hsc($_['Update_failed']).'
'; + return false; + }else {return true;} +}//end Update_config() //******************************************************* + + + + +function Change_PWUN_response($PWUN, $msg) {//********************************** + //Update $USERNAME or $HASHWORD. Default $page = changepw or changeun + global $_, $ONESCRIPT, $USERNAME, $HASHWORD, $EX, $MESSAGE, $page, + $ONESCRIPT_file, $ONESCRIPT_file_backup, $CONFIG_FILE, $CONFIG_FILE_backup, $VALID_CONFIG_FILE; + + // trim white-space from input values + $current_pass = trim($_POST['password']); + $new_pwun = trim($_POST['new1']); + $confirm_pwun = trim($_POST['new2']); + + $error_msg = $EX.''.hsc($msg).' '; + + //If all fields are blank, do nothing. + if ( ($current_pass == "") && ($new_pwun == "") && ($confirm_pwun == "") ) { + return; + } + //If any field is blank... + elseif ( ($current_pass == "") || ($new_pwun == "") || ($confirm_pwun == "") ) { + $MESSAGE .= $error_msg.hsc($_['change_pw_07']).'
'; + } + //If new & Confirm values don't match... + elseif ($new_pwun != $confirm_pwun) { + $MESSAGE .= $error_msg.hsc($_['change_pw_04']).'
'; + } + //If incorrect current p/w, logout. (new == confirm at this point) + elseif (hashit($current_pass) != $HASHWORD) { + $MESSAGE .= $error_msg.'
'.hsc($_['change_pw_03']).'
'; + Logout(); + } + //Else change username or password + else { + if ($PWUN == "pw") { + $search_for = '$HASHWORD '; //include space after $HASHWORD + $replace_with = '$HASHWORD = "'.hashit($new_pwun).'";'; + $success_msg = ''.hsc($_['change_pw_01']).''; + }else { //$PWUN = "un" + $search_for = '$USERNAME '; //include space after $USERNAME + $replace_with = '$USERNAME = "'.$new_pwun.'";'; + $success_msg = ''.hsc($_['change_un_01']).''; + } + + //If specified & it exists, update external config file. + if ( $VALID_CONFIG_FILE ) { + $MESSAGE .= hsc($_['change_pw_05']).' '.hsc($_['change_pw_06']).'. . . '; + $updated = Update_config($search_for, $replace_with, $CONFIG_FILE, $CONFIG_FILE_backup); + }else{ //Update OneFileCMS + $MESSAGE .= hsc($_['change_pw_05']).' OneFileCMS . . . '; + $updated = Update_config($search_for, $replace_with, $ONESCRIPT_file, $ONESCRIPT_file_backup); + } + + if ($updated === false) { $MESSAGE .= $error_msg.'
'; } + else { $MESSAGE .= $success_msg.'
'; } + + $page = "admin"; //Return to Admin page. + } +}//end Change_PWUN_response() //************************************************ + + + + +function Logout() {//*********************************************************** + global $page; + session_regenerate_id(true); + session_unset(); + session_destroy(); + session_write_close(); + unset($_GET); + unset($_POST); + $_SESSION = array(); + $_SESSION['valid'] = 0; + $page = 'login'; +}//end Logout() //************************************************************** + + + + +function Login_Page() {//******************************************************* + global $_, $ONESCRIPT; +?> + + + +

+
+ + + + + +
+ + 0) { $MESSAGE .= ''.hsc($_['login_msg_01a']).' '.$attempts.' '.hsc($_['login_msg_01b']).'
'; } + + if ( ($attempts >= $MAX_ATTEMPTS) && ($elapsed < $LOGIN_DELAY) ){ + $LOGIN_DELAYED = ($LOGIN_DELAY - $elapsed); + $MESSAGE .= hsc($_['login_msg_02a']).' '.hsc($_['login_msg_02b']); + return; + } + + //Trim any incidental whitespace before validating. + $_POST['password'] = trim($_POST['password']); + $_POST['username'] = trim($_POST['username']); + + //validate login. + if ( ($_POST['password'] == "") || ($_POST['username'] == "") ) { + return; //Ignore login attempt if either username or password is blank. + + }elseif ( (hashit($_POST['password']) == $HASHWORD) && ($_POST['username'] == $USERNAME) ) { + session_regenerate_id(true); + $_SESSION['user_agent'] = $_SERVER['HTTP_USER_AGENT']; //for user consistancy check. + $_SESSION['valid'] = 1; + $page = "index"; + if ( is_file($LOGIN_ATTEMPTS) ) { unlink($LOGIN_ATTEMPTS); } //delete count/file of $LOGIN_ATTEMPTS + + }else{ + file_put_contents($LOGIN_ATTEMPTS, ++$attempts); //increment attempts + $MESSAGE = $EX.''.hsc($_['login_msg_03']).$attempts.'
'; + if ($attempts >= $MAX_ATTEMPTS) { + $LOGIN_DELAYED = $LOGIN_DELAY; + $MESSAGE .= hsc($_['login_msg_02a']).' '.hsc($_['login_msg_02b']); + } + } + + //Log login attempts + if ($LOG_LOGINS) { + $log_file = Convert_encoding($LOGIN_LOG_file); + $pass_fail = $_SESSION['valid'].' '; + $timestamp = date("Y-m-d H:i:s").' '; + $client_IP = $_SERVER['REMOTE_ADDR'].' '; + $client_port = $_SERVER['REMOTE_PORT'].' '; + $client = '"'.$_SERVER['HTTP_USER_AGENT'].'"'; + + file_put_contents($log_file, $pass_fail.$timestamp.$client_IP.$client_port.$client."\n",FILE_APPEND); + }// +}//end Login_response() //****************************************************** + + + + +function Create_Table_for_Listing() {//***************************************** + global $_, $ONEFILECMS, $ipath, $ipath_OS, $ICONS, $TABINDEX, $ACCESS_ROOT, $DIRECTORY_COLUMNS; + + //Header row: | Select All|[ ]|[X](folders first) Name (ext) | Size | Date | + + $new_path = URLencode_path(dir_name($ipath)); //for "../" entry in dir list. + + $file_owner_header = $file_group_header = ""; + if (function_exists('posix_getpwuid')) { + $file_owner_header = $_['Owner']; + $file_group_header = $_['Group']; + } + + $ti = $TABINDEX + 6; + if ($ipath == $ACCESS_ROOT) + { $file_0 = " "; } + else + { $file_0 = "{$ICONS['up_dir']} .. /"; } + + // is a dummy input to make sure files[] is always an array for Select_All() & Confirm_Ready(). +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ TYPE=checkbox NAME=select_all VALUE=select_all> +
+
sogw +
+ TYPE=checkbox id=folders_first_ckbox NAME=folders_first VALUE=folders_first checked> +
+ + href="#" id=header_sorttype>() + href="#" id=header_filename> +
href="#" id=header_filesize> href="#" id=header_filedate>
+ ".readlink($filename_OS); } + else { $file_stats['link_target'] = ""; } + + return $file_stats; + +}//end Get_File_Stats() {//***************************************************** + + + + +function Get_DIRECTORY_DATA($raw_list) {//************************************** + global $_, $ONESCRIPT, $ipath, $ipath_OS, $param1, $ICONS, $MESSAGE, + $FTYPES, $FCLASSES, $EXCLUDED_LIST, $STYPES, $SHOWALLFILES, + $DIRECTORY_DATA, $ENC_OS; + + //Doesn't use global $filename or $filename_OS in this function (because they shouldn't exist on the Index page) + //$filename below is JUST the file's name. In other functions, it's the full/path/filename + + clearstatcache(); + + $file_count = 0; //final count to exclude . & .., and any $excluded file names + foreach ($raw_list as $raw_filename) { //$raw_list is in server's File System encoding + + if ( ($raw_filename == '.') || ($raw_filename == '..') ) {continue;} + + $filename_OS = $ipath_OS.$raw_filename; + + $file_stats = Get_File_Stats($filename_OS); + + //Normalize filename encoding for general use & display. (UTF-8, which may not be same as the server's File System) + if ($ENC_OS == 'UTF-8') {$filename = $raw_filename;} + else {$filename = Convert_encoding($raw_filename,'UTF-8');} + + //Get file .ext & check against $STYPES (files types to show) + $filename_parts = explode(".", mb_strtolower($filename)); + + //Check for no $ext: "filename" or ".filename" + $segments = count($filename_parts); + if( $segments === 1 || (($segments === 2) && ($filename_parts[0] === "")) ) { + $ext = ''; + } else { $ext = end($filename_parts); } + + //Check $filename & $ext against white & black lists. If not to be shown, get next $filename... + if (!is_dir($filename_OS)) { + if ($SHOWALLFILES || in_array($ext, $STYPES)) { $SHOWTYPE = TRUE; } else { $SHOWTYPE = FALSE; } + if (in_array($filename, $EXCLUDED_LIST)) { $excluded = TRUE; } else { $excluded = FALSE; } + if ( !$SHOWTYPE || in_array($filename, $EXCLUDED_LIST) ) { continue; } + } + + //Set icon type based on if dir, or file type ($ext). + if (is_dir($filename_OS)) { $type = 'dir'; } + else { $type = $FCLASSES[array_search($ext, $FTYPES)]; } + + //Determine icon to show + if (in_array($type,$FCLASSES)) { $icon = $ICONS[$type];} + elseif ($type == 'dir') { $icon = $ICONS['folder']; } + else { $icon = $ICONS['bin']; } //default + + //Store data + $DIRECTORY_DATA[$file_count] = array('', '', 0, 0, 0, '', '', '', '', ''); + $DIRECTORY_DATA[$file_count][ 0] = $type; //used to determine icon & f_or_f + $DIRECTORY_DATA[$file_count][ 1] = $filename; + $DIRECTORY_DATA[$file_count][ 2] = $file_stats['size']; + $DIRECTORY_DATA[$file_count][ 3] = $file_stats['mtime']; + $DIRECTORY_DATA[$file_count][ 4] = Set_IS_OFCMS($ipath.$filename); //If = 1, Don't show ren, del, ckbox. + $DIRECTORY_DATA[$file_count][ 5] = $ext; //##### Is this used? + $DIRECTORY_DATA[$file_count][ 6] = $file_stats['perms']; + $DIRECTORY_DATA[$file_count][ 7] = $file_stats['owner']; + $DIRECTORY_DATA[$file_count][ 8] = $file_stats['group']; + $DIRECTORY_DATA[$file_count][ 9] = $file_stats['link_target']; + $DIRECTORY_DATA[$file_count][10] = $file_stats['is_writable']; //1 or 0 (true or false) + + $file_count++; + }//end foreach file + + return $file_count; +}//end Get_DIRECTORY_DATA() //************************************************** + + + + +function Index_Page_buttons_top($file_count) {//******************************** + global $_, $ONESCRIPT, $param1, $ICONS, $TABINDEX; + + echo '
'."\n"; + + echo '
'."\n"; + if ($file_count > 0) { + echo '
'."\n"; //end mcd_submit + + echo ''; //end front_links + + echo '
'."\n"; //end index_page_buttons + +} //end Index_Page_buttons_top() //********************************************* + + + + +function Index_Page() {//******************************************************* + global $ONESCRIPT, $ipath_OS, $param1, $INPUT_NUONCE, $DIRECTORY_DATA, $DIRECTORY_COUNT; + + //Get current directory list (unsorted) + $raw_list = scandir('./'.$ipath_OS); + $DIRECTORY_COUNT = Get_DIRECTORY_DATA($raw_list); + + if ($DIRECTORY_COUNT < 1) { $json_encoded_DIRECTORY_DATA = "[]"; } + else { $json_encoded_DIRECTORY_DATA = json_encode($DIRECTORY_DATA); } + + //
to contain directory, including buttons at top. + echo "\n"; + echo "\n"; //along with $page, affects response + echo $INPUT_NUONCE; //Needed for file permission updates. + + Index_Page_buttons_top($DIRECTORY_COUNT); + + Create_Table_for_Listing(); //sets up table with empty + + echo "
\n\n\n"; + echo "\n"; + + init_ICONS_js(); + Index_Page_scripts(); + Index_Page_events(); +}//end Index_Page() //********************************************************** + + + + +function Edit_Page_buttons_top($text_editable,$file_ENC, $file_stats) {//******* + global $_, $ONESCRIPT, $param1, $param2, $filename, $filename_OS, $IS_OFCMS, + $WYSIWYG_VALID, $EDIT_WYSIWYG, $WYSIWYG_label, $MESSAGE; + + clearstatcache(); + + //[View Raw] button. + if ($text_editable) { + $view_raw_button = '\n"; + } else {$view_raw_button = '';} + + //[Wide View] / [Normal View] button. Label is what button will do, not an indicator the current state. + $wide_view_button = ""; + if ($text_editable && !$EDIT_WYSIWYG) { + if ($_COOKIE['wide_view'] === "on") { $wv_label = hsc($_['Normal_View']); } + else { $wv_label = hsc($_['Wide_View']); } + $wide_view_button = "\n"; + } + + //[Edit WYSIWYG] / [Edit Source] button. + $WYSIWYG_button = ''; + if ($text_editable && $WYSIWYG_VALID && !$IS_OFCMS) { //Only show when needed/applicable + //Set current mode for Edit page, and label for [Edit WYSIWIG/Source] button + if ( isset($_COOKIE['edit_wysiwyg']) && ($_COOKIE['edit_wysiwyg'] == '1')) { + $EDIT_WYSIWYG = '1'; $WYSIWYG_label = $_['Source']; } //wysiwyg mode + else { $EDIT_WYSIWYG = '0'; $WYSIWYG_label = $_['WYSIWYG']; } //plain text mode + + $WYSIWYG_button = ''; + } + + //[Close] button + $close_button = ''; + +?> +
+
+ + +   + + FileTimeStamp('.$file_stats['mtime'].', 1, 1, 1);'; ?> + +
+
+ +
+ + + + +
+
+
+ button doesn't work. (I don't know why.) + $reset_button = ''; + if ($WYSIWYG_VALID && $EDIT_WYSIWYG) {$reset_button = '';} + + echo '
'; + + if ($text_editable && !$too_large_to_edit && !$IS_OFCMS && $writable) { //Show save & reset only if editable file + echo ''; + echo ''; //Submit Button + echo $reset_button; + }//end if editable + + function RCD_button($action, $icon, $label) {//*************** + global $ICONS; + echo ''; + }//end RCD_button() //**************************************** + + //Don't show [Rename] or [Delete] if viewing OneFileCMS itself. + if (!$IS_OFCMS && $writable) { RCD_button('renamefile', 'ren_mov', $_['Ren_Move']); } + /*** Always show Copy ***/ { RCD_button('copyfile' , 'copy' , $_['Copy']); } + if (!$IS_OFCMS && $writable) { RCD_button('deletefile', 'delete' , $_['Delete']); } + + echo '
'; + +}//end Edit_Page_buttons() //*************************************************** + + + + +//****************************************************************************** +function Edit_Page_form($ext, $text_editable, $too_large_to_edit, $too_large_to_view, $file_ENC){ + global $_, $ONESCRIPT, $param1, $param2, $param3, $filename, $filename_OS, $ITYPES, $INPUT_NUONCE, $EX, $MESSAGE, + $FILECONTENTS, $WYSIWYG_VALID, $EDIT_WYSIWYG, $IS_OFCMS, $MAX_EDIT_SIZE, $MAX_VIEW_SIZE, $LINE_WRAP; + + //Line-wrap on or off? $LINE_WRAP default value set in configuration section. + //Used to set initial value of on/off button below textarea. A default value is in config section. + if (isset($_COOKIE['line_wrap'])) { + if (($_COOKIE['line_wrap'] === "on") || ($_COOKIE['line_wrap'] === "off")) { + $LINE_WRAP = $_COOKIE['line_wrap']; + } + } + + $too_large_to_edit_message = + ''.hsc($_['too_large_to_edit_01']).' '.number_format($MAX_EDIT_SIZE).' '.hsc($_['bytes']).'
'. + hsc($_['too_large_to_edit_02']).'
'.hsc($_['too_large_to_edit_03']).'
'.hsc($_['too_large_to_edit_04']); + + $too_large_to_view_message = + ''.hsc($_['too_large_to_view_01']).' '.number_format($MAX_VIEW_SIZE).' '.hsc($_['bytes']).'
'. + hsc($_['too_large_to_view_02']).'
'.hsc($_['too_large_to_view_03']).'
'; + + clearstatcache(); + + $file_stats = Get_File_Stats($filename_OS); + $file_perms = Format_Perms($file_stats['perms']); + $writable = $file_stats['is_writable']; + + if (!$writable) { + $MESSAGE .= ""; + $MESSAGE .= $file_perms." ".$file_stats['owner']." ".$file_stats['group']." :".get_current_user().": "; + $MESSAGE .= $_['edit_txt_05']." ".$_['edit_txt_00']."
"; + } + + echo "\n".'
'."\n"; + + echo $INPUT_NUONCE; + + Edit_Page_buttons_top($text_editable, $file_ENC, $file_stats); + + if ( !in_array( mb_strtolower($ext), $ITYPES) ) { //If non-image... + + //Did htmlspecialchars return an empty string from a non-empty file? + $bad_chars = ( ($FILECONTENTS == "") && ($file_stats['size'] > 0) ); + + if (!$text_editable) { $MESSAGE .= hsc($_['edit_txt_01']).'
'; } + elseif ( $text_editable && $too_large_to_view ) { + echo '

'.$too_large_to_view_message.'

'; + } else { + + if ($IS_OFCMS || $too_large_to_edit || !$writable) {$readonly = "readonly";} else {$readonly = "";} + + if ( $too_large_to_edit ) { $MESSAGE .= $too_large_to_edit_message; } + + if ($bad_chars){ //Show message: possible bad character in file + echo '
'.$EX.hsc($_['edit_txt_02']).'
'; + echo hsc($_['edit_txt_03']).'
'; + echo hsc($_['edit_txt_04']).'
'."\n"; + }else{ //show editable \n"; + echo "\n"; + + $wrap_on_off = hsc($_['Line_Wrap'])." "; + $wrap_on_off .= "" .hsc($_['on']) ."/"; + $wrap_on_off .= "".hsc($_['off']).""; + + echo ""; + } + }//end if/elseif... + + }//end if non-image + + Edit_Page_buttons($text_editable, $too_large_to_edit, $writable); + echo "\n
\n"; + + Edit_Page_scripts(); + + if ( !$IS_OFCMS && $text_editable && !$too_large_to_edit && !$bad_chars && $writable) {Edit_Page_Notes();} +}//end Edit_Page_form() //****************************************************** + + + + +function Edit_Page_Notes() {//************************************************** + global $_, $MAX_IDLE_TIME; + $SEC = $MAX_IDLE_TIME; + $HRS = floor($SEC/3600); + $SEC = fmod($SEC,3600); + $MIN = floor($SEC/60); if ($MIN < 10) { $MIN = "0".$MIN; }; + $SEC = fmod($SEC,60); if ($SEC < 10) { $SEC = "0".$SEC; }; + $HRS_MIN_SEC = $HRS.':'.$MIN.':'.$SEC; +?> +
+
+
1) + + +
+
2)
+
+ $MAX_EDIT_SIZE); + $too_large_to_view = (filesize($filename_OS) > $MAX_VIEW_SIZE); + + //Don't load $WYSIWYG_PLUGIN if not needed + if (!$text_editable || $too_large_to_edit) {$WYSIWYG_VALID = 0;} + + //Get file contents + if (($text_editable && !$too_large_to_view) || $IS_OFCMS) { + $raw_contents = file_get_contents($filename_OS); + $file_ENC = mb_detect_encoding($raw_contents); //ASCII, UTF-8, ISO-8859-1, etc... + if ($file_ENC != 'UTF-8') { $raw_contents = mb_convert_encoding($raw_contents, 'UTF-8', $file_ENC); } + }else{ + $file_ENC = ""; + $raw_contents = ""; + } + + + if (PHP_VERSION_ID < 50400) { $FILECONTENTS = hsc($raw_contents); } + else { $FILECONTENTS = htmlspecialchars($raw_contents,ENT_SUBSTITUTE | ENT_QUOTES, 'UTF-8'); } + + if ($too_large_to_view || !$text_editable) { $header2 = "";} + elseif ($text_editable && !$too_large_to_edit && !$IS_OFCMS) { $header2 = hsc($_['edit_h2_2']); } + else { $header2 = hsc($_['edit_h2_1']); } + + echo '

'.$header2.' '; + echo ''; + echo hsc(basename($filename)).''; + echo '

'."\n"; + + Edit_Page_form($ext, $text_editable, $too_large_to_edit, $too_large_to_view, $file_ENC); + + if ( in_array( $ext, $ITYPES) ) { Show_Image($filename1); } //If image, show below the [Rename/Move] [Copy] [Delete] buttons + + echo '
'; + + //If viewing OneFileCMS itself, show Edit Disabled message. + if ($IS_OFCMS && $page == "edit") { + $MESSAGE .= ''; + $MESSAGE .= ''; + $MESSAGE .= ''.$EX.hsc($_['edit_caution_02']).'   '.$_['edit_txt_00'].'
'; + } +}//end Edit_Page() //*********************************************************** + + + + +function Edit_response() {//***If on Edit page, and [Save] clicked ************* + global $_, $EX, $MESSAGE, $filename, $filename_OS; + + $contents = $_POST['contents']; + + $contents = str_replace("\r\n", "\n", $contents); //Normalize EOL + $contents = str_replace("\r" , "\n", $contents); //Normalize EOL + + $bytes = file_put_contents($filename_OS, $contents); + + if ($bytes !== false) { + $MESSAGE .= ''.hsc($_['edit_msg_01']).' '.number_format($bytes).' '.hsc($_['edit_msg_02']).'
'; + }else{ + $MESSAGE .= $EX.''.hsc($_['edit_msg_03']).'
'; + } +}//end Edit_response() //******************************************************* + + + + +function Upload_Page() {//****************************************************** + global $_, $ONESCRIPT, $ipath, $param1, $INPUT_NUONCE, $UPLOAD_FIELDS, $MAIN_WIDTH; + + $max_file_uploads = ini_get('max_file_uploads'); + if ($max_file_uploads < 1) { $max_file_uploads = $UPLOAD_FIELDS; } + if ($max_file_uploads < $UPLOAD_FIELDS) { $UPLOAD_FIELDS = $max_file_uploads; } + + //$main_width is used below to determine size (width) of in FF. + $main_width = $MAIN_WIDTH * 1; //set in config section. Default is 810px. + $main_units = mb_substr($MAIN_WIDTH, -2); //should be px, pt, or em. + //convert to px. 16px = 12pt = 1em + if ( $main_units == "em") { $main_width = $main_width * 16 ; } + elseif ( $main_units == "pt") { $main_width = $main_width * (16 / 12); } + + echo '

'.hsc($_['Upload_File']).'

'; + echo '

'; + echo hsc($_['upload_txt_03']).' '.ini_get('upload_max_filesize').' '.hsc($_['upload_txt_01']).'
'; + echo hsc($_['upload_txt_04']).' '.ini_get('post_max_size') .' '.hsc($_['upload_txt_02']).'
'; + + echo '

'; + echo $INPUT_NUONCE; + + echo '
'; + echo '
'; //So
'; + + for ($x = 0; $x < $UPLOAD_FIELDS; $x++) { + //size attibute is for FF (and is not em, px, pt, or %). + //width attribute is for IE & Chrome, and can be set via css (in style_sheet()). + //In FF, width of is 121px. If size=2, width = 128, etc. The base value is 114px. + echo '
'."\n"; + } + echo '

'; + Cancel_Submit_Buttons($_['Upload']); + echo "\n

\n"; +}//end Upload_Page() //********************************************************* + + + + +function Upload_response() {//************************************************** + global $_, $ipath, $ipath_OS, $page, $EX, $MESSAGE, $UPLOAD_FIELDS; + + $page = "index"; //return to index. + + $filecount = 0; + foreach ($_FILES['upload_file']['name'] as $N => $name) { + if ($name == "") { continue; } //ignore empty upload fields + + $filecount++; + $filename_up = $ipath.$_FILES['upload_file']['name'][$N]; //just filename, no path. + $filename_OS = Convert_encoding($filename_up); + + $savefile_msg = ''; + + $MAXUP1 = ini_get('upload_max_filesize'); + //$MAXUP2 = ''; //number_format($_POST['MAX_FILE_SIZE']).' '.hsc($_['bytes']); + $ERROR = $_FILES['upload_file']['error'][$N]; + + if ( $ERROR == 1 ){ $ERRMSG = hsc($_['upload_err_01']).' upload_max_filesize = '.$MAXUP1;} + elseif (($ERROR > 1) && ($ERROR < 9)) { $ERRMSG = hsc($_['upload_err_0'.$ERROR]); } + else { $ERRMSG = ''; } + + if ( ($ipath === false) || (($ipath != "") && !is_dir($ipath_OS))) { + $MESSAGE .= $EX.''.hsc($_['upload_msg_02']).'
'; + $MESSAGE .= ''.hsc($ipath).'
'; + $MESSAGE .= hsc($_['upload_msg_03']).'
'; + }else{ + $MESSAGE .= ''.hsc($_['upload_msg_04']).' '.hsc(basename($filename_up)).'
'; + + if ( isset($_POST['ifexists']) && ($_POST['ifexists'] == 'overwrite') ) { + if (is_file($filename_OS)) { $savefile_msg .= hsc($_['upload_msg_07']) ; } + }else{ //rename to "file.etc.001" etc... + $filename_up = add_serial_num($filename_up, $savefile_msg); + } + + $filename_OS = Convert_encoding($filename_up); + if(move_uploaded_file($_FILES['upload_file']['tmp_name'][$N], $filename_OS)) { + $MESSAGE .= ''.hsc($_['upload_msg_05']).' '.$savefile_msg.'
'; + } else{ + $MESSAGE .= ''.$EX.hsc($_['upload_msg_06']).' '.$ERRMSG.'
'; + } + } + }//end foreach $_FILES + + if ($filecount == 0) { $page = "upload"; } //If nothing selected, just reload Upload page. +}//end Upload_response() //***************************************************** + + + + +function New_Page($title, $new_f_or_f) {//********************************************** + global $_, $FORM_COMMON, $INVALID_CHARS; + + echo '

'.hsc($title).'

'; + echo $FORM_COMMON; + echo '

'.hsc($_['new_file_txt_01'].' '.$_['new_file_txt_02']); + echo ' '.hsc($INVALID_CHARS).'

'; + echo '

'; + Cancel_Submit_Buttons($_['Create']); + echo "\n\n"; +}//end New_Page() //************************************************************ + + + + +function New_response($post, $isfile) {//*************************************** + global $_, $ipath, $ipath_OS, $filename, $filename_OS, $page, $param1, $param2, $param3, $MESSAGE, $EX, $INVALID_CHARS, $WHSPC_SLASH; + + $page = "index"; //Return to index if folder, or on error. + + $new_name = trim($_POST[$post], $WHSPC_SLASH); //Trim whitespace & slashes. + + $filename = $ipath.$new_name; + $filename_OS = Convert_encoding($filename); + + if ($isfile) { $f_or_f = "file"; } + else { $f_or_f = "folder"; } + + $msg_new = ''.hsc($new_name).'
'; + + if (has_invalid_char($new_name)){ + $MESSAGE .= $EX.''.hsc($_['new_file_msg_01']).' '.$msg_new; + $MESSAGE .= ''.hsc($_['new_file_msg_02']).' '.hsc($INVALID_CHARS).''; + + }elseif ($new_name == ""){ //No new name given. + $page = "new".$f_or_f; + $param3 = '&p=index'; //For [Cancel] button + + }elseif (file_exists($filename_OS)) { //Does file or folder already exist ? + $MESSAGE .= $EX.''.hsc($_['new_file_msg_04']).' '.$msg_new; + + }elseif ($isfile && touch($filename_OS) ) { //Create File + $MESSAGE .= ''.hsc($_['new_file_msg_05']).' '.$msg_new; //New File success. + $page = "edit"; //Return to edit page. + $param2 = '&f='.rawurlencode(basename($filename)); //for Edit_Page() buttons + $param3 = '&p=edit'; //for Edit_Page() buttons + + }elseif (!$isfile && mkdir($filename_OS,0755)) { //Create Folder + $MESSAGE .= ''.hsc($_['new_file_msg_07']).' '.$msg_new; //New folder success + $ipath = $filename; //return to new folder + $ipath_OS = Convert_encoding($filename); + $param1 = '?i='.URLencode_path($ipath); + + }else{ + $MESSAGE .= $EX.''.hsc($_['new_file_msg_01']).':
'.$msg_new; //'Error - new file not created:' + } +}//end New_response() //******************************************************** + + + + +function Set_Input_width() {//************************************************** + global $_, $MAIN_WIDTH, $ACCESS_ROOT; + + // Adjust (shorten) width based on width of $ACCESS_ROOT + // (width of ) = $MAIN_WIDTH - (Width of

'.hsc($action.' '.$title).'

'; + + echo $FORM_COMMON; + echo ''; + echo ''; + + echo ''; + echo '
'; + + echo ''; + echo ''.hsc('/'.$ACCESS_ROOT).''; + echo '
'; + + echo '('.hsc($_['CRM_txt_02']).')

'; + Cancel_Submit_Buttons($action); + echo "\n\n"; +}//end CRM_Page() //************************************************************ + + + + +function CRM_response($action, $msg1, $show_message = 3) {//******************** + //$action = 'rCopy' or 'rename'. Returns 0 if successful, 1 on error. + //$show_message: 0 = none; 1 = errors only; 2 = successes only; 3 = all messages (default). + global $_, $ONESCRIPT, $ipath, $ipath_OS, $filename, $page, $param1, $param2, $param3, + $MESSAGE, $EX, $INVALID_CHARS, $WHSPC_SLASH; + + $old_full_name = trim($_POST['old_full_name'], $WHSPC_SLASH); //Trim whitespace & slashes. + $new_name_only = trim($_POST['new_name'], $WHSPC_SLASH); + $new_location = trim($_POST['new_location'], $WHSPC_SLASH); + if ($new_location != "") { $new_location .= '/'; } + $new_full_name = $new_location.$new_name_only; + $filename = $old_full_name; //default if error. + + //for function calls that access the server file system, such as rCopy, rename, file_exists, etc... + $old_full_name_OS = Convert_encoding($old_full_name); + $new_full_name_OS = Convert_encoding($new_full_name); + $new_location_OS = Convert_encoding($new_location); + + $isfile = 0; if (is_file($old_full_name_OS)) { $isfile = 1;} //File or folder? + + //Common message lines + $com_msg = '

'.hsc($_['From']).'
'.hsc($_['To']).'
'; + $com_msg .= ': '.hsc($old_full_name).'
'; + $com_msg .= ': '.hsc($new_full_name).'
'; + + $bad_name = ""; //bad file or folder name (can be either old_ or new_) + + $err_msg = ''; //Error message. + $scs_msg = ''; //Success message. + + $error_code = 0; //1 = success (no error), 0 = an error. Used for return value. + + //Check old name for invalid chars (like .. ) (Unlikely to be false outside a malicious attempt) + if ( Check_path($old_full_name,$show_message) === false ) { + $bad_name = $old_full_name; + }elseif ( !file_exists($old_full_name_OS) ) { + $err_msg .= $EX.''.hsc($msg1.' '.hsc($_['CRM_msg_02'])).'
'; + $bad_name = $old_full_name; + //Ignore if new name is blank. + }elseif ( mb_strlen($new_name_only) == 0 ) { + $page = 'copyfile'; + $param3 = '&p=copyfile'; + return 0; + //Check new name for invalid chars, including slashes. + }elseif ( has_invalid_char($new_name_only) ) { + $err_msg .= $EX.''.hsc($_['new_file_msg_02']).' '.hsc($INVALID_CHARS).'
'; + $bad_name = $new_name_only; + //Check new location for invalid chars etc. + }elseif ( Check_path($new_location,$show_message) === false ) { + $bad_name = $new_location; + //$new_location must already exist as a directory + }elseif ( ($new_location != "") && !is_dir($new_location_OS) ) { + $err_msg .= $EX.''.hsc($msg1.' '.hsc($_['CRM_msg_01'])).'
'; + $bad_name = $new_location; + //Don't overwrite existing files. + }elseif ( file_exists($new_full_name_OS) ) { + $bad_name = $new_full_name; + $err_msg .= $EX.''.hsc($msg1.' '.hsc($_['CRM_msg_03'])).'
'; + }else{ //attempt $action + $error_code = $action($old_full_name_OS, $new_full_name_OS); + if ( $error_code > 0 ) { + $scs_msg .= ''.hsc($msg1.' '.hsc($_['successful'])).'
'.$com_msg; + if ($isfile) { $filename = $new_full_name; } + $ipath = $new_location; + $ipath_OS = $new_location_OS; + }else{ + $err_msg .= $EX.''.hsc($_['CRM_msg_05'].' '.$msg1).'
'.$com_msg; + } + }// + + if (($bad_name !='' ) && ($error_code == 0)) { $err_msg .= ''.hsc($bad_name).'
'; } + + if (($show_message & 1) && ($error_code == 0)) { $MESSAGE .= $err_msg; } //Show error message. + if ( $show_message & 2) { $MESSAGE .= $scs_msg; } //Show success message. + + //Prior page should be either index or edit + $page = $_SESSION['recent_pages'][1]; + $param1 = '?i='.URLencode_path($ipath); + if ($isfile & $page == "edit") {$param2 = '&f='.rawurlencode(basename($filename));} + + return $error_code; // +}//end CRM_response() //******************************************************** + + + + +function Delete_response($target, $show_message=3) {//************************** + global $_, $ipath, $ipath_OS, $param1, $filename, $param2, $page, $MESSAGE, $EX; + + if ($target == "") { return 0; } //Prevent accidental delete of entire website. + + $target = Check_path($target,$show_message); + $target = trim($target,'/'); + $page = "index"; //Return to index + + //If came from admin page, return there. + if ( $_SESSION['admin_page'] ) { $page = 'admin'; } + + $err_msg = ''; //On error, set this message. + $scs_msg = ''; //On success, set this message. + + $error_code = rDel($target); + if ($error_code > 0) { // 0 = error, > 0 is number of successes + $scs_msg .= ''.hsc($_['Deleted']).': '; + $scs_msg .= ''.hsc(basename($target)).'
'; + $ipath = dir_name($target); //Return to parent dir. + $ipath_OS = Convert_encoding($ipath); + $param1 = '?i='.URLencode_path($ipath); + $filename = ""; + $param2 = ""; + }else { //Error + $err_msg .= $EX.''.hsc($_['delete_msg_03']).' '.hsc($target).'
'; + $page = $_SESSION['recent_pages'][1]; + if ($page == "edit") { + $filename = $target; + $param2 = '&f='.basename($filename); + } + } + + if ($show_message & 1) { $MESSAGE .= $err_msg; } //Show error message. + if ($show_message & 2) { $MESSAGE .= $scs_msg; } //Show success message. + + return $error_code; +}//end Delete_response() //***************************************************** + + + + +function MCD_Page($action, $page_title, $classes = '') {//********************** + //$action = mcd_mov or mcd_cpy or mcd_del + global $_, $ONESCRIPT, $ipath, $ipath_OS, $param1, $filename, $page, + $ICONS, $ACCESS_ROOT, $ACCESS_PATH, $INPUT_NUONCE, $MESSAGE; + + //Prep for a single file or folder + if( $page == "deletefile" || $page == "deletefolder" ){ + $_POST['mcdaction'] = 'delete'; //set mcdaction != copy or move (see below). + + if ($page == "deletefile") { $_POST['files'][1] = basename($filename); } + //If $page == deletefolder, $_POST['files'][1] is set in Verify_Page_Conditions() + } + + Set_Input_width(); + + echo '

'.hsc($page_title).'

'; + + echo '
'.$INPUT_NUONCE; + echo ''."\n"; + + if ( ($_POST['mcdaction'] == 'copy') || ($_POST['mcdaction'] == 'move') ) { + echo ''; + echo ''.hsc('/'.$ACCESS_ROOT).''; + echo ''; + echo '

('.hsc($_['CRM_txt_02']).')

'; + } + + echo '

'.hsc($_['Are_you_sure']).'

'; + Cancel_Submit_Buttons($page_title); + + //List selected folders & files + $full_list = Sort_Seperate($ipath, $_POST['files']); + + echo ''; + echo ''."\n"; + foreach ($full_list as $file) { + $file_OS = Convert_encoding($file); + if (is_dir($ipath_OS.$file_OS)) { echo ''; } + else { echo ''; } + echo ''."\n"; + } + + echo '
'.hsc($_['Selected_Files']).':
'.$ICONS['folder'].' '.hsc($file).' /
' .hsc($file).'
'; + echo "\n
\n"; +}//end MCD_Page() //************************************************************ + + + + +function MCD_response($action, $msg1, $success_msg = '') {//******************** + global $_, $ipath, $ipath_OS, $EX, $MESSAGE, $WHSPC_SLASH; + + $files = $_POST['files']; //List of files to delete (path not included) + $errors = 0; //number of failed moves, copies, or deletes + $successful = 0; + + $new_location = ""; + if (isset($_POST['new_location'])) { + $new_location = $_POST['new_location']; + $new_location_OS = Convert_encoding($_POST['new_location']); + } + + $show_message = 1; //1= show error msg only. + + if ( ($new_location != "") && !is_dir($new_location_OS)) { + $MESSAGE .= $EX.''.hsc($msg1.' '.$_['CRM_msg_01']).'
'; + $MESSAGE .= ''.hsc($_POST['new_location']).'
'; + return; + }elseif ($action == 'rDel') { + foreach ($files as $file){ + if ($file == "") {continue;} //a blank file name would cause $ipath to be deleted. + $error_code = Delete_response($ipath.$file, $show_message); + $successful += $error_code; + if ($error_code == 0) {$errors++;} + } + }else { //move or rCopy + $mcd_ipath = $ipath; //CRM_response() changes $ipath to $new_location + + foreach ($files as $file){ + $_POST['old_full_name'] = $mcd_ipath.$file; + $_POST['new_name'] = $file; + //$_POST['new_location'] should already be set by the client ( via MCD_Page() ). + $error_code = CRM_response($action, $msg1, $show_message); + $successful += $error_code; + if ($error_code == 0) {$errors++;} + } + } + + if ($errors) {$MESSAGE .= $EX.' '.$errors.' '.hsc($_['errors']).'.
';} + + $MESSAGE .= ''.$successful.' '.hsc($success_msg).'
'; + + if ($action != 'rDel') { + if ($successful > 0) { //"From:" & "To:" lines if any successes. + $MESSAGE .= '
'.hsc($_['From']).'
'.hsc($_['To']).'
'; + $MESSAGE .= ': '.hsc($mcd_ipath).'
'; + $MESSAGE .= ': '.hsc($ipath).'
'; + } + } +}//end MCD_response() //******************************************************** + + + + +function Format_Perms($perms_oct) {//******************************************* + //$perms_oct is a 3 or 4 digit octal string (7777). + + //file file |s s s|owner|group|world + //permissions t y p e|u g t|r w x|r w x|r w x + // + //bits 1|4 2 1|4 2 1|4 2 1|4 2 1|4 2 1 + //octal 1 7 7 7 7 7 + // + //bits 8 4 2 1|8 4 2 1|8 4 2 1|8 4 2 1 + //hex F F F F + + $ugt = ['...', '..t', '.g.', '.gt', 'u..', 'u.t', 'ug.', 'ugt']; //SetUid SetGid sTicky + $rwx = ['---', '--x', '-w-', '-wx', 'r--', 'r-x', 'rw-', 'rwx']; + + if (strlen($perms_oct) > 3) { $ugidsticky = substr($perms_oct, -4, 1); } + else { $ugidsticky = 0; } + $owner = substr($perms_oct, -3, 1); + $group = substr($perms_oct, -2, 1); + $world = substr($perms_oct, -1, 1); + + return "[$perms_oct][".$ugt[$ugidsticky]." ".$rwx[$owner]." ".$rwx[$group]." ".$rwx[$world]."]"; + +}//end Format_Perms() {//******************************************************* + + + + +function Update_File_Permissions() {//****************************************** + //Validate new_perms & update. + //$_POST['new_perms'] must be an octal value with 3 or 4 digits (0-7) only. + global $_, $MESSAGE; + + $new_perms = trim($_POST['new_perms']); + $len = strlen($new_perms); + $errors = 0; //No errrors + $ipath = $_POST['ipath']; + $ipath_OS = Convert_encoding($ipath); + $filename = $_POST['perms_filename']; + $filename_OS = Convert_encoding($ipath.$filename); //Full path/filename + + //Verify that each digit is octal (0-7), and that $new_perms is only 3 or 4 digits in length. + if (preg_match("/^[0-7]{3,4}$/", $new_perms) != 1) { $errors++; } + + if ($errors > 0) { $MESSAGE .= "".$_['Invalid'].": [$new_perms] ".$_['Permissions_msg_1']."."; } + + //Validate path & filename. Valid_Path() required to prevent access outside $ACCESS_ROOT. + if (!Valid_Path($ipath_OS, false)) { $errors++; $MESSAGE .= $_['Invalid_path'].". \n"; } + if (!file_exists($filename_OS)) { $errors++; $MESSAGE .= $_['get_get_msg_01']."\n "; } + + if ($errors == 0) { + //Update the file permissions... + if (!chmod($filename_OS, octdec($new_perms))) { + $errors++; + $MESSAGE .= "".$_['Update_failed'].": "; + } + } + clearstatcache(); + $new_perms = decoct((fileperms($filename_OS) & 07777)); //May not actually be new, if chmod() failed. + $new_perms = str_pad($new_perms, 3, "0", STR_PAD_LEFT); //Always at least three digits: 000 + + if ($errors == 0) { + $MESSAGE .= "".hsc($_['meta_txt_03'])." "; + $MESSAGE .= " ".Format_Perms($new_perms)." ".hsc($filename)."
"; + } + + $new_perms_response = ""; + $new_perms_response['new_perms'] = $new_perms; + $new_perms_response['perms_filename'] = $ipath.$filename; + $new_perms_response['nuonce'] = $_SESSION['nuonce']; + $new_perms_response['early_output'] = ob_get_clean(); //Should always be empty unless error or trouble-shooting. + $new_perms_response['errors'] = $errors.""; + $new_perms_response['MESSAGE'] = $MESSAGE; + $new_perms_response['writable'] = is_writable($filename_OS) * 1; //1 or 0 (true or false) + echo json_encode($new_perms_response); +}//end Update_File_Permissions() //********************************************* + + + + +function Page_Title() {//***Page_Title()************************* + global $_, $page; + + if (!$_SESSION['valid']) { return $_['Log_In']; } + elseif ($page == "admin") { return $_['Admin_Options']; } + elseif ($page == "hash") { return $_['Generate_Hash']; } + elseif ($page == "changepw") { return $_['pw_change']; } + elseif ($page == "changeun") { return $_['un_change']; } + elseif ($page == "edit") { return $_['Edit_View']; } + elseif ($page == "upload") { return $_['Upload_File']; } + elseif ($page == "newfile") { return $_['New_File']; } + elseif ($page == "copyfile" ) { return $_['Copy_Files']; } + elseif ($page == "copyfolder" ) { return $_['Copy_Files']; } + elseif ($page == "renamefile") { return $_['Ren_Move'].' '.$_['File'];} + elseif ($page == "deletefile") { return $_['Del_Files']; } + elseif ($page == "deletefolder") { return $_['Del_Files']; } + elseif ($page == "newfolder") { return $_['New_Folder']; } + elseif ($page == "renamefolder") { return $_['Ren_Folder']; } + elseif ($page == "mcdaction" && ($_POST['mcdaction'] == "copy") ) { return $_['Copy_Files'];} + elseif ($page == "mcdaction" && ($_POST['mcdaction'] == "move") ) { return $_['Move_Files'];} + elseif ($page == "mcdaction" && ($_POST['mcdaction'] == "delete") ) { return $_['Del_Files']; } + else { return $_SERVER['SERVER_NAME']; } +}//end Page_Title() //********************************************************** + + + + +function Load_Selected_Page() {//*********************************************** + global $_, $ONESCRIPT, $ipath, $filename, $page; + + if (!$_SESSION['valid']) { Login_Page(); } + elseif ($page == "admin") { Admin_Page(); } + elseif ($page == "hash") { Hash_Page(); } + elseif ($page == "changepw") { Change_PWUN_Page('pw', 'password', $_['pw_change'], $_['pw_new'], $_['pw_confirm']);} + elseif ($page == "changeun") { Change_PWUN_Page('un', 'text', $_['un_change'], $_['un_new'], $_['un_confirm']);} + elseif ($page == "edit") { Edit_Page(); } + elseif ($page == "upload") { Upload_Page();} + elseif ($page == "newfile") { New_Page($_['New_File'] , "new_file"); } + elseif ($page == "newfolder") { New_Page($_['New_Folder'], "new_folder");} + elseif ($page == "copyfile") { CRM_Page($_['Copy'], $_['File'] , 'copy_file' , $filename);} + elseif ($page == "copyfolder") { CRM_Page($_['Copy'], $_['Folder'], 'copy_file' , $ipath);} + elseif ($page == "renamefile") { CRM_Page($_['Ren_Move'], $_['File'] , 'rename_file', $filename);} + elseif ($page == "renamefolder") { CRM_Page($_['Ren_Move'], $_['Folder'], 'rename_file', $ipath);} + elseif ($page == "deletefile") { MCD_Page('mcd_del', $_['Del_Files'],'verify_del'); } + elseif ($page == "deletefolder") { MCD_Page('mcd_del', $_['Del_Files'],'verify_del'); } + elseif ($page == "mcdaction") { + if ($_POST['mcdaction'] == 'move') { MCD_Page('mcd_mov', $_['Move_Files']); } + if ($_POST['mcdaction'] == 'copy') { MCD_Page('mcd_cpy', $_['Copy_Files']); } + if ($_POST['mcdaction'] == 'delete'){ MCD_Page('mcd_del', $_['Del_Files'], 'verify_del'); } + } + else /* default if session valid */ { Index_Page(); } +}//end Load_Selected_Page() //************************************************** + + + + +function Respond_to_POST() {//************************************************** + global $_, $VALID_POST, $ipath, $page, $EX, $ACCESS_ROOT, $MESSAGE; + + // $_POST['key']'s must all be unique, or order of if/elseif's below becomes significant. + + if (!$VALID_POST) { return; } + + //First, validate any $_POST'ed paths against $ACCESS_ROOT. + if (isset($_POST["old_full_name"]) && !Valid_Path($_POST["old_full_name"], false)) { + //unlikely, but just in case + $MESSAGE .= $EX.''.hsc($_['Invalid_path']).': '.hsc($_POST["old_full_name"]).''; + $VALID_POST = 0; + return; + } + if (isset($_POST["new_location"])) { + $_POST["new_location"] = $ACCESS_ROOT.$_POST["new_location"]; + if (!Valid_Path($_POST["new_location"], false)) { + $MESSAGE .= $EX.''.hsc($_['Invalid_path']).': '.hsc($_POST["new_location"]).''; + $VALID_POST = 0; + return; + } + } + + if (isset($_POST['mcd_mov'] )) { MCD_response('rename', $_['Ren_Move'], $_['mcd_msg_01']); } //move == rename + elseif (isset($_POST['mcd_cpy'] )) { MCD_response('rCopy' , $_['Copy'] , $_['mcd_msg_02']); } + elseif (isset($_POST['mcd_del'] )) { MCD_response('rDel' , $_['Delete'] , $_['mcd_msg_03']); } + elseif (isset($_POST['whattohash'] )) { Hash_response(); } + elseif (isset($_POST['pw'] )) { Change_PWUN_response('pw', $_['change_pw_02']);} + elseif (isset($_POST['un'] )) { Change_PWUN_response('un', $_['change_un_02']);} + elseif (isset($_POST['filename'] )) { Edit_response(); } + elseif (isset($_POST['new_file'] )) { New_response('new_file' , 1);} //1=file + elseif (isset($_POST['new_folder'] )) { New_response('new_folder', 0);} //0=folder + elseif (isset($_POST['rename_file'] )) { CRM_response('rename', $_['Ren_Move']);} + elseif (isset($_POST['copy_file'] )) { CRM_response('rCopy' , $_['Copy'] );} + elseif (isset($_FILES['upload_file']['name'])) { Upload_response(); } + elseif (isset($_POST['new_perms'] )) { Update_File_Permissions(); } //die()'s after return from Resopnd_to_POST(). + + //If Changed p/w, u/n, or other Admin Page action, make sure to not return to a folder outside of $ACCESS_ROOT. + Valid_Path($ipath, true); +}//end Respond_to_POST() //***************************************************** + + + + +function init_ICONS_js() {//**************************************************** + global $ICONS; + + //Currently, only icons for dir listing are needed in js +?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'; + } + + Language_and_config_adjusted_styles(); + +}//end Load_style_sheet() //**************************************************** + + + + +//****************************************************************************** +//Main logic to determine page action +//****************************************************************************** + +Default_Language(); + +$setup_messages = System_Setup(); + +Session_Startup(); + +if (!isset($_SESSION['admin_page'])) { + $_SESSION['admin_page'] = false; + $_SESSION['admin_ipath'] = ''; +} + +if ($_SESSION['valid']) { + + undo_magic_quotes(); + + Init_ICONS(); + + Get_GET(); + + if ($page == "phpinfo") { phpinfo(); die; } + + Valid_Path($ipath, true); + + Validate_params(); + + Init_Macros(); //Needs to be after Get_Get()/Validate_params()/Valid_Path() + + //$ACCESS_ROOT.$ACCESS_PATH == $ipath + $ipath_len = mb_strlen($ipath); + $ACCESS_PATH = ''; + if (($ACCESS_ROOT_len < $ipath_len)) { + $ACCESS_PATH = trim(mb_substr($ipath, $ACCESS_ROOT_len), ' /').'/'; + } + + Respond_to_POST(); + + Verify_Page_Conditions(); //Must come after Respond_to_POST() + + if ($page != "login") { $MESSAGE .= $setup_messages; } //Must come after Verify_Page_Conditions() + + if (isset($_POST['new_perms'])) { die(); } //die() here just for clarity. + + Update_Recent_Pages(); + + //Don't show current/path/ header on some pages. + $Show_Path = true; + $pages_dont_show_path = array("login","admin","hash","changepw","changeun"); + if ( in_array($page, $pages_dont_show_path) ){ $Show_Path = false; } // + +}//end if $_SESSION[valid] + +//end logic to determine page action ******************************************* + + + + +//****************************************************************************** +//Output page contents +//****************************************************************************** +$early_output = ob_get_clean(); // Should be blank unless trouble-shooting. +ob_start(); +header('Content-type: text/html; charset=UTF-8'); +?> + + + + +'.hsc($MAIN_TITLE.' - '.Page_Title()).''."\n"; + +Load_style_sheet(); + +Common_Scripts(); + +Error_reporting_status_and_early_output(0,0); //0,0 will only show early output. + +if ($_SESSION['valid']) { echo '
'; } +else { echo '
'; } + +Page_Header(); + +if ($_SESSION['valid'] && $Show_Path) { Current_Path_Header(); } + +$TABINDEX_XBOX = $TABINDEX++; //Messages, and the [X] box, not displayed until later. +echo '
'; + +Load_Selected_Page(); + +//footer... +if ($_SESSION['valid']) { + //Countdown timer + echo "
\n"; + echo ""; + echo "".hsc($_['time_out_txt']).""; + + //Adjust $TABINDEX to account for contents of directory list (created by Assemble_Insert_row()). + //Directory list is created client-side by js, so tabindex is incremented by the js at that point. + //Each row in directory list (with a filename) has 6 tab-able/focusable items: + // [m] [c] [d] [x] [sogw] [file name] + if (isset($DIRECTORY_COUNT)) { $TAB_INDEX = "tabindex=".($TABINDEX + ($DIRECTORY_COUNT * 6)); } + else { $TAB_INDEX = ""; } + + //Admin link + if ( ($_SESSION['admin_page'] === false) ) { + echo ''.hsc($_['Admin']).''; + } +}//end footer + +echo "\n
\n"; //end main/login_page + + +if ( ($page == "edit") && $WYSIWYG_VALID && $EDIT_WYSIWYG ) { include($WYSIWYG_PLUGIN_OS); } + +//Display any $MESSAGE's +echo "\n\n\n\n"; + + //##### ACTUAL COUNTDOWN STARTS ON THE SERVER. + //##### DO I NEED TO ACCOUNT FOR TIME RECEIVING & LOADING PAGE CLIENT SIDE? + +//start any timers... +if ($_SESSION['valid']) { echo Timeout_Timer($MAX_IDLE_TIME, 'timer0', 'LOGOUT'); } +if ($page == 'edit') { echo Timeout_Timer($MAX_IDLE_TIME, 'timer1', 'LOGOUT'); } +if ($LOGIN_DELAYED > 0) { echo Timeout_Timer($LOGIN_DELAYED, 'timer0', ''); } + +echo "\n"; //*********************************************************** +//##### Header (UTF-8) for [View Raw] incorrect or not getting sent?? +//##### If file has non-ascii characters, browers display in ISO-8859-1/Windows-1252, +//##### Except IE, which asks to download the file... +//##### When browsers manually set to UTF-8, files display fine. + +//##### END OF FILE ############################################################ diff --git a/readme.markdown b/readme.markdown old mode 100644 new mode 100755 index 7737d2d..0426f96 --- a/readme.markdown +++ b/readme.markdown @@ -1,141 +1,191 @@ # OneFileCMS -## Yeah, it's exactly what you think. - -![OneFileCMS](http://onefilecms.com/images/screenshots/branded_index.jpg) - -OneFileCMS is just that. It's a flat, light, one file CMS (Content Management System) entirely contained in an easy-to-implement, highly customizable, database-less PHP script. - -Coupling a utilitarian code editor with all the basic necessities of an FTP application, OneFileCMS can maintain a whole website completely in-browser without any external programs. - -**Demo**: [http://php.opensourcecms.com/scripts/details.php?scriptid=340](http://php.opensourcecms.com/scripts/details.php?scriptid=340) - -## Features +## Yes, that's *exactly* what it is! + +OneFileCMS is a simple CMS (Content Management System) contained entirely in a single, database-less, PHP/Javascript. + +With basic editing, upload, and file managing functions, OneFileCMS can maintain an entire website completely in-browser without any external programs. + +### File Manager: +![OneFileCMS](http://self-evident.github.com/OneFileCMS/images/OFCMS_screenshot.04.png) + +### Text Editor: +![OneFileCMS](http://self-evident.github.com/OneFileCMS/images/OFCMS_screenshot_edit.02.png) + +-------------------------------------------------------------------------------- +## Contents: +- [Demo](#demo) +- [Features](#features) +- [Installation](#installation) +- [Requirements](#requirements) +- [FAQ](#faq) +- [Limitations and Considerations](#limitations) +- [Needed/potential improvements](#potential) +- [License, Credit, Et Cetera](#license) +- [General layout/structure of OneFileCMS.php](#layout) +- [Logs](#logs) + +-------------------------------------------------------------------------------- +## Demo + +- Just download & try the [current version](https://raw.github.com/Self-Evident/OneFileCMS/master/onefilecms.php) - it's one file! + +-------------------------------------------------------------------------------- +## Features -- Validating, semantic, and commented markup. Tested in FF, Safari, and IE7/IE8. -- Possibly the easiest installation process ever -- All the basic features of an FTP application like renaming, deleting, copying, and uploading
- _(Of course, for more complex processes like batch renaming or mass uploads/deletions, you're going to want to break out an actual FTP program.)_ -- Gracefully degrading CSS and Javascript -- 100% re-brandable with title/footer text stored in variables and a modifiable filename -- Externally hosted CSS and images for smaller file size
- _(But you can switch it out to your own stylesheet if you need to!)_ -- Smart alert if you try to leave without saving your edits - -## Installation - -Download [this file](https://raw.github.com/rocktronica/OneFileCMS/master/onefilecms.php). - -Your username and password are inlined. Edit them to something less obvious. - - // CONFIGURATION INFO - $config_username = "username"; - $config_password = "password"; - -Optional variables thereafter: password hint, title, footer text, filetypes to disable, and filenames to ignore - -You can also change the name of the file to something else. Be careful making it a folder's default file; your server may get stuck in redirects. - -Upload! +- All the basic file management features like renaming, moving, copying, deleting, and uploading. +- Sort directory listings by file name, extension, size, or date. +- Keyboard navigation of directory list. (Arrows, Page Up/Down, Home, End) +- A basic text editor with line numbers. +- A WYSIWYG editor may be added as a plugin. +- A login delay after too many invalid login attempts. +- Adjustable idle time before auto-logout. +- Easily modifiable. +- Multi-language support. +- Lots more... +- Possibly The easiest installation process ever! -Depending on how your stack is set up, you may also have to modify the file permissions of your site's folders to allow OneFileCMS to modify and create files. ([More about that here.](http://catcode.com/teachmod/)) Make sure onefilecms.php and its parent folder are allowed to execute, with CHMOD at 777 or 755. Check with your host if you're not sure, and be aware of any inherent security concerns. +-------------------------------------------------------------------------------- +## Installation -## FAQ +1) **Download** the [current version](https://raw.github.com/Self-Evident/OneFileCMS/master/onefilecms.php). -### Where's the WYSIWYG? What about syntax highlighting? +2) **Upload** to anywhere on your site. + +3) **Log in** ! -WYSWIWYG editors have been requested but probably won’t ever come standard, as they’d bloat the system out and/or make it more than one file, sort of defeating the novelty. Plus, if you’re working in PHP or non-HTML code, they're generally more hindrance than anything else. +The default login info is "username" and "password". Of course, you'll want to change those... -Just because I don't want to do it, though, doesn't mean it's impossible. About halfway through, look for this line (If you're searching for it, it's the second instance): +As with any CMS, you may also have to modify the file permissions of your site's folders to allow OneFileCMS to modify and create files. Check with your host if you're not sure, and be aware of any inherent security concerns. - // EDIT +You can also change the file name from "onefilecms.php" to something else, such as "admin.php". (Be careful about making it a folder's default file: your server may get stuck in redirects.) -This is the edit page code. Its textareas can be modified to work with whatever editor you like. If the editor is initiated via jQuery, you can call it in the jQ code in the footer. +-------------------------------------------------------------------------------- +## Requirements -### I found something that could be better. Can I suggest it to you? +- PHP 5.1+ + (Only tested on versions 5.2.8, 5.2.17, 5.3.3, and 5.4 + ) +- A Javascript enabled browser. +- Most modern browsers probably work, but I only test on Firefox and Chrome. +- And if you wish to see the icons- a browser that supports inline SVG. + (If your browser doesn't support inline SVG, OneFileCMS will still work, but with text icons instead.) +- File permission privileges on your host. -Yes, of course, you can! +-------------------------------------------------------------------------------- +## FAQ -I may not have the bandwidth to implement every feature, but I'll do what I can. If it's urgent, contact me. +- [Multi-Language Support?](#language) +- [I found something that could be better. Can I suggest it to you?](#suggestions) +- [Can I have more than one username/password?](#multiuser) +- [This is basically just a file manager with a text editor- why is it being called a CMS?](#handsaw) +- [Why do I get a "Stop running this script?" alert during login?](#slowlogin) +- [Where's the WYSISWYG?](#WYSIWYG) -Otherwise, try [forking the file and submitting your changes to me](https://github.com/blog/844-forking-with-the-edit-button). +### Multi-Language Support? -Everything's welcome! +Yes! While English (EN) is the default, the following laguages are also available: -### This is basically just a file manager with a text editor. Why is it being called a Content Management System? +- Deutsch (DE) courtesy of [codeless](http://github.com/codeless). +- Espanõla (ES) courtesy of [fermuch](http://github.com/fermuch). +- Nederlands (NL) courtesy of [symsec](http://github.com/symsec). +- Pусский (RU) courtesy of [zaykin](https://github.com/zaykin). -Because "OneFileFileManagerTextEditor" doesn't quite have the same ring to it, duh. +If you speak another language and would like to contribute, translations are welcomed and appreciated! Just use the English language file (or any of the others) as a template, and translate each word, phrase, etc., as appropriate. -### Multi-Language Support? +### I found something that could be better. Can I suggest it to you? -Maybe later! +Yes, of course! -### Can I have more than one username/password? +I may not have the time/bandwidth/inclination to implement every feature, but I 'll do what I can. If you find a bug, please file a report on the issues page. -The reason there isn't default support for multiple users is that all of their info will have to be stored together, more or less in plain text, at the top of onefilecms.php. Giving people different usernames and passwords then is sort of futile, since everyone who can log in can view onefilecms's source and config variables. (This answer kind of ignores MD5 hashes but is valid for most considerations.)  +### Can I have more than one username/password? -### Is the JavaScript at the end of file really needed? When I remove it, everything works fine. +Yes! Well, sort of... indirectly. Upload or create additional copies of OneFileCMS, but give them different file names.(ex: OneFile1.php and OneFile2.php etc...) Then, in each copy, maintain different usernames, passwords, and $session\_name config values. + +Now, since there is no database or other means of granular control or access logging, multiple usernames provides limited utility. However, having at least one working backup copy of OneFileCMS available is recommended in case the primary copy gets corrupted. -It isn't entirely necessary, but it does nice little progressive enhancements like warn if you try to leave w/o saving and stuff like that. Feel free to take it out if you're trying to trim down your figure. +### This is basically just a file manager with a text editor- why is it being called a CMS? -## Change Log +Because it is. It may be simple, but it can get the job done. While you wouldn't want to build a new house from the ground up with just a hammer, saw, and tape measure, you can "manage" quite a bit with just those tools. -### 1.1.6 +And, because "OneFileCMS" sounds cool. -- Breadcrumb navigation (courtesy of [Self-Evident](https://github.com/Self-Evident/)), CSS file and some minor changes to it
- Installation is still as usual, but, now, if you have _onefilecms.css_ in the same folder as _onefilecms.php_, it'll be linked instead of the normal [http://onefilecms.com/style.css](http://onefilecms.com/style.css). -### 1.1.5 +### Why do I get a "Stop running this script?" alert during login? -- Fixed a disallowed redirect vulnerability
Many thanks to Abhi M Balakrishnan from [OWASP Mantra Team](http://www.getmantra.com/) for his help +OneFile's login functions take condsiderably longer* to run on IE, version 8 at least, than on Chrome or Firefox. Just click [ No ] on the alert, and the login should finish after a few more seconds. +(*About 8 seconds -vs- 1/4 second on my test system.) -### 1.1.4 +The delay is the result of the client-side "pre-hash" OneFileCMS performs on your password before submitting the login to OneFileCMS server-side. Not counting the time the alert is waiting for a response, the 8 seconds previously mentioned is from a 2.5gz single-core XP system. -- JavaScript cleanup and jQuery upgrade -- Visit Site = / -- Now on GitHub! +See the global variable "$PRE\_ITERATIONS" at the end of System\_Setup(). It can be adjusted, but it's best to do so on a local copy in a development setup, then upload the updated copy. -### 1.1.3 (1/10/2012) +### Where's the WYSISWYG? -- Fixed a upload bug leftover from 1.1.2's CSRF protection +OneFileCMS can be easily configured to work with [TinyMCE](http://tinymce.moxiecode.com) or [CKEditor](http://ckeditor.com) (and possibly others), but the editors themselves must be obtained from their respective sites. For basic setup instructions, read the appropriate "init" file from the extras/ directory in the OneFileCMS repo. -### 1.1.2 (9/21/11) -- More CSRF protection for logged-in users +-------------------------------------------------------------------------------- +## Limitations & Considerations -### 1.1.1 (1/9/10) +- If you need to upload a lots of files, an FTP program may be a bit more flexible & practicle. -- CSRF protection (thanks Steve and Rene) -- Support for storing password as an MD5 hash (thanks, durilka!) +- Directories with hundreds of files can take several seconds to display. For instance, on my system- a 2.5gz desktop running XP, it takes 2 to 4 seconds to display a directory with 200 files. -### 1.1.0 (10/18/09) +- OneFileCMS would not be the best option for a site that requires different levels of privileges, unless all of the users are trusted to stay within their designated areas of responsibility. Since OneFileCMS allows file uploads and editing files directly on the web server, there is simply no way to secure against any particular action. -- config_footer variable for branding or analytics code -- config_disabled variable to disallow editing of files like images, zips, icons, etc -- config_excluded variable to exclude specific files (or filetypes) from being shown in the index -- Shows hidden files (files that start with a "." like ".htaccess") on index listing -- "noindex" meta tag so Google doesn't crawl your backend -- Fixed a couple minor CSS and link bugs in the example site. -- Updated license page to clarify commercial license usage per domain and upgrade. + These issues, of course, are not unique to OneFileCMS - as they will exist in any CMS that permits unrestricted file editing & uploads. -### 1.0.1 (9/24/09) +- As with any website, if your website's connection is not encrypted (doesn't use SSL/TLS), passwords & usernames will be sent in clear text* during login. + *As of version 3.4.15, a client-side hash of the user's "plain-text" password is sent to the server. So, while this client-side hash is still a "plain-text" password as far as the server is concerned, the user's actual raw password is protected from immediate exposure. -- Relative CSS links and navigation in example site to work better with the demo (No change to OneFileCMS itself) +-------------------------------------------------------------------------------- +## License, Credit, Et Cetera -### 1.0 (9/5/09) +- Available under the MIT and BSD licenses. +- Original concept and development by github.com/rocktronica +- Maintained by github/Self-Evident +- Contributors: A. M Balakrishnan, github.com/codeless, github.com/fermuch, github.com/symsec, github.com/zaykin +- Written in PHP, JavaScript, HTML, CSS, and SVG. +- Icons for versions thru 1.1.6 by [famfamfam](http://www.famfamfam.com/). +- To report a bug or request a feature, please file an issue via Github. +- And, of course, please feel free to fork away! -- Launch! +-------------------------------------------------------------------------------- +## Needed/potential improvements -## Requirements +- With Chrome, and possibly Safari, issue with Edit page: Clicking browser [back] & then browser [forward], with file changed and not saved. On return (after [forward] clicked), file still has changes, but indicators are green (saved/unchanged). Does not affect FF 7+ or IE 8+. +- Be aware that only some very basic data & error checking is performed. (But, it's getting better...) +- With line numbering, word-wrap is now break-all (wraps in middle of words instead at nearest white-space as with break-word). +- Anything else? -- UNIX/Linux host, Apache -- PHP5 (PHP4 untested) -- File permission privileges +-------------------------------------------------------------------------------- +### General layout/structure of OneFileCMS.php + +CONFIGURATION SECTION + +SYSTEM SETUP/VARIABLES + +DEFAULT LANGUAGE + +SESSION & MISC FUNCTIONS + +SVG $ICONS & FUNCTIONS + +PAGE & RESPONSE FUNCTIONS + +JAVASCRIPT FUNCTIONS + +STYLESHEET + +LOGIC TO DETERMINE PAGE ACTION + +GENERATE/OUTPUT THE PAGE -## Credit, License, Et Cetera +-------------------------------------------------------------------------------- +## [Change Log](http://self-evident.github.com/OneFileCMS/changelog.html) -Written in PHP, XHTML, CSS, and [jQuery](http://jquery.com/). Icons by [famfamfam](http://www.famfamfam.com/). +## [Git Log](https://raw.github.com/Self-Evident/OneFileCMS/gh-pages/master-branch.git.log) -Available under the MIT and BSD license. -To report a bug or request a feature, please file an issue via Github. Forks encouraged! \ No newline at end of file +