need to add messages for subu errors I've added to the end of
the list in subu.lib.c
+2019-03-14T10:43:50Z
+ should mod all to he subudb routines to return a message, probably
+ strdup(sqlite_errmsg(db)), then the callers to these routines can just pass
+ mess in rather than making up new ones for each situation. The error code
+ probably already carries the contexts specific message. Or perhaps add
+ a string cat function for message strings, that would run through a stream
+ and free the originals.
--- /dev/null
+/*
+Dynamic Array
+
+*/
+
+void d_alloc(subudb_subu_element **base, size_t *s, size_t item_size){
+ *s = 4 * item_size;
+ *base = malloc(*s);
+}
+
+// doubles size of an array
+void d_expand(void **base, void **pt, size_t *s){
+ size_t offset = ((unsigned char *)*pt - (unsigned char *)*base);
+ size_t new_s = *s << 1;
+ void *new_base = malloc( new_s );
+ memcpy( new_base, *base, offset + 1);
+ free(base);
+ *base = new_base;
+ *pt = new_base + offset;
+ *s = new_s;
+}
+
+// true when pt has run off the end of the area currently allocated for the array
+bool d_bounds(void *base, void *pt, size_t s){
+ return pt >= base + s;
+}
+
+void d_push(void **base, void **pt, size_t *s, void *item, size_t item_size){
+ while( *pt + item_size >= *base + *s ){
+ expand(base, pt, s);
+ }
+ memcpy(*pt, item, item_size);
+ *pt += item_size;
+}
+
+// special case when the dynamic array is holding pointers to items on the heap
+void d_map(void *base, void *end_pt){
+ void *pt = base;
+ while( pt != end_pt ){
+ free(pt->subuname);
+ free(pt->subu_username);
+ pt++;
+ }
+ free(base);
+}
char *envp[1];
envp[0] = (char *) NULL;
int dispatch_err = dispatch_exec(argv, envp);
+ free(map);
if( dispatch_err != 0 ){
#ifdef DEBUG
dispatch_f_mess(command, dispatch_err, "dispatch_exec");
return 0;
}
-#if 0
-
-int subu_bind_all(char **mess, sqlite3 *db, char *subuname){
+int subu_bind_all(char **mess, sqlite3 *db){
int rc;
if(mess)*mess = 0;
+ char **free_list;
- //--------------------------------------------------------------------------------
- size_t subuname_len;
- rc = allowed_subuname(mess, subuname, &subuname_len);
- if(rc) return rc;
- #ifdef DEBUG
- dbprintf("subuname is well formed\n");
- #endif
-
//--------------------------------------------------------------------------------
uid_t masteru_uid;
gid_t masteru_gid;
uid_to_name_and_home(masteru_uid, &masteru_name, &masteru_home)
||
mk_subuland(masteru_home, &subuland)
- ||
- mk_subuhome(subuland, subuname, &subuhome)
;
- if(rc) RETURN(rc);
+ if(rc){
+ free(masteru_name);
+ free(masteru_home);
+ free(subuland);
+ }
#ifdef DEBUG
dbprintf("masteru_home, subuhome: \"%s\", \"%s\"\n", masteru_home, subuhome);
#endif
//--------------------------------------------------------------------------------
- // removal from db
-
- db_begin(db);
-
- char *subu_username = 0;
- rc = subudb_Masteru_Subu_get_subu_username(db, masteru_name, subuname, &subu_username);
+ subudb_subu_element *sa;
+ subudb_subu_element *sa_end;
+ rc = subudb_Masteru_Subu_get_subus(db, masteru_name, &sa, &sa_end);
if( rc != SQLITE_OK ){
- if(mess) *mess = strdup("subu requested for removal not found under this masteru in db file");
- rc = SUBU_ERR_SUBU_NOT_FOUND;
- db_rollback();
- RETURN(rc);
+ if(mess)*mess = strdup("db access failed when fetching a list of subus");
+ return rc;
}
- #ifdef DEBUG
- printf("subu_username: \"%s\"\n", subu_username);
- #endif
-
- rc = subudb_Masteru_Subu_rm(db, masteru_name, subuname, subu_username);
- if( rc != SQLITE_OK ){
- if(mess)*mess = strdup("removal of masteru subu relation failed");
- db_rollback();
- RETURN(SUBU_ERR_DB_FILE);
+ if( sa == sa_end ) return 0; // no subus to bind
+
+ // a limitation of our error reporting approach is that we can only
+ // return one error, but here is a loop that might generate many
+ uint rc_count = 0;
+ subudb_subu_element *pt = sa;
+ while( pt != sa_end ){
+ rc = mk_subuhome(subuland, pt->subuname, &subuhome);
+ if(!rc) rc = subu_bind(NULL, masteru_name, pt->subu_username, subuhome);
+ if(rc) rc_count++;
+ pt++;
}
- #ifdef DEBUG
- dbprintf("removed the masteru_name, subuname, subu_username relation\n");
- #endif
-
- rc = db_commit(db);
- if( rc != SQLITE_OK ){
- if(mess)*mess = strdup("removal of masteru subu relation in unknown state, exiting");
- RETURN(SUBU_ERR_DB_FILE);
+ if(rc_count==1){
+ return rc;
}
-
- // even after removing the last masteru subu relation, we still do not remove
- // the max subu count. Hence, a masteru will keep such for a life time.
-
-
- //--------------------------------------------------------------------------------
- // Only masteru can remove directories from masteru/subuland, so we switch to
- // masteru's uid to perform the rmdir.
- //
- {
- #ifdef DEBUG
- dbprintf("as masteru, removing the directory \"%s\"\n", subuhome);
- #endif
- int dispatch_err = dispatch_f_euid_egid
- (
- "masteru_rmdir_subuhome",
- masteru_rmdir_subuhome,
- (void *)subuhome,
- masteru_uid,
- masteru_gid
- );
- if( dispatch_err <= ERR_DISPATCH || dispatch_err == SUBU_ERR_RMDIR_SUBUHOME ){
- #ifdef DEBUG
- dispatch_f_mess("dispatch_f_euid_egid", dispatch_err, "masteru_rmdir_subuhome");
- #endif
- if(mess)*mess = strdup(subuhome);
- RETURN(SUBU_ERR_RMDIR_SUBUHOME);
- }
+ if(rc_count > 1){
+ mess = strdup("multiple errors occured while binding subus");
+ RETURN(SUBU_ERR_BIND);
}
-
- //--------------------------------------------------------------------------------
- // Delete the subservient user account
- {
- #ifdef DEBUG
- dbprintf("deleting user \"%s\"\n", subu_username);
- #endif
- #if BUG_SSS_CACHE_RUID
- #ifdef DEBUG
- dbprintf("setting inherited real uid to 0 to accomodate SSS_CACHE UID BUG\n");
- #endif
- if( setuid(0) == -1 ){
- rc = SUBU_ERR_BUG_SSS;
- RETURN(rc);
- }
- #endif
- char *command = "/usr/sbin/userdel";
- char *argv[3];
- argv[0] = command;
- argv[1] = subu_username;
- argv[2] = (char *) NULL;
- char *envp[1];
- envp[0] = (char *) NULL;
- int dispatch_err = dispatch_exec(argv, envp);
- if( dispatch_err != 0 ){
- #ifdef DEBUG
- dispatch_f_mess("dispatch_exec", dispatch_err, command);
- #endif
- if(mess)*mess = userdel_mess(dispatch_err);
- RETURN(SUBU_ERR_FAILED_USERDEL);
- }
- #ifdef DEBUG
- dbprintf("deleted user \"%s\"\n", subu_username);
- #endif
- }
-
- #ifdef DEBUG
- dbprintf("finished subu-rm-0(%s)\n", subuname);
- #endif
- RETURN(0);
+ return RETURN(0);
}
-
-#endif
if( rc == SQLITE_OK ){
subudb_subu_element *pt = sa;
while( pt != sa_end ){
- printf("%s\n", *pt);
+ printf("%s %s\n", pt->subuname, pt->subu_username);
pt++;
}
rc = sqlite3_close(db);
//--------------------------------------------------------------------------------
-// generic array expander
-static void expand(void **base, void **pt, size_t *s){
- size_t offset = ((unsigned char *)*pt - (unsigned char *)*base);
- size_t new_s = *s << 1;
- void *new_base = malloc( new_s );
- memcpy( new_base, *base, offset + 1);
- free(base);
- *base = new_base;
- *pt = new_base + offset;
- *s = new_s;
-}
-static bool off_alloc(void *base, void *pt, size_t s){
- return pt == base + s;
-}
-
// we return and array of subudb_subu_info
#if INTERFACE
struct subudb_subu_element{
};
#endif
static void subu_element_alloc(subudb_subu_element **base, size_t *s){
- *s = 4 * sizeof(subudb_subu_element);
- *base = malloc(*s);
+ dalloc((void *)base, s, sizeof(subudb_subu_element));
}
void subu_element_free(subudb_subu_element *base, subudb_subu_element *end_pt){
subudb_subu_element *pt = base;
--- /dev/null
+
+(defun undedicate-window (&optional window)
+ (interactive)
+ (set-window-dedicated-p (or window (get-buffer-window)) nil))
+
+;; Removing annoying dedicated buffer nonsense
+(defun switch-to-buffer! (buffer-or-name &optional norecord force-same-window)
+ "Like switch-to-buffer but works for dedicated buffers \(though
+it will ask first)."
+ (interactive
+ (list (read-buffer-to-switch "Switch to buffer: ") nil 'force-same-window))
+ (when (and (window-dedicated-p (get-buffer-window))
+ (yes-or-no-p "This window is dedicated, undedicate it? "))
+ (undedicate-window))
+ (switch-to-buffer buffer-or-name norecord force-same-window))
+
+(defun toggle-window-dedication (&optional window)
+ (interactive)
+ (let ((window (or window (get-buffer-window))))
+ (set-window-dedicated-p window (not (window-dedicated-p window)))))
+
+(global-set-key (kbd "C-x d") 'toggle-window-dedication)
+
+;; fix 'feature' of broken gdb where it takes control of an
+;; emacs window, and locks the user out from switching from it
+;;
+;; yes and this fix breaks file name completion...
+;;
+;; (defun set-window-undedicated-p (window flag)
+;; "Never set window dedicated."
+;; flag)
+;; (advice-add 'set-window-dedicated-p :override #'set-window-undedicated-p)
+;;
+;; Toggle window dedication
+
+ (defun toggle-window-dedicated ()
+ "Toggle whether the current active window is dedicated or not"
+ (interactive)
+ (message
+ (if (let (window (get-buffer-window (current-buffer)))
+ (set-window-dedicated-p window
+ (not (window-dedicated-p window))))
+ "Window '%s' is dedicated"
+ "Window '%s' is normal")
+ (current-buffer)))
+
+ (global-set-key "\C-q" 'toggle-window-dedicated)
+
+;; (setq ring-bell-function (lambda ()
+;; (call-process-shell-command
+;; "xset led 3; xset -led 3" nil 0 nil)))
+;;
+;; (setq ring-bell-function nil)
+
+ (setq ring-bell-function
+ (lambda ()
+ (call-process-shell-command "xset led named 'Scroll Lock'")
+ (call-process-shell-command "xset -led named 'Scroll Lock'")))
+
+
+;; preferable to have keys for the characters, but the keyboard is already overloaded ..
+;; (define-key key-translation-map (kbd "<f9> p") (kbd "¬"))
+;; (set-input-method “latin-9-prefix)
+
+ (global-set-key [f1] 'help-command)
+ (global-set-key "\C-h" 'nil)
+ (define-key key-translation-map (kbd "M-S") (kbd "§"))
+
+ (global-set-key (kbd "C-x g phi SPC") [?φ]) ; phi for phase
+ (global-set-key (kbd "C-x g Phi SPC") [?Φ])
+
+ (global-set-key (kbd "C-x g d SPC") [?δ])
+ (global-set-key (kbd "C-x g D SPC") [?Δ]) ; this is 'delta' is not 'increment'!
+ (global-set-key (kbd "C-x g delta SPC") [?δ])
+ (global-set-key (kbd "C-x g Delta SPC") [?Δ]) ; this is 'delta' is not 'increment'!
+
+
+ (global-set-key (kbd "C-x g g SPC") [?γ])
+ (global-set-key (kbd "C-x g G SPC") [?Γ])
+ (global-set-key (kbd "C-x g gamma SPC") [?γ])
+ (global-set-key (kbd "C-x g Gamma SPC") [?Γ])
+
+ (global-set-key (kbd "C-x g l SPC") [?λ])
+ (global-set-key (kbd "C-x g L SPC") [?Λ])
+ (global-set-key (kbd "C-x g lambda SPC") [?λ])
+ (global-set-key (kbd "C-x g Lambda SPC") [?Λ])
+
+ (global-set-key (kbd "C-x g p SPC") [?π])
+ (global-set-key (kbd "C-x g P SPC") [?Π])
+ (global-set-key (kbd "C-x g pi SPC") [?π])
+ (global-set-key (kbd "C-x g Pi SPC") [?Π])
+
+ (global-set-key (kbd "C-x g > = SPC") [?≥])
+ (global-set-key (kbd "C-x g < = SPC") [?≤])
+ (global-set-key (kbd "C-x g ! = SPC") [?≠])
+ (global-set-key (kbd "C-x g neq SPC") [?≠])
+
+ (global-set-key (kbd "C-x g nil SPC") [?∅])
+
+ (global-set-key (kbd "C-x g not SPC") [?¬])
+
+ (global-set-key (kbd "C-x g and SPC") [?∧])
+ (global-set-key (kbd "C-x g or SPC") [?∨])
+
+ (global-set-key (kbd "C-x g exists SPC") [?∃])
+ (global-set-key (kbd "C-x g all SPC") [?∀])
+
+ (global-set-key (kbd "C-x g do SPC") [?⟳]) ; do
+ (global-set-key (kbd "C-x g rb SPC") [?◨])
+ (global-set-key (kbd "C-x g lb SPC") [?◧])
+
+ (global-set-key (kbd "C-x g cont SPC") [?➜]) ; continue
+ (global-set-key (kbd "C-x g thread SPC") [?☥]) ; thread
+
+ (global-set-key (kbd "C-x g in SPC") [?∈]) ; set membership
+
+
+
+;; lisp
+;;
+ (setq lisp-indent-offset 2)
+ (setq inferior-lisp-program "sbcl")
+
+ (modify-syntax-entry ?[ "(]" lisp-mode-syntax-table)
+ (modify-syntax-entry ?] ")[" lisp-mode-syntax-table)
+ (modify-syntax-entry ?{ "(}" lisp-mode-syntax-table)
+ (modify-syntax-entry ?} "){" lisp-mode-syntax-table)
+
+;; get the pwd in shell mode from the prompt rather than guessing by
+;; watching the commands typed .. yes! now shell variables and source
+;; scripts will work
+;; in bashrc: export PS1='\n$(/usr/local/bin/Z)\u@\h§\w§\n> '
+;;
+ (add-hook 'shell-mode-hook
+ (lambda ()
+ (shell-dirtrack-mode -1)
+ (dirtrack-mode 1)))
+
+ (add-hook 'dirtrack-directory-change-hook
+ (lambda ()
+ (message default-directory)))
+
+ (setq dirtrack-list '("§\\(.*\\)§\n> " 1))
+
+;; use a backrevs dir rather than leaving ~file droppings everywhere
+;;
+ (setq backup-directory-alist `(("." . "~/emacs_backrevs")))
+ (setq backup-by-copying t)
+
+;; stop the 'tab' character polution
+;;
+ (setq-default indent-tabs-mode nil)
+
+;; turn off the poison C-z key. Use C-x C-z or the command suspend-emacs
+;;
+ (global-set-key (kbd "C-z") nil)
+
+;; truncate rather than wrapping lines (use horizontal scroll to see to the right)
+;;
+ (set-default 'truncate-lines t)
+ (setq truncate-partial-width-windows nil)
+ (setq-default fill-column 80)
+
+;; recover some window real estate
+;; c-x mode-line to toggle the mode-line on and off
+;;
+ (defun mode-line () "toggles the modeline on and off"
+ (interactive)
+ (setq mode-line-format
+ (if (equal mode-line-format nil)
+ (default-value 'mode-line-format)) )
+ (redraw-display))
+
+ (tool-bar-mode -1)
+ (menu-bar-mode -1)
+
+
+(put 'upcase-region 'disabled nil)
+(put 'narrow-to-region 'disabled nil)
+(put 'downcase-region 'disabled nil)
+(put 'set-goal-column 'disabled nil)
+
+
+(custom-set-variables
+ ;; custom-set-variables was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(ansi-color-names-vector
+ ["#212526" "#ff4b4b" "#b4fa70" "#fce94f" "#729fcf" "#e090d7" "#8cc4ff" "#eeeeec"])
+ '(custom-enabled-themes (quote (wheatgrass)))
+ '(geiser-racket-binary "racket")
+ '(send-mail-function (quote smtpmail-send-it))
+ '(tool-bar-mode nil))
+(custom-set-faces
+ ;; custom-set-faces was added by Custom.
+ ;; If you edit it by hand, you could mess it up, so be careful.
+ ;; Your init file should contain only one such instance.
+ ;; If there is more than one, they won't work right.
+ '(default ((t (:family "DejaVu Sans Mono" :foundry "PfEd" :slant normal :weight bold :height 98 :width normal)))))
+
+(put 'erase-buffer 'disabled nil)