char * ipr_file_set_path ( char * filename, // Filename to process char * path // Desired path ) { icl_shortstr_t formatted; // assert (filename); assert (path); ipr_file_strip_path (filename); icl_shortstr_cpy (formatted, path); # if (defined (__WINDOWS__)) if (strlast (path) != '/' && strlast (path) != '\\') # else if (strlast (path) != '/') # endif icl_shortstr_cat (formatted, "/"); icl_shortstr_cat (formatted, filename); icl_shortstr_cpy (filename, formatted); return (filename); }
static void read_msg (int msgid) { static int lastid = 32767; /* Last message we read */ if (msgfile == NULL) { snprintf (msgline, sizeof (msgline), "** Message %d not found - file not open **\n", msgid); return; /* Message not found in file */ } if (msgid == -1) /* Get next ignoring numbers? */ { if (!file_read (msgfile, msgline)) strncpy (msgline, "0000 .", sizeof (msgline)); /* "." signals */ /* end of file */ } else { if (msgid <= lastid) /* If necessary, back to start */ rewind (msgfile); for (;;) { if (!file_read (msgfile, msgline)) { snprintf (msgline, sizeof (msgline), "0000 ** Message %d not found **\n", msgid); break; /* Message not found in file */ } if ((isdigit (*msgline)) && (atoi (msgline) == msgid)) { lastid = msgid; break; } } } /* Remove first four digits of message */ memmove (msgline, msgline + 4, strlen (msgline) - 3); /* Remove leading space, if any */ if (msgline [0]) memmove (msgline, msgline + 1, strlen (msgline)); /* Append system message if reqd */ if (*msgline && strlast (msgline) == '$') { strlast (msgline) = 0; strcat (msgline, ": "); strcat (msgline, strerror (errno)); } /* Kill newline at end of line */ if (*msgline && strlast (msgline) == '\n') strlast (msgline) = 0; }
EXC_TYPE CMsgFilesRelay::StartMsgRetrieval (const UINT32 /* ulMsgNo */) { EXC_TYPE exc=Reset(TRUE); // delete any previously open file TCHAR szFilePath[MAX_PATH+2]=_T(""); UINT uid=GetTempFileName((IsEmptyStr(m_lpszFilesDir) ? _T(".") : m_lpszFilesDir), (IsEmptyStr(m_lpszFilesPrefix) ? _T("p3r") : m_lpszFilesPrefix), 0, szFilePath); if (0 == uid) return EPATHNAMESYNTAX; if (!IsEmptyStr(m_lpszFilesSuffix)) { exc = _tremove(szFilePath); LPTSTR lpszSuffix=_tcsrchr(szFilePath, _T('.')); if (NULL == lpszSuffix) { lpszSuffix = strlast(szFilePath); lpszSuffix = strladdch(lpszSuffix, _T('.')); } if (_T('.') == *m_lpszFilesSuffix) _tcscpy(lpszSuffix, m_lpszFilesSuffix); else _tcscpy((lpszSuffix+1), m_lpszFilesSuffix); } if ((exc=strupdatebuf(szFilePath, m_lpszFilePath)) != EOK) return exc; if (NULL == (m_fp=_tfopen(m_lpszFilePath, _T("wb")))) return EFNEXIST; return EOK; }
Bool ipr_file_is_writeable ( char * filename // File to examine ) { Bool rc = 0; // Not documented // assert (filename); if (ipr_file_is_directory (filename)) rc = ((s_file_mode (filename) & S_IWRITE) != 0); else if (strlast (filename) == '/') rc = FALSE; else rc = ((s_file_mode (filename) & S_IWRITE) != 0); return (rc); }
char *SourcePath() { int i; char *RetS; char *Env = Environment(); do Env++; while ((Env[-1] != 0) || (Env[0] != 0)); do Env++; while (Env[0] != 0); Env++; RetS = Env + strlen(Env); while ((RetS > Env) && (strlast(RetS[-1], PATHSEP) < 0)) RetS--; i = RetS - Env; RetS = malloc(i + 1); if (RetS) { strncpy(RetS, Env, i); RetS[i] = 0; } return RetS; }
/* * Main */ int main(int argc, char *argv[]) { struct stat file; state st; char self[64]; char selector[BUFSIZE]; char buf[BUFSIZE]; char *dest; char *c; #ifdef HAVE_SHMEM struct shmid_ds shm_ds; shm_state *shm; int shmid; #endif /* Get the name of this binary */ if ((c = strrchr(argv[0], '/'))) sstrlcpy(self, c + 1); else sstrlcpy(self, argv[0]); /* Initialize state */ #ifdef HAVE_LOCALES setlocale(LC_TIME, DATE_LOCALE); #endif init_state(&st); srand(time(NULL) / (getpid() + getppid())); /* Handle command line arguments */ parse_args(&st, argc, argv); /* Open syslog() */ if (st.opt_syslog) openlog(self, LOG_PID, LOG_DAEMON); /* Make sure the computer is turned on */ #ifdef __HAIKU__ if (is_computer_on() != TRUE) die(&st, ERR_ACCESS, "Please turn on the computer first"); #endif /* Refuse to run as root */ #ifdef HAVE_PASSWD if (st.opt_root && getuid() == 0) die(&st, ERR_ACCESS, "Refusing to run as root"); #endif /* Try to get shared memory */ #ifdef HAVE_SHMEM if ((shmid = shmget(SHM_KEY, sizeof(shm_state), IPC_CREAT | SHM_MODE)) == ERROR) { /* Getting memory failed -> delete the old allocation */ shmctl(shmid, IPC_RMID, &shm_ds); shm = NULL; } else { /* Map shared memory */ if ((shm = (shm_state *) shmat(shmid, (void *) 0, 0)) == (void *) ERROR) shm = NULL; /* Initialize mapped shared memory */ if (shm && shm->start_time == 0) { shm->start_time = time(NULL); /* Keep server platform & description in shm */ platform(&st); sstrlcpy(shm->server_platform, st.server_platform); sstrlcpy(shm->server_description, st.server_description); } } /* For debugging shared memory issues */ if (!st.opt_shm) shm = NULL; /* Get server platform and description */ if (shm) { sstrlcpy(st.server_platform, shm->server_platform); if (!*st.server_description) sstrlcpy(st.server_description, shm->server_description); } else #endif platform(&st); /* Read selector */ if (fgets(selector, sizeof(selector) - 1, stdin) == NULL) selector[0] = '\0'; /* Remove trailing CRLF */ chomp(selector); if (st.debug) syslog(LOG_INFO, "client sent us \"%s\"", selector); /* Handle hURL: redirect page */ if (sstrncmp(selector, "URL:") == MATCH) { st.req_filetype = TYPE_HTML; sstrlcpy(st.req_selector, selector); url_redirect(&st); return OK; } /* Handle gopher+ root requests (UMN gopher client is seriously borken) */ if (sstrncmp(selector, "\t$") == MATCH) { printf("+-1" CRLF); printf("+INFO: 1Main menu\t\t%s\t%i" CRLF, st.server_host, st.server_port); printf("+VIEWS:" CRLF " application/gopher+-menu: <512b>" CRLF); printf("." CRLF); if (st.debug) syslog(LOG_INFO, "got a request for gopher+ root menu"); return OK; } /* Convert HTTP request to gopher (respond using headerless HTTP/0.9) */ if (sstrncmp(selector, "GET ") == MATCH || sstrncmp(selector, "POST ") == MATCH ) { if ((c = strchr(selector, ' '))) sstrlcpy(selector, c + 1); if ((c = strchr(selector, ' '))) *c = '\0'; st.req_protocol = PROTO_HTTP; if (st.debug) syslog(LOG_INFO, "got HTTP request for \"%s\"", selector); } /* Save default server_host & fetch session data (including new server_host) */ sstrlcpy(st.server_host_default, st.server_host); #ifdef HAVE_SHMEM if (shm) get_shm_session(&st, shm); #endif /* Loop through the selector, fix it & separate query_string */ dest = st.req_selector; if (selector[0] != '/') *dest++ = '/'; for (c = selector; *c;) { /* Skip duplicate slashes and /./ */ while (*c == '/' && *(c + 1) == '/') c++; if (*c == '/' && *(c + 1) == '.' && *(c + 2) == '/') c += 2; /* Start of a query string (either type 7 or HTTP-style)? */ if (*c == '\t' || (st.opt_query && *c == '?')) { sstrlcpy(st.req_query_string, c + 1); if ((c = strchr(st.req_query_string, '\t'))) *c = '\0'; break; } /* Start of virtual host hint? */ if (*c == ';') { if (st.opt_vhost) sstrlcpy(st.server_host, c + 1); /* Skip vhost on selector */ while (*c && *c != '\t') c++; continue; } /* Copy valid char */ *dest++ = *c++; } *dest = '\0'; /* Remove encodings from selector */ strndecode(st.req_selector, st.req_selector, sizeof(st.req_selector)); /* Deny requests for Slashdot and /../ hackers */ if (strstr(st.req_selector, "/.")) die(&st, ERR_ACCESS, "Refusing to serve out dotfiles"); /* Handle /server-status requests */ #ifdef HAVE_SHMEM if (sstrncmp(st.req_selector, SERVER_STATUS) == MATCH) { if (shm) server_status(&st, shm, shmid); return OK; } #endif /* Remove possible extra cruft from server_host */ if ((c = strchr(st.server_host, '\t'))) *c = '\0'; /* Guess request filetype so we can die() with style... */ st.req_filetype = gopher_filetype(&st, st.req_selector, FALSE); /* Convert seletor to path & stat() */ selector_to_path(&st); if (st.debug) syslog(LOG_INFO, "path to resource is \"%s\"", st.req_realpath); if (stat(st.req_realpath, &file) == ERROR) { /* Handle virtual /caps.txt requests */ if (st.opt_caps && sstrncmp(st.req_selector, CAPS_TXT) == MATCH) { #ifdef HAVE_SHMEM caps_txt(&st, shm); #else caps_txt(&st, NULL); #endif return OK; } /* Requested file not found - die() */ die(&st, ERR_NOTFOUND, NULL); } /* Fetch request filesize from stat() */ st.req_filesize = file.st_size; /* Everyone must have read access but no write access */ if ((file.st_mode & S_IROTH) == 0) die(&st, ERR_ACCESS, "File or directory not world-readable"); if ((file.st_mode & S_IWOTH) != 0) die(&st, ERR_ACCESS, "File or directory world-writeable"); /* If stat said it was a dir then it's a menu */ if ((file.st_mode & S_IFMT) == S_IFDIR) st.req_filetype = TYPE_MENU; /* Not a dir - let's guess the filetype again... */ else if ((file.st_mode & S_IFMT) == S_IFREG) st.req_filetype = gopher_filetype(&st, st.req_realpath, st.opt_magic); /* Menu selectors must end with a slash */ if (st.req_filetype == TYPE_MENU && strlast(st.req_selector) != '/') sstrlcat(st.req_selector, "/"); /* Change directory to wherever the resource was */ sstrlcpy(buf, st.req_realpath); if ((file.st_mode & S_IFMT) != S_IFDIR) c = dirname(buf); else c = buf; if (chdir(c) == ERROR) die(&st, ERR_ACCESS, NULL); /* Keep count of hits and data transfer */ #ifdef HAVE_SHMEM if (shm) { shm->hits++; shm->kbytes += st.req_filesize / 1024; /* Update user session */ update_shm_session(&st, shm); } #endif /* Log the request */ if (st.opt_syslog) { syslog(LOG_INFO, "request for \"gopher://%s:%i/%c%s\" from %s", st.server_host, st.server_port, st.req_filetype, st.req_selector, st.req_remote_addr); } /* Check file type & act accordingly */ switch (file.st_mode & S_IFMT) { case S_IFDIR: log_combined(&st, HTTP_OK); gopher_menu(&st); break; case S_IFREG: log_combined(&st, HTTP_OK); gopher_file(&st); break; default: die(&st, ERR_ACCESS, "Refusing to serve out special files"); } /* Clean exit */ return OK; }
char * conv_number_str ( const char *number, /* Number to convert */ int flags, /* Number formatting flags */ char dec_point, /* Decimal point: '.' or ',' */ int decimals, /* Number of decimals, or 0 */ int dec_format, /* How are decimals shown? */ int width, /* Output field width, or 0 */ int sign_format /* How are negatives shown? */ ) { static char formatted [FORMAT_MAX + 1], /* Formatted return string */ zero [CONV_MAX_DECS + 2]; /* Default value if needed */ int sep_stop, /* Where we put next sep_char */ dec_stop, /* Where we put decimal point */ decs_wanted = decimals, /* Number of decimals wanted */ decs_seen, /* Number of decimals output */ sign_pos, /* Where we put sign, if any */ digits; /* Number of digits read so far */ char *dest, /* Store formatted number here */ sign_char, /* Number's sign: ' ', '+', '-' */ sep_char, /* Thousands separator '.' or ',' */ drop_zero, /* We suppress this char */ ch; /* Next character in picture */ Bool have_zero; /* TRUE if whole number is zero */ ASSERT (width <= FORMAT_MAX); ASSERT (dec_point == '.' || dec_point == ','); conv_reason = 0; /* No conversion errors so far */ /* --------------------------------- Prepare to copy digits ---------*/ if (decs_wanted > CONV_MAX_DECS) { conv_reason = CONV_ERR_DECS_OVERFLOW; return (NULL); /* Error - too many decimals */ } /* If value is empty, use "0" with enough decimals as default value */ /* We allow one whole digit and as many decimals as needed. */ if (strnull (number)) { strpad (zero, '0', decs_wanted + 1); number = zero; } /* Pick-up sign character if present */ if (*number == ' ' || *number == '+' || *number == '-') sign_char = *number++; else sign_char = ' '; /* While leading zero is '0' we blank-out zeros in the number */ drop_zero = (char) (flags & FLAG_N_ZERO_FILL? ' ': '0'); /* Prepare for decimals */ if ((flags & FLAG_N_DECIMALS) == 0) decs_wanted = 0; if (strchr (number, '.')) dec_stop = (int) (strchr (number, '.') - (char *) number); else dec_stop = strlen (number) - decs_wanted; if (dec_stop < 1) { conv_reason = CONV_ERR_DECS_MISSING; return (NULL); /* Error - too few decimals */ } /* Prepare for thousands-separators if FLAG_N_THOUSANDS */ if ((flags & FLAG_N_THOUSANDS) && !(flags & FLAG_N_ZERO_FILL)) { /* Get number of whole digits, allowing for decimals & dec sign */ sep_char = (char) (dec_point == '.'? ',': '.'); sep_stop = (dec_stop - (decs_wanted? decs_wanted + 1: 0)) % 3; if (sep_stop == 0) sep_stop = 3; /* Get into range 1..3 */ } else { sep_char = ' '; sep_stop = 0; /* No thousands separators */ } /* --------------------------------- Copy the digits ----------------*/ digits = 0; /* No digits loaded yet */ decs_seen = 0; /* No decimals output yet */ have_zero = TRUE; /* Assume number is zero */ dest = formatted; /* Format number */ while (*number) /* until we hit the terminator */ { ch = *number++; if (ch == '.') continue; /* Ignore '.' in number */ digits++; if (ch == drop_zero && digits < dec_stop) ch = ' '; else if (isdigit (ch)) { drop_zero = ' '; if (ch > '0') have_zero = FALSE; } if (ch != ' ' || (width > 0 && !(flags & FLAG_N_LEFT))) { *dest++ = ch; /* Output this digit */ if (digits > dec_stop) decs_seen++; /* Count the decimal digit */ else if (digits == dec_stop) /* Handle decimal stop */ { /* with optional point */ if (flags & FLAG_N_DECIMALS) *dest++ = dec_point; sep_stop = 0; /* And kill further thousand seps */ } } /* Output thousands separator unless we are in blank area */ if (digits == sep_stop) { if (ch != ' ') *dest++ = sep_char; sep_stop += 3; } } *dest = 0; /* Terminate the string nicely */ /* --------------------------------- Post-format the result ---------*/ if (decs_wanted > 0) { /* Output trailing decimal zeroes if not supplied */ if (decs_seen == 0) *dest++ = dec_point; while (decs_seen < decs_wanted) { *dest++ = '0'; decs_seen++; } /* Drop all decimals if format is DEC_HIDE_ALL */ if (dec_format == DECS_HIDE_ALL) while (*dest != dec_point) dest--; /* Drop-off trailing zero */ else /* Drop trailing decimal zeroes if format is DEC_DROP_ZEROS */ if (dec_format == DECS_DROP_ZEROS) while (*dest != dec_point) { if (*(dest - 1) > '0') break; else dest--; /* Drop-off trailing zero */ } *dest = 0; /* Terminate the string nicely */ } /* Justify within width if width > 0 */ sign_pos = 0; /* Sign normally comes at start */ digits = strlen (formatted); if (flags & FLAG_N_SIGNED) { digits++; /* Allow for eventual sign */ if (sign_format == SIGN_FINANCIAL) digits++; /* Sign shown like (123) */ } while (digits < width) { if (flags & FLAG_N_LEFT && !(flags & FLAG_N_ZERO_FILL)) strcat (formatted, " "); else { stropen (formatted, FALSE); /* Insert blank at start of string */ if (flags & FLAG_N_ZERO_FILL) formatted [0] = '0'; else sign_pos++; /* Skip leading space */ } digits++; } /* Format sign if FLAG_N_SIGNED */ if (flags & FLAG_N_SIGNED) { if (sign_format == SIGN_NEG_LEAD || sign_format == SIGN_ALL_LEAD || sign_format == SIGN_FINANCIAL) stropen (formatted, FALSE); if (sign_format == SIGN_NEG_TRAIL || sign_format == SIGN_ALL_TRAIL || sign_format == SIGN_FINANCIAL) strcat (formatted, " "); if (!have_zero) /* Zero has no sign */ switch (sign_format) { case SIGN_NEG_LEAD: if (sign_char != '-') break; /* Fall through if negative sign */ case SIGN_ALL_LEAD: formatted [sign_pos] = sign_char; break; case SIGN_NEG_TRAIL: if (sign_char != '-') break; /* Fall through if negative sign */ case SIGN_ALL_TRAIL: strlast (formatted) = sign_char; break; case SIGN_FINANCIAL: if (sign_char == '-') { formatted [0] = '('; strlast (formatted) = ')'; } break; } } /* If all zeroes, return a blank string if FLAG_N_ZERO_BLANK */ if ((flags & FLAG_N_ZERO_BLANK) && have_zero) { memset (formatted, ' ', width); formatted [width] = 0; } if (width > 0 && (strlen (formatted) > (size_t) width)) { conv_reason = CONV_ERR_NUM_OVERFLOW; return (NULL); /* Overflow -- number too large */ } else return (formatted); }
int CFilesIconsAssoc::GetSuffixIconIndex (LPCTSTR lpszFilePath) { if (IsEmptyStr(lpszFilePath)) return m_nDefTypeIcon; LPCTSTR lpszSuffix=strlast(lpszFilePath); for ( ; lpszSuffix > lpszFilePath; lpszSuffix--) if (_T('.') == *lpszSuffix) break; // if no suffix found use default icon if (_T('.') != *lpszSuffix) return m_nDefTypeIcon; int nIdx=(-1); // handle special case for executables if (0 == _tcsicmp(lpszSuffix, _T(".exe"))) { if (m_iconsMap.Lookup(lpszFilePath, nIdx)) return nIdx; HICON hSmallIcon=NULL, hLargeIcon=NULL; UINT uINum=ExtractIconEx(lpszFilePath, 0, &hLargeIcon, &hSmallIcon, 1); if (0 == uINum) hLargeIcon = NULL; if (hSmallIcon != NULL) VERIFY(DestroyIcon(hSmallIcon)); if (hLargeIcon != NULL) { nIdx = m_imgList.Add(hLargeIcon); if ((-1) != nIdx) { // remember association for next time m_iconsMap.SetAt(lpszFilePath, nIdx); return nIdx; } } } if (m_iconsMap.Lookup(lpszSuffix, nIdx)) return nIdx; // find out associated icon image (if any) SHFILEINFO sfi; ZeroMemory(&sfi,sizeof(sfi)); DWORD dwRes=SHGetFileInfo(lpszSuffix, FILE_ATTRIBUTE_NORMAL, &sfi, (sizeof sfi), SHGFI_USEFILEATTRIBUTES|SHGFI_ICON); // sfi.hIcon contains the large icon for the file. if (NULL == sfi.hIcon) return m_nDefTypeIcon; nIdx = m_imgList.Add(sfi.hIcon); if ((-1) == nIdx) return m_nDefTypeIcon; // remember association for next time m_iconsMap.SetAt(lpszSuffix, nIdx); return nIdx; }
/* * Return gopher filetype for a file */ char gopher_filetype(state *st, char *file, char magic) { FILE *fp; char buf[BUFSIZE]; char *c; int i; /* If it ends with an slash it's a menu */ if (!*file) return st->default_filetype; if (strlast(file) == '/') return TYPE_MENU; /* Get file suffix */ if ((c = strrchr(file, '.'))) { c++; /* Loop through the filetype array looking for a match*/ for (i = 0; i < st->filetype_count; i++) if (strcasecmp(st->filetype[i].suffix, c) == MATCH) return st->filetype[i].type; } /* Are we allowed to look inside files? */ if (!magic) return st->default_filetype; /* Read data from the file */ if ((fp = fopen(file , "r")) == NULL) return st->default_filetype; i = fread(buf, 1, sizeof(buf) - 1, fp); buf[i] = '\0'; fclose(fp); /* GIF images */ if (sstrncmp(buf, "GIF89a") == MATCH || sstrncmp(buf, "GIF87a") == MATCH) return TYPE_GIF; /* JPEG images */ if (sstrncmp(buf, "\377\330\377\340") == MATCH) return TYPE_IMAGE; /* PNG images */ if (sstrncmp(buf, "\211PNG") == MATCH) return TYPE_IMAGE; /* mbox */ if (strstr(buf, "\nFrom: ") && strstr(buf, "\nSubject: ")) return TYPE_MIME; /* MIME */ if (strstr(buf, "\nContent-Type: ")) return TYPE_MIME; /* HTML files */ if (buf[0] == '<' && (strstr(buf, "<html") || strstr(buf, "<HTML"))) return TYPE_HTML; /* PDF and PostScript */ if (sstrncmp(buf, "%PDF-") == MATCH || sstrncmp(buf, "%!") == MATCH) return TYPE_DOC; /* compress and gzip */ if (sstrncmp(buf, "\037\235\220") == MATCH || sstrncmp(buf, "\037\213\010") == MATCH) return TYPE_GZIP; /* Unknown content - binary or text? */ if (memchr(buf, '\0', i)) return TYPE_BINARY; return st->default_filetype; }
SYMTAB * ini_dyn_load ( SYMTAB *load_symtab, const char *filename) { FILE *inifile; SYMTAB *symtab, /* Symbol table to populate */ *envtab; /* Environment, as symbol table */ char *section = NULL, /* Filled as we scan through */ *keyword = NULL, /* the ini file */ *value = NULL, *fromptr, *toptr, *section_end; /* Null byte at end of section */ ASSERT (filename); inifile = file_locate ("PATH", filename, NULL); if (load_symtab) /* Use specified symbol table */ symtab = load_symtab; /* or create a new one */ else { symtab = sym_create_table (); if (symtab == NULL) return (NULL); /* Quit if insufficient memory */ } /* Store control variables in symbol table */ if (inifile || load_symtab == NULL) { sym_assume_symbol (symtab, "filename", filename); snprintf (iniline, sizeof (iniline), "%ld", timer_to_date (get_file_time (filename))); sym_assume_symbol (symtab, "filedate", iniline); snprintf (iniline, sizeof (iniline), "%ld", timer_to_time (get_file_time (filename))); sym_assume_symbol (symtab, "filetime", iniline); } if (!inifile) return (symtab); /* File not found; empty table */ /* Now load the ini file, starting from the beginning */ envtab = env2symb (); fseek (inifile, 0, SEEK_SET); FOREVER { if (ini_scan_section (inifile, &keyword, &value)) { if (section) { section_end = strchr (section, '\0'); ASSERT (section_end); xstrcat (section, ":", keyword, NULL); value = tok_subst (value, envtab); /* Handle value in quotes */ if (*value == '"') { /* Unescape value if necessary */ if (strchr (value, '\\')) { toptr = value; for (fromptr = value; *fromptr; fromptr++) { if (*fromptr == '\\') { fromptr++; if (*fromptr == 'n') *toptr++ = '\n'; else *toptr++ = *fromptr; } else *toptr++ = *fromptr; } *toptr = '\0'; } strlast (value) = '\0'; sym_assume_symbol (symtab, section, value + 1); } else sym_assume_symbol (symtab, section, value); mem_strfree (&value); *section_end = '\0'; } } else if (keyword) /* Found new section */ { section = keyword; sym_assume_symbol (symtab, section, ""); } else break; } file_close (inifile); sym_delete_table (envtab); sym_sort_table (symtab, NULL); /* Sort table by symbol name */ return (symtab); }
Bool ini_scan_section ( FILE *inifile, char **keyword, char **value) { int remaining; /* Space remaining in line buffer */ char *first, *valueptr, *lineptr; /* Read through file until we find what we are looking for */ while (file_read (inifile, iniline)) { strcrop (iniline); if (strnull (iniline)) continue; /* Skip empty lines */ /* Calculate space remaining in buffer after this line; we need to * know this later if we start reading continuation lines. */ remaining = LINE_MAX - strlen (iniline); first = strskp (iniline); /* Skip leading spaces */ if (*first == ';' || *first == '#' || *first == 0) continue; /* Comment line */ else if (*first == '!') { first = strskp (first + 1); trace (first); } else /* Have name = value */ if (sscanf (first, "[%[^]]", ini_section) == 1) { *keyword = strlwc (ini_section); *value = NULL; return (FALSE); /* New section name */ } else if (streq (first, "[]")) { /* Allow empty section names */ strcpy (ini_section, ""); *keyword = ini_section; *value = NULL; return (FALSE); /* New section name */ } else { if (*first == '"') { /* Name in quotes */ valueptr = strchr (first + 1, '"'); if (valueptr) { first++; *valueptr = ' '; valueptr = strchr (valueptr + 1, '='); } } else valueptr = strchr (first, '='); if (valueptr == NULL) { coprintf ("E: illegal definition in ini file"); return (FALSE); } *valueptr++ = '\0'; strcpy (ini_keyword, strcrop (strlwc (first))); while (*valueptr == ' ') valueptr++; /* and leading spaces */ if (*valueptr == '"') { /* Have value in quotes */ /* Get continuation lines as necessary and possible */ first = &strlast (valueptr); while (*first == '-' && remaining > 0) { if (!file_readn (inifile, first, remaining)) break; /* Abrubt end of file */ strcrop (first); remaining -= strlen (first) - 1; first += strlen (first) - 1; } /* Now find closing quote and terminate value there */ for (lineptr = valueptr + 1; *lineptr; lineptr++) { if (*lineptr == '\\') lineptr++; /* Ignore next char */ else if (*lineptr == '"') { lineptr [1] = '\0'; break; /* Closing quote, end of value */ } } } else { /* Have unquoted value */ strconvch (valueptr, ';', '\0'); strconvch (valueptr, '#', '\0'); } strcrop (valueptr); strcpy (ini_value, valueptr); *keyword = ini_keyword; *value = ini_value; return (TRUE); /* Found keyword = value */ } } *keyword = NULL; return (FALSE); /* End of file */ }