int sln(const char* path) { stralloc s, d; char* to; ssize_t i; stralloc_init(&s); stralloc_copys(&s, path); stralloc_init(&d); stralloc_copy(&d, &s); while(reduce(&d)) { buffer_puts(buffer_2, "'"); buffer_putsa(buffer_2, &d); buffer_puts(buffer_2, "' -> '"); buffer_putsa(buffer_2, &s); buffer_puts(buffer_2, "'\n"); buffer_flush(buffer_2); stralloc_nul(&s); stralloc_nul(&d); if(mklink_sa(&s, &d) == -1) { errmsg_warnsys("symlink failed", NULL); exit(2); } stralloc_copy(&s, &d); } return 0; }
int main() { static stralloc sa; /* static makes sure sa is initialized and empty; * use stralloc_init to initialize and stralloc_copys(&sa,"") to empty */ if (buffer_get_token_sa(buffer_0,&sa," \t\n",3)==0) { buffer_putsa(buffer_1,&sa); buffer_putnlflush(buffer_1); } return 0; }
int main() { stralloc sa; int res; stralloc_init(&sa); res=buffer_get_token_sa_pred(buffer_0,&sa,ishttp); buffer_puts(buffer_1,"buffer_get_token_sa_pred returned "); buffer_putlong(buffer_1,res); buffer_putsflush(buffer_1,".\n\n"); buffer_putsa(buffer_1,&sa); buffer_flush(buffer_1); return 0; }
int main() { stralloc sa; buffer b; stralloc line; stralloc_init(&sa); stralloc_init(&line); stralloc_copys(&sa,"this is a test\nline 2\n"); buffer_fromsa(&b,&sa); while (buffer_getline_sa(&b,&line)==0) { buffer_puts(buffer_1,"got line: \""); if (stralloc_chop(&line)!='\n') break; buffer_putsa(buffer_1,&line); buffer_putsflush(buffer_1,"\"\n"); stralloc_copys(&line,""); } return 0; }
int xml_read_function(xmlreader* reader, xmlnodeid id, stralloc* name, stralloc* value, HMAP_DB** attrs) { switch(id) { case XML_TEXT: { buffer_putsa(buffer_1, value); break; } case XML_ELEMENT: { int closing = reader->closing || reader->self_closing; if(reader->closing) --depth; if(!(reader->closing && !prev_closing && stralloc_equal(&prev_element, name)) && stralloc_length(&prev_element)) { buffer_puts(buffer_1, "\n"); buffer_putnspace(buffer_1, depth * 2); } buffer_putm_3(buffer_1, "<", reader->closing ? "/" : "", name->s); if(attrs && *attrs && (*attrs)->list_tuple) { buffer_putspace(buffer_1); xml_print_attributes(*attrs, buffer_1, " ", "=", "\""); } buffer_puts(buffer_1, reader->self_closing ? (name->s[0] == '?' ? "?>" : "/>") : ">"); stralloc_copy(&prev_element, name); prev_closing = closing; if(!reader->closing && !reader->self_closing) ++depth; break; } default: break; } return 1; }
int list_dir_internal(stralloc* dir, char type) { size_t l; struct dir_s d; stralloc pre; int dtype; int is_dir, is_symlink; size_t len; #if !WINDOWS_NATIVE struct stat st; static dev_t root_dev; #endif char *name, *s; (void)type; while(dir->len > 1 && IS_DIRSEP(dir->s[dir->len - 1])) dir->len--; stralloc_nul(dir); #if !WINDOWS_NATIVE if(root_dev == 0) { if(stat(dir->s, &st) != -1) { root_dev = st.st_dev; } } #endif if(dir_open(&d, dir->s) != 0) { buffer_puts(buffer_2, "ERROR: Opening directory "); buffer_putsa(buffer_2, dir); buffer_puts(buffer_2, " failed!\n"); buffer_flush(buffer_2); goto end; } if(dir->s[dir->len - 1] != DIRSEP_C) stralloc_cats(dir, DIRSEP_S); l = dir->len; while((name = dir_read(&d))) { unsigned int mode = 0, nlink = 0, uid = 0, gid = 0; uint64 size = 0, mtime = 0; dtype = dir_type(&d); dir->len = l; if(str_equal(name, "") || str_equal(name, ".") || str_equal(name, "..")) { continue; } stralloc_readyplus(dir, str_len(name) + 1); str_copy(dir->s + dir->len, name); dir->len += str_len(name); is_symlink = !!(dtype & D_SYMLINK); #if !WINDOWS_NATIVE if(!opt_deref && lstat(dir->s, &st) != -1) { if(root_dev && st.st_dev) { if(st.st_dev != root_dev) { continue; } } } #endif #if !WINDOWS_NATIVE if(S_ISLNK(st.st_mode)) { stat(dir->s, &st); } mode = st.st_mode; #endif if(dtype) { is_dir = !!(dtype & D_DIRECTORY); } else { #if WINDOWS_NATIVE is_dir = 0; #else is_dir = !!S_ISDIR(mode); #endif } if(dtype & D_SYMLINK) is_symlink = 1; #if !WINDOWS_NATIVE nlink = st.st_nlink; uid = st.st_uid; gid = st.st_gid; size = st.st_size; mtime = st.st_mtime; #else mode = (is_dir ? 0040000 : 0100000) | (is_symlink ? 0120000 : 0); #if USE_READDIR if(!is_dir) { size = dir_size(&d); /* dir_INTERNAL(&d)->dir_entry->d_name); */ mtime = dir_time(&d); } else { mtime = 0; size = 0; } #else size = dir_size(&d); mtime = dir_time(&d, D_TIME_MODIFICATION); #endif #endif if(opt_list && size >= opt_minsize) { stralloc_init(&pre); /* Mode string */ mode_str(&pre, mode); stralloc_catb(&pre, " ", 1); /* num links */ make_num(&pre, nlink, 3); stralloc_catb(&pre, " ", 1); /* uid */ make_num(&pre, uid, 0); stralloc_catb(&pre, " ", 1); /* gid */ make_num(&pre, gid, 0); stralloc_catb(&pre, " ", 1); /* size */ make_num(&pre, size, 6); stralloc_catb(&pre, " ", 1); /* time */ make_num(&pre, mtime, 0); /* make_time(&pre, mtime, 10); */ stralloc_catb(&pre, " ", 1); } /* fprintf(stderr, "%d %08x\n", is_dir, dir_ATTRS(&d)); */ if(is_dir) stralloc_catc(dir, opt_separator); if(dir->len > MAX_PATH) { buffer_puts(buffer_2, "ERROR: Directory "); buffer_putsa(buffer_2, dir); buffer_puts(buffer_2, " longer than MAX_PATH (" STRINGIFY(MAX_PATH) ")!\n"); /*buffer_putulong(buffer_2, MAX_PATH); buffer_puts(buffer_2, ")!\n");*/ buffer_flush(buffer_2); goto end; } s = dir->s; len = dir->len; if(len >= 2 && s[0] == '.' && IS_DIRSEP(s[1])) { len -= 2; s += 2; } if(opt_list && size >= opt_minsize) buffer_putsa(buffer_1, &pre); if(opt_relative_to) { size_t sz = str_len(opt_relative_to); if(str_diffn(s, opt_relative_to, sz) == 0) { s += sz; len -= sz; while(*s == '\\' || *s == '/') { s++; len--; } } } if(size >= opt_minsize) { buffer_put(buffer_1, s, len); buffer_put(buffer_1, "\n", 1); buffer_flush(buffer_1); } if(is_dir && (opt_deref || !is_symlink)) { dir->len--; list_dir_internal(dir, 0); } } end: dir_close(&d); return 0; }
int dir_type(struct dir_s* d) { int r = 0; #if !USE_READDIR && (defined(_WIN32) || defined(_WIN32) || defined(__MSYS__)) if(dir_INTERNAL(d)->dir_finddata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) r |= D_SYMLINK; else if(dir_INTERNAL(d)->dir_finddata.dwFileAttributes & 0x10) r |= D_DIRECTORY; else if(dir_INTERNAL(d)->dir_finddata.dwFileAttributes & 0x20) r |= D_FILE; #else #ifndef DT_DIR #define DT_DIR 4 #endif #ifndef DT_REG #define DT_REG 8 #endif #ifndef DT_LNK #define DT_LNK 10 #endif #if defined(_DIRENT_HAVE_D_TYPE) || (!defined(__MSYS__) && !defined(__CYGWIN__)) switch((dir_TYPE(d))) { case DT_DIR: { r |= D_DIRECTORY; break; } case DT_REG: { r |= D_FILE; break; } case DT_LNK: { r |= D_SYMLINK; break; } case 0: default: { break; } } #else { stralloc sa; struct stat st; DIR* dh = dir_INTERNAL(d)->dir_handle; stralloc_init(&sa); dir_path(d, &sa); stralloc_nul(&sa); if(lstat(sa.s, &st) != -1) { if(S_ISLNK(st.st_mode)) r |= D_SYMLINK; else if(S_ISDIR(st.st_mode)) r |= D_DIRECTORY; else if(S_ISREG(st.st_mode)) r |= D_FILE; } #ifdef DEBUG_OUTPUT buffer_puts(buffer_2, "dir_type path: "); buffer_putsa(buffer_2, &sa); buffer_putnlflush(buffer_2); #endif // printf("dh: %p __d_dirname: %s\n", dh, dh->__d_dirname); stralloc_free(&sa); } //#error No dirent type method #endif #endif return r; }
/* change working directory * ----------------------------------------------------------------------- */ int builtin_cd(int argc, char **argv) { int c; int ok = 0; int symbolic = 1; const char *arg; unsigned long len; unsigned long n; stralloc newcwd; /* check options, -L for symlink, -P for physical path */ while((c = shell_getopt(argc, argv, "LP")) > 0) { switch(c) { case 'L': symbolic = 1; break; case 'P': symbolic = 0; break; default: builtin_invopt(argv); return 1; } } arg = argv[shell_optind]; stralloc_init(&newcwd); /* empty argument means chdir(HOME) */ if(arg == NULL) { arg = var_value("HOME", &len); if(arg[0] == '\0') { sh_msg("HOME variable not set!"); return 1; } } len = str_len(arg); /* when it isn't an absolute path we have to check CDPATH */ if(arg[0] != '/') { char path[PATH_MAX + 1]; const char *cdpath; /* loop through colon-separated CDPATH variable */ cdpath = var_value("CDPATH", NULL); do { /* too much, too much :) */ if((n = str_chr(cdpath, ':')) + len + 1 > PATH_MAX) { /* set error code and print the longer string in the error msg */ errno = ENAMETOOLONG; return builtin_errmsgn(argv, (n > len ? cdpath : arg), (n > len ? n : len), strerror(errno)); } /* copy path prefix from cdpath if present */ if(n) { byte_copy(path, n, cdpath); cdpath += n; path[n++] = '/'; } /* copy the argument and canonicalize */ str_copy(&path[n], arg); ok = shell_realpath(path, &newcwd, symbolic, &sh->cwd); /* skip the colon */ if(*cdpath == ':') cdpath++; } while(*cdpath && !ok); } /* absolute path */ else { /* last cdpath length set to 0, because we're not using cdpath here */ n = 0; ok = shell_canonicalize(arg, &newcwd, symbolic); } stralloc_nul(&newcwd); /* try to chdir() if everything's ok */ if(ok && chdir(newcwd.s) == 0) { /* print path if prefix was taken from cdpath */ if(n) { buffer_putsa(fd_out->w, &newcwd); buffer_putnlflush(fd_out->w); } /* set the path */ stralloc_move(&sh->cwd, &newcwd); /* if the path has symlinks then set sh->cwdsym */ sh->cwdsym = (ok > 1); return 0; } /* we failed */ builtin_error(argv, newcwd.s); stralloc_free(&newcwd); return 1; }
/* sets or displays current hostname * ----------------------------------------------------------------------- */ int builtin_hostname(int argc, char **argv) { int c; int force = 0; /* check options */ while((c = shell_getopt(argc, argv, "f")) > 0) { switch(c) { case 'f': force = 1; break; default: builtin_invopt(argv); return 1; } } /* if there is an argument we set it as new hostname */ if(argv[shell_optind]) { unsigned long n; n = str_len(argv[shell_optind]); /* unless force is set and if the new hostname is the same as the current then do not update it */ if(!force && n == sh_hostname.len && !byte_diff(sh_hostname.s, n, argv[shell_optind])) return 0; #ifdef HAVE_SETHOSTNAME /* set the supplied hostname */ #if !defined(__CYGWIN__) && !defined(__MINGW32__) if(sethostname(argv[shell_optind], n)) #else errno = ENOSYS; #endif { /* report any error */ builtin_error(argv, "sethostname"); return 1; } #endif /* on success update internal hostname */ stralloc_copyb(&sh_hostname, argv[shell_optind], n); } /* if there is no argument we display the current hostname */ else { /* force re-get of hostname by clearing it now */ if(force) stralloc_zero(&sh_hostname); /* get hostname if it isn't there */ if(sh_hostname.len == 0) shell_gethostname(&sh_hostname); /* report errors */ if(sh_hostname.len == 0) { builtin_error(argv, "gethostname"); return 1; } /* finally output the hostname */ buffer_putsa(fd_out->w, &sh_hostname); buffer_putnlflush(fd_out->w); } return 0; }